Guide for in-store logistics

As soon as the master data and prices are done, it’s time for getting the logistics setup.

In this guide you will learn how to integrate Front Systems to support the most common in-store logistics processes as well as getting in-store transactions back into your ERP, BI, and so on.

Now lets get started !

Deliveries

RECOMMENDED

Whether it’s an auto replenishment triggered in your ERP, or it’s a seasonal pre-order, you need the orders to be imported into Front Systems as deliveries. Deliveries can easily be received by store associates from within Front Systems app and/or back office.

When a delivery is received (fully or partially) , the ERP will be updated with what was received. This provides your ERP with data so it can complete internal processes. Eg invoicing, as well as making sure the ERP has live stock levels from the stores.

Creating Delivery

As soon as a delivery is made available in the ERP, it must be fed into Front Systems so its available for receiving.

Heres how to create a delivery:

Get a list of all stores inc stock
GET /api/Stores
---
[
{
"StoreId": 2066,
"StoreNo": "",
"Legalname": "Showroom AS",
"Orgnum": "123456789",
"StoreName": "Showroom Oslo",
"Address": "Bogstadveien 12",
"PostalCode": "0205",
"City": "Oslo",
"Country": "Norge",
"CountryCode": "NOR",
"Email": "showroom@frontsystems.no",
"Web": "showroom.frontsystems.no",
"Phone": "22556444",
"StockId": 1446,
"Currency": "NOK",
"TimeZone": "W. Europe Standard Time",
"TimeZoneInfo": "Europe/Oslo"
}
]

Pulling the stores endpoint will ensure you have both storeid and stockid which you need to create a delivery.
TIP: The StoreNo can be assigned per store with your own id. For example the unique store number in your ERP. (must be assigned by your Front systems contact person)
Create a Delivery
PUT /api/Delivery

Example how to create a delivery with 5 qty of a product

{
"extRef": "Delivery no 1",
"stockId": 1,
"storeId": 1,
"orderDate": "2020-08-18T19:32:31.983Z",
"expectedDeliveryDate": "2020-08-18T19:32:31.983Z",
"comment": "string",
"insertAsConfirmed": true,
"orderLines": [
{
"gtin": "7031581726143",
"qty": 5,
"cost": 100
}
]
}

Get delivery status

When a delivery is received (partially or fully) within Front Systems you will want to get the ERP updated with the items actually received.
This is achieved by pulling deliveries endpoint.

Get Deliveries
GET /api/GetOrdersV3?stockid=xxx

Where stockid is the Front Systems Stock used by the relevant store.

Example response

{
"OrderId": 1910774,
"Ordernumber": "SO54654",
"Description": null,
"OrderDate": "2021-05-04T00:00:00.000",
"Brand": "Bergans",
"Season": "S2021",
"TotalConfirmedQty": 58,
"TotalConfirmedCost": 25794,
"TotalReceivedQty": 58,
"TotalReceivedCost": 25794,
"ToStockId": 1446,
"OrderType": 1,
"OrderStatus": 4,
"Completed": false,
"Products": [
{
"ProductId": 5373100,
"Size": 0,
"SizeLabel": 1,
"Name": "RABOT DOWN BLANKET 300",
"Number": "5754-13742",
"Variant": "Navy/StrongBlue",
"Color": "Navy/StrongBlue",
"Label": "75",
"Description": null,
"QtyConfirmed": 0.0,
"QtyReceived": 5.000,
"Cost": 734.810,
"Identifier": "7031582100072"
},
{
"ProductId": 5373100,
"Size": 0,
"SizeLabel": 1,
"Name": "RABOT DOWN BLANKET 300",
"Number": "5754-13742",
"Variant": "Navy/StrongBlue",
"Color": "Navy/StrongBlue",
"Label": "80",
"Description": null,
"QtyConfirmed": 5.000,
"QtyReceived": 0.0,
"Cost": 734.810,
"Identifier": "7031582100072"
}
}

Realtime delivery status updates with webhooks

Alternatively you can get updates by webhooks. That way you can choose to get a payload to your endpoint when there has been either a ; DeliveryCreated, DeliveryUpdated or DeliveryCompleted event in Front Systems, and you can set it up pr. store if that is preferable to your case.

The payloads are very similar but will change depending on what occured. See examples below:

Here you see a delivery of the type "DirectDelivery" wich will result in a stockMovement happening. As a result of that the stockMovements array will be present and populated. If this was a "PlannedDelivery" (inserted with property insertAsConfirmed = true) delivery type that would be empty until an update was done after the store received some or all of the items.

Example "Created"

{   
"stockId": 3082,
"stockExtId": null,
"isCompleted": true,
"products": [
{
"identifier": "0749693715502",
"gtin": "00012345678905",
"quantityExpected": 6,
"quantityReceived": 6,
"currentStockLevel": 21,
"costPrice": null,
"costPriceCurrency": "NOK",
"stockMovements": [
"movementId": 197977019,
"createdDateTime": "2022-10-18T11:08:45.323",
"quantity": 4,
"costPrice": 200
]
}
],
"expectedDeliveryDate": "2022-10-18",
"companyId": 843,
"orderId": 3046966,
"orderReference": "OrdNr-Okt18.234123",
"comment": "Text",
"type": "DirectDelivery",
"status": "Delivered",
"createdDateTime": "2022-10-18T11:08:08.367",
"updatedDateTime": "2022-10-18T11:21:00.797"
}

Example "Updated - Partial Receive"

In this example the store has received 4 of the total 6 items and changed the costPrice to 31 instead of the original 200.
NB! Both these actions alone would create an event it self if the user saved between the actions.

{
"stockId": 3082,
"stockExtId": null,
"isCompleted": false,
"products": [
{
"identifier": "0749693715502",
"gtin": "",
"quantityExpected": 6,
"quantityReceived": 4,
"currentStockLevel": 25,
"costPrice": 31,
"costPriceCurrency": "NOK",
"stockMovements": [
{
"movementId": 197981175,
"createdDateTime": "2022-10-18T11:39:50.253",
"quantity": 4,
"costPrice": 31
}
]
}
],
"expectedDeliveryDate": "2022-10-18",
"companyId": 843,
"orderId": 3046967,
"orderReference": "OrdNr-Okt18.275223",
"comment": "Text",
"type": "PlannedDelivery",
"status": "Delivered",
"createdDateTime": "2022-10-18T11:20:08.367",
"updatedDateTime": "2022-10-18T11:39:50.173"
}

Stock levels and stock movements

OPTIONAL

Front Systems is the source of truth when it comes to stock levels in store. In case you need to get
the stock movements and/or stock levels in another system, eg ERP, OMS etc, then you can pull that from the API. Additionally you can subscribe to the StockMovementCreated Webhook so you can update your integrated systems in real time.

Get stock levels
POST /api/Stock

Use this to get the stock levels from stores periodically (eg once per week) to make sure they are reconciled.
The quantity in the response is the total stock level.
Note: This endpoint uses the POST verb even though it returns data and does not update or insert anything.

Example of request body

{
"stockIds": [1446],
"useGTIN": true
}

Example response

[
{
"id": "7020041284958",
"stockId": 1446,
"quantity": 1.000
},
{
"id": "7020580004710",
"stockId": 1446,
"quantity": 3.000
}
]

Get stock movements
GET /odata/Stockmovements
A stock movement represents an item which has increased or decreased in qty with a specific time stamp.

Stock movement types are
1 = sale
3 = delivery
4 = transfer
5 = reconciled by stock take
NOTE: When using the odata API like this endpoint, you may use $filer and $select to limit the response.

Example query params

GET 
https://frontsystemsapis.frontsystems.no/odata/Stockmovements

Query params:
from='2021-06-01'
to='2021-06-03'
$select=EAN,Qty,Stockid,Stock,MoveDateTime

Example response

{
"odata.metadata": "https://api.frontsystems.no/odata/$metadata#Stockmovements&$select=EAN,Qty,Stockid,%20Stock,%20MoveDateTime",
"value": [
{
"EAN": "7020580008718",
"Qty": -1,
"Stockid": 1446,
"Stock": "Oslo",
"MoveDateTime": "2021-05-04T13:53:00.277"
},
{
"EAN": "2058500022693",
"Qty": -1,
"Stockid": 1446,
"Stock": "Oslo",
"MoveDateTime": "2021-05-04T11:00:04.157"
}
]
}

Example response

{
"odata.metadata": "https://api.frontsystems.no/odata/$metadata#Stockmovements&$select=EAN,Qty,Stockid,%20Stock,%20MoveDateTime",
"value": [
{
"EAN": "7020580008718",
"Qty": -1,
"Stockid": 1446,
"Stock": "Oslo",
"MoveDateTime": "2021-05-04T13:53:00.277"
},
{
"EAN": "2058500022693",
"Qty": -1,
"Stockid": 1446,
"Stock": "Oslo",
"MoveDateTime": "2021-05-04T11:00:04.157"
}
]
}


If you want to keep your integrated system updated with live stock status, then you can subscribe to the StockMovementCreated webhook.
Here you can see an example of how to create the subscription which is permanent until you delete the subscription.

WEBHOOK - StockMovementCreated
Create webhook subscription
POST /api/Webhooks

Example of request

{
"event": "StockMovementCreated",
"url": "https://yourcalbackurl.com?token=abc"
}

Example response

{ 
"companyId": 585,
"movementId": 143677379,
"stockId": 1446,
"stockExtId": "",
"sku": "048692520209",
"gtin": "5711451796491",
"type": "Sale",
"quantity": -1,
"stockLevel": 2,
"createdDateTime": "2021-10-27T09:58:02.41"
}

example response

POS SETTLEMENTS

OPTIONAL

Getting the financial pos settlement into your ERP in real time or near real time is easy. It doesn't matter which system you are using, the data you need to feed them is all the same.

As soon as a pos settlement has been completed in a pos, it will be available for you to insert into your ERP-system via the API. Remember that each POS has its own pos settlement. It is possible to have multiple pos settlements per pos pr day.

In the below example you will see how you can pull for pos settlements for all pos across all stores. A good practise is to setup your integration to request this endpoint at the end of the day or during the night.

Get POS settlements
GET /api/possettlement

Example of response

[
{
"SETTLEMENTID": 1222378,
"BatchNumber": "11",
"StoreNo": "XXNO03",
"StoreInfo": "461003",
"StoreName": "Bogstadveien AS",
"POSID": 4530,
"PosName": "Bogstadveien TEST P01",
"PersonName": "Einar Andreas FRONT",
"SettlementTimeStamp": "2021-02-23T09:45:44.78",
"DateTimeFrom": "2021-02-22T12:20:42.007",
"DateTimeTo": "2021-02-23T09:45:44.78",
"ReceiptNoFrom": 130000060,
"ReceiptNoTo": 130000073,
"Currency": "NOK",
"GrossTotal": 11192,
"GrossDiscount": 1948.89,
"GrandTotal": 9243.11,
"NetTotal": 7394.49,
"VATTotal": 1848.62,
"VATArea1": 1848.62,
"VATArea2": 0,
"VATArea3": null,
"OpeningCashBalance": 2695,
"ClosingCashBalance": 4434,
"Discrepancy": 100,
"Comment": "",
"PaymentTypes": [
{
"PaymentTypeId": "1",
"Type": "Card",
"SubType": "bankaxept",
"Currency": "NOK",
"CurrencyTendered": 1399,
"Amount": 1399
},
{
"PaymentTypeId": "1",
"Type": "Card",
"SubType": "mc",
"Currency": "NOK",
"CurrencyTendered": 1399,
"Amount": 1399
},
{
"PaymentTypeId": "2",
"Type": "Cash",
"SubType": "ForeignCash",
"Currency": "EUR",
"CurrencyTendered": 50,
"Amount": 485
}, {
"PaymentTypeId": "2",
"Type": "Cash",
"SubType": "Cash",
"Currency": "NOK",
"CurrencyTendered": 2089,
"Amount": 2089
},
{
"PaymentTypeId": "2",
"Type": "Cash",
"SubType": "ForeignCash",
"Currency": "USD",
"CurrencyTendered": 150,
"Amount": 1271
},
{
"PaymentTypeId": "5",
"Type": "Giftcard",
"SubType": "Giftcard in",
"Currency": "NOK",
"CurrencyTendered": 700,
"Amount": 700
},
{
"PaymentTypeId": "5",
"Type": "Giftcard",
"SubType": "Giftcard old in",
"Currency": "NOK",
"CurrencyTendered": 1300,
"Amount": 1300
},
{
"PaymentTypeId": "5",
"Type": "Giftcard",
"SubType": "Giftcard out",
"Currency": "NOK",
"CurrencyTendered": -600,
"Amount": -600
},
{
"PaymentTypeId": "116",
"Type": "Cash",
"SubType": "Rounding",
"Currency": "NOK",
"CurrencyTendered": 0.11,
"Amount": 0.11
},
{
"PaymentTypeId": "8",
"Type": "Voucher",
"SubType": "Voucher in",
"Currency": "NOK",
"CurrencyTendered": 1399,
"Amount": 1399
},
{
"PaymentTypeId": "8",
"Type": "Voucher",
"SubType": "Voucher old in",
"Currency": "NOK",
"CurrencyTendered": 1200,
"Amount": 1200
},
{
"PaymentTypeId": "8",
"Type": "Voucher",
"SubType": "Voucher out",
"Currency": "NOK",
"CurrencyTendered": -1399,
"Amount": -1399
}
],
"Withdrawals": [
{
"PaymentTypeId": 2,
"Type": "Cash",
"SubType": "Bank deposit ",
"Amount": -400
}
],
"Deposits": [
{
"PaymentTypeId": 2,
"Type": "Cash",
"SubType": "Cash in to POS",
"Amount": 150
}
]
}]


Note: An alternative to exporting POS settlements from the API, is to export it via Backoffice Portal as a file. Use this option if you cant find time to integrate with your ERP the first period of rollout.

SALES TRANSACTIONS (POS Orders)

You can really get your dream come true when it comes to having super cool dashboards in your offices showing all kinds of KPIs in real time. For that you simply have to pull sales transactions from the below endpoint into your ERP or Business Intelligence platform of your choice.
In case you need to import sales transactions into a BI-platform, using our special oData endpoints very convenient because many BI-tools support it out of the box. Anyways, here's how you can get started by pulling sales transactions.

Just two sentences about oData-api. Most of our endpoints are standard REST-apis, but some of the api endpoints have been based on the specifications of oData.
The difference is that our oData format works out of the box with many BI-tools (eg. PowerBI, Taubleu, Excel...), they are rad-only (only GET) and you can get improved performance by limiting your requests by using the specific oData syntax like $filer, $select, etc.

Okay, now to the fun part.

Howto Pull sales transactions 
GET /odata/Saleslines
TIP: use header Accept:application/json to format the response. Else you will get XML
Also consider using $filter and $select to limit the size of the request and response to increase performance.
-
Example request using some paramaters to limit the request and response.
/odata/Saleslines?from='2021-06-10 13:00:00.000'&to='2021-06-10 14:00:00.000'&$select=STOREID_FK,SaleDateTime,Qty,EAN,Price,FullPrice

Giving the response like this

{
"odata.metadata": "https://api.frontsystems.no/odata/$metadata#Saleslines&$select=STOREID_FK,SaleDateTime,Qty,EAN,Price,FullPrice",
"value": [
{
"STOREID_FK": 2080,
"SaleDateTime": "2021-05-04T11:52:52",
"Qty": "1.00",
"EAN": "7020580008718",
"Price": "64.95",
"FullPrice": "799.00"
}
]
}

In case you would like to get more details on your sales dashboards like product master data, then just make sure you also pull products into your BI-tool for mapping.
To do so use the oData Products endpoint. Note that this endpoint returns product data on variant level without sizes, gtins, skus etc. If you need those, you must use the oData ProductListSizes endpoint. Alternatively you can use the standard Products endpoint which is an equivalent to the ProductListSizes endpoint depending on your taste.

SaleCreated Webhook
If you want to keep your integrated system updated with sales in real time, then you can subscribe to the SaleCreated webhook.
So at the second a sale is completed in a POS, you will get the payload into your subscribing endpoint.
Here you can see an example of how to create the subscription which is permanent until you delete the subscription.

WEBHOOK - SaleCreated
Create webhook subscription
POST /api/Webhooks

Example of request

{
"event": "SaleCreated",
"url": "https://yourcalbackurl.com?token=abc"
}

SaleCreated payload response is like this

{ 
"receiptNo": "653000583",
"receiptFormatted": "<ArrayOfPrintLine xmlns=\"http://schemas.datacontract.org/2004/07/KTKservice\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\"><PrintLine><PType>Bitmap</PType><Value/></PrintLine><PrintLine><PType>Feed</PType><Value/></PrintLine><PrintLine><PType>SmallCenter</PType><Value>Front Systems AS</Value></PrintLine><PrintLine><PType>SmallCenter</PType><Value>Lysaker torg 25</Value></PrintLine><PrintLine><PType>SmallCenter</PType><Value>1366 Oslo</Value></PrintLine><PrintLine><PType>SmallCenter</PType><Value>Tlf.: 22556444</Value></PrintLine><PrintLine><PType>SmallCenter</PType><Value>sales@frontsystems.com</Value></PrintLine><PrintLine><PType>SmallCenter</PType><Value>www.frontsystems.com</Value></PrintLine><PrintLine><PType>SmallCenter</PType><Value>Org.no.: 123456789</Value></PrintLine><PrintLine><PType>SmallCenter</PType><Value>Foretaksregisteret</Value></PrintLine><PrintLine><PType>Feed</PType><Value/></PrintLine><PrintLine><PType>BigCenterBold</PType><Value>SALGSKVITTERING</Value></PrintLine><PrintLine><PType>SmallLeftUnderline</PType><Value> </Value></PrintLine><PrintLine><PType>SmallLeftUnderline</PType><Value>Tid: 2021.10.27 09:30 Kvittnr.: 0653000583</Value></PrintLine><PrintLine><PType>SmallLeft</PType><Value>Ant. Vare Rab. Pris</Value></PrintLine><PrintLine><PType>SmallLeft</PType><Value> 1 M Samsøe Sam T-skjorte Lem crew neck 100 999.00</Value></PrintLine><PrintLine><PType>SmallLeftUnderline</PType><Value> </Value></PrintLine><PrintLine><PType>SmallLeftBold</PType><Value>Total: 999.00</Value></PrintLine><PrintLine><PType>SmallLeftUnderline</PType><Value>Her av MVA 199.80</Value></PrintLine><PrintLine><PType>Feed</PType><Value/></PrintLine><PrintLine><PType>SmallLeft</PType><Value>MVA sammendrag:</Value></PrintLine><PrintLine><PType>SmallLeft</PType><Value> 25.0% 199.80</Value></PrintLine><PrintLine><PType>Feed</PType><Value/></PrintLine><PrintLine><PType>SmallLeft</PType><Value>Oppgjør:</Value></PrintLine><PrintLine><PType>SmallLeft</PType><Value> Credit card 999.00</Value></PrintLine><PrintLine><PType>SmallLeft</PType><Value>BAX: 111010-77370690\n27/10/2021 09:30\n\nBankAxept\nContactless\n**************0108-1\nAID:D5780000021010\nTVR:8000048000\nTSI:2800\nREF:235 010689008610\nRESP:00 GODKJENT\nPIN-kode verifisert\n\nNOK= 999,00\n \nTRUMF REGISTRERT</Value></PrintLine><PrintLine><PType>SmallLeftUnderline</PType><Value> </Value></PrintLine><PrintLine><PType>SmallLeft</PType><Value>POSID: 2653 </Value></PrintLine><PrintLine><PType>SmallLeft</PType><Value>Du ble hjulpet av: Mari </Value></PrintLine><PrintLine><PType>SmallLeftUnderline</PType><Value> </Value></PrintLine><PrintLine><PType>Feed</PType><Value/></PrintLine><PrintLine><PType>BigCenter</PType><Value>Ha det fint da :)</Value></PrintLine><PrintLine><PType>Barcode</PType><Value>SC653000583</Value></PrintLine><PrintLine><PType>Feed</PType><Value/></PrintLine></ArrayOfPrintLine>",
"receiptUrl": "https://r.frontsystems.com?id=c26a3b84-8a04-4798-b0f6-1aae4d15622b",
"orderNo": null,
"createdDateTime": "2021-10-27T09:30:23.558731",
"updatedDateTime": null,
"paymentLines": [
{
"type": "Card",
"subType": "bankaxept",
"currency": "NOK",
"currencyTendered": 999.00,
"txRef": "ABC",
"text": "BAX: 111010-77370690\n27/10/2021 09:30\n\nBankAxept\nContactless\n**************0108-1\nAID:D5780000021010\nTVR:8000048000\nTSI:2800\nREF:235 010689008610\nRESP:00 GODKJENT\nPIN-kode verifisert\n\nNOK= 999,00\n \nTRUMF REGISTRERT",
"amount": 999.00
}
],
"orderLines": [
{
"rowId": "",
"gtin": "5711451796491",
"brand": "Samsøe Samsøe",
"name": "Lem crew neck 10000",
"variant": "BLUE SURF",
"number": "M19222303",
"colour": "BLÅ",
"size": "9",
"sizeText": "M",
"group": "T-skjorte",
"season": "1",
"imageUrl": "https://image.frontsystems.com/7edeb8df-a3b4-4dcf-8968-5fd8a59466d4/724ca781-dbc6-4921-a114-5992160ad17e.jpg",
"quantity": 1.0,
"price": 999.0,
"vat": 199.8,
"vatPercent": 0.25,
"fullPrice": 999.0,
"discount": 0.0,
"discountPercent": 0.0,
"receiptLabel": "M Samsøe Sam T-skjorte Lem crew neck 10000 BLUE S",
"shipFromOnlineStore": false
}
],
"store":
{
"storeExtId": "NOOSL01",
"storeName": "Front Systems AS",
"organizationNumber": "123456789",
"posId": 2653,
"posName": "Showroom Self-checkout (active)",
"salesPerson": "Mari",
"currency": "NOK",
"address":
{
"address1": "Lysaker torg 25",
"city": "Oslo",
"postalCode": "1366",
"country": "Norway",
"countryCode": "NO"
}
},
"customer":
{
"email": "",
"firstName": "",
"lastName": "",
"companyName": "",
"phoneCountryPrefix": "",
"phone": "",
"address":
{
"firstName": "",
"lastName": "",
"address1": "",
"city": "",
"postalCode": "",
"country": "Norway",
"countryCode": "NO"
}
},
"shippingAddress":
{
"firstName": "",
"lastName": "",
"address1": "",
"city": "",
"postalCode": "",
"country": "Norway",
"countryCode": "NO"
},
"vatTotal": 199.8,
"total": 999.0
}