CMI
primedocs integriert sich auf mehrere Arten mit CMI. Welche Variante passt, hängt davon ab, wo der Dokumenterstellungsprozess startet und welche Clients im Einsatz sind:
| Variante | Prozessstart | Bausteine |
|---|---|---|
| A: Connect (Desktop zu Desktop) | CMI Desktop | Connect über Konsolenaufruf |
| B: Web zu Web | CMI Web | Connect Session Template |
| C: CMI als Datenquelle und Ablageziel | primedocs | HttpDataProvider (Select) und Output Management |
Die URLs in den Beispielen (cmi.example.com) sind Platzhalter. Die effektiven Hosts und Pfade (inkl. Mandant) sind installationsspezifisch und werden durch CMI bereitgestellt. Die Beispiele zeigen die Key-Elemente der Konfiguration. Schemas, Felder und Mappings sind auf den konkreten Anwendungsfall anzupassen.
Voraussetzungen für die Varianten B und C
Die CMI-REST-Schnittstellen erfordern eine OAuth-2.0-Authentifizierung. Beides wird im DataSource-Admin vorbereitet:
- Connected Service für CMI: Unter Settings → Connected Services einen Connected Service anlegen (in den Beispielen mit dem Key
CMI). Alle Konfigurationen referenzieren ihn überConnectedServiceKeyund setzen das Zugriffstoken über den Platzhalter{__ConnectedService.AccessToken__}ein (typischerweise imAuthorization-Header). - URL-Freigabe für
InvokeUrl: Die CMI-Ziel-URLs, an die hochgeladen bzw. abgelegt wird (Varianten B und C), unter Settings → Connect Settings → InvokeUrl - Configuration freigeben. Ohne diese Freigabe wird derInvokeUrl-Aufruf blockiert.
Variante A: Connect (Desktop zu Desktop)
Im reinen Desktop-Umfeld ruft CMI Desktop den primedocs Desktop Client automatisch im Hintergrund auf und übergibt dabei eine Connect-Datei mit den Daten des Geschäfts (z.B. Empfänger, Betreff, Referenzen). Aus Sicht des Benutzers ist das ein Vorgang in CMI, ohne manuellen Zwischenschritt.
Technisch setzt CMI dazu den Konsolenaufruf des primedocs-Clients ab (kein Aufruf von Hand):
.\primedocs.exe /connect "C:\Temp\Geschaeft-1234.pdcx"
primedocs erstellt daraus das Dokument. Die Ablage in CMI übernimmt anschliessend CMI selbst. Details zum Aufrufmechanismus (Dateiendungen, Protokollhandler, Abruf des Connect-XML von einer URL): Dokumentgenerierung starten.
Variante B: Web zu Web (Connect Session Template)
CMI Web bettet primedocs web ein (iframe oder neuer Tab) und startet über die URL eines Connect Session Templates eine vorinitialisierte Dokumenterstellung:
https://{instanz}/app/web/session/template/cmi?saveLocationCmiTenant={tenant}&saveLocationCmiToken={token}&document={dokument-guid}
Die Parameternamen sind frei wählbar. Sie müssen nur mit dem übereinstimmen, was das Session Template über $.parameter(…) konsumiert. In diesem Beispiel übergibt CMI:
| Parameter | Zweck |
|---|---|
saveLocationCmiTenant | CMI-Mandant für die spätere Ablage. |
saveLocationCmiToken | Token des CMI-Dokuments, unter dem das Ergebnis abgelegt wird. |
document | GUID des CMI-Dokuments, die dem Initializer zum Laden der Geschäftsdaten dient. |
Der Ablauf:
- Die Initializers laden beim Start der Session Daten aus CMI (
HttpDataProvider→ CMI-ContentProvider-API) und übernehmen die Ablage-Parameter (CodeDataProvider). - Der Benutzer wählt die Vorlage, füllt das Formular aus und generiert das Dokument.
- Die
OnSuccess-Commands laden das Dokument zu CMI hoch (InvokeUrl), bestätigen die Ablage (ShowDialog) und melden den Abschluss an das einbettende CMI (BrowserParentPostMessage), damit CMI den Prozess fortsetzen kann.
Connect Session Template
<ConnectSessionTemplatesConfiguration>
<ConnectSessionTemplate Name="cmi">
<Initializers>
<!-- Lädt Daten des CMI-Dokuments über die ContentProvider-API -->
<HttpDataProvider ConnectedServiceKey="CMI">
<Configuration>
<Step>
<Request Method="POST">
<Url><![CDATA[https://cmi.example.com/{tenant}/v2/ContentProvider]]></Url>
<Header Name="Authorization" Value="Bearer {__ConnectedService.AccessToken__}" />
<Header Name="Content-Type" Value="application/json" />
<BodyBuilder><![CDATA[
function main() {
return JSON.stringify({
dokumentGuid: $.parameter("document"),
contentProviderKeys: [ "Kontakte" ]
});
}
]]></BodyBuilder>
</Request>
<Response>
<Data JsonPath="$.Kontakte[*]">
<Code>
function main() {
return {
Forms: {
Kontakte: {
"Key": source("name"),
"Name": source("displayName")
}
}
};
}
</Code>
</Data>
</Response>
</Step>
</Configuration>
</HttpDataProvider>
<!-- Übernimmt den CMI-Ablageort aus den URL-Parametern -->
<CodeDataProvider>
<Code><![CDATA[
function main() {
return {
Data: {
"CmiTenant": $.parameter("saveLocationCmiTenant"),
"CmiToken": $.parameter("saveLocationCmiToken")
}
};
}
]]></Code>
</CodeDataProvider>
</Initializers>
<Commands>
<OnSuccess>
<!-- Lädt das generierte Dokument zu CMI hoch -->
<InvokeUrl ConnectedServiceKey="CMI">
<Step>
<MultipartFormDataRequest>
<Url field-Content="Fields.UploadUrl" />
<Header Name="Authorization" Value="Bearer {__ConnectedService.AccessToken__}" />
<Header Name="Accept" Value="application/json" />
<File Name="file" field-FileName="Fields.FileName">
<Document />
</File>
</MultipartFormDataRequest>
</Step>
</InvokeUrl>
<ShowDialog Title="CMI" Message="Das Dokument wurde erfolgreich in CMI abgelegt." />
<!-- Informiert das einbettende CMI über den Abschluss -->
<BrowserParentPostMessage TargetOrigin="https://cmi.example.com">
<Code><![CDATA[
function main() {
return {
type: "template-chooser-document-uploaded",
name: $("Fields.FileName")
};
}
]]></Code>
</BrowserParentPostMessage>
</OnSuccess>
</Commands>
</ConnectSessionTemplate>
</ConnectSessionTemplatesConfiguration>
Die verfügbaren contentProviderKeys und die Feldstruktur der Antwort definiert CMI. Die Transformation in die Forms-Struktur erfolgt im Code-Element über source(…).
Zugehörige Dokumentfunktionen der Vorlage
Data nimmt die Ablage-Parameter auf, Fields baut daraus die Upload-URL, Forms definiert die Zielstruktur für die geladenen CMI-Daten:
<DataConfiguration>
<Schema>
<Text Id="CmiTenant" />
<Text Id="CmiToken" />
</Schema>
</DataConfiguration>
<FieldsConfiguration>
<Fields>
<Text Name="UploadUrl">
<Code><![CDATA[
function main() {
return "https://cmi.example.com/" + $("Data.CmiTenant") + "/v1/Template/" + $("Data.CmiToken");
}
]]></Code>
</Text>
<Text Name="FileName" Value="Dokument.docx" />
</Fields>
</FieldsConfiguration>
<FormsConfiguration>
<Elements>
<ObjectCollection Id="Kontakte" Label="Kontakt" SelectedObjectId="Kontakt">
<Schema>
<Text Id="Key" Label="Key" />
<Text Id="Name" Label="Name" />
</Schema>
</ObjectCollection>
</Elements>
</FormsConfiguration>
Durch SelectedObjectId steht die Auswahl des Benutzers den Feldern und Platzhaltern als Forms.Kontakt zur Verfügung (z.B. $("Forms.Kontakt").Name), siehe Forms.
Word-Content-Controls mit dem Namensschema CMI_[FELDNAME] sowie Bookmarks werden von CMI bei der Weiterverarbeitung des Dokuments automatisch befüllt. So lassen sich CMI-Metadaten ergänzen, ohne dass primedocs die Daten liefern muss.
Bis primedocs 4.0 wurde die CMI-Web-Integration über das <cmi>-Element in der primedocs.config und die feste URL /app/web/cmi konfiguriert. Der Connect-Session-Template-Ansatz löst diese Konfiguration ab: Datenbezug, Upload-Endpunkt, Authentifizierung (Connected Service statt Client-Secret in der Konfigurationsdatei) und das Verhalten nach der Generierung sind frei konfigurierbar.
Variante C: CMI als Datenquelle und Ablageziel
Diese Variante ist interessant, wenn das Dokument nicht aus CMI heraus erstellt wird (etwa direkt in primedocs web oder im Office), aber trotzdem Daten eines CMI-Geschäfts einfliessen sollen und/oder das Ergebnis nach CMI zurückgeschrieben werden soll. Die beiden Bausteine sind unabhängig voneinander einsetzbar.
Geschäft aus CMI laden (Select)
Ein Object in der Forms-Konfiguration erhält einen HttpDataProvider, der die CMI-Such-API aufruft. Der Benutzer sucht das Geschäft im Formular. Die Werte stehen der Vorlage anschliessend als Forms.Geschaeft.* zur Verfügung.
<FormsConfiguration>
<Elements>
<Text Id="FileName" Label="Dokumentname" Value="primedocs Dokument" />
<Object Id="Geschaeft" Label="CMI-Geschäft">
<Schema>
<Text Id="Id" Label="Id" />
<Text Id="Titel" Label="Titel" />
<Text Id="Typ" Label="Typ" />
<Text Id="Status" Label="Status" />
<Text Id="Nummer" Label="Nummer" />
<Text Id="Beginn" Label="Beginn" />
</Schema>
<Summary>
<Field Id="Nummer" />
<Field Id="Titel" />
</Summary>
<DataProviders>
<HttpDataProvider DisplayName="CMI" ConnectedServiceKey="CMI">
<SearchParameters>
<Text Id="Term" Label="Suchbegriff" Required="true" />
</SearchParameters>
<Configuration>
<Step>
<Request Method="GET">
<UrlBuilder><![CDATA[
function main() {
const baseUrl = "https://cmi.example.com/api";
return baseUrl + "/AbstraktesGeschaeft/Search/FULLTEXT[" + $("Term") + "]";
}
]]></UrlBuilder>
<Header Name="Authorization" Value="Bearer {__ConnectedService.AccessToken__}" />
</Request>
<Response>
<Data JsonPath="$[*]">
<Mapping>
<Map Source="guid" Target="Id" />
<Map Source="typeName" Target="Typ" />
<Map Source="titel" Target="Titel" />
<Map Source="lifecycleStatus" Target="Status" />
<Map Source="laufnummer" Target="Nummer" />
<Map Source="beginn" Target="Beginn" />
</Mapping>
</Data>
</Response>
</Step>
</Configuration>
</HttpDataProvider>
</DataProviders>
</Object>
</Elements>
</FormsConfiguration>
Dokument nach CMI schreiben (Output Management)
Ein DesktopOutput im Output Management legt das Dokument zweistufig über die CMI-API ab: Zuerst wird das Dokument-Objekt im Geschäft angelegt, dann die generierte Datei als PDF eingecheckt.
Die Fields-Konfiguration liefert den Dateinamen und den Request-Body:
<FieldsConfiguration>
<Fields>
<Text Name="FileName">
<Code><![CDATA[
function main() {
let fileName = $("Forms.FileName");
if (fileName == null) {
fileName = "Dokument";
}
if (!fileName.toLowerCase().endsWith(".pdf")) {
fileName += ".pdf";
}
return fileName;
}
]]></Code>
</Text>
<Text Name="CreateDocumentBody">
<Code><![CDATA[
function main() {
if ($("Forms.Geschaeft") == null) {
return "";
}
return JSON.stringify({
titel: $("Forms.FileName"),
version: 0,
bemerkung: "Via primedocs generiert",
geschaeft: {
guid: $("Forms.Geschaeft").Id
}
});
}
]]></Code>
</Text>
</Fields>
</FieldsConfiguration>
Der Output führt die beiden Schritte über einen InvokeUrl-Command aus:
<OutputConfiguration>
<DesktopOutput Name="In CMI ablegen">
<Commands>
<InvokeUrl ConnectedServiceKey="CMI">
<!-- Schritt 1: Dokument-Objekt im CMI-Geschäft anlegen -->
<Step>
<Request Method="POST">
<Url>https://cmi.example.com/api/Dokument</Url>
<Header Name="Authorization" Value="Bearer {__ConnectedService.AccessToken__}" />
<Header Name="Content-Type" Value="application/json" />
<Body field-Content="Fields.CreateDocumentBody" />
</Request>
<Response>
<Property Name="DokumentGuid" JsonPath="$" />
</Response>
</Step>
<!-- Schritt 2: Generierte Datei als PDF einchecken -->
<Step>
<MultipartFormDataRequest>
<Url>https://cmi.example.com/api/Dokument/CheckIn/{DokumentGuid}</Url>
<Header Name="Authorization" Value="Bearer {__ConnectedService.AccessToken__}" />
<Header Name="Accept" Value="application/json" />
<File Name="file" field-FileName="Fields.FileName" ContentType="application/pdf">
<Document Conversion="Pdf" />
</File>
</MultipartFormDataRequest>
</Step>
</InvokeUrl>
</Commands>
</DesktopOutput>
</OutputConfiguration>
Für primedocs web und die Office Web Add-Ins lässt sich dieselbe Ablage als WebOutput konfigurieren, denn InvokeUrl gehört zu den web-fähigen Commands (siehe Output Management).
Verwandte Themen
- Connect Session Templates: benannte, vorinitialisierte Connect-Sessions
- Connected Services: Authentifizierung gegen externe Dienste im Namen des Benutzers
- HttpDataProvider: Datenbezug aus HTTP-/REST-APIs (Select)
- Output Management: Übermittlung des Dokuments an Endpunkte
- Connect Commands:
InvokeUrl,ShowDialog,BrowserParentPostMessage - Dokumentgenerierung starten: Konsolenaufruf und Protokollhandler