Dokument

Volltextsuche

Die aus den Controls bekannte Suche nach dem Dokumentvolltext kann mit folgendem Befehl aufgerufen werden:

var docIds = await dms.Document.FilterDocumentIds(searchString);

FilterDocumentIds

Diese Methode kann mit einem einfachen und einem komplexen Filter aufgerufen werden. Filter dienen dazu, Dokumente anhand der in der Datenbank gespeicherten Indexdaten (NICHT Volltext) zu suchen. Ein komplexer Filter ist eine Kombination aus mehreren (auch hierarchischen) einfachen Filtern.

einfache Filter

var filter = new SimpleExpression(operator, feld, wert);
var documentIds = await dms.Document.FilterDocumentIds(filter);

Optional kann zu dem Filter noch eine Sortierung angegeben werden. Dazu erstellt man eine Liste (1., 2., … Sortierfeld) mit Feldern, nach denen das Ergebnis sortiert sein soll. Je Feld kann angegeben werden, ob auf- oder absteigend sortiert werden soll.

var orders = new List<OrderDefinition>();
orders.Add(new OrderDefinition() 
{
    Fieldname = STP.Ecm.ApiCore.Fieldname.Document.Title,
    Direction = OrderDirection.Ascending
});
// Laden aller, nach Titel sortierten, Dokument-IDs, die in der Akte 01/2021 liegen
var filter = new SimpleExpression(
                     SimpleOperator.Equals, 
                     STP.Ecm.ApiCore.Fieldname.Dossier.Filenumber,
                     "01/2021");
var sortedDocumentIds = await dms.Document.FilterDocumentIds(filter, order);

Mit einfachen Filtern sind die Suchen nach Werte aus genau einem Feld möglich. Sollen mehrere Felder, oder auch mehrere Werte eines Feldes, berücksichtigt werden, müssen komplexe Filter verwendet werden.

komplexe Filter

Hiermit können mehrere SimpleExpression-Elemente Und/Oder verknüpft werden. Ein ComplexExpression-Element kann eine Liste von einfachen Ausdrücken (SimpleExpression) und/oder eine Liste mit komplexen Ausdrücken aufnehmen. Damit ist eine Baumstruktur möglich.

Beispiel, um nach Dokumenten in einer bestimmten Akte, welche die Dokumentkategorie “Rot” oder “Blau” gesetzt haben, zu suchen:

var filter = new ComplexExpression(ComplexOperator.And);
var categoryFilter = new ComplexExpression(ComplexOperator.Or);
categoryFilter.SimpleExpressions.Add(new SimpleExpression(
                   SimpleOperator.Equals,
                   STP.Ecm.ApiCore.Fieldname.Document.Category,
                   "Rote Kategorie"));
categoryFilter.SimpleExpressions.Add(new SimpleExpression(
                   SimpleOperator.Equals,
                   STP.Ecm.ApiCore.Fieldname.Document.Category,
                   "Blaue Kategorie"));
filter.ComplexExpressions.Add(categoryFilter);

filter.SimpleExpressions.Add(new SimpleExpression(
                   SimpleOperator.Equals,
                     STP.Ecm.ApiCore.Fieldname.Dossier.Filenumber,
                     "01/2021"));

Einschränkung nach Themen

Es kann ein Filter auch auf ein oder mehrere Themen beschränkt werden. Dazu wird als dritter Parameter eine Liste mit Themennamen (interne Namen, nicht Anzeigenamen) angegeben.

Um zum Beispiel nach Dokumenten in der Wissenbasis zu suchen, deren Titel mit “Artikel” beginnt, ruft man folgendes auf:

var filter = new SimpleExpression(
                     SimpleOperator.Like,
                     STP.Ecm.ApiCore.Fieldname.Document.Title, 
                     "Artikel%");
var documentIds = await dms.Document.FilterDocumentIds(
                     filter, 
                     null, 
                     new [] { "Jurathek" });

Sortieren

Hat man bereits eine Liste mit Dokument-Ids und möchte diese Umsortieren, kann dies mit dem folgenden Aufruf erfolgen (hier wird nach Titel sortiert).

var orders = new List<OrderDefinition>();
orders.Add(new OrderDefinition() 
{
    Fieldname = STP.Ecm.ApiCore.Fieldname.Document.Title,
    Direction = OrderDirection.Ascending
});
var sortedIds = await dms.Document.SortIds(unsortedIds, orders);

Import

//Import setzt Dokumentklasse:
var docDto = new DmsDocumentDto{
                 DocumentClass = @"stp.wza.claim"
             };

dms.Document.Import(FileInfo file, DmsDocumentDto docDto)

Import Dokument mit DmsDocumentDto.

dms.Document.Import(localFileInfo, title, containerId)

Damit kann auf einfache Weise ein Dokument importiert werden.

dms.Document.Import(Stream stream, DmsDocumentDto docDto)

Import Dokument mit Stream Inhalt und DmsDocumentDto.

Import und Update Rendition

Import und/oder Aktualisierung der Rendition zu einem Dokument mit DocumentRenditionDto.

dms.Document.ImportNewOrUpdateRendition(renditionDto, stream)

Hiermit kann auf einfache Weise eine Rendition für eine Dokumentenversion in den RenditionStore importiert werden. Der Inhalt wird über einen Stream bereitgestellt. Ausfüllen der DocumentRenditionDto: |Wert|Bedeutung| |-|-| |Type|Renditiontyp, z.B. “ocr” als (freier) String| |DocumentId|Die Guid des Dokuments im DMS.| |DocVersion|Die Versionsnummer des Dokuments zu welcher die Rendition gehört.| |Extension|Die Dateinamenerweiterung als freier String.|

Die Properties UpdateCount, Created, ContentSize sind Rückgabewerte.

Die Rückgabe ist vom Typ RenditionResultDto. Hier sind zusätzlich noch die Felder Error (string) und Success(bool) enthalten.

Für diese Operationen werden die Notifications vom Typ NewRenditionCreated oder RenditionChanged mit Übergabe der RenditionResultDto gesendet.

Inhalt direkt in Stream herunterladen

Um den Inhalt eines Dokument in Stream zu speichern, ohne lokale Datei zuverwenden, wird der folgende Aufruf verwendet:

var success = await dms.Document.DownloadContent(documentId, StreamContents = stream =>
                    {
                        //Inhalt aus stream lesen!
                    });

Inhalt herunterladen

Um den Inhalt eines Dokument lokal zu speichern, wird der folgende Aufruf verwendet:

var success = await dms.Document.DownloadContent(documentId, targetFilePath);

Der targetFilePath ist ein Dateiname, welcher verwendet wird um das Dokument lokal zu speichern. Der Dateiname ist vollständig anzugeben, also der komplette Pfad, mit korrekter Dateierweiterung. Der obige Aufruf speichert die letzte Version des Dokuments im Originalformat unter dem angegebenen Dateinamen ab.

Soll eine PDF-Variante oder eine andere Version gespeichert werden, können noch Downloadoptionen angegeben werden.

var config = new DocumentDownloadConfig();
config.Version = DocumentVersionIdentifier.Specific(1);
config.Format = DocumentDownloadFormat.Pdf;
dms.Document.DownloadContent(documentId, targetFilePath, config);

Hiermit wird die erste (also die älteste) Version des Dokuments als Pdf heruntergeladen.

An Formaten stehen die folgenden Werte aus DocumentDownloadFormat zur Verfügung:

Wert Bedeutung
Original Man erhält den originalen Inhalt, welcher ins DMS importiert wurde
Pdf Es wird ein Pdf erstellt. Sollte das Dokument bereits ein Pdf sein, wird der originale Inhalt geliefert. Entspricht der Dokumentvorschau in DMS.
PdfA Es wird ein Pdf im Format PDF-A-2a geliefert.
Rendition Es wird der Inhalt der über den Renditiontype (in DocumentDownloadConfig) angegebenen Rendition geliefert.

Hinweis zu PdfA: Sollte das Ausgabeformat PdfA sein, so greift die Einstellung für den beA-Export. Insbesondere die dort ausgeschlossenen Dateitypen. Soll ein dort angegebener Typ nach PDF-A gewandelt werden, wirft die Api eine Exception.

Dokumentdaten laden

Um die Daten (nicht den Inhalt) zu einem oder mehrerer Dokumente zu laden wird folgender Aufruf verwendet:

var documentDatas = await dms.Document.LoadDocumentData(listOfIds);

Es ist ratsam hier nicht mehrere Tausend Einträge zu laden, sondern Listen nur in Blöcken von maximal 400 Einträgen anzufordern.

Feld ‘Format’

In documentData und DmsDocumentVersionDto gibt es ein Feld ‘Format’. Das Feld ‘Format’ enthält zur Zeit (DMS Version 8.6.1) nur zwei Werte, nämlich ‘PDF/A’ and ‘XRechnung’.

Liste der Renditions zu einem Dokument abrufen

In documentData befindet sich auch die Liste aller Renditions als List<DocumentRenditionDto>. Zusätzlich sind in den Daten für die Versionen DmsDocumentVersionDto ebenfalls jeweils eine Liste der Renditions enthalten.

Dokumentdaten ändern

Ändern kann man die Daten eines Dokument mit dem Update-Befehl. Es wird die ID des Dokuments benötigt und eine Liste mit Änderungen, welche angewendet werden sollen. ### UpdateCount Für die Methode “Update” gibt es eine neue Variante mit einem UpdateCount um transaktional sicher zu sein. Die alte Methode ist obsolete und wird in einer zukünftigen Version entfernt. (LoadDocument() lädt diesen UpdateCount im Dto mit.)

var changes = new List<FieldUpdateInfo>();
changes.Add(new FieldUpdateInfo() {
    FieldKey = STP.Ecm.ApiCore.Fieldname.Document.Title,
    Value = "Neuer Titel"
});

//Dokumentklasse ändern:
changes.Add(new FieldUpdateInfo(){
            FieldKey = Fieldname.Document.Class,
            Value = "stp.wza.claim"
       });

var resultDocumentId = await dms.Document.Update(documentId, updateCount, changes);

Falls Update erfolgreich ist, wird der Rückgabewert auf DokumentId gesetzt. Falls Konflikt auftritt, ist der Rückgabewert null.

Dokument verschieben

Hiermit können Dokumente in ein anderes Register verschoben werden.

var moveInfos = await dms.Document.Move(documentIds, targetContainerId, targetTrayId);

Dokumente können auch über Aktengrenzen hinwegverschoben werden, jedoch gehen dabei die Indexdaten verloren. Als Ergebnis wird für jedes angegebene Dokument das Ergebnis des Verschiebens zurückgegeben. Die Info enthalt:

DocumentMovedInfo. Bedeutung
DocumentId Id des verschobenen Dokuments
PreviousContainerId Id der bisherigen Akte/Ordner
PreviousTrayId Id des Registers in welchem das Dokument vorher lag.
CurrentContainerId Id der Akte/Ordner in welcher das Dokument jetzt liegt.
CurrentTrayId Id des Registers in welchem das Dokument jetzt liegt.

Dokument zum Löschen markieren

Wird ein Dokument zum Löschen markiert wandert es in den Papierkorb des Anwenders. Dazu gibt es die folgende Methode:

var success = await dms.Document.MarkDocumentForDelete(listOfDocumentIds);

Um die Dokumente wieder aus dem Papierkorb an ihren Ursprungsort zurückzuholen ruft man das hier auf:

var success = await dms.Document.UnmarkDocumentForDelete(listOfDocumentIds);

Wichtig: Diese Methode unterstützt serverseitig keine Impersonierung. Die Löschmarkierung wird immer mit dem Benutzer gesetzt, welcher die Api initial instanziiert hat.

Rendition(s) zu einem Dokument löschen

Um Renditions zu löschen, gibt es die folgende Methode:

var success = await dms.Document.DeleteRenditions(listOfDocumentRenditionDtos);

Analog zum Import wird über die Datenstruktur DocumentRenditionDto, die zu löschende(n) Rendition(s) spezifiziert. Maßgeblich sind die Properties: Id, DocumentId, DocVersion, Type. Die Rückgabe ist eine Liste vom Typ RenditionResultDto. Hier sind zusätzlich noch die Felder Error (string) und Success(bool) enthalten.

Folgende Fälle werden bei der Löschanforderung pro DocumentRenditionDto unterschieden: - wird die Id angegeben ist die einzelne Rendition damit spezifiziert. Es wird nur diese Rendtion gelöscht. Das Dokument und die Version sind implizit bekannt. - wird die DocumentId, DocVersion und Type angegeben ist damit eine einzelne Rendition spezifiziert. - wird die DocumentId und DocVersion angegeben, so werden alle Renditions zu dieser Dokumentversion gelöscht. - wird die DocumentId und Type angegeben, werden alle Rendtions diesen Typs in allen Versionen des Dokuments gelöscht. - wird nur die ‘DocumentId’ angegeben, werden alle Renditions (in allen Versionen) gelöscht.

Die Angabe der DocumentId ist erforderlich, falls nicht die Id der Rendition angegeben wurde.

Für diese Operationen wir die Notification vom Typ RenditionDeleted mit Übergabe der RenditionResultDto pro gelöschter Rendition gesendet.

Dokumentinhalt ändern

Um den Inhalt des Dokuments zu verändern (bearbeiten), muss das Dokument ausgecheckt werden. Das bedeutet, dass es für andere Anwender dauerhaft gesperrt wird. Mit dem Befehl

var edit = await dms.Document.Checkout(documentDto, targetFilePath);

erhält man ein Bearbeitungsobjekt. Das Dokument wird also gesperrt und der aktuelle Inhalt unter dem angegebenen Dateinamen (targetFilePath) lokal abgelegt.

Über das Edit-Objekt können nun nicht direkt Veränderungen am Dokument vorgenommen werden, aber die Änderungen, welche an der Datei durch einen externen Editor wie Word/Excel/… vorgenommen wurde, wieder in das DMS zurückführen.

Wurde der Checkout in einer früheren Sitzung vorgenommen, so kann er auch wieder aufgenommen und fortgesetzt werden.

var edit = await dms.Document.ReattachToCheckout(documentDto, targetFilePath);

Der Checkout wird dabei nicht erneut vorgenommen, sondern es müssen die folgenden Bedingungen existieren: 1. Die Datei, welche unter targetFilePath angegeben ist, muss existieren. 2. Das Dokument muss in DMS für den angemeldeten oder impersonierten Benutzer permanent gesperrt sein.

Speichern

Mit edit.Save() wird eine Zwischenspeicherung ausgeführt. Der aktuelle Inhalt der Datei wird nach DMS übertragen und überschreibt den aktuellen Inhalt. Das Dokument bleibt dabei weiterhin ausgecheckt, also gesperrt.

Bearbeitung abbrechen

Mit edit.DropChanges() wird die Verarbeitung abgebrochen. Die Lokale Datei wird dadurch nutzlos und das Dokument auf dem Server wieder freigegeben (entsperrt).

Beenden mit Überschreiben

Dies entspricht im Wesentlichen dem Save(), nur dass die Bearbeitung beendet wird und das Dokument auf dem Server wieder freigegeben wird.

edit.FinishWithOverwrite();

Beenden mit neuer Version

Auch hier wird die Bearbeitung abgeschlossen. Der aktuelle Inhalt der Datei wird aber als neue Version zum Dokument importiert. Optional kann eine Kommentar direkt an der Methode mitgegeben werden.

edit.FinishWithNewVersion("bearbeitet, wie besprochen");

Lokale Datei als neue Version übernehmen

Es kann auch eine vollkommen unabhängige lokale Datei als neue Version zum Dokument übernommen werden. Dabei wird die Bearbeitung abgeschlossen und die angegebene Datei als Inhalt für die neue Version verwendet.

edit.FinishWithNewVersionAndNewContent(localFilename);

Dies kann zum Beispiel bei einer Formatänderung nach Pdf verwendet werden.

Titel und Kommentar ändern

An dem edit-Objekt kann ein Titel und ein Kommentar gesetzt werden. Bei allen Aktionen (außer DropChanges) werden diese Werte, sofern gesetzt, übernommen.

Anhänge klammern

Setzen

Es können zu einem Dokument anhänge angeklammert werden. Zum Beispiel bei einer E-Mail die zusätzlich importierten Anhangsdokumente.

bool success = await dms.Document.ClipAttachmentsToDocument(idOfDocument, idsOfAttachments, CLipType.eMail);

Die idOfDocument ist die ID des Hauptdokuments, an welches die Anhänge gehängt werden sollen. In der Regel ist das die E-Mail oder eine beA-Nachricht. idsOfAttachments ist eine Liste von Dokument-Ids der Dokumente, die als Anhang mit dem Hauptdokument verbunden werden sollen. Der dritte Parameter gibt die Art des Anhangs an. Zur Auswahl stehende Werte sind:

ClipType. Bedeutung
beA Anhang einer beA-Nachricht
eMail Anhang einer E-Mail
Scan Zusammengehörende Dokumente durch einen Scanvorgang

Wurde die Klammerung erfolgreich vorgenommen wird true als Ergebnis geliefert.

Abfragen

Die Anhänge zu einem Dokument können über folgenden Aufruf abgefragt werden:

var modus = HierarchyModus.DirectAttachmentsOnly;
var attachedDocumentIds = await dms.Document.GetAttachments(documentId, modus);

Die Ergebnisliste enthält die Dokument-Ids aller angehängten Dokumente, welche über die Klammerungsmethodik gesetzt worden sind. Anmerkung: Der Kontextmenüaufruf in den DMS-Clients können auch E-Mails über ihren Vorgang zusammen bringen. Dies ist mit dieser Methode nicht möglich. Die Liste enthält Elemente vom Typ AttachmentReference:

AttachmentReference. Typ Bedeutung
DocumentId Guid Id des angehängten Dokuments
Type AttachmentType Typ des Anhangs
AttachmentType. Bedeutung
beA Anhang einer beA-Nachricht
EMail Anhang einer E-Mail
Scan Zusammengehörende Dokumente durch einen Scanvorgang

Eine Klammerung ist immer additiv. Es kann als für ein Hauptdokument mehrfach die Klammerung aufgerufen werden. Die Liste der Anhänge vergrößert sich dadurch. Sollten Anhangsdokumente bereits als Anhang zugeordnet sein, werden diese nicht erneut zugeordnet.

Hierarchie-Modus (ab DMS 7.5.2002)

Bei der Abfrage kann man einen Hierarchie-Modus angeben. Dieser gibt an, wie hierarchische Anhangsstrukturen ab dem angegebenen Dokument durchsucht werden sollen.

Hauptdokument (Nr 1)
- Anhang 1 (Nr 2)
- Anhang 2 (Nr 3)
- Anhang 3 (Nr 4)
   - Anhang 3.1 (Nr 6)
       - Anhang 3.1.1 (Nr 7)
- Anhang 4 (Nr 5)

Hat man eine solche Struktur und ruft die Methode zum Beispiel für das Dokument mit der Nummer 4 auf (“Anhang 3”), hat man über den Modus 3 verschiedene Möglichkeiten, wie die Ergebnisliste zusammengestellt wird:

HierarchyModus. Bedeutung Ergebnisliste
DirectAttachmentsOnly Nur die direkten Anhänge 4,6
DirectAttachmentsHierarchically Ab dem Dokument alle untergeordneten Dokumente 4,6,7
EntireStructure Komplette Struktur ab Hauptdokument 1,2,3,4,6,7,5

Im Falle von EntireStructure wird vom angegebenen Dokument aus zuerst nach dem Hauptdokument gesucht. Dieses hat kein übergeordnetes Dokument. Von da aus wird dann die komplette Hierarchie zurückgegeben. In der flachen Liste werden die jeweiligen Anhänge immer direkt nach dem jeweiligen übergeordneten Dokument eingefügt. Daher kommen 6 und 7 auch direkt nach 4 und erst im Anschluß die 5.

Auswirkungen

Wir bei einem Dokument eine Anhangsbeziehung hergestellt, dann kann diese über das Feld AnhangStatus am Dokumentobject (DmsDocumentDto) abgefragt werden. Das Feld ist vom Typ Int32 und kann die folgenden Werte enthalten: |AnhangStatus|Bedeutung| |-|-| |0|Dokument hat keine Anhangsbeziehung.| |1|Das Dokument hat Anhänge.| |2|Das Dokument ist Anhang eines anderen Dokuments.| |3|Das Dokument ist ein Anhang und hat selber Anhänge.|

Protokolleintrag erstellen

Dms protokolliert die meisten Aktionen, über die ein Dokument eingesehen werden kann. Die Api erlaubt zusätzliche Einträge zu dem Protokoll hinzuzufügen, damit weitergehende Aktionen mit einem heruntergeladenen Dokumentinhalt eingetragen werden können.

var reason = CheckoutReason.Print;
dms.Document.AddProtocolEntry(documentId, documentVersion, reason);

In diesem Fall wird darüber informiert, dass das Dokument gedruckt wurde. Der Protokolleintrag wird automatisch um den aktuellen Zeitstempel und den angemeldeten Benutzer ergänzt.

Verknüpfung mit