Migrating to v2 receipts

We are currently rolling out a new way of receiving products in Picqer. The main difference is that, in the new version, products will be added directly to the stock. Whereas before this would happen upon completing the receipt.

To support this new flow we needed to change parts of the API, especially to make products in the receipt unmutable since they're already added to the stock.

A user can change the version of a receipt on a per-receipt basis, which means you’ll have to support both versions simultaneously. Once a receipt has been created and at least one product is received, the version of that specific receipt cannot be changed anymore.

Changes in the "receipt" resource

You can identify the type of receipt by looking at the version property in the returned receipt object.
One of the main differences in this new resource is that expected products are no longer exposed. Instead, the "products" key exposes the products that are actually received and thus added to the stock.

Note that a user can receive the same products multiple times, for example at different locations.

This new resource is returned in both the collection as the detail endpoint mixed with v1 receipts.

Change V1 V2
Added field version (also added to v1 resource) version
Renamed field products.stock_location products.location
Removed field remarks -
Removed field amount_received_excessive -
Removed field completed_by -
Removed field products.amount_backorders -
Removed field products.amount_more_than_ordered -
Removed field products.amount_previously_received -
Removed field products.amount_receiving -
Removed field products.candidate_purchaseorders -
Removed field products.locations -
Removed field products.product_locations -
Removed field products.stock -
Added field - products.created_at
Added field - products.received_by_iduser
Added field - products.reverted_at
Added field - products.reverted_by_iduser
The v2 receipt resource
{ "idreceipt": 469364, "receiptid": "RC2020-1071", "idwarehouse": 18, "version": 2, "status": "processing", "supplier": { "idsupplier": 55151, "name": "Schoenmaker Kramer" }, "purchaseorder": { "idpurchaseorder": 612084, "purchaseorderid": "20201023" }, "status": "processing", "remarks": null, "completed_by": null, "amount_received": 1, "completed_at": null, "created": "2020-11-11 14:18:42", "updated": "2020-11-11 14:18:42", "products": [ { "idreceipt_product": 14959405, "idpurchaseorder_product": 9473892, "idproduct": 13177709, "idpurchaseorder": 612084, "productcode": "AA568904", "productcode_supplier": "SEC-AA568904", "name": "Secrid Eco Drive Calculator Lumix", "barcode": "5480962989264", "amount": 1, "amount_ordered": 5, "added_by_receipt": false, "abc_classification": null, "received_by_iduser: 1, "reverted_at": null, "reverted_by_iduser": null, "image": null, "location": { "idlocation": 2059474, "idwarehouse": 18, "parent_idlocation": 2059472, "type": "location", "name": "A.2.1.2", "remarks": null, "unlink_on_empty": false, "location_type": { "idlocation_type": 1, "name": "Standaard", "default": true, "color": "#0000f0" }, "is_bulk_location": false } } ] }

Fetching the expected products

It is still possible to see which products are expected for a certain receipt, but this is moved to a new endpoint.

You can request the expected-products for a receipt, or for a particular product. For example in case of a receipt for a supplier instead of a specific purchase-order.

The expected-product resource
{ "product": { "idproduct": 114, "idvatgroup": 1, "idsupplier": 4, "productcode": "0195949018510", "name": "Apple iPhone 15 Pro", "price": 1000, "fixedstockprice": 0, "productcode_supplier": "", "deliverytime": 0, "description": "", "barcode": "", "unlimitedstock": false, "assembled": false, "type": "normal", "weight": 0, "length": null, "width": null, "height": null, "minimum_purchase_quantity": 0, "purchase_in_quantities_of": 0, "hs_code": "", "country_of_origin": "", "show_on_portal": true, "active": true, "comment_count": 0, "analysis_abc_classification": null, "analysis_pick_amount_per_day": null, "tags": {}, "productfields": [], "images": [], "stock": [], "pricelists": [] }, "totals": { "expected": 10, "received": 5, "remaining": 5 }, "strategies": [ { "strategy": "automatic", "parameters": {}, "ordered": 10, "received": 5, "remaining": 5 }, { "strategy": "purchaseorder_product", "parameters": { "idpurchaseorder_product": 572 }, "purchaseorderid": "PO2024-1163", "ordered": 10, "received": 5, "remaining": 5 }, { "strategy": "new", "parameters": {}, "idpurchaseorder": null, "purchaseorderid": null } ] }


A new concept are the strategies which are returned in the expected products resource. These strategies can be used when adding a product to the receipt. As of now there are 3 types of strategies:

  1. automatic - This strategy will automatically divide the amount over open purchaseorder products. This strategy is only relevant for receipts not based on a specific purchase-order.
  2. purchaseorder_product - This strategy will register the amount on a specific purchaseorder product.
  3. new - This strategy will add the product to either the linked purchaseorder or a freshly created purchaseorder for excessive products.

Since the automatic strategy can result in mutiple entries for different purchase-order products the add product endpoint returns a collection of receipt-products instead of a single receipt-product when called on a v2 receipt.

Reverting a receipt-product

Sometimes a mistake has been made while registering a receipt, it is therefore possible in a v2 receipt to revert a receipt-product. This is only possible when the stock is still available on the location that it was added to. It will effectively decrease the stock by the received amount and mark the receipt-product as reverted.

A reverted entry will be reflected in the receipt.products.* resources under the reverted_at & reverted_by_iduser field.

Deprecated endpoints

The following endpoints will not work for v2 receipts anymore:

  • PUT https://example.picqer.com/api/v1/receipts/{idreceipt}/products/{idreceipt_product}
  • POST https://example.picqer.com/api/v1/receipts/{idreceipt}/mark-all-received