pixiCreatePOSInvoice
Creates a new POS invoice, or adds lines to an open one, from an XML document and books the sold items out of stock.
Creates a point-of-sale (POS) invoice for a cash register. All data is passed in one XML document in XML.
Parsing
- Header from
POSINVOICE/HEADER:REGISTERID(required),POSHEADERKEY(optional, an existing invoice to extend),COMMENT,CUSTOMERNREXTERNAL(optional) andGENERALBIN(optional general POS bin). - Lines from
POSINVOICE/LINES/LINE:ITEMNRINT,QUANTITY,PRICE,DISCOUNTPERCENT(default 0) andBIN(preferred bin, default empty).COMMANDis read but not used.
Lookups
- The customer is looked up by
Customers.CustomerNrExternal; its address key is stored on the invoice. - The open POS session (
EndTimeis NULL) of the register with the latestStartTimesupplies the location, the session ID and the user name. - Each line's item is looked up by
ItemNrInt; the item's EAN/UPC is taken over.
Validation (in this order; the first failure ends the call with an ERROR row)
REGISTERIDis present.- If
POSHEADERKEYis given, the invoice exists inPOSheader2and its status is notCLOorSTO. - An open POS session exists for the register.
- All items exist.
- If
CUSTOMERNREXTERNALis given, the customer exists. - No quantity is negative.
DISCOUNTPERCENTis between 0 and 100.
Execution (in one transaction)
- Without
POSHEADERKEYa new invoice header is created with the internal procedurePixi_POSNewInvoice(document typeINV). That procedure also records a session event and publishes the MQ eventPOSInoviceCreated. - The header is updated: customer address,
InvoiceComment, update user and update date. - For every line:
- A
POSitem2row is inserted with quantity, price, discount and EAN/UPC. - Take-out bins are suggested with
BINas priority bin andGENERALBINas general bin, in ascending order. - The suggestions are stored in
POSItemBinSelection. - The stock is booked out of the bins (action type 4, stock movement refs
SMORef15 /SMTRef12). - If the booking fails for a line, the whole call is rolled back.
- A
- On success one row with
ReturnCode=OKand the invoice key inMessageis returned.
Notes
- Column name differs by case: the success row has the column
Message, the error row hasMESSAGE. XML element names are case-sensitive, so a client has to read both. - XML parsing outside the error handling:
sp_xml_preparedocumentruns outside theTRYblock. A NULL or malformedXMLtherefore comes back asSqlMessageand not as anERRORrow. The XML document handle is never released withsp_xml_removedocument. - Data type errors: values in the XML that cannot be converted (for example non-numeric
QUANTITYorPRICE) cause anERRORrow with the SQL Server message. - Overwritten header fields: when an existing invoice is extended, its lines are appended and existing lines stay unchanged.
PHCusAddrKeyandInvoiceCommentare always overwritten, with NULL ifCUSTOMERNREXTERNALorCOMMENTis missing. - New invoice for key 0: an empty or
0POSHEADERKEYis treated as "create new". - Misleading item error: the 'Item not found' message takes the item number of an arbitrary line, not necessarily the missing one. If that
ITEMNRINTis missing, the message is empty. The message is truncated to 150 characters. - Unchecked line values: a NULL quantity and a NULL price are not rejected; a quantity of 0 is accepted.
PRICEis stored as given and not taken from the item master data. - Batch numbers and best-before dates: the stock booking passes no batch number or best-before date, so only bin stock without batch number or best-before date qualifies. Items managed by Charge or best-before date will probably fail with a stock message.
- Bin logic not attached: the actual choice of bins happens in
Pixi_POS_GetTakeOutBinsandPixi_POSSuggestBinTakeOut. Stock is booked out inPixi_InvBinTakeOut. These are not attached, so the exact bin order and the take-out messages cannot be documented here. - Side effects of the called procedures:
POSSession_eventandPOSBinTrackare written, the MQ eventPOSInoviceCreatedis published, and take-out errors are logged inLogTable. - Transaction: all changes run in one transaction and are rolled back on any error. Lookups use
NOLOCK, and the header update usesROWLOCK.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
XML
|
varchar(max) xml |
NULL |
XML document with the root Example:
|
Response
Result set 1 · On success
Status row with the key of the created or extended POS invoice.
| Column | Type | Description |
|---|---|---|
ReturnCode
|
varchar(2) string |
Always |
Message
Nullable |
int |
|
Result set 2 · On any error inside the processing (validation, data conversion, stock booking)
Error row. All changes have been rolled back.
| Column | Type | Description |
|---|---|---|
ReturnCode
|
varchar(5) string |
Always |
MESSAGE
Nullable |
nvarchar(4000) string |
Error text ( |
Response example
<SqlRowSet1>
<row>
<ReturnCode>OK</ReturnCode>
<Message>10452</Message>
</row>
</SqlRowSet1>
Error messages
| Status | Message | Cause |
|---|---|---|
| ERROR | Mandatory data not present (REGISTERID)! | `HEADER/REGISTERID` is missing or empty. Always send the register ID. |
| ERROR | Unable to edit existing invoice (does not exist or wrong status) | `POSHEADERKEY` was given, but the invoice does not exist or has the status `CLO` or `STO`. Only open invoices can be extended. |
| ERROR | Error creating new invoice- POS is not started! | There is no open POS session (without end time) for the register. Start the POS session first. |
| ERROR | Item not found, ItemNrInt:{ItemNrInt} | At least one `ITEMNRINT` does not match an item. The number in the message is from an arbitrary line and may not be the missing one. |
| ERROR | Customer not found! | `CUSTOMERNREXTERNAL` was given but matches no customer. Check the external customer number or leave it out. |
| ERROR | Only positives for item Quantity! | A line has a negative `QUANTITY`. |
| ERROR | DISCOUNTPERCENT can be from 0 to 100! | A line has a `DISCOUNTPERCENT` below 0 or above 100. |
| ERROR | Adding item to invoice line failed, ItemKey:{ItemKey}, message:{Message} | Booking the stock out of the bins failed for a line, typically because of insufficient stock. Possible messages include `NoItemStockInGeneral`, `ItemNotonPOS`, `BundleNotonPOS`, `NoStockOnPOS`, 'One of the bundled items has insufficient quantity on stock! (...)', 'Internal error' or a message from the stock take-out. The text is truncated to 150 characters. |
Examples
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);
Tables used
- SQL object:
- dbo.pipiCreatePOSInvoice