Importing line items of business objects
When importing complete business objects (Shipments, Orders or Allgemeines Geschäftsobjekt), their line items can be identified in the Import by specifying the (lineItemId) or they can be placed in the hierarchy of line items.
►NOTE◄ This does not apply to Manifests, since their line item hierarchy is by definition single-level and merely an enumeration of Shipments assigned to the manifest as line items. Therefore, neither a line item number nor an Line item type is relevant for manifest items.
Background to the hierarchy of line items
Technically, all line items (including child items) of a business object are managed on the same level. In the XML export of the business object they appear as lineItem elements within the lineItems element and within the database, line items of all levels populate the same table. The hierarchical structure results from the assignment of a line item number managed by the system, which is called the field 'Line item no.' (lineItemId) and contains a text structured as follows:
Structure for the lineItemId
[<Präfix>]<Laufnummer der 1. Hierarchieebene>[.<Laufnummer der 2. Hierarchieebene>[.<Laufnummer der 3. Hierarchieebene> etc. ]]
The prefix is assigned depending on the Line item type category. It consists of a maximum of 3 letters and is empty for the standard line item category by default.
For each hierarchy level, a separate integer sequence number ascending from 1 is determined and automatically assigned.
A period ('.') is inserted as a separator between the sequence numbers of different hierarchy levels.
Example:
The following example shows for any business object a line item hierarchy with up to three levels for the standard Line item type and three service line items in two hierarchy levels.
Line item hierarchy |
XML structure |
|
<lineItems> |
All line items are listed equally in the XML. The hierarchy is reflected here only in the values of the fields lineItem and parentLineItem.
The id ('ID') of the line item is uniquely determined across all line items of all the business objects and is assigned automatically.
The lineItemId ('Line item no.') is only uniquely determined within the business object and defines the line item type and a sequence number per hierarchy level.
The parentLineItemId ('Parent line item no.') refers to the line item no. (lineItemId) of the directly superior item in the hierarchy or the prefix for the line item types for the items of the 1st hierarchy level.
Using the line item number during import
If an Import uses the action UPDATE (or CREATE OR UPDATE) for the business object, when a lineItemId is specified for a lineItem, the system first checks whether it already exists:
If a line item with the specified lineItemId, already exists, the existing line item is updated with the imported data.
If the specified lineItemId does not exist, a new line item is added. Its positon in the hierarchy is determined as follows:
Based on the specified lineItemId, the system checks whether the addressed parent item already exists for the child line items.
If the lineItemId refers to the highest level (i.e. no child item), then a new item is always created at this level.
If the parent line item exists, a new item is added to the corresponding hierarchy level.
If the parent line item is missing, an error occurs.
When the business object is saved, the sequence numbers of all line items are updated and populated again with continuously ascending integers per level.
To put it simply, any integer number can be assigned as a sequence number during Import as long as it is higher than the highest index number already assigned in the respective level and the parent line item implied in the lineItemId.
►NOTE◄ It is basically possible to use Control attributes in connection with line items that are identified by a line item number. But this is only relevant for core:delete (Delete individual elements). The control attribute core:skipResolve (Skip resolving of existing object data) must not be used in connection with the identification via the line item number (with the value true), since without loading object data, no comparison with the line item number can be performed. If the addressed position already exists, the import will fail (error message: Failed to merge: Can't handle multiple index change in one step). If the core:skipResolve (Skip resolving of existing object data) control attribute is required, the corresponding position must be identified by its ID (id) which can be determined from the line item number using a preprocessor search (see Preprocessors).
Simple example:
The business object already has three standard line items in two levels before the import updates it.
lineItemIds |
lineItemIds |
lineItemIds |
1 |
|
1 (unchanged) |
The import refers to a known line item number (1.2) and an unknown line item number (1.999) in the second level.
The line item with the known line item number (1.2) is updated.
The line item with the unknown line item number (1,999) is created and assigned the number 1.3.
Further examples:
The business object already has two service line items (with the identifier SVC) in the entry level before the import updates it.
lineItemIds |
lineItemIds |
lineItemIds |
SVC1 |
|
SVC1 (unchanged) |
The import provides data for two child line items of the existing line items that will be newly created.
If only the first service line item would be available in the initial situation, the import would fail with an error because the parent line item SVC2 is not defined.
lineItemIds |
lineItemIds |
lineItemIds |
SVC1 |
|
|
However, if the import includes the required service line item SVC2, then the import of the child items works as desired:
lineItemIds |
lineItemIds |
lineItemIds |
SVC1 |
|
SVC1 (unchanged) |
►CAUTION◄ The references between newly added line items must be 'consistent' within imports, and not in relation to the final numbering that is only performed when saving.
lineItemIds |
lineItemIds |
lineItemIds |
SVC1 |
|
|
The line item SVC999 would be assigned the systematic lineItemId SVC2.
Within the same import, however, child line items would still have to use SVC999 as their parent 'address'.
The following procedure therefore delivers the desired result:
lineItemIds |
lineItemIds |
lineItemIds |
SVC1 |
|
SVC1 (unchanged) |
On the other hand, this approach would be workable but not effective:
lineItemIds |
lineItemIds |
lineItemIds |
SVC1 |
|
SVC1 (unchanged) |
Here the second reference to the new child item SVC999.99 would override the data of the previous assignment as an update.