Mapping.ini

Aus IMPS
Zur Navigation springen Zur Suche springen

Detailbeschreibung aus Konfiguration

Funktionen

Auf der rechten Seite des Gleichheitszeichens in allen Sections muss ein Funktionsaufruf folgen. Konstante Werte können mit "Return <Wert>" umgesetzt werden.

Ansonsten kann jede TCL-Funktion und jede benutzerdefinierte Funktion, die im Includeverzeichnis liegt, benutzt werden.

Allgemeingültige Funktionen sollten dem Produkt beigefügt und für zukünftige Versionen zur Verfügung gestellt werden.

Änderung ab Version 23.0

Wenn keine Variablenzuweisung erfolgt (also links kein Wert steht), dann kann das Gleichheitszeichen weggelassen werden. Sollte ein Gleichheitszeichen in Zeile vorkommen, so gibt es 3 mögliche Lösungswege:

  • die Autokorrektur kann die Zeile selbständig korrigieren (allerdings werden Leerzeichen vor und nach dem Gleichheitszeichen durch genau ein Leerzeichen ersetzt!)
  • das Gleichheitszeichen wird in der Zeile durch \x3D ersetzt
  • oder für die Zeile wird doch das führende Gleichheitszeichen verwendet

Diese Anpassungen wurden im INI-Package vorgenommen.

Beispiel:

; Transport und Verpackungskosten   
_TMP_DISCOUNT_BLOCKS   = $::impsXML GetXMLBlocks SpecifiedLogisticsServiceCharge %_TMP_TRADE_SETTLEMENT% -nocase %_TMP_NOC%
                         FOREACH ::custommap::discountBlock %_TMP_DISCOUNT_BLOCKS%
                           Set _TMP_innerArray {}
                           Lappend _TMP_innerArray "discType"
                           Lappend _TMP_innerArray "003"                           
                           Lappend _TMP_innerArray "orgValue"
                           Lappend _TMP_innerArray [$::impsXML GetXMLValue AppliedAmount $::custommap::discountBlock -nocase %_TMP_NOC%]
                           Lappend _TMP_innerArray "value"
                           Lappend _TMP_innerArray [string map {"." ","} [$::impsXML GetXMLValue AppliedAmount $::custommap::discountBlock -nocase %_TMP_NOC%]]   
                           Lappend _TMP_innerArray "currency"
                           Lappend _TMP_innerArray [lindex [regexp %_TMP_NOC_STRING% -inline {currencyID\x3D.([^>]+).>} %_TMP_SUM_AMOUNTS%] 1]                     
                           Lappend _TMP_innerArray "discountIncrease"
                           Lappend _TMP_innerArray [ImpSysValue LOGISTIC_CLASS_NO "10085"]
                           Lappend _TMP_innerArray "discountType"
                           Lappend _TMP_innerArray "4"                              
                           Lappend _TMP_innerArray "taxTypeCode"
                           Lappend _TMP_innerArray [$::impsXML GetXMLValue TypeCode $::custommap::discountBlock -nocase %_TMP_NOC%]
                           Lappend _TMP_innerArray "taxCategoryCode"
                           Lappend _TMP_innerArray [$::impsXML GetXMLValue CategoryCode $::custommap::discountBlock -nocase %_TMP_NOC%]
                           Lappend _TMP_innerArray "taxPercent"
                           Lappend _TMP_innerArray [string map {"." ","} [$::impsXML GetXMLValue RateApplicablePercent $::custommap::discountBlock -nocase %_TMP_NOC%]]                              
                           Lappend _TMP_inner2Array "reason"
                           Lappend _TMP_inner2Array [$::impsXML GetXMLValue Description $::custommap::discountBlock -nocase %_TMP_NOC%]                                           
                           Lappend _TMP_discountArray %_TMP_innerArray%
                         ENDFE

Eigene Operationen auf dem Webserviceobjekt durchführen

Werden Daten aus Corsa für die Bewertung eines Sachverhaltes benötigt, so können Daten aus Corsa direkt über das Webserviceobjekt abgefragt werden.

Ein typisches Einsatzgebiet ist die Fragestellung, ob eine bestimmte Datenkonstellation zu einem eindeutigen Objekt in Corsa führt und Rückgabe der Objekt-ID.

Es gibt eine Funktion WebserivceCall, die das WebsericeObjekt bereitstellt und eine benutzerdefinierte Funktion aufruft, ihr als ersten Parameter das WebserviceObjekt zur Verfügung stellt und die restlichen Parameter durchreicht.


Beispiel:

[GLOBAL]
OBJECTID   = WebserviceCall GetID_test %MITGLIEDSNUMMER%
OBJECTKIND = Return MITGL
OBJECTTYPE = Return P


mit benutzerdefinerter Funktion GetId.tbc im Includeverzeichnis

proc GetID_test {webserviceObject id} {
 ....
return $id
}


Soll direkt eine Methode des Corsa Webservice Package aufgerufen werden, so ist der Zusatz Direct zu verwenden:

WebserviceCall Direct DeleteObject %OBJECT_ID%

Objekttyp

Die folgenden Objekttypen werden unterstützt.


S

Dokument


D

Akte


P

Person


E

Organisation


C

Workflow


V

Immobilie

SKIP-Funktionalität

Ein Skipfunktionalität, die z.B. eine Objektanlage verhindert, wenn das Objekt schon in Corsa vorhanden ist, wird über ein *SKIP* in der OBJECTID realisiert.

Dieses Skip kann in Abhängigkeit vom Inhalt durch eine benutzerdefinierte Funktion eingefügt werden.

Beispiel s. Anwendungsfall SKIP.


Auftreten eines Regelwerkfehlers (frühe Interpretation)

Ein Fehler im Regelwerk führt dazu, dass die Datei der definierten Fehlerbehandlung übergeben wird.

Fehler können auch absichtlich durch die error-Funktion ausgelöst werden.

Kommt es zu einem Fehler, so werden die restlichen Regel für die aktuelle Datenzeile noch ausgeführt, um eventuell weitere vorhandene Fehler angezeigt zu bekommen, alle geplanten Transaktionen werden dann aber verworfen und das Dateitupel wird in einem zeitgestempelten Ordner in das ErrorDir verschoben.

Achtung: Im Regelwerk durchgeführte Vorregistrierungen o.ä. werden nicht selbständig zurückgerollt. Das muss im Regelwerk in ERROR erfolgen.


Auftreten eines Transaktionsfehlers (späte Interpretation)

Wenn während der Transaktionsverarbeitung ein Fehler auftritt, so wird dieser über das EVENT PROCESSTAERROR gemeldet.

Wichtig ist, dass diese Message auch zugestellt wird, wenn sie relevant ist.

Handelt es sich um ein kritisches Ereignis, das schiefgeht, so ist zu überlegen, ob nicht der ganze Prozess via "H" angehalten wird.

In jedem Fall sollte der Wert "M" gesetzt sein. Dieser sorgt dafür, dass die interne Statusvariable ::script::taError auf 1 gesetzt wird. Dieser Wert wird im Regelwerk abgefragt, um gewisse Dinge nach einem Fehler anders als im Regelfall auszuführen.

Nach der letzten Transaktion wird die Variable wieder selbständig auf 0 gesetzt.


Schlüssel

Die Schlüssel werden ähnlich wie Tcl-Variablen interpretiert. Das heißt, dass der Ausdruck interpretierbar sein muss.

Ein {{ .... %WERT%}} wird nicht funktionieren, ein [list [list .... %WERT%]] schon.


Beispiel:

[GLOBAL]
OBJECTID    = WebserviceCall ::CreateObject::DocumentByQuery Invoice *DUMMY* [list [list qrtReference dUnique qcAnd qoEqual %_tmp_unique%]] {} [list [list dUnique %_tmp_unique%]]

Felder der Indexdatei

Wenn Feldinhalte aus der CSV-Datei verwendet werden sollen, dann ist der Spaltenname aus der Überschrift (Zeile 1) in Prozentzeichen zu verwenden.

Beispiel:

input.csv

VORNAME;NACHNAME;PERSID
Daniel;Hebel;1337

mapping.ini

persoon.roepnaam  = Return %VORNAME%

Vordefinierte Schlüssel

%_TOTALTEXT%

Dieser Schlüssel enthält den gesamten Text der Datendatei, wenn isCSV auf 0 gesetzt ist.


%_FILENAME%

Dieser Schlüssel enthält Pfad+Name der Datendatei.


gesammelte Schlüssel

Alle Werte, die in [SYSTEMFIELDS], [REFERENCEFIELDS] und [GLOBAL] definiert werden, stehen im Folgenden als %WERTE% zur Verfügung. Dabei werden die Sections genau in dieser Reihenfolge abgearbeitet. Werte in [SYSTEMFIELDS] und [REFERENCEFIELDS], die mit _TMP_ beginnen, werden nicht an das Folgesystem übergeben, sondern stellen Tempfelder für das Mapping dar.


_TMP_MEMO  = Rex_1{(Schritt.*)16} %_TOTALTEXT%
MEMOTEXT   = Return %_TMP_MEMO%


Sollen nur Befehle ausgeführt werden, das Ergebnis jedoch nicht gespeichert werden, so kann die linke Seite auch ganz weggelassen werden.

 set ::custommap::bestLaunchingYear 1909


Mit der Funktion Set (nicht zu verwechseln mit dem Tcl-Befehl set, der auf ::custommap::var angewendet wird) können auch Schlüssel direkt geschrieben werden. Dabei wird der Wert, der mit %<Variablenname>% gezogen wird, aktualisiert, nicht jedoch der Wert für die Uploadliste (bis Version 17.22). Das kann allerdings manuell durch eine Selbstzuweisung erreicht werden. Seit der Version 17.23 wird der Wert standardmäßig in die Uploadliste geschrieben. Das alte Verhalten kann aber mit dem Parameter -updateList 0 erreicht werden.

; Verhalten bis 23.17 oder bei Verwendung von -storeToUpload 0 (ab 23.18) nach dem Set:
data/launchingYear = 1904
data/badYear       = Return %data/launchingYear%
                     Set data/launchingYear 1909 -storeToUpload 0
data/goodYear      = Return %data/launchingYear%
; hier würde an den Folgeprozess immer noch data/launchingYear  == 1904 übergeben werden, ebenso data/badYear, während data/goodYear den Wert 1909 hätte

data/launchingYear = Return %data/launchingYear%
; goodYear und badYear wären unverändert, aber data/launchingYear wäre jetzt auf 1909 gesetzt


Der Antagonist zu Set ist Get <FIELDNAME>. Er ist immer statt der %FIELDNAME%-Syntax zu verwenden, wenn die Anzahl der Substitutionsstufen nicht ausreicht, um %FIELDNAME% aufzulösen. Das kommt z.B. bei Schleifen im Regelwerk vor. Auch bei Leerzeichen im Feldnamen kann das erforderlich sein.

; die %FIELDNAME% Variable würde nicht aufgelöst, da sie erst innerhalb der Schleife da ist. Mit Get kann sie dennoch verwendet werden.
  foreach indexHeader $::mapping::indexHeaderList {lappend ::mapping::indexHeaderValueList [list $indexHeader [CheckDefinition [Get ${indexHeader}]]]}

; Leerzeichen im Variablennamen
  LogMessage "Dokumenttyp: [Get "Doc Type"]"


Welche Felder überhaupt aktuell definiert sind, kann mit dem Befehl GetFieldNames <optionale Parameter> abgefragt werden. Dabei werden folgende optionale Parameter unterstützt:

-tmpFields: sollen _TMP_-Felder auch zurückgeben werden? (0/1)    
-emptyField: soll das Leerfeld auch zurückgegeben werden? (0/1)       
-fileNameField: soll das Feld _FILENAME auch zurückgegeben werden? (0/1) 
-totalTextField: soll Totaltext, sofern lizenziert, auch zurückgegeben werden? (0/1)
-filter: nur Felder zurückliefern, die einem definierten Muster entsprechen (default "*")        
-mode: Methode, mit der der Filter ausgewertet wird (-glob / -regexp / -exact)          


Beispiel:

; alle Felder außer _FILENAME, <leer> und _TOTALTEXT, die den String "BANK" im Namen enthalten 
  LogMessage "[GetFieldNames -tmpFields 1 -filter *BANK*]"


Wird eine if-Anweisung ohne else verwendet, so wird im else-Fall ein Leerstring übergeben (also kein *NOT_DEF*).

Variablen

Im Mapping-Regelwerk ist die Verwendung von Variablen erlaubt. Um Konflikte mit internen Variablen zu vermeiden, ist ein Namespace ::custommap vorhanden, in den die benutzerdefinierten Variablen gelegt werden sollten. Für bestimmte Szenarios gibt es auch feste Variablen im Namespace ::mapping, die an passenden Stellen in dieser Webdokumentation erwähnt werden.


line

Kann z.B. in der System.ini verwendet werden.

Bei isCSV==1 ist hier die aktuelle Zeile enthalten, sonst der ganze Text.

actualLineCounter

Enthält die Zeilennummer der gerade verarbeiteten Zeile. Damit kann z.B. die entsprechende Mapping.ini in Abhängigkeit von der Zeile verwendet werden.


totalLinesCounter

enthält die Gesamtanzahl der Zeilen in der CSV-Datei. Mit actualLineCounter und totalLinesCounter kann z.B. ermittelt werden, ob man sich in der letzten Zeile befindet, um dort eine andere Mapping.ini zu verwenden.

ACHTUNG: Eine Leerzeile am Ende wird als Zeile mitgezählt!


::main::importDir

Der Name des aktuellen Importverzeichnissses


::mapping::CreateMetaDocument(DSPTemplateID)

Wenn der DSP-Parameter bei der Erstellung der automatischen Dokumentenregistrierung verwendet werden soll, so muss diese Variable gesetzt sein.

WICHTIG!! Kann ausschließlich bei neuen Registrierungen verwendet werden! Wenn eine Vorregistrierung erstellt wird, darf diese Variable nicht gesetzt werden. Der Parameter muss bei der Vorregistrierung Include#::Document als Minusparameter übergeben werden!

::mapping::CreateMetaDocument(DuplicateID)

Wenn die DuplicateID bei der Erstellung der automatischen Dokumentenregistrierung verwendet werden soll, so muss diese Variable gesetzt sein.

Dieser Wert wird für jede Datenzeile zurückgesetzt.

WICHTIG!! Kann ausschließlich bei neuen Registrierungen verwendet werden! Wenn eine Vorregistrierung erstellt wird, darf diese Variable nicht gesetzt werden. Der Parameter muss bei der Vorregistrierung Include#::Document als Minusparameter übergeben werden!

::mapping::headerValues(<key/tag>)

Bei SERVICE == 4 oder 8 können hier die Schlüssel bzw. Tags der Datenstruktur und die zugehörigen Werte für den Kopfbereich definiert werden. So ist es möglich Daten außerhalb der Positionsstruktur zu schreiben. Die Felder werden nur einmal pro Datei zurückgesetzt und erst am Ende geschrieben, d.h. die Daten können während der Verarbeitung aller Datenzeilen gesammelt werden.


      = set ::mapping::headerValues(KOPFWERT) 27          
      = set ::mapping::headerValues(undNochEiner) "42"


::mapping::headerTagOpenMode(<tag>)

Bei SERVICE == 8 kann definiert werden, ob das Tag sofort wieder geschlossen wird (1) oder erst nach dem Positionsbereich (0). Ohne Einrichtung wird hier 1 interpretiert.

; Deklaration der äußeren Felder
   = set ::mapping::headerValues(soap:Body)     ""
   = set ::mapping::headerTagOpenMode(soap:Body)   0
   = set ::mapping::headerValues(Cases_Tabel)   ""
   = set ::mapping::headerTagOpenMode(Cases_Tabel) 0
   
; die Reihenfolge muss stimmen, da die Tags nicht sofort geschlossen werden
   = set ::mapping::headerSort [list soap:Body Cases_Tabel]


::mapping::headerTagAttribues(<tag>)

Bei SERVICE == 8 können Attribute als key/value-Liste an das öffnende Tag übergeben werden.

 = set ::mapping::headerTagAttribues(undNochEier) [list Buch "Per Anhalter durch die Galaxis" Autor "Douglas Adams" Bewertung "5/5"]

::mapping::headerSort

Bei SERVICE == 4 oder 8 kann die Reihenfolge definiert werden, in der die Daten in die resultierende Datenstruktur geschrieben werden. Das ist vor allem bei XML wichtig, wenn die Tags nicht sofort wieder geschlossen werden.

 = set ::mapping::headerSort {undNochEiner KOPFWERT}

::mapping::urlParamList

Bei SERVICE == 4 oder 8 können beim Webserviceaufruf URL-Parameter übergeben werden. Das funktioniert sowohl für POST als auch für GET. Dabei werden die einzelnen Parameter abwechselnd key/value-mäßig übergeben. Hat der Wert das Format {[$this <method>]}, so wird die Methode des entsprechenden Jobobjektes aufgerufen.

 = set ::mapping::urlParamList [list uniqueID %supplier/uniqueID% checkSum {[$this Data2SHA]}]

::mapping::overwriteInitArgs(<PARAM>)

Einige Werte aus der system.ini sollte im Mappingregelwerk für den aktuellen Import überschrieben werden können. Das funktioniert mit der Arrayvariablen ::mapping::overwriteInitArgs, mit der es möglich ist Werte für die aktuelle Verarbeitung temporär zu überschreiben. Beim nächsten Datensatz wird wieder die Standarddefinition verwendet. Folgende Werte aus der system.ini können überschrieben werden (das vorangestelle JOBS<n>_ der veralterten Jobdefinition ist hier nicht erlaubt!). Param kann folgende Werte haben:

 HOST, PORT, METHOD, RECORDKEY, HTTPHEADER, CHECKERRORFUNC, CHECKUPLOADFUNC, UPLOADDATA, SENDEMPTYDATA, HTTPPOST, PROTGENDATA, USERPWD, SSLVERIFYPEER, CURLPARAM, ROOTTAG

Umgang mit Leerzeilen in und am Ende einer csv-Datei

Leerzeilen in der csv-Datei, oder, was wahrscheinlicher ist, ein Zeilentrenner am Ende, werden ab Version 11.6 nicht mehr unterdrückt.

Es ist allerdings möglich, das durch eine geeignete mapping.ini abzufangen.

So kann z.B. das Szenario "CSV Datei mit CRLF am Ende wird in eine VarTab gschrieben" wie folgt gelöst werden.


system.ini:

MappingFile          = ./mapping/case_mapping.ini
MAPPINGRULE          = expr {$line eq ""}
MAPPINGFILEIF        = ./mapping/leer.ini


case_mapping.ini:

[GLOBAL]
OBJECTID    = Return WV00000015
OBJECTKIND  =
OBJECTTYPE  = Return C

[VARTAB]
TABLEID   = subst wThemaSB
SCREENID  = subst 1010
INDEXCMD  = list subst {$wBemerk}
REPLACE   =  list [list wSB %WSB% ___wSB %###WSB% wThema %WTHEMA% wBemerk %WBEMERK%]

leer.ini:

[GLOBAL]
OBJECTID    = join WV00000015
OBJECTKIND  =
OBJECTTYPE  = join C

[VARTAB]
TABLEID   = subst wThemaSB
SCREENID  = subst 1010
INDEXCMD  = list subst {$wBemerk}

Bei der Verwendung von json oder XML (SERVICE == 4 oder 8) ist es zusätzlich nötig den Befehl IGNORE aufzurufen, der ab dem Zeitpunkt des Aufrufs dafür sorgt, dass die meisten Befehle für die späte Verarbeitung nicht mehr erzeugt werden. Bei anderem Importen kann es verwendet werden.

Erstellen eines neuen Importjobs aus dem Regelwerk

Es kann jetzt direkt aus dem Mapping-Regelwerk ein neuer Importjob erstellt werden, der danach vom selben oder einem anderen Importservice verarbeitet werden kann.

Damit entfallen viele manuelle Operationen in Includes weg, die meistens auch nicht transaktionssicher gebaut werden und oft die Serviceevents nicht richtig abfangen.


Das ganze funktioniert über den Befehl NewImport.

Sonderzeichen

Prozent

Das Sonderzeichen % darf im Regelwerk nicht verwendet werden, da es als Platzhalter für Variablen (%var%) dient. Es muss mit \x25 gequotet werden.


Beispiel:

format \x25c 66

Sections

GLOBAL

[GLOBAL]


OBJECTID

Das ist ein Pflichtfeld.

Es muss eine bestehende ID oder eine neue ID zugewiesen werden, die zu der in Corsa definierten Formatangabe passt.

Ist in Corsa "Autonummerierung" gewählt, so geht das vor, wenn eine unbekannte, zum definierten Nummerformat passende ID, übergeben wird.

Enthält die ObjectID den Begriff *SKIP*, so wird die Verarbeitung übersprungen und ein Protokolleintrag erzeugt, in dem der Begriff*SKIP* entfernt wird. Wird zum Beispiel 10000/01*SKIP* als ObjectID vergeben, so taucht im Protokoll nur 10000/01 auf.

Parameter = handform

Ist der Parameter auf Ja so wird am Dokumenttyp die Maske für manuelle eine Nummerierung eingeblendet in die ein Format der Nummerierung eingetragen wird. Die Dokumenten ID muss dann immer dieser Maske entsprechen. Diese kann man auch leer lassen, was ich persönlich aber nicht tun würde!

Ist der Parameter auf Nein so wird am Dokumenttyp ein Start- und Stopp-Bereich eingeblendet. Die Dokumenten ID muss dann immer in diesem Bereich liegen und wird bei Nichtangabe die nächsthöhere verwenden jedoch keine Nummern auffüllen. Also die höchste im System existierende DokID des Dokumententyps + 1.

Das Verhalten ist also sowie von Jens beschrieben.

Grundsätzlich stelle ich mir bei der Einrichtung von Dokumententypen die Frage ob dies Dokumente die ausschließlich über Geschäftsprozesse kommen sind, oder Benutzerdokumente die ggf. manuell registriert werden.

1. Geschäftsprozessdokumente Sind zur Registrierung bei den Benutzern ausgeblendet und wir wissen wie wir die DokId generieren. Alternativ verwende ich viel lieber das dUnique Feld um die automatische Nummerierung von Corsa nicht zu tangieren. Bei der Entscheidung die DokId manuell vorzugeben wähle ich handform=ja und definiere den Bereich den wir generieren. Grundsätzlich finde ich die Maske sorgt für ein übersichtlicheres System. Bei Bestandskunden sollten wir im Einzelfall schauen was sinnvoll ist.

2. Benutzerdokumente Sollten immer eine automatische Nummerierung haben.


Beispiel:

OBJECTID = WebserviceCall GetID_test %MITGLIEDSNUMMER%


Anwendungsfall Autonummerierung


Sollen Objekte, wenn sie schon in Corsa vorhanden sind, aktualisiert und ansonsten mit einer von Corsa vorgegebenen ID im System angelegt werden, so ist das natürlich möglich.

In diesem Fall muss als erstes in Corsa der Nummerierungstyp (1) auf Automatisch eingeschaltet werden. Danach ist ein Start- und ein Stoppwert in identischem Nummernformat (2) zu definieren:

graphic


In der entsprechenden Mapping.INI-Datei ist im Bereich [GLOBAL] beim Feld OBJECTID eine benutzerdefinierte Funktion aufzurufen, die aus den übergebenen Daten z.B. via Querywebserviceabfrage in Richtung Corsa ermittelt, ob das Datenobjekt schon in Corsa vorhanden ist oder nicht. Ist es vorhanden, so muss diese Funktion die ID des Corsaobjektes zurückgeben, ist es neu, so muss eine ID, die zum Nummernformat (2) passt aber noch nicht in Corsa vorhanden ist, zurückzugeben.

Es empfiehlt sich dabei den Stoppwert zu verwenden, falls dieser noch frei ist.


Mit folgender Beispielfunktion wird geschaut, ob die Personen-ID schon existiert. Wenn ja, wird die ID zurückgegeben, wenn nicht der Stoppwert (Das ist nur ein Beispiel und dient der Veranschaulichung! Das Szenario ist in der Realität nicht sinnvoll. Hier müssen andere Kriterien herangezogen werden, um beurteilen zu können, ob das Objekt schon vorhanden ist. Das Beschreiben eines UniqueKey-Felder ist nicht mehr notwendig):

Get_ID.tbc:

proc GetID_Sample {webserviceObject id} {
 set id [lindex [$webserviceObject GetFields P $id Vorlage:Persoon.persoon id {}] 1]
 if {$id eq ""} {
  set id "PM9999"
 }
 return $id
} 
  
 

Anwendungsfall *SKIP*


Es gibt Szenarios, bei denen es sinnvoll ist Daten nur einmal anzulegen und alle weiteren Aktualisierungen zu ignorieren.

Das gilt zum Beispiel für die Anlage von Dummykontaktdaten, die immer dann angelegt werden, wenn Akten und Dokumente schon verknüpft werden sollen, die reale Adresse aber noch nicht zur Verfügung steht.

Ein weiterer Anwendungsfall ist zum Beispiel die Anlage von Monatsakten, die zwingend vorhanden sein müssen, aber nicht mehr geändert werden.

Für diese Skip-Szenarios muss von einer benutzerdefinierten Funktion geprüft werden, ob das Objekt schon vorhanden ist. Wenn nicht wird die ID oder beim "Anwendungsfall Autonummerierung" der Stoppwert zurückgegeben. Wenn doch, so wird die ID gefolgt von der Zeichenkette "*SKIP*" übergeben.

Dadurch werden aber nicht die mitgeführten Dateien bearbeitet. Werden sie nicht separat betrachtet, so landen sie, da sie für den Importservice unbekannt sind, im Errorverzeichnis. Was im SKIP-Fall passiert, wird unter [SKIP,CMD] definiert.

Skip.tbc

proc Skip_Sample {webserviceObject id} {
 set id [lindex [$webserviceObject GetFields P $id Vorlage:Persoon.persoon id {}] 1]
 if {$id ne ""} {
 append id "*SKIP*"
 }
 return $id
}

TYPE

vormals OBJECTKIND

Es muss eine gültige Objektart zugewiesen werden, wenn ein neues Objekt angelegt wird. Bei einer Datenaktualisierung schadet es aber nicht.


Beispiel:

TYPE = Return MITGL

KIND

vormals OBJECTTYPE

Es muss ein gültiger Objekttyp zugewiesen werden.


Beispiel:

KIND = Return P

SYSTEMFIELDS

Systemfelder (Tabelle + Feldname aus std/w-brbvs0.r) werden mit den Daten aus der CSV-Datei, Funktionsergebnissen oder statischen Werten gefüllt. Die Felder können auch in einem Importkanal direkt abgefragt werden:

= LogMessage "Queryfields = [WebserviceCall Direct GetQueryFields D]"
= LogMessage "Registrationfields = [WebserviceCall Direct GetRegistrationFields D]"

graphic

Dabei sollte eine Doppeldefinition der Systemfelder vermieden werden, da die Werte der ersten Definition sonst verloren gehen.


Leere Macros werden automatisch entfernt! Ob leere Felder an Corsa übergeben werden, wird mit UseEmptyValues gesteuert.

Felder, die mit _tmp_ beginnen, werden nicht an Corsa übergeben.

Ist isCSV auf 0 gesetzt, so befindet sich der gesamte Inhalt der Datendatei in %_TOTALTEXT%.


Lautet das Feld MEMOTEXT, so wird der Inhalt an das Memofeld übergeben (bei SERVICE == 1). Aber Achtung, je nach Konfiguration des Corsa-Parameters "mmss" wird der Inhalt hier angehängt oder überschrieben.

Die Section steht bei SERVICE == 1 und 2 zur Verfügung, bei 1 wird an Corsa übergeben, bei 2 muss der Export manuell exportiert werden.

Beispiel:

[SYSTEMFIELDS]
persoon.naam       = Return %NAME%
persoon.naam       = string trim %persoon.naam%
                   = LogMessage %persoon.naam%
persoon.roepnaam   = Return %VORNAME%
persoon.geslacht   = string map {"Mann" "m" "Frau" "v"} %GESCHLECHT%
adres.straat/prv   = Return %STRASSE%
adres.postkode/prv = Return %PLZ%
adres.plaats/prv   = Return %ORT%
MEMOTEXT           = Return "Memo von %_TMP_OID%"


InsertFields

Mit der Funktion InsertFields {field1 value1 field2 value .... field<n> value<n>}, die (nur) in [SYSTEMFIELDS] und [REFERENCEFIELDS] verwendet werden darf, können dynamisch Felder und die zugehörigen Befehle ins Regelwerk eingefügt werden. Sie werden an der Stelle eingefügt, wo die Funktion definiert ist.

_TMP_EXPLODE = InsertFields {data/InsertField01 "Wert IF 01" data/InsertField02 "Wert IF 02"}


DeleteField

Mit DeleteField kann ein Feld der [FIELDS]-Section gelöscht werden, so dsss es weder im Output, noch in Abfragefunktion auftaucht. Das ist z.B dann sinnvoll, wenn vom Vorprozess Informationen als Felder vorhanden sind, die in nachfolgenden Prozessen nicht mehr auftauchen sollen.

DeleteField "data/own/id"

InsertArray

Mit InsertArray <path to array> <key/value list>, das (nur) in [FIELDS] bei SERVICE == 4 oder 8 verwendet werden darf, können ganze Arrays in die Datenstruktur gebracht werden. Dabei wird als erstes der Weg bis zum Array übergeben, danach eine Listen mit den einzelnen Arrayzeilen als Key/Value-Liste. Es können auch verschachtelte Strukturen definiert werden, die dann rekursiv aufgelöst werden. Dafür wird statt des Schlüssels der Pfad ab der aktuellen Position angegeben und statt des Wertes eine Liste, die weitere Listen mit den einzelnen Arrayelementen enthält. Das ganze kann auch noch mit Wertarrays (s.DATATYPES) kombiniert werden.

Das Verhalten des Quotings kann ab 19.56 mit den beiden Parametern IA_QUOTE_QUOTES (Quoten der Anführungszeichen) und IA_QUOTE_BRACES (Quoten der geschweiften Klammern) sowohl global als auch beim Import definiert werden. Standardmäßig sind beide angeschaltet.

_TMP_LIST    = list {value1 11 value2 12 value3 13} {value1 21 value2 22 value3 23} {value1 31 value2 32 value3 33 inner/array {{iv11 11 iv12 12} {iv21 21 iv22 22}}}
_TMP_EXPLODE = InsertArray data/InsertArray %_TMP_LIST%

Nicht verwendbare Corsa-Systemfelder

Unimportable

CX_FIELDS

Die Section wird unterstützt, wenn SERVICE == 4 ist. In ihr erfolgt die Definition der JSON-Struktur, die an den ClassiX Webservice (oder ggf. andere Rest-Webservices, die Json verwenden) übergeben wird. Es wird aber empfohlen statt CX_FIELDS lieber FIELDS zu benutzen!

Die einzelnen Ebenen der Jsonstruktur werden im Regelwerk per "/" getrennt. Sie beziehen sich auf die einzelnen Datensätze. Kopfdaten können über die Variable ::mapping::headerValues(<FELDNAME>) übergeben werden.

[CX_FIELDS]
data/documentType              = Return %JSON.DOCUMENTTYPE%
; check, whether bad values exist
data/invoice/deliveredSpanDate = CheckDefinition [regsub {^-$} %INVOICE.DELIVERY.SPANDATE% ""]
; empty Array
data/invoice/amounts/taxes     = Return "\[\]"

                                 set ::mapping::headerValues(headerValue1) 42          
                                 set ::mapping::headerValues(headerValue2) "The Hitchhiker's Guide to the Galaxy"

data/funnyValue/set            = Return *INIT*
; ==> "set": "*INIT*"
data/funnyValue/set2           = Set data/funnyValue/set {new value}
; ==> "set2": "new value"
data/funnyValue/set3           = Return %data/funnyValue/set%
; ==> "set3": "new value"

FIELDS

Die Section wird unterstützt, wenn SERVICE > 1 ist. Bei SERVICE == 4 kann sie alternativ zu CX_FIELDS verwendet werden.


Bei SERVICE == 2 und UPLOADDATA == 1 wird der Inhalt der Feldes WS_DATA_GENERATED direkt als hochzuladener Content an einen Webservice übergeben, allerdings nur, wenn das Feld auch definiert ist. Wenn es den Wert *NOT_DEF* hat, so gilt es ebenfalls als nicht definiert! Ob eine Übergabe bei leerem Inhalt erfolgt, wird über SERVICE,SENDEMPTYDATA gesteuert, dass standardmäßig 0 ist. Bei SERVICE == 2 kann mit FILE_DATA_GENERATED auch der Inhalt einer zu schreibenden Datendatei festgelegt werden, wenn die Daten im Filesystem abgelegt werden soll, bei SERVICE == 4 oder 8 wird die automatisch generierte JSON bzw. XML in die Datei geschrieben.

[FIELDS]
WS_DATA_GENERATED   = Return %_TOTALTEXT%
FILE_DATA_GENERATED = BuildPADStructure %_TOTALTEXT%

REFERENCEFIELDS

Zusatzfelder werden mit den Daten aus der CSV-Datei, Funktionsergebnissen oder statischen Werten gefüllt. Links vom Gleichheitszeichen befindet sich das Corsa Zusatzfeld.

Dabei sollte eine Doppeldefinition der Systemfelder vermieden werden, da die Werte der ersten Definition sonst verloren gehen.

Werte in ein Mehrfach-Zusatzfeld schreiben funktioniert mit dem Trennzeichen, welches unter System.ini#ValueSep konfiguriert ist.


Leere Macros werden automatisch entfernt! Ob leere Felder an Corsa übergeben werden, wird mit UseEmptyValues gesteuert.

Felder, die mit _tmp_ beginnen, werden nicht an Corsa übergeben.

Ist isCSV auf 0 gesetzt, so befindet sich der gesamte Inhalt der Datendatei in %_TOTALTEXT%.

Beispiel:

[REFERENCEFIELDS]
MGNR    = Return %MITGLIEDSNUMMER%
_TMP_NR = Return 1
_TMP_NR = expr { %_TMP_NR% + 1 }
          LogMessage %_TMP_NR%  
 

InsertFields

Mit der Funktion InsertFields {field1 command1 field2 command2 .... field<n> command<n>}, die (nur) in [SYSTEMFIELDS] und [REFERENCEFIELDS] verwendet werden darf, können dynamisch Felder und die zugehörigen Befehle ins Regelwerk eingefügt werden. Sie werden an der Stelle eingefügt, wo die Funktion definiert ist.

ATTRIBUTES

Bei UseWebservice == 8 (XML) gibt es keine [REFERENCEFIELDS], dafür aber [ATTRIBUTES]. Hier können Attribute für ein Tag definiert werden. Dabei muss die linke Seite der Definition einem bereits definiertem Tag entsprechen. Die Attribute werden als Liste mit abwechselnd Key und Value definiert.

[FIELDS] 
data/misc/ibanCode = CheckDefinition %DOC.BANK.IBAN%
...
[ATTRIBUTES]
data/misc/ibancode = list blz 40164024 kto 3052711


DATATYPES

Bei UseWebservice == 4 (json) werden die Werte standardmäßig als String definiert. Das ist aber nicht immer gewünscht, da es auch numerische Werte, null oder gar Wertearrays gibt. Alle Felder, die in [FIELDS] oder [CX_FIELDS] verwendet wurden, können hier typmäßig umdefiniert werden. Das gilt auch für Wertearrays innerhalb von Arrays! Dabei gibt es die folgenden gültigen Werte (ACHTUNG: direkt zu definieren, ohne Return o.ä.):

  • array: Mit der Deklaration array wird eine Liste in der Felddefinition automatisch in die Jsonarraystruktur umgewandelt (z.B [1,2,3,4,5])
  • noQuoting oder <leer> sorgen dafür, dass keine Anführungsstriche um den Wert in der Jsonstruktur ergänzt werden (z.B 1 oder null)


[FIELDS]
data/numeric = Return 4711
data/array   = list 1 2 3 4 5
data/null    = Return null 

[DATATYPES]
data/numeric = noQuoting
data/array   = array
data/null    =

VARTAB

VarTab-Daten können in Corsa via Importservice angelegt, geändert oder gelöscht werden.

Die entsprechende Konfiguration passiert hier.

Werden keine VARTAB-Daten benötigt, so kann die Konfiguration auch weggelassen werden.


Zusätzlich zu den hier beschriebenen Parametern müssen noch OBJECTTYPEund OBJECTIDdefiniert sein,

Es ist möglich, ganze Tabelle über eine CSV-Datei einzulesen, wenn isCSV==1 gesetzt ist, sonst können die Werte direkt in der Mapping.dat oder einer inkludierten Funktion bereitgestellt werden, oder es kann, wenn lizenziert, die CIMINER-Funktionalität verwendet werden.


TABLEID

Die ID der zu bearbeitenden VarTab wird hier angegeben.

Wenn VarTabs verwendet werden, ist dieses Feld zwingend erforderlich!


Beispiel:

[VARTAB]
TABLEID = Return wThemaSB


SCREENID

Die SCREENID wird hier angegeben.

Wenn VarTabs verwendet werden, ist dieses Feld zwingend erforderlich!


Beispiel:

[VARTAB]
SCREENID = Return 1010


INDEXCMD

Hier muss zwingend ein Kommando eingegeben werden, mit dem ein eindeutiger Bezeichner generiert wird, um den REPLACE oder den DELETE-Befehl zu ermöglichen. Dabei können die Spaltenbezeichner der VarTab als Variablen angesprochen werden.

ACHTUNG: Variablennamen sind case sensitive!

Ein eindeutiger Schlüssel kann immer über die $regel_id generiert werden.

ACHTUNG: das zusätzliche $ bei der $regel_id muss weggelassen werden (also nicht $$regel_id oder so etwas).

Beispiel:

[VARTAB]
INDEXCMD = list subst {$regel_id}

oder

[VARTAB]
INDEXCMD = list subst {$wBemerk}


ADD

Datenzeilen, die angelegt werden sollen, werden hier definiert.

Es handelt sich um eine Liste, die aus n Sublisten besteht. Jede dieser Sublisten ist eine Key/Value-Liste. Es werden immer abwechselnd die Spaltenbezeichnung der VarTag ($regel_id heißt hier regel_id!) und der zugehöriger Wert eingegeben.

Steht der Schalter isCSV auf 1, so wird dieser Ausdruck für jede Datenzeile durchlaufen. Die Spaltenüberschriften der CSV-Datei können dabei wie gehabt verwendet werden (%THEMA% etc.).

Es können auch benutzerdefinierte Funktionen aus dem Include-Verzeichnis verwendet werden, um die Datenstruktur zu erstellen.

ACHTUNG: ###-Felder können nicht editiert werden!


Beispiel:

[VARTAB]
ADD =  list [list wSB %WSB%  wThema %WTHEMA% wBemerk %WBEMERK%]


REPLACE

Datenzeilen, die geändert werden sollen, werden hier definiert.

Es handelt sich um eine Liste, die aus n Sublisten besteht. Jede dieser Sublisten ist eine Key/Value-Liste. Es werden immer abwechselnd die Spaltenbezeichnung der VarTag ($regel_id heißt hier regel_id!) und der zugehöriger Wert eingegeben.

Steht der Schalter isCSV auf 1, so wird dieser Ausdruck für jede Datenzeile durchlaufen. Die Spaltenüberschriften der CSV-Datei können dabei wie gehabt verwendet werden (%THEMA% etc.).

Es können auch benutzerdefinierte Funktionen aus dem Include-Verzeichnis verwendet werden, um die Datenstruktur zu erstellen.

Durch den Ausdruck in INDEXCMD wird ermittelt, welcher Datensatz betroffen ist. Existieren mehrere in Frage kommende Sätze, so wird eine Fehlermeldung erzeugt. Existiert kein Treffer, so werden die Daten angehängt.

ACHTUNG: ###-Felder ,.,mk nop äp3,

+nicht editiert werden!


Beispiel:

[VARTAB]
REPLACE = list [list wSB %WSB% wThema %WTHEMA% wBemerk %WBEMERK%]


DELETE

Datenzeilen, die gelöscht werden sollen, werden hier definiert.

Es handelt sich um eine Liste, die aus n Sublisten besteht. Jede dieser Sublisten ist eine Key/Value-Liste. Es werden immer abwechselnd die Spaltenbezeichnung der VarTag ($regel_id heißt hier regel_id!) und der zugehöriger Wert eingegeben.

Steht der Schalter isCSV auf 1, so wird dieser Ausdruck für jede Datenzeile durchlaufen. Die Spaltenüberschriften der CSV-Datei können dabei wie gehabt verwendet werden (%THEMA% etc.).

Es können auch benutzerdefinierte Funktionen aus dem Include-Verzeichnis verwendet werden, um die Datenstruktur zu erstellen.

Durch den Ausdruck in INDEXCMD wird ermittelt, welcher Datensatz betroffen ist. Existieren mehrere in Frage kommende Sätze, so wird eine Fehlermeldung erzeugt.

ACHTUNG: ###-Felder können nicht editiert werden!


Beispiel:

[VARTAB]
DELETE = list [list regel_id %ID%]

LINKS

In der Sektion Links können Zugriffsbereiche und unterstützt Objekt-/Objektverknüpfungen definiert werden.



CONFIDENTIALITIES

Mit diesem Feld werden die Zugriffsbereiche erstellt.

Diese Feld kann mehrfach definiert werden. Die einzelnen Definitionen werden einfach hintereinander ausgeführt.

Das Ergebnis, das hier zugewiesen wird, muss eine mit Leerzeichen getrennte TCL-Liste sein. Eventuell vorhandene andere Steuerzeichen (þ) können in einer benutzerdefinierten Funktion substituiert werden.

Ist ein hinzuzufügender Zugriffsbereich schon vorhanden, so gibt es keine Fehlermeldung!

Um einen Zugriffsbereich zu entfernen kann dies per WebserviceCall realisiert werden

[SYSTEMFIELDS]
_TMP_ZB               = Return "MGVERW"
                      = if {[WebserviceCall Direct ModConfidentialities "MC_Delete" "S" %_TMP_DOCID% {%_TMP_ZB%}] == 1} {LogMessage "Zugriffsbereich %_TMP_ZB% wurde von %_TMP_DOCID% getrennt"}

[ERROR]
                      = WebserviceCall Direct ModConfidentialities "MC_Add" "S" %_TMP_DOCID% {%_TMP_ZB%}

CONFIDENTIALITIES_AFTERUPLOAD

Mit diesem Feld werden die Zugriffsbereiche erstellt. Im Gegensatz zu CONFIDENTIALITIES werden diese Zugriffsbereich erst gesetzt, wenn die Dateien schon hochgeladen sind.

Diese Feld kann mehrfach definiert werden. Die einzelnen Definitionen werden einfach hintereinander ausgeführt.

Das Ergebnis, das hier zugewiesen wird, muss eine mit Leerzeichen getrennte TCL-Liste sein. Eventuell vorhandene andere Steuerzeichen (þ) können in einer benutzerdefinierten Funktion substituiert werden.

Ist ein hinzuzufügender Zugriffsbereich schon vorhanden, so gibt es keine Fehlermeldung!

Dieser Parameter sollte nicht unbedacht verwendet werden, da sonst ggf. Dokumente eingesehen werden können, die nicht eingesehen werden sollten.


LINKOBJECTTYPE

Mit diesem Feld wird der Objekttyp des zu verknüpfenden Objektes beschrieben.

Diesem Feld muss immer ein Eintrag LINKOBJECTIDS folgen!

Diese Feld kann mehrfach definiert werden. Die einzelnen Definitionen werden einfach hintereinander ausgeführt.

Das Ergebnis, das hier zugewiesen wird, muss eine definierter und kombinierbarer Objekttyp sein.


Beispiel:

[LINKS]
LINKOBJECTTYPE = Return S
LINKOBJECTIDS  = list AD00000004 AD00000003
LINKOBJECTTYPE = Return D
LINKOBJECTIDS  = Return AK00001.01

OPTIONS

Das Feld muss hinter LINKOBJECTTYPE stehen.

Hier können für Person/Organisation oder Organisation/Organisation die Kanteninformationen definiert werden.

Dabei können $objectID und $linkObjectID verwendet werden. Die Definition wird für alle $linkObjectID durchlaufen.


Vor dem Verknüpfen wird eine eventuelle Verknüpfung gelöscht, da sonst kein Aktualisieren möglich ist!

Wird anstelle der einzelnen Verknüpfungsdaten "-DELETE" verwendet, so wird eine vorhandene Verlinkung gelöscht.


Beispiel:

OPTIONS = list Department $objectID Function $linkObjectID Fax Faxen Phone 02304/123456
OPTIONS = list Department Sachbearbeitung Function Sachbearbeiter Fax 02304/654321 Phone 02304/123456 Email test@test.de DateFrom 01/01/2016 DateUntil 31/12/2016
; LÖSCHEN EINER VERKNÜPFUNG
OPTIONS = Return "-DELETE"

LINKOBJECTIDS

Mit diesem Feld wird der Objekttyp des zu verknüpfenden Objektes beschrieben.

Diesem Feld muss immer ein Eintrag LINKOBJECTTYPE vorausgehen!

Diese Feld kann mehrfach definiert werden. Die einzelnen Definitionen werden einfach hintereinander ausgeführt.

Das Ergebnis, das hier zugewiesen wird, muss eine mit Leerzeichen getrennte TCL-Liste sein. Eventuell vorhandene andere Steuerzeichen (þ) können in einer benutzerdefinierten Funktion substituiert werden.

Ist eine zu erstellende Objektverknüpfung schon vorhanden, so kommt es zu Fehler und bei entsprechender Konfiguration zum Beenden des Imports. Das kann jedoch einfach durch eine benutzerdefinierte Funktion abgefangen werden, die nur die Objektverknüpfungen in LINKOBJECTIDS zurückgibt, die noch nicht da sind.


Beispiel:

[LINKS]
LINKOBJECTTYPE   = Return S
LINKOBJECTIDS    = list AD00000004 AD00000003
LINKOBJECTTYPE   = Return D
LINKOBJECTIDS    = list AK00001.01INK

RTYPE

Ein spezieller Verknüpfungstyp kann zwischen Objekten angegeben werden. Dieser Verknüpfungstyp muss in Corsa vorhanden sein.

Dieser Verknüpfungstyp wird für alle hier definierten LINKOBJECTIDS verwendet, es sein denn, die RTYPES liegen auch als Liste vor und haben gleich viele Elemente wie die ID-Liste; dann wird jedes Objekt mit dem zugehörigem Typen verbunden.


Beispiel:

[LINKS]
LINKOBJECTTYPE   = Return S
LINKOBJECTIDS    = list AD00000004 AD00000003
RTYPE            = list ATT MAIL
LINKOBJECTTYPE   = Return D
LINKOBJECTIDS    = list AK00001.01INK

DOCTYPES

Mit diesem Feld werden die Vorgangstypen definiert.

Diese Feld kann mehrfach definiert werden. Die einzelnen Definitionen werden einfach hintereinander ausgeführt.

Das Ergebnis, das hier zugewiesen wird, muss eine mit Leerzeichen getrennte TCL-Liste sein. Eventuell vorhandene andere Steuerzeichen (þ) können in einer benutzerdefinierten Funktion substituiert werden.

Es können mehrere Workflows des selben Vorgangstypen gestartet werden.

UPLOAD

Der Uploadblock wird für jede Zeile einer CSV bei isCSV == 1 ausgeführt. Die Schlüssel funktionieren nur in der hier definierten Reihenfolge korrekt! Dabei gelten NAT, ARC, OCR, TMB nur für UseWebservice == 1 und FILE für UseWebservice == 2!


NAT

Name der Quelldatei inklusive Pfad. Der aktuelle Importpfad steht in ::main::importDir.

Wenn der Dateiname identisch zur Datendatei (z.B. IDX) und immer eine .pdf ist:

NAT = ErrorIfNotExists [file rootname %_FILENAME%].pdf

Wenn die Datei mit im Unterordner liegt, der Dateiname aber nicht identisch zur IDX ist, sondern im Feld NATFILENAME in der IDX steht:

NAT = ErrorIfNotExists [file join [file dirname %_FILENAME%] %NATFILENAME%]

Wenn die Datei mit Pfad im Feld NATFILENAME in der IDX steht:

NAT = ErrorIfNotExists %NATFILENAME%

Wenn die Datei ohne Pfad im Feld NATFILENAME in der IDX steht und die Dateien an einem fest definierten Ort liegen:

NAT = ErrorIfNotExists [file join "D:/invoices/data/" %NATFILENAME%]

NATVERSION

Die Version der Quelldatei. Dabei gibt -1 die aktuelle Version an und 0 die nächste freie Nummer.


NATVERSION = Return 0

NATDSACTION

optional

DSAction Anweisung für die Datei. Wenn sie nicht definiert ist, so wird DSActionCMD verwendet.

Bei -action NONE wird die CMC-Standardeinstellung verwendet, bei <> NONE werden die definierten Funktionen zusätzlich aktiviert. Bei "-action {DSAction {}}" wird keine Aktion von der CMC ausgeführt. Es können Funktionen einzeln angegeben werden:

- acPDF -> Erstellt die Archivdatei
- acFTI -> Erstellt die TXT Datei mit Abbyy oder per PDF to TXT
- acTMB -> Erstellt das Vorschaubild aus der PDF (Thumbnail)


; CMC Einstellungen verwenden
NATDSACTION = Return "-action NONE"

oder

; CMC Einstellungen verwenden + PDF-Erstellung + FTI Erstellung
NATDSACTION = Return "-action {DSAction { acPDF acFTI }}"

NATDESCRIPTION

Der Versionstext, der hier definiert ist, wird in Corsa verwendet.

Wird dieser Parameter weggelassen, so wird der Standardtext "Importservice" verwendet.


NATDESCRIPTION = Return "geändert in der mapping.ini"

NATDOCUMENTNAME

Der Dokumentname, der in Corsa angezeigt wird, kann explizit gesetzt werden.


NATDOCUMENTNAME = Return {ein Bild.tif}

NATMODE

MODE steht für move/delete und steuert, ob die Datei da liegen bleibt, wo sie ist (0), oder, je nach BackupDir-Einstellung verschoben oder gelöscht wird (1). Der Standard ist 1.

Bei 2 wird die Datei gelöscht, auch wenn Backup eingestellt ist. Bei 3 wird sie auch im Fehlerfall in der späten Interpretation gelöscht. Bei 4 wird sie sogar im Fehlerfall in der frühen Interpretation gelöscht.


NATMODE = Return 0

NATSHA256

Steuerung der Überprüfung des Uploads mit Hilfe des SHA256-Vergleichs, der Standard ist 1. Die Mappingdefinition überschreibt die Importdefinition.

Bei 0 erfolgt kein Vergleich. Bei 1 wird der SHA256 automatisch generiert und mit dem Corsawert verglichen. Bei Übergabe des SHA256 wird dieser verwendet und mit dem Corsawert verglichen. Das ist immer dann sinnvoll, wenn er sowieso schon generiert wurde.

 NATSHA256 = Return %uniqueID%


NATDELETEVERSION

Es wird definiert, ob alle Versionen (falls von den Rechten möglich) oberhalb der angegebenen Version gelöscht werden sollen. Diese Angabe ist optional, als Standard wird die Einstellung bei der Importdefinition in der system.ini verwendet.

 NATDELETEVERSION = Return 1

ARC

Name der Archivdatei inklusive Pfad. Der aktuelle Importpfad steht in ::main::importDir.


ARC = ErrorIfNotExists[file rootname %_FILENAME%].pdf

ARCVERSION

Die Version der Archivdatei. Dabei gibt -1 die aktuelle Version an.


ARCVERSION = Return -1

ARCDSACTION

optional

DSAction Anweisung für die Archivdatei. Wenn sie nicht definiert ist, so wird {} verwendet.

Bei -action NONE wird die CMC-Standardeinstellung verwendet.


ARCDSACTION = Return "-action NONE"

ARCMODE

MODE steht für move/delete und steuert, ob die Datei da liegen bleibt, wo sie ist (0), oder, je nach BackupDir-Einstellung verschoben oder gelöscht wird (1). Der Standard ist 1.

Bei 2 wird die Datei gelöscht, auch wenn Backup eingestellt ist.


ARCMODE = Return 0

ARCSHA256

Steuerung der Überprüfung des Uploads mit Hilfe des SHA256-Vergleichs, der Standard ist 1. Die Mappingdefinition überschreibt die Importdefinition.

Bei 0 erfolgt kein Vergleich. Bei 1 wird der SHA256 automatisch generiert und mit dem Corsawert verglichen. Bei Übergabe des SHA256 wird dieser verwendet und mit dem Corsawert verglichen. Das ist immer dann sinnvoll, wenn er sowieso schon generiert wurde.

 ARCSHA256 = Return %uniqueID%

OCR

Name der OCRdatei inklusive Pfad. Der aktuelle Importpfad steht in ::main::importDir.


OCR = ErrorIfNotExists[file rootname %_FILENAME%].txt

OCRVERSION

Die Version der OCR-Datei. Dabei gibt -1 die aktuelle Version an.


OCRVERSION = WebserviceCall  ::DocVersion::NextVersion %OBJECTID%

OCRDSACTION

optional

DSAction Anweisung für die OCRdatei. Wenn sie nicht definiert ist, so wird {} verwendet.

Bei -action NONE wird die CMC-Standardeinstellung verwendet.


OCRDSACTION = Return "-action NONE"

OCRMODE

MODE steht für move/delete und steuert, ob die Datei da liegen bleibt, wo sie ist (0), oder, je nach BackupDir-Einstellung verschoben oder gelöscht wird (1). Der Standard ist 1.

Bei 2 wird die Datei gelöscht, auch wenn Backup eingestellt ist.


OCRMODE = Return 0


OCRSHA256

Steuerung der Überprüfung des Uploads mit Hilfe des SHA256-Vergleichs, der Standard ist 1. Die Mappingdefinition überschreibt die Importdefinition.

Bei 0 erfolgt kein Vergleich. Bei 1 wird der SHA256 automatisch generiert und mit dem Corsawert verglichen. Bei Übergabe des SHA256 wird dieser verwendet und mit dem Corsawert verglichen. Das ist immer dann sinnvoll, wenn er sowieso schon generiert wurde.

 OCRSHA256 = Return %uniqueID%

TMB

Name der Thumbnaildatei inklusive Pfad. Der aktuelle Importpfad steht in ::main::importDir.


TMB = ErrorIfNotExists[file rootname %_FILENAME%].png

TMBVERSION

Die Version der Thumbnaildatei. Dabei gibt -1 die aktuelle Version an.


TMBVERSION = Return -1

TMBDSACTION

optional

DSAction Anweisung für die Thumbnaildatei. Wenn sie nicht definiert ist, so wird {} verwendet.

Bei -action NONE wird die CMC-Standardeinstellung verwendet.


TMBDSACTION = Return "-action NONE"

TMBMODE

MODE steht für move/delete und steuert, ob die Datei da liegen bleibt, wo sie ist (0), oder, je nach BackupDir-Einstellung verschoben oder gelöscht wird (1). Der Standard ist 1.

Bei 2 wird die Datei gelöscht, auch wenn Backup eingestellt ist.


TMBMODE = Return 0


TMBSHA256

Steuerung der Überprüfung des Uploads mit Hilfe des SHA256-Vergleichs, der Standard ist 1. Die Mappingdefinition überschreibt die Importdefinition.

Bei 0 erfolgt kein Vergleich. Bei 1 wird der SHA256 automatisch generiert und mit dem Corsawert verglichen. Bei Übergabe des SHA256 wird dieser verwendet und mit dem Corsawert verglichen. Das ist immer dann sinnvoll, wenn er sowieso schon generiert wurde.

 TMBSHA256 = Return %uniqueID%

FILE

Bei SERVICE == 2, 4 und 8 werden Dateien in einem Verzeichnis abgelegt, wenn das definiert ist. Mit FILE-Anweisungen können die abzulegenden Dateien definiert werden. Dabei wird bei FILE eine Liste erwartet.

 FILE     = glob -noc [file join [file dirname %_FILENAME%] *.pdf]

FILEMODE

Zu jedem FILE kann ein FILEMODE definiert werden (1 == verschieben, 0 == Datei liegen lassen). Dieser Schalter ist optional und im Standard auf 1.

 FILE        = list [$::impsXML GetXMLValue NAME %_TOTALTEXT%]
 FILEMODE    = Return 0
 FILE        = list C:/test/filePlus/testdata/MANIFEST_at8.6.txt
 FILEMODE    = Return 1

TIMESTAMP

Wenn TIMESTAMP aktiviert ist, so wird Daten- und Dokumentdatei(en) automatisch ein Zeitstempel hinzugefügt.

 TIMESTAMP = Return 0

Optional, default == 1

ACHTUNG: Für jede Datei wird ein neuer TIMESTAMP erzeugt. Sollen mehrere Dateien den gleichen TIMESTAMP bekommen, so ist der Schalter auf 0 zu setzen und die Dateien sollten im Mapping-Regelwerk umbenannt werden. Einen aktuellen TIMESTAMP liefer ::String::GetTimeStamp.

SUBDIR

Wenn die Dateien aus FILE nicht in ein plattes Verzeichnis, sondern in ein Unterverzeichnis gelegt werden sollen, so ist das Unterverzeichnis zu definieren:

 SUBDIR   = ::String::GetTimeStamp

ACHTUNG: Falls SUBDIR ausgeschaltet ist, der Dateiname nicht eindeutig ist und er nicht überschrieben werden (s. OVERWRITEFILE) soll, so muss entweder manuell im Mapping-Regelwerk oder mit der Verwendung von TIMESTAMP dafür gesorgt werden, dass die Dateinamen eindeutig werden.

ENCODING

Wenn die Dateien aus FILE nicht als utf-8 gespeichert werden sollen, so kann das definiert werden

 ENCODING = GetSystemEncoding


OVERWRITEFILE

Soll eine Zieldatei, sofern sie schon vorhanden ist, überschrieben werden, so wird das hier eingestellt.

 OVERWRITEFILE = Return 1

Optional, default == 0

ACHTUNG: OVERWRITEFILE gilt nicht für DATAFILE. Das wird immer überschrieben (s. WRITEMODE)!

WRITEMODE

Schreibmodus nur für DATAFILE. Standardmäßig wird der Inhalt angehängt, wenn schon eine Datei mit gleichem Namen existiert. Das kann durch den Schreibmodus (w, w+) geändert werden.

 WRITEMODE = w

Optional, default == "a"

DATAFILE

Der Name einer Datendatei definiert werden, die automatisch im zugehörigen Verzeichnis angelegt wird, kann definiert werden. Dabei wird der im Mapping-Regelwerk zugewiesen Inhalt aus FIELDS,FILE_DATA_GENERATED als Textinhalt geschrieben (SERVICE == 2) oder es wird direkt die generierte JSON oder XML verwendet (SERVICE == 4 oder 8).

 ; Beispiel für SERVICE == 2
 [FIELDS]
 FILE_DATA_GENERATED = Return %CONTENT%
 
 [UPLOAD]
 DATAFILE = Return an3xorg.txt
 ; Beispiel für SERVICE == 4 oder 8
 [FIELDS]
 invoice/no   = Return %NO%
 invoice/date = Return %DATE%
 
 [UPLOAD]
 ; bei SERVICE == 4
 DATAFILE = Return veg_269.json
 ; bei SERVICE == 8
 ;DATAFILE = Return veg_269.xml

ACHTUNG: Die Datei wird überschrieben, selbst wenn OVERWRITEFILE==0 gesetzt ist.

DECLARE

Mit dem DECLARE-Block ist es möglich Dateien, die nicht hochgeladen werden sollen, trotzdem der automatischen Sicherung zuzufügen oder sie zu löschen. Dabei wird die generelle Einstellung berücksichtig, ob gesichert oder gelöscht wird. Das lässt sich jedoch über FILEMODE individuell steuern.


Neu ab der Version 15.6

FILENAMES

Es wird eine Liste mit Dateinamen (inkusive Pfad) eingegeben, die dann automatisch von IMPS verarbeitet wird, auch wenn sie nicht hochgeladen wird.

 FILENAMES = list "[file rootname %_FILENAME%].docx" "[file join [file dirname %_FILENAME%] test.idx]" 
 FILENAMES = list [file join [file dirname %_FILENAME%] test.pdf]
 FILEMODE  = Return 2

FILEMODE

MODE steht für move/delete und steuert, ob die Datei da liegen bleibt, wo sie ist (0), oder, je nach BackupDir-Einstellung verschoben oder gelöscht wird (1). Der Standard ist 1.

Bei 2-4 wird die Datei gelöscht, auch wenn Backup eingestellt ist, allerdings mit folgenden Unterschieden:

  • 2: Im Fehlerfall wird die Datei nicht gelöscht, sondern in den Errorordner verschoben
  • 3: Tritt der Fehler erst während der späten Interpretation auf, so wird die Datei gelöscht, sonst in den Errorordner verschoben
  • 4: Die Datei wird immer gelöscht, selbst wenn der Fehler in der frühen Interpretation auftriff und Datenverlust droht (VORSICHT!)

POSTIMPORT

Diese Section ist für die Befehlsdefinition gedacht. Sie wird nach dem Regelwerk, aber vor ERROR und OK, ausgeführt.

Bei isCSV==1 wird es für jede Datenzeille ausgeführt.

[POSTIMPORT]
CMD = set ::errlevel %OBJECTID%
CMD = LogMessage "Fehler mit Fehlercode $::errlevel"

ERROR

Diese Section ist für die Befehlsdefinition gedacht, die dann ausgefährt wird, wenn es bei der Interpretation der Mapping.dat einen Fehler gibt.

So können z.B. bereits angelegte Objekte (nur aus benutzerdefinierten Funktionen möglich) wieder entfernt werden. Die Message MAPPING_ERROR wird erst danach ausgeführt.

Bei isCSV==1 wird es für jede Datenzeille ausgeführt. Sollen für alle aufgelaufenen Zeilen Dinge zurückgerollt werden, so können sie z.B. in einer Liste gespeichert und im Fehlerfall iterativ abgearbeitet werden.

CMD


Die einzelnen Codezeilen können in mehreren CMD-Anweisungen definiert werden.


In diesem Beispiel wird das erzeugte Objekt genau dann wieder gelöscht, wenn es einen Fehler gegeben hat und das Objekt neu angelegt wurde.


[GLOBAL]
OBJECTID    = Return %_TMP_OID%
OBJECTKIND  = Return DOK
OBJECTTYPE  = Return S

[SYSTEMFIELDS]
TMP_OID            = WebserviceCall ::CreateObject::DocumentByQuery DOK *DUMMY* [list [list qrtReference BATTODO qcAnd qoEqual %tmp_1%]] {{ws-ps_ob.object_type P} {ws-ps_ob.object_id 00000.01}} Vorlage:BATTODO % tmp 1%
_tmp_objectCreated  = Return $::mapping::objectCreated

[ERROR]
CMD = if {%_tmp_objectCreated%} {WebserviceCall Direct DeleteObject "%OBJECTTYPE%" "%OBJECTID%"}

OK

Diese Section ist für die Befehlsdefinition gedacht, die dann ausgefährt wird, wenn es bei der Interpretation der Mapping.dat keinen Fehler gibt.

Bei isCSV==1 wird es für jede Datenzeille ausgeführt. Soll etwas nur einmal z.B. am Ende passieren, so kann das via actualLineCounter und totalLinesCounter gesteuert werden.


CMD


Die einzelnen Codezeilen können in mehreren CMD-Anweisungen definiert werden.

[OK]
CMD = LogMessage "Kein Fehler aufgetreten"

SKIP

Mit dieser Section wird der Code definiert, der bei einem SKIP-Ereignis ausgeführt werden soll.


CMD


Die einzelnen Codezeilen können in mehreren CMD-Anweisungen definiert werden.

[SKIP]
CMD = LogMessage "SKIP: Lösche File [file rootname %_FILENAME%].pdf"
CMD = catch {file delete [file rootname %_FILENAME%].pdf}
CMD = LogMessage "SKIP: Lösche File [file rootname %_FILENAME%].tif"
CMD = catch {file delete [file rootname %_FILENAME%].tif}

LATECOMMANDS

Diese Sektion wird ganz am Ende der mapping.ini ausgeführt. Mit dem Befehl LateTCL können die Werte in die späte Interpretation geschoben werden.


CMD


Die einzelnen Codezeilen können in mehreren CMD-Anweisungen definiert werden.

 [LATECOMMANDS]
 CMD             = LateTCL {LogMessage "mit Fehler in der Verarbeitung und Initwert: $::mapping::testValue"} -mode 0
 CMD             = LateTCL {LogMessage "ohne Fehler in der Verarbeitung"} -mode 1
 CMD             = LateTCL {LogMessage "IMMER - egal ob Fehler oder nicht"}

Soll dabei auf den generierten Inhalt zugegriffen werden (z.B um eine Prüfsumme zu bilden, so passiert das über die Methode GetResponse des Jobobjektes in der späten Interpretation.

 [LATECOMMANDS]
 CMD             = LateTCL {set ::mapping::building_id "[dict get [json::json2dict [$::job GetResponse]] location id]"} -mode 1


Wichtige Hinweise bei der Verwendung von LateTCL. Sie waren schon immer gültig, aber ab der Version 22.0 werden Fehler hier nicht mehr toleriert.

  • Der Block hinter LateTCL muss eine Liste sein. Es darf kein String sein! Wann immer hier Anführungszeichen benutzt werden, ist mit Problemen zu rechnen!
  • Wenn die Liste mit geschweiften Klammern verwendet wird, dann werden Variablen und Funktionen erst in der späten Interpretation umgesetzt.
  • Wenn die Liste in der Form "[list ...]" verwendet wird, dann wird alles schon in der frühen Interpretation umgesetzt. Variablen und Funktionen, die in diesem Szenario erst spät interpretiert werden sollen, werden dann gequotet.


Beispiel:

Mapping

[FIELDS]
                   = set ::custommap::counter 268

[LATECOMMANDS]
; %Prozent-Variablen% stehen nur in der frühen Interpretation zur Verfügung 
CMD = LateTCL [list LogMessage "  *** LATECOMMANDS,CMD loggt %TEST/TIME% *** "]
; %Prozent-Variablen% stehen nur in der frühen Interpretation zur Verfügung
CMD = LateTCL { LogMessage "  *** LATECOMMANDS,CMD loggt %TEST/TIME% *** " }
CMD = LateTCL { LogMessage $::custommap::counter; ::testfuncs::Incr }
; Variablen haben alle der Werte der späten Interpretation
CMD = LateTCL { LogMessage " #001 $::custommap::counter [::testfuncs::Incr ] $::custommap::counter" }
; Der erste Wert wird früh interpretiert, der zweite wird spät interpretiert
CMD = LateTCL [ list LogMessage " #002 $::custommap::counter \[::testfuncs::Incr \] \$::custommap::counter" ]

Protokoll

; %Prozent-Variablen% stehen nur in der frühen Interpretation zur Verfügung 
process transaction: Tcl if 1 {LogMessage {  *** LATECOMMANDS,CMD loggt 1707135615 *** }}
   *** LATECOMMANDS,CMD loggt 1707135615 *** 
; %Prozent-Variablen% stehen nur in der frühen Interpretation zur Verfügung
process transaction: Tcl if 1 { LogMessage "  *** LATECOMMANDS,CMD loggt [Get TEST/TIME] *** " }
   *** LATECOMMANDS,CMD loggt *NOT_DEF* *** 
process transaction: Tcl if 1 { LogMessage $::custommap::counter; ::testfuncs::Incr }
   268
; Variablen haben alle der Werte der späten Interpretation
process transaction: Tcl if 1 { LogMessage " #001 $::custommap::counter [::testfuncs::Incr ] $::custommap::counter" }
   #001 269 270 270
; Der erste Wert wird früh interpretiert, der zweite wird spät interpretiert
process transaction: Tcl if 1 {LogMessage { #002 268 [::testfuncs::Incr ] $::custommap::counter}}
   #002 268 271 271

Empfehlung

Es hat sich gezeigt, dass die Verwendung von [list ...] in der Regel die beste Wahl ist. Innerhalb sind dann alle Werte, die erst in der späten Interpretation ausgeführt werden sollen, zu schützen. Das Schützen einzelner Elemente wie z.B. Variablen geht am Besten über "\", ganze sind besser über { BLOCK } zu schützen. Soll die komplette Anweisung ist der späten Interpretation ausgeführt werden (und nur dann!), dann umfasst der Block die ganze Anweisung.