Joboptionen

Jeder dms.XML*-Serverjob nimmt einen semikolongetrennten Options-String entgegen, etwa INITFIELDS=0;CHECKKEYFIELDS=0. Die Optionsklassen bilden diese Optionen getypt ab: eine Methode pro Option, und jede Klasse bietet nur die Optionen an, die ihr Job tatsächlich akzeptiert.

Die häufigsten Optionen sind zusätzlich als eigene Parameter verfügbar (check_mandatory, hard_delete, copy_cascading, …). Die Optionsobjekte ergänzen diese, sie ersetzen sie nicht.

1. Klassen

Klasse Job Verwendet von

ECMInsertOptions

dms.XMLInsert

insert(), insert_and_get(), insert_variant(), insert_variant_and_get()

ECMUpdateOptions

dms.XMLUpdate

update(), update_and_get()

ECMUpsertOptions

dms.XMLImport

upsert() — Vereinigung aus Insert- und Update-Optionen, weil XMLImport je nach Suchergebnis in den einen oder anderen Zweig läuft

ECMDeleteOptions

dms.XMLDelete

delete()

ECMMoveOptions

dms.XMLMove

move()

ECMCopyOptions

dms.XMLCopy

copy()

2. Verwendung

Die Objekte sind unveränderlich: jede Methode gibt ein neues Objekt zurück, Aufrufe lassen sich verketten.

  • Sync

  • Async

from ecmind_blue_client.ecm import ECMInsertOptions

object_id, _ = ecm.dms.insert(
    InvoiceDocument(Title="Rechnung Nr. 42"),
    folder_id=folder.system.id,
    options=ECMInsertOptions().init_fields(False).check_key_fields(False),
)
from ecmind_blue_client.ecm import ECMInsertOptions

object_id, _ = await ecm.dms.insert(
    InvoiceDocument(Title="Rechnung Nr. 42"),
    folder_id=folder.system.id,
    options=ECMInsertOptions().init_fields(False).check_key_fields(False),
)

Beim Upsert-Builder ist es eine Builder-Methode:

from ecmind_blue_client.ecm import ECMUpsertOptions

object_id, type_id, hits, action = (
    ecm.dms.upsert(InvoiceFolder(Title="Rechnung 2024"))
    .search(InvoiceFolder.Title == "Rechnung 2024")
    .options(ECMUpsertOptions().init_fields(False))
    .execute()
)

3. Vorrang

Optionen, die aus den getypten Parametern abgeleitet werden, und Optionen aus dem Optionsobjekt werden zusammengeführt. Bei einem Konflikt gewinnt das Optionsobjekt:

# check_mandatory=False würde CHECKOBLIGATION=0 senden,
# das Optionsobjekt setzt es auf 1 zurück.
ecm.dms.insert(model, check_mandatory=False, options=ECMInsertOptions().check_obligation(True))
# gesendet wird: CHECKOBLIGATION=1

Damit lässt sich die clientseitige Pflichtfeldprüfung überspringen, ohne die serverseitige mit abzuschalten.

4. Durchgängiges Beispiel: Import aus einem Altsystem

Der häufigste Anlass für Joboptionen ist ein Import, der die Werte vollständig mitbringt und deshalb an den serverseitigen Automatismen scheitert. Typisch sind drei Punkte: der Objekttyp hat Key-Felder, die der Server initialisieren und auf Eindeutigkeit prüfen will, es tauchen Katalogwerte auf, die noch nicht gepflegt sind, und einzelne Strings sind länger, als die Feldlänge erlaubt.

from ecmind_blue_client.ecm import ECMInsertOptions, ECMUpdateOptions

# Einmal bauen, in der Schleife wiederverwenden: die Objekte sind unveränderlich.
IMPORT_INSERT = (
    ECMInsertOptions()
    .init_fields(False)        # der Import liefert die Werte selbst
    .check_key_fields(False)   # Belegnummer ist ein Key-Feld und bereits eindeutig
    .check_catalogue(False)    # Kostenstellen sind im Katalog noch nicht gepflegt
    .truncate_values(True)     # zu lange Altbestände kürzen statt abzulehnen
)
IMPORT_UPDATE = ECMUpdateOptions().check_catalogue(False).truncate_values(True)

for record in legacy_records:
    treffer = (
        ecm.dms.select(InvoiceDocument)
        .where(InvoiceDocument.InvoiceNumber == record.number)
        .execute()
    )
    if treffer:
        doc = treffer[0]
        doc.Title = record.title
        ecm.dms.update(doc, options=IMPORT_UPDATE)
    else:
        ecm.dms.insert(
            InvoiceDocument(Title=record.title, InvoiceNumber=record.number),
            folder_id=ziel_ordner,
            options=IMPORT_INSERT,
        )

Jede dieser Optionen schaltet eine Prüfung ab, die es aus gutem Grund gibt. Sie gehören in einen bewusst abgegrenzten Import- oder Migrationspfad, nicht in den normalen Anwendungscode. check_key_fields(False) etwa lässt Dubletten in einem Key-Feld zu, wenn die Eindeutigkeit nicht anderweitig sichergestellt ist.

5. Nur Key-Felder abschalten

Wenn ausschliesslich die Key-Feld-Automatik stört, genügt:

options=ECMInsertOptions().init_fields(False).check_key_fields(False)

6. Nicht abgedeckte Optionen

Serveroptionen ohne eigene Methode (etwa neu hinzugekommene) setzt raw():

ECMInsertOptions().raw("SOMENEWOPTION", True)

raw() wendet keine Job-Prüfung an — der Aufrufer ist dafür verantwortlich, dass der Zieljob die Option kennt.

Ein bestehender Optionsstring lässt sich übernehmen:

ECMInsertOptions.from_string("INITFIELDS=0;CHECKKEYFIELDS=0")

7. Abgrenzung zur Klasse Options

Die Klasse ecmind_blue_client.Options gehört zur deprecateten Legacy-API (Client.xml_import()). Sie ist flach, ohne Job-Zuordnung, und sollte in neuem Code nicht mehr verwendet werden.

8. Siehe auch