Importieren von Geschäftsobjekt-Positionen

Wenn vollwertige Geschäftsobjekte (Sendungen, Bestellungen oder Allgemeines Geschäftsobjekt) importiert werden, können deren Positionen im Import durch die Angabe für die Positionsnummer (lineItemId) identifiziert bzw. in der Hierarchie der Positionen eingeordnet werden.

HINWEIS◄ Dies betrifft nicht die Manifeste, da deren Positionshierarchie per Definition einstufig und lediglich eine Aufzählung von dem Manifest zugeordneten Sendungen als Positionen ist. Für Manifest-Positionen ist daher weder eine Positionsnummer noch ein Positionstyp relevant.

Hintergrund zur Hierarchie der Positionen

Technisch sind werden alle Positionen (also auch die Unterpositionen) eines Geschäftsobjekts in derselben Ebene verwaltet. Im XML-Export des Geschäftsobjekts erscheinen sie als lineItem-Elemente innerhalb des lineItems-Elements und innerhalb der Datenbank bevölkern Positionen aller Ebenen dieselbe Tabelle. Die hierarchische Struktur ergibt sich aus der vom System verwalteten Zuordnung einer Positionsnummer, die als Feld "Positions Nr." (lineItemId) bezeichnet wird und einen wie folgt strukturierten Text enthält:

Struktur für die lineItemId

[<Präfix>]<Laufnummer der 1. Hierarchieebene>[.<Laufnummer der 2. Hierarchieebene>[.<Laufnummer der 3. Hierarchieebene> etc. ]]

  • Das Präfix wird abhängig vom Positionstyp zugeordnet. Es besteht aus maximal 3 Buchstaben und ist für den Positionstyp Standard per Standard leer.

  • Für jede Hierarchieebene wird eine eigene ganzzahlige Laufnummer aufsteigend von 1 ermittelt und automatisch zugewiesen.

  • Als Trennzeichen zwischen den Laufnummern unterschiedlicher Hierarchieebenen wird ein Punkt (".") eingefügt.

Beispiel:

Das folgende Beispiel zeigt für ein beliebiges Geschäftsobjekt eine Positionshierarchie mit bis zu drei Ebenen für den Standard-Positionstyp sowie drei Service-Positionen in zwei Hierarchieebenen.

Positionshierarchie

XML-Struktur


1
1.1
1.2
1.3
2
2.1
2.1.1
2.1.2
2.2
SVC1
SVC1.1
SVC1.2
<lineItems>
<lineItem id="10815" ... lineItemId="1" parentLineItemId="">
<lineItem id="10816" ... lineItemId="1.1" parentLineItemId="1">
<lineItem id="10817" ... lineItemId="1.2" parentLineItemId="1">
<lineItem id="10818" ... lineItemId="1.3" parentLineItemId="1">
<lineItem id="10819" ... lineItemId="2" parentLineItemId="">
<lineItem id="10821" ... lineItemId="2.1" parentLineItemId="2">
<lineItem id="10822" ... lineItemId="2.1.1" parentLineItemId="2.1">
<lineItem id="10823" ... lineItemId="2.1.2" parentLineItemId="2.1">
<lineItem id="10824" ... lineItemId="2.2" parentLineItemId="2.2">
<lineItem id="10825" ... lineItemId="SVC1" parentLineItemId="SVC">
<lineItem id="10826" ... lineItemId="SVC1.1" parentLineItemId="SVC1">
<lineItem id="10827" ... lineItemId="SVC1.2" parentLineItemId="SVC1">
</lineItems>
  • Alle Positionen werden im XML gleichberechtigt aufgelistet. Die Hierarchie spiegelt sich hier nur in den Werten der Felder lineItem und parentLineItem.

  • Die id ("ID") der Position ist über alle Positionen aller Geschäftsobjekte hinweg eindeutig bestimmt und wird automatisch vergeben.

  • Die lineItemId ("Positions Nr. ") ist nur innerhalb des Geschäftsobjekts eindeutig bestimmt und definiert Positionstyp und eine Laufnummer je Hierarchieebene.

  • Die parentLineItemId ("übergeord. Positions Nr.") verweist auf die Positions Nr. (lineItemId) der in der Hierarchie unmittelbar übergeordneten Position bzw. das Präfix für den Positionstyp für die Positionen der 1. Hierarchieebene.

Verwendung der Positionsnummer beim Import

Sofern ein Import für das Geschäftsobjekt die Aktion UPDATE (bzw. CREATE OR UPDATE) verwendet, wird bei Angabe einer lineItemId für ein lineItem zunächst geprüft, ob diese bereits existiert:

  • Existiert bereits eine Position mit der angegebenen lineItemId, dann wird die bestehende Position mit den importierten Daten aktualisiert .

  • Existiert die angegebene lineItemId nicht, dann wird eine neue Position hinzugefügt. Deren Hierarchieposition wird dabei wie folgt ermittelt:

    • Ausgehend von der angegebenen lineItemId wird für Unterpositionen geprüft, ob die adressierte übergeordnete Position bereits existiert.

      • Betrifft die lineItemId die höchste Ebene (also keine Unterposition), dann wird immer eine neue Position in dieser Ebene angelegt.

      • Existiert die übergeordnete Position, dann wird eine neue Position in der betreffenden Hierarchieebene hinzugefügt.

      • Fehlt die übergeordnete Position, dann tritt ein Fehler auf.

    • Beim Speichern des Geschäftsobjekts werden die Laufnummern aller Positionen aktualisiert und wieder mit lückenlos aufsteigenden Ganzzahlen je Ebene besetzt.

Vereinfacht gesagt, kann man anzulegenden Positionen beim Import beliebige Ganzzahlen als Laufnummer zuordnen, solange diese höher sind als die höchste bereits vergebene Indexnummer in der jeweiligen Ebene und die in der lineItemId implizierte übergeordnete Position existiert.

HINWEIS◄ Es ist grundsätzlich möglich, Steuerungsattribute und Knoten in Verbindung mit Positionen zu verwenden, die per Positionsnummer identifiziert werden. Allerdings ist dies nur für core:delete (Löschen individueller Elemente) praxisrelevant. Das Steuerungsattribut core:mode="NO_RESOLVE" (Überspringen des Abrufs bestehender Objektdaten) darf in Verbindung mit der Identifikation über die Positionsnummer nicht (mit dem Wert true) verwendet werden, da ohne das Laden von Objektdaten kein Abgleich mit der Positionsnummer erfolgen kann. Falls die adressierte Position bereits existiert, schlägt daher der Import fehl (Fehlermeldung: Failed to merge: Can't handle multiple index change in one step). Falls das Steuerungsattribut core:mode="NO_RESOLVE" (Überspringen des Abrufs bestehender Objektdaten) erforderlich ist, muss die betreffende Position unbedingt anhand der ID (id) identifiziert werden, die ggf. ausgehend von der Positionsnummer über eine Suche per Pre-Prozessor (s. Präprozessoren) ermittelt werden kann.

Einfaches Beispiel:

Das Geschäftsobjekt verfügt vor dem Import, der es aktualisieren soll, bereits über drei Standard-Positionen in zwei Ebenen.

lineItemIds
vor Import

lineItemIds
im Import

lineItemIds
nach Import

1
1.1
1.2



1.2
1.999
1 (unverändert)
1.1 (unverändert)
1.2 (aktualisiert)
1.3 (neu erstellt)

Der Import bezieht sich auf eine bekannte Positionsnummer (1.2) und eine unbekannte Positionsnummer (1.999) in der zweiten Ebene.

  • Die Position mit der bekannten Positionsnummer (1.2) wird aktualisiert.

  • Die Position mit der unbekannten Positionsnummer (1.999) wird neu erstellt und erhält die Positionsnummer 1.3.

Weitere Beispiele:

Das Geschäftsobjekt verfügt vor dem Import, der es aktualisieren soll, bereits über zwei Service-Positionen (mit der Kennung SVC) in der Einstiegsebene.

lineItemIds
vor Import

lineItemIds
im Import

lineItemIds
nach Import

SVC1


SVC2


SVC1.1
SVC1.2

SVC2.1
SVC2.2
SVC1 (unverändert)
SVC1.1 (neu erstellt)
SVC1.2 (neu erstellt)
SVC2 (unverändert)
SVC1.2 (neu erstellt)
SVC1.3 (neu erstellt)
  • Der Import liefert Daten für je zwei Unterpositionen der bestehenden Positionen, die neu erstellt werden.

Wäre in der Ausgangssituation nur die erste Service-Position vorhanden, dann würde der Import insgesamt mit einem Fehler scheitern, da die übergeordnete Position SVC2 nicht definiert ist.

lineItemIds
vor Import

lineItemIds
im Import

lineItemIds
nach Import

SVC1




SVC1.1
SVC1.2

SVC2.1
SVC2.2

images/s/-95e2zf/9012/8yg2g7/_/images/icons/emoticons/warning.svg FEHLER images/s/-95e2zf/9012/8yg2g7/_/images/icons/emoticons/warning.svg

Liefert der Import allerdings benötigte Service-Position SVC2 mit, dann funktioniert der Import der Unterpositionen dagegen, wie gewünscht:

lineItemIds
vor Import

lineItemIds
im Import

lineItemIds
nach Import

SVC1




SVC1.1
SVC1.2
SVC2
SVC2.1
SVC2.2
SVC1 (unverändert)
SVC1.1 (neu erstellt)
SVC1.2 (neu erstellt)
SVC2 (neu erstellt)
SVC2.1 (neu erstellt)
SVC2.2 (neu erstellt)

►ACHTUNG◄ Die Bezüge zwischen neu hinzugefügten Postionen muss innerhalb der Imports "stimmig" sein und nicht in Bezug auf die erst beim Speichern vorgenommene abschließende Nummerierung.

lineItemIds
vor Import

lineItemIds
im Import

lineItemIds
nach Import

SVC1




SVC1.1
SVC1.2
SVC999
SVC2.1
SVC2.2

images/s/-95e2zf/9012/8yg2g7/_/images/icons/emoticons/warning.svg FEHLER images/s/-95e2zf/9012/8yg2g7/_/images/icons/emoticons/warning.svg


  • Der Position SVC999 würde hier zwar letztendlich die systematische lineItemId SVC2 zugewiesen.

    • Innerhalb desselben Imports müssten Unterpositionen aber noch auf SVC999 als übergeordnete "Adresse" verwenden.

Der folgende Ansatz liefert daher das gewünschte Ergebnis:

lineItemIds
vor Import

lineItemIds
im Import

lineItemIds
nach Import

SVC1




SVC1.1
SVC1.2
SVC999
SVC999.1
SVC999.2
SVC1 (unverändert)
SVC1.1 (neu erstellt)
SVC1.2 (neu erstellt)
SVC2 (neu erstellt)
SVC2.1 (neu erstellt)
SVC2.2 (neu erstellt)

Lauffähig aber nicht zielführend wäre dagegen dieser Versuch:

lineItemIds
vor Import

lineItemIds
im Import

lineItemIds
nach Import

SVC1




SVC1.1
SVC1.2
SVC999
SVC999.99
SVC999.99
SVC1 (unverändert)
SVC1.1 (neu erstellt)
SVC1.2 (neu erstellt)
SVC2 (neu erstellt)
SVC2.1 (neu angelegt ...
... und dann aktualisiert)

Hier würde die zweite Referenz auf die neue Unterposition SVC999.99 die Daten der vorherigen Zuordnung als Aktualisierung übersteuern.