The Transfer module allows you to export a variety of documents or data from xentral. In addition to various output formats and output channels, you are also offered various triggers for the export (e.g. the document status, label, ID or date of a document, etc.). For this you use the Smarty transfer module.
With the help of Smarty you can now define the target format of the output data yourself and with the help of
-
functions (like truncate),
-
enrich it with SQL queries
-
and modify it with logic by applying loops, conditions or similar.
In the Transmit module, Smarty is available for incoming and outgoing messages. The template
-
for outgoing messages the target format expected by the remote station
-
for incoming messages the xentral internal format for processing (in most cases xentral XML).
Here you can find out which document types and data you can export or import.
In the Transmit module you can export the following document types via Smarty:
-
Order
-
Delivery bill
-
Invoice
-
Credit note
-
Offer
-
Order
-
Return
You can also export the following data using Smarty templates:
-
Article
-
Stock numbers
-
Stocks
-
Stock locations
-
In the Transfer module you can import the following document types via Smarty:
-
Sales order: technical name 'auftrag' (XML, CSV)
-
Purchase order: technical name 'bestellung' (XML, CSV)
-
Production: technical name 'produktion' (XML, CSV)
-
Return: technical name 'retoure' (XML, CSV)
In addition, you can import (read) the following data:
-
Stock numbers
-
article data
-
Tracking information
To import all document types, you have to select the transfer format smarty and save it. Then a new checkbox appears under Receive voucher, which is called Import all voucher types.
You can partially read errors during the readout from the monitor or the logfile.
Sending data from xentral (also called "outbound") allows you to convert the data from xentral
-
into a target format and then to export it
-
export it to a third party system
A template file could look like this:
<?xml version="1.0" encoding="utf-8"?> <auftrag> <status>{$beleg->status}</status> <datum>{$beleg->datum|date_format:'%d.%m.%Y'}</datum> <lieferdatum>{$beleg->lieferdatum}</lieferdatum> <versandart>{$beleg->versandart}</versandart> <zahlungsweise>{$beleg->zahlungsweise}</zahlungsweise> <belegnr>{$beleg->belegnr}</belegnr> <kundennummer>{$beleg->kundennummer}</kundennummer> <name>{$beleg->name}</name> <strasse>{$beleg->strasse}</strasse> <plz>{$beleg->plz}</plz> <ort>{$beleg->ort}</ort> <positionen> {foreach from=$beleg->positionen key=keyrow item=position}{* Positionen *} <position> <nummer>{$position->nummer}</nummer> <bezeichnung>{$position->bezeichnung}</bezeichnung> <beschreibung>{$position->beschreibung}</beschreibung> <menge>{$position->menge}</menge> <preis>{$position->preis}</preis> <einheit>{$position->einheit}</einheit> </position> {/foreach} </positionen> {if $beleg->versand} <tracking> {foreach from=$beleg->versand key=keyversand item=tracking}{* Versand *} <tracking>{$tracking->tracking}</tracking> {/foreach} </tracking> {/if} </auftrag>
Importing data into xentral (also called "inbound") allows you to import the data
-
from another system,
-
interpret it, then
-
convert it to an xentral target format, and then import it
-
import it into xentral.
Note
All content entered in the inbound converter is based on the standard templates from the Transfer module. These also represent the maximum amount of information to be processed. Information that is supplied above and beyond this will be ignored.
By default, most content is parsed correctly using the $object array. If the representation does not fit, you can work with alternative arrays.
-
$csv: an array of objects with the header columns as keys
-
$csvwithoutheader: an array of objects without header columns; call the columns in the notation col0, col1, etc.
-
$xml: an object that was gaparst from an xml
-
$object: is an $xml if original data was a valid xml
-
$original: is the original string of the input
-
{"The order contains no items"|error}
outputs an error to Smarty, which is logged to the transfer monitor
-
{"SELECT number FROM item"|assignsql assign="itemnumbers"}
stores the result of the SQL query into the $articlenumbers variable
-
{$original|replace: "1.0": "2.0"|getxml assign="newxml"}
replaces all strings 1.0 to 2.0 and saves it to a new object $neuesxml
-
{$position->number|pregreplace:'/[^0-9]/':''}
performs a regular replacement on the one object
Below we show you examples of inbound data conversion.
<?xml version="1.0" encoding="UTF-8"?> <response> <xml> {assign var="letztebestellnummer" value=0}{assign var="ersterbeleg" value=1} <auftrag_list>{foreach from=$object key=keyrow item=position}{if $letztebestellnummer <> $position->beleg_belegnr and $ersterbeleg == 0} </auftrag_position_list> </auftrag> {/if} {if $letztebestellnummer <> $position->beleg_belegnr or $ersterbeleg == 1} <auftrag> {$ersterbeleg = 0}{$letztebestellnummer= $position->beleg_belegnr} <datum>{$position->beleg_datum|date_format:"%d.%m.%Y"}</datum> <versandart>{$position->beleg_versandart}</versandart> <status>{$position->beleg_status}</status> <projekt>{$position->beleg_projekt}</projekt> <name>{$position->beleg_name_firma|escape:"html"}</name> <adresszusatz>{$position->beleg_name_nachname|escape:"html"} {$position->beleg_name_vorname|escape:"html"}</adresszusatz> <strasse>{$position->beleg_adresse_strasse} {$position->beleg_adresse_hausnummer|escape:"html"}</strasse> <plz>{$position->beleg_plz}</plz> <ort>{$position->beleg_ort}</ort> <ihrebestellnummer>{$position->beleg_belegnr}</ihrebestellnummer> <internebezeichnung>{$position->POSNR|string_format:"%.0f"}</internebezeichnung> <email>{$position->beleg_email}</email> <telefon>{$position->beleg_telefon}</telefon> <lieferunterabteilung> </lieferunterabteilung> <internebemerkung> </internebemerkung> <auftrag_position_list>{/if} <auftrag_position> <name>{$position->artikel_bezeichnung|escape:"html"}</name> <menge>{$position->artikel_menge}</menge> <nummer>{$position->artikel_nummer}</nummer> </auftrag_position> {/foreach} </auftrag_position_list> </auftrag> </auftrag_list> </xml> </response>
Background: Stock figures were partially transferred by Fulfiller without MHD/batch info. Via SQL it is checked whether the article is subject to MHD/batch. If yes, the template is extended by static information.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <response xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <xml> <artikel_list> {assign var="counter" value = 0} {foreach from=$object->xml->artikel_list->artikel key=key item=item} {assign var="Nummer" value=$object->xml->artikel_list->artikel[$counter++]->nummer} {"SELECT nummer, mindesthaltbarkeitsdatum, chargenverwaltung FROM artikel WHERE nummer = '$Nummer' and lagerartikel = 1 and geloescht<>1 "|assignsql assign="artikel"} <artikel> <nummer>{$item->nummer}</nummer> <lagerzahl>{$item->lagerzahl}</lagerzahl> {if !($item->lager_platz)} <lager_platz>Hauptlager</lager_platz>{else} <lager_platz>{$item->lager_platz}</lager_platz> {/if} {if $artikel[0]->nummer == $item->nummer && $artikel[0]->mindesthaltbarkeitsdatum == 1 && $artikel[0]->chargenverwaltung == 2} <mhd>31.12.9999</mhd> <charge>DUMMY</charge> {elseif $artikel[0]->nummer == $item->nummer && $artikel[0]->chargenverwaltung == 2} <charge>DUMMY</charge> {/if} </artikel> {/foreach} </artikel_list> </xml> </response>
Note
Array of $csvwithoutheader is not printed over the screen of $object. You can also print the content of $csvwithoutheader e.g. with {$csvwithoutheader|@debug_print_var}. The column call is done using the notation col0-n.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <response xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <xml> <artikel_list> {foreach from=$csvwithoutheader key=keyrow item=Ab} <artikel> <nummer>{$Ab->col0}</nummer> <lagerzahl>{$Ab->col1}</lagerzahl> </artikel> {/foreach} </artikel_list> </xml> </response>
API is available as a technical transfer type in the standard. Other available transfer types are FTP, FTPS (username and password, no certificates), SFTP, e-mail and local storage on the server.
Smarty is handled in the same way here as when any other transfer type is used. However, there may be api-specific requirements to consider here, such as authentication, headers, or application-type. If you are working with authentication that requires a password, no entries will be displayed in the Files tab. Successful transfers can only be tracked in the Transfer Monitor at the current time if the corresponding document or action has "uploaded" in a green success message. It is possible that only insufficient error messages are reported back during the transfer, which is why you have to rely on detailed error logging from the target system here.
Here we show you special features of Smarty in the Transfer module.
In all documents you can access linked documents with the help of Smarty. For example, if a delivery bill exists for an order, there is also an array $beleg->lieferschein[], in which the corresponding information of the referenced delivery bill is available. This way you can quickly access supplementary document numbers, delivery dates, batches or serial numbers - even when creating an order. The delivery note number, for example, can be accessed directly via $beleg->lieferschein[0]->belegnr
The following data is available in the respective documents, provided that a corresponding document exists in the system.
In the order:
-
$voucher->order[]
-
$voucher->quotation[]
-
$document->delivery bill[]
-
$voucher->invoice[]
-
$voucher->return[]
-
$voucher->credit note[]
In delivery note:
-
$voucher->order[]
-
$voucher->invoice[]
Examples:
You need to use SQL for the following examples. You can find the general syntax for SQL queries in the transfer module in the SQL queries section of this article.
Serial number: The serial number for a delivery note is stored in the belege_chargesnmhd table. You can access this value via the following SQL code:
{foreach from=$beleg->positionen key=keyrow item=position}{* Positionen *} <position> (...) {"SELECT wert FROM beleg_chargesnmhd WHERE doctype = 'lieferschein' AND type = 'sn' AND pos = '{$position->id}' "|assignsql assign="sn"} <seriennummer>{$sn[0]->wert}</seriennummer>
Internet number: To access the internet number of the sales order linked to the delivery note, you can use the following SQL code:
<lieferschein> (...) {"SELECT internet FROM auftrag WHERE id = '{$beleg->auftragid}' "|assignsql assign="internet"} <internet>{$internet[0]->internet}</internet>
In the invoice:
-
$voucher->order[]
-
$voucher->delivery bill[]
You can also use the line items to retrieve "underlying" structures that are not stored directly in the document. An example is the weight of an item. You can retrieve this via {$position->articledata->weight}. So you can calculate and transfer the total weight of all articles of a document by multiplying the quantity of the position and adding up all weights. With $position->articledata you can access all columns from the table article. You should always consider whether information from the article master data might already have been changed in the order item. In case of doubt you should use the value from the document.
In the Transfer module, you can also create general SQL queries to enrich data and output them in the output templates. To do this, use the following syntax:
{"SELECT gln, rechnung_gln FROM adresse where lieferantennummer = '{$beleg->lieferantennummer}' "|assignsql assign="adressdata"}
You can then access the result via the assigned array adressdata:
{$adressdata[0]->gln} // for the targeted call of the array
Date values can be output as requested:
-
Int. date format (ISO 8601): {$voucher->date|date_format:'%Y-%m-%d'}
-
German date format (DIN 5008): {$voucher->date|date_format:'%d.%m.%Y'}
Numbers can be reformatted as needed. Here at the example of the column "Quantity":
-
Output without decimal places (as integer): {$position->quantity|string_format:'%d'}
-
Output with one decimal place: {$position->quantity|string_format:'%.1f'}
-
Output with two decimal places: {$position->quantity|string_format:'%.2f'}
Basically, all formats can be output that are available through the sprintf function in PHP.
Here you can find a list of the different field definitions. A complete listing of the available fields including a translation of the field names and a description of the contents in English is linked below each screenshot.
With the help of the integrated template engine Smarty, character-based output structures of data formats such as CSV, XML or JSON can be easily and flexibly adapted to the customer's needs. Basically, all that needs to be done is to copy the existing target format into a text file and fill it with the appropriate variables. These can still be reformatted in the process.
Document data can be found e.g. in the Smarty variable $beleg (document) and are addressed in the usual PHP object notation, e.g. $beleg->kundennummer (customer number) or $beleg->belegnr. (document number). The naming is similar to the naming of database column names.
Access to more complex structures is also possible (depending on the document). For example, the underlying order can be accessed in the delivery note: $beleg->auftrag (sales order) ->lieferdatum (delivery date). Shortened example with fictitious format:
{* Beleg-Stammdaten -------------------------------- *} {$beleg->status} {$beleg->datum|date_format:'%d.%m.%Y'} {$beleg->belegnr} {$beleg->kundennummer} {$beleg->name} {* Access to data of the underlying order *} {$beleg->auftrag->lieferdatum} {* Other fields removed *}
{* Positionen - Beginn ------------------------------ *} {* loop through all available items *} {foreach from=$beleg->positionen key=keypos item=position} {$position->nummer} {$position->name} {$position->beschreibung} {$position->menge} {$position->preis} {* Other fields removed *} {/foreach} {* Positionen - Ende -------------------------------- *}
In the following we have summarized some examples that allow you to output different delivery note formats in EDI, CSV and XML. Please check the column labels (CSV), tag names (XML) and EDI specifications for your own application. Of course, other output formats (such as JSON) are also conceivable.
The following example lists a detailed example for an export of a delivery bill in different formats.
"tracking"; "document_status"; "document_date"; "document_delivery_date"; "document_actual_delivery_date"; "document_shipping_method"; "document_payment_method"; "document_document_nr"; "document_main_document_nr"; "document_customer_number"; "document_name"; "document_department"; "document_subdepartment"; "document_address_addition"; "voucher_contact_person"; "voucher_phone"; "voucher_email"; "voucher_country"; "voucher_street"; "voucher_plz"; "voucher_location"; "voucher_project"; "voucher_action"; "voucher_internal_note"; "voucher_internal_name"; "voucher_free_text"; "voucher_your_order_number"; "voucher_delivery_condition"; "voucher_type"; "item_number"; "item_designation"; "item_description"; "item_quantity"; "item_price"; "item_discount"; "item_currency"; "item_delivery_date"; "item_sort"; "item_tax"; "item_unit"; "item_tariff_number"; "item_country_of_origin"; "item_article_number_customer"; "desired_delivery_date"; "item_free_field1"; "item_free_field2"; "item_free_field3"; "item_free_field40"{foreach from=$voucher->items key=keyrow item=item}{* items *}\"{$item->tracking}";\"{$voucher->status}";\"{$voucher->date|date_format: '%d. %m. %Y'}";\"{$voucher->delivery date}";\"{$voucher->actual delivery date}";\"{$voucher->shipping method}";\"{$voucher->payment method}";\"{$voucher->voucher_number}";\"{$voucher->main_voucher_number}"; \"{$voucher->name}";\"{$voucher->department}";\"{$voucher->subdepartment}";\"{$voucher->address}";\"{$voucher->contact person}";\"{$voucher->phone}";\"{$voucher->email}";\"{$voucher->country}"; \"{$voucher->street}";\"{$voucher->plz}";\"{$voucher->location}";\"{$voucher->project}";\"{$voucher->action}";\"{$voucher->internal remark}";\"{$voucher->internal name}";\"{$voucher->free text}"; \"{$document->your order number}";\"{$document->delivery condition}";\"{$document->type}";\"{$item->number}";\"{$item->designation}";\"{$item->description}";\"{$item->quantity|string_format: '%. 2f'}";\"{$item->price}";\"{$item->discount}";\"{$item->currency}";\"{$item->delivery date}";\"{$item->location}";\"{$item->sales tax}";\"{$item->unit}";\"{$item->tariff number}"; \"{$item->country of origin}";\"{$item->part number customer}";\"{$voucher->order->date of delivery}";\"{$item->free field1}";\"{$item->free field2}";\"{$item->free field3}";\{* If applicable. other free fields *}";\"{$position->freefield40}";\ {/foreach}
{$voucher->status} {$voucher->date|date_format:'%d.%m.%Y'} {$voucher->delivery date} {$voucher->actual delivery date} {$voucher->shipping method} {$voucher->payment method} {$voucher->document number} {$voucher->main document number} {$voucher->customer number} {$voucher->name} {$voucher->department} {$voucher->subdepartment} {$voucher->address supplement} {$document->contact person} {$document->phone} {$document->email} {$document->country} {$document->street} {$documents->plz} {$voucher->location} {$voucher->project} {$voucher->action} {$voucher->internal remark} {$voucher->internal description} {$voucher->free text} {$voucher->your order number} {$voucher->delivery condition} {$voucher->type} {foreach from=$voucher->items key=keypos item=item} {$item->number} {$item- >name} {$item->description} {$item->quantity} {$item->price} {$item->discount} {$item->currency} {$item->delivery date} {$item->location} {$item->tax} {$item->unit} {$item->tariff number} {$item->country of origin} {$item->article number customer} {$item->freefield1} {$item->freefield2} {$item->freefield3} {* Other free fields if necessary *} {$item->freefield40} {/foreach} {if $bill->shipping} {foreach from=$bill->shipping key=keyshipping item=tracking} {* shipping *} {$tracking->tracking} {/foreach} {/if}
The following examples are shown as a supplement to the above code examples, which only take into account the specifics related to BBDs in an item.
The following examples are shown as a supplement to the above code examples, taking into account only the specifics related to batches in an item.
In the following, examples are shown as a supplement to the above code examples, which only take into account the special features related to MHDs and batches in an item.