pixiCreatePOSInvoice
Legt aus einem XML-Dokument eine neue POS-Rechnung an oder ergänzt eine offene um Positionen und bucht die verkauften Artikel aus dem Bestand aus.
Legt eine Kassenrechnung (POS-Rechnung) für eine Kasse an. Alle Daten werden in einem XML-Dokument im Parameter XML übergeben.
Einlesen
- Kopfdaten aus
POSINVOICE/HEADER:REGISTERID(Pflicht),POSHEADERKEY(optional, eine bestehende Rechnung, die ergänzt wird),COMMENT,CUSTOMERNREXTERNAL(optional) undGENERALBIN(optionaler allgemeiner POS-Lagerplatz). - Positionen aus
POSINVOICE/LINES/LINE:ITEMNRINT,QUANTITY,PRICE,DISCOUNTPERCENT(Standard 0) undBIN(bevorzugter Lagerplatz, Standard leer).COMMANDwird gelesen, aber nicht verwendet.
Ermittlungen
- Der Kunde wird über
Customers.CustomerNrExternalgesucht; sein Adressschlüssel wird an der Rechnung gespeichert. - Die offene POS-Session (
EndTimeist NULL) der Kasse mit der neuestenStartTimeliefert Lager, Session-ID und Benutzernamen. - Der Artikel jeder Position wird über
ItemNrIntgesucht; dessen EAN/UPC wird übernommen.
Prüfungen (in dieser Reihenfolge; der erste Fehler beendet den Aufruf mit einer ERROR-Zeile)
REGISTERIDist vorhanden.- Bei Angabe von
POSHEADERKEYexistiert die Rechnung inPOSheader2und ihr Status ist wederCLOnochSTO. - Für die Kasse existiert eine offene POS-Session.
- Alle Artikel existieren.
- Bei Angabe von
CUSTOMERNREXTERNALexistiert der Kunde. - Keine Menge ist negativ.
DISCOUNTPERCENTliegt zwischen 0 und 100.
Ausführung (in einer Transaktion)
- Ohne
POSHEADERKEYwird über die interne ProzedurPixi_POSNewInvoiceein neuer Rechnungskopf angelegt (BelegartINV). Diese Prozedur schreibt zusätzlich ein Session-Ereignis und veröffentlicht das MQ-EreignisPOSInoviceCreated. - Der Kopf wird aktualisiert: Kundenadresse,
InvoiceComment, Änderungsbenutzer und Änderungsdatum. - Für jede Position:
- Eine
POSitem2-Zeile mit Menge, Preis, Rabatt und EAN/UPC wird angelegt. - Entnahme-Lagerplätze werden vorgeschlagen, mit
BINals Prioritäts-Lagerplatz undGENERALBINals allgemeinem Lagerplatz, in aufsteigender Reihenfolge. - Die Vorschläge werden in
POSItemBinSelectiongespeichert. - Der Bestand wird von den Lagerplätzen ausgebucht (Aktionstyp 4, Lagerbewegungsreferenzen
SMORef15 /SMTRef12). - Schlägt die Buchung einer Position fehl, wird der gesamte Aufruf zurückgerollt.
- Eine
- Bei Erfolg wird eine Zeile mit
ReturnCode=OKund dem Rechnungsschlüssel inMessagezurückgegeben.
Hinweise
- Spaltenname unterscheidet sich in der Schreibweise: Die Erfolgszeile hat die Spalte
Message, die Fehlerzeile die SpalteMESSAGE. XML-Elementnamen unterscheiden Groß- und Kleinschreibung, daher muss ein Client beide auslesen. - XML-Parsing außerhalb der Fehlerbehandlung:
sp_xml_preparedocumentläuft außerhalb desTRY-Blocks. Ein NULL-Wert oder ungültigesXMLkommt daher alsSqlMessagezurück und nicht alsERROR-Zeile. Das XML-Dokument-Handle wird nie mitsp_xml_removedocumentfreigegeben. - Datentypfehler: Nicht konvertierbare Werte im XML (z. B. nicht numerische
QUANTITYoderPRICE) führen zu einerERROR-Zeile mit der SQL-Server-Meldung. - Überschriebene Kopffelder: Wird eine bestehende Rechnung ergänzt, werden die Positionen angehängt; vorhandene Positionen bleiben unverändert.
PHCusAddrKeyundInvoiceCommentwerden immer überschrieben, mit NULL, wennCUSTOMERNREXTERNALoderCOMMENTfehlt. - Neue Rechnung bei Schlüssel 0: Ein leerer oder
0-Wert inPOSHEADERKEYwird als „neu anlegen“ behandelt. - Irreführende Artikel-Fehlermeldung: Die Meldung 'Item not found' enthält die Artikelnummer einer beliebigen Position, nicht unbedingt die des fehlenden Artikels. Fehlt dort
ITEMNRINT, ist die Meldung leer. Die Meldung wird auf 150 Zeichen gekürzt. - Ungeprüfte Positionswerte: Eine NULL-Menge und ein NULL-Preis werden nicht abgewiesen; eine Menge von 0 wird akzeptiert.
PRICEwird wie übergeben gespeichert und nicht aus den Artikelstammdaten übernommen. - Chargen und MHD: Die Bestandsbuchung übergibt keine Charge und kein Mindesthaltbarkeitsdatum, daher kommt nur Lagerplatzbestand ohne Charge und ohne MHD in Frage. Chargen- oder MHD-geführte Artikel scheitern daher voraussichtlich mit einer Bestandsmeldung.
- Lagerplatzlogik nicht beigefügt: Die eigentliche Lagerplatzwahl erfolgt in
Pixi_POS_GetTakeOutBinsundPixi_POSSuggestBinTakeOut. Der Bestand wird inPixi_InvBinTakeOutausgebucht. Diese Objekte sind nicht beigefügt, daher lassen sich die genaue Lagerplatzreihenfolge und die Entnahmemeldungen hier nicht dokumentieren. - Nebeneffekte der aufgerufenen Prozeduren:
POSSession_eventundPOSBinTrackwerden geschrieben, das MQ-EreignisPOSInoviceCreatedwird veröffentlicht, und Entnahmefehler werden inLogTableprotokolliert. - Transaktion: Alle Änderungen laufen in einer Transaktion und werden bei jedem Fehler zurückgerollt. Lesezugriffe verwenden
NOLOCK, die KopfaktualisierungROWLOCK.
Parameter
| Parameter | Typ | Standardwert | Beschreibung |
|---|---|---|---|
XML
|
varchar(max) xml |
NULL |
XML-Dokument mit dem Wurzelelement Beispiel:
|
Antwort
Result-Set 1 · Bei Erfolg
Statuszeile mit dem Schlüssel der angelegten oder ergänzten POS-Rechnung.
| Spalte | Typ | Beschreibung |
|---|---|---|
ReturnCode
|
varchar(2) string |
Immer |
Message
Kann leer sein |
int |
|
Result-Set 2 · Bei jedem Fehler während der Verarbeitung (Prüfung, Datenkonvertierung, Bestandsbuchung)
Fehlerzeile. Alle Änderungen wurden zurückgerollt.
| Spalte | Typ | Beschreibung |
|---|---|---|
ReturnCode
|
varchar(5) string |
Immer |
MESSAGE
Kann leer sein |
nvarchar(4000) string |
Fehlertext ( |
Beispielantwort
<SqlRowSet1>
<row>
<ReturnCode>OK</ReturnCode>
<Message>10452</Message>
</row>
</SqlRowSet1>
Fehlermeldungen
| Status | Meldung | Ursache |
|---|---|---|
| ERROR | Mandatory data not present (REGISTERID)! | `HEADER/REGISTERID` fehlt oder ist leer. Die Kassen-ID muss immer übergeben werden. |
| ERROR | Unable to edit existing invoice (does not exist or wrong status) | `POSHEADERKEY` wurde angegeben, aber die Rechnung existiert nicht oder hat den Status `CLO` oder `STO`. Nur offene Rechnungen können ergänzt werden. |
| ERROR | Error creating new invoice- POS is not started! | Für die Kasse existiert keine offene POS-Session (ohne Endzeit). Zuerst die POS-Session starten. |
| ERROR | Item not found, ItemNrInt:{ItemNrInt} | Mindestens eine `ITEMNRINT` passt zu keinem Artikel. Die Nummer in der Meldung stammt aus einer beliebigen Position und ist nicht unbedingt die fehlende. |
| ERROR | Customer not found! | `CUSTOMERNREXTERNAL` wurde angegeben, passt aber zu keinem Kunden. Externe Kundennummer prüfen oder weglassen. |
| ERROR | Only positives for item Quantity! | Eine Position hat eine negative `QUANTITY`. |
| ERROR | DISCOUNTPERCENT can be from 0 to 100! | Eine Position hat einen `DISCOUNTPERCENT` unter 0 oder über 100. |
| ERROR | Adding item to invoice line failed, ItemKey:{ItemKey}, message:{Message} | Die Ausbuchung des Bestands von den Lagerplätzen ist für eine Position fehlgeschlagen, typischerweise wegen zu geringen Bestands. Mögliche Meldungen sind `NoItemStockInGeneral`, `ItemNotonPOS`, `BundleNotonPOS`, `NoStockOnPOS`, 'One of the bundled items has insufficient quantity on stock! (...)', 'Internal error' oder eine Meldung der Bestandsentnahme. Der Text wird auf 150 Zeichen gekürzt. |
Beispiele
POST https://apigateway.descartes.com/tms/pixi/
Content-Type: text/xml; charset=utf-8
Authorization: Basic BASE64(USERNAME:PASSWORD)
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="https://apigateway.descartes.com/tms/pixi/">
<SOAP-ENV:Body>
<ns1:pixiCreatePOSInvoice>
<!-- <XML><![CDATA[<POSINVOICE><HEADER><REGISTERID>KASSE01</REGISTERID><POSHEADERKEY></POSHEADERKEY><COMMENT>Walk-in sale</COMMENT><CUSTOMERNREXTERNAL>CUST-10023</CUSTOMERNREXTERNAL><GENERALBIN>POS-GENERAL</GENERALBIN></HEADER><LINES><LINE><ITEMNRINT>4711</ITEMNRINT><QUANTITY>2</QUANTITY><PRICE>19.99</PRICE><DISCOUNTPERCENT>10</DISCOUNTPERCENT><BIN>A-01-02</BIN><COMMAND>ADD</COMMAND></LINE><LINE><ITEMNRINT>4712</ITEMNRINT><QUANTITY>1</QUANTITY><PRICE>5.50</PRICE><DISCOUNTPERCENT>0</DISCOUNTPERCENT><BIN></BIN><COMMAND>ADD</COMMAND></LINE></LINES></POSINVOICE>]]></XML> -->
</ns1:pixiCreatePOSInvoice>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
curl -X POST 'https://apigateway.descartes.com/tms/pixi/' \
--user 'USERNAME:PASSWORD' \
--header 'Content-Type: text/xml; charset=utf-8' \
--data-binary @- <<'XML'
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="https://apigateway.descartes.com/tms/pixi/">
<SOAP-ENV:Body>
<ns1:pixiCreatePOSInvoice>
<!-- <XML><![CDATA[<POSINVOICE><HEADER><REGISTERID>KASSE01</REGISTERID><POSHEADERKEY></POSHEADERKEY><COMMENT>Walk-in sale</COMMENT><CUSTOMERNREXTERNAL>CUST-10023</CUSTOMERNREXTERNAL><GENERALBIN>POS-GENERAL</GENERALBIN></HEADER><LINES><LINE><ITEMNRINT>4711</ITEMNRINT><QUANTITY>2</QUANTITY><PRICE>19.99</PRICE><DISCOUNTPERCENT>10</DISCOUNTPERCENT><BIN>A-01-02</BIN><COMMAND>ADD</COMMAND></LINE><LINE><ITEMNRINT>4712</ITEMNRINT><QUANTITY>1</QUANTITY><PRICE>5.50</PRICE><DISCOUNTPERCENT>0</DISCOUNTPERCENT><BIN></BIN><COMMAND>ADD</COMMAND></LINE></LINES></POSINVOICE>]]></XML> -->
</ns1:pixiCreatePOSInvoice>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
XML
<?php
$soapClient = new SoapClient(null, [
'login' => 'USERNAME',
'password' => 'PASSWORD',
'location' => 'https://apigateway.descartes.com/tms/pixi/',
'uri' => 'https://apigateway.descartes.com/tms/pixi/',
]);
$arguments = [
// 'XML' => '<POSINVOICE><HEADER><REGISTERID>KASSE01</REGISTERID><POSHEADERKEY></POSHEADERKEY><COMMENT>Walk-in sale</COMMENT><CUSTOMERNREXTERNAL>CUST-10023</CUSTOMERNREXTERNAL><GENERALBIN>POS-GENERAL</GENERALBIN></HEADER><LINES><LINE><ITEMNRINT>4711</ITEMNRINT><QUANTITY>2</QUANTITY><PRICE>19.99</PRICE><DISCOUNTPERCENT>10</DISCOUNTPERCENT><BIN>A-01-02</BIN><COMMAND>ADD</COMMAND></LINE><LINE><ITEMNRINT>4712</ITEMNRINT><QUANTITY>1</QUANTITY><PRICE>5.50</PRICE><DISCOUNTPERCENT>0</DISCOUNTPERCENT><BIN></BIN><COMMAND>ADD</COMMAND></LINE></LINES></POSINVOICE>',
];
$soapArguments = [];
foreach ($arguments as $name => $value) {
$soapArguments[] = new SoapVar($value, XSD_STRING, '', '', $name);
}
$response = $soapClient->__soapCall('pixiCreatePOSInvoice', $soapArguments);
Verwendete Tabellen
- SQL-Objekt:
- dbo.pipiCreatePOSInvoice