iVendNextDevelopers Request a sandbox

S34 — Purchase orders checked by your ERP (a document check)

A distributor's ERP knows things iVendNext does not: which suppliers are on hold, and how much of its monthly purchasing budget the company has left. This app asks it before every purchase order is submitted, from Desk, an import or the API:

The ERP says The buyer sees
The supplier is on hold the order is not submitted: "The ERP holds this supplier: invoice 4471 is unpaid." It stays a draft
The order is over what the company has left of this month's budget needs approval by Purchase Manager ("Over the monthly budget: 7,500.00 USD left."). Whoever submits it meets this: a user without the role is refused, and a purchase manager is asked to approve, and a yes submits
All clear the order is submitted, and its ERP order number is filled in by the ERP (ERP-PO-9912)

It uses the document check extension point (doccheck/1, POS app from train T11). The recipe: A rule checked before a document is submitted.

What the shop does

  1. Install the app from the App library (or paste its manifest into Retail Extension Package in Desk), read what it will do and consent. The install adds the field ERP order number to Purchase Order and the check, switched off. Nothing changes yet.
  2. Give the role Purchase Manager to the people who may approve an order over the monthly budget.
  3. Switch the check on: open it (Retail Extension Subscription, ERP purchase order check), read what is sent, tick the consent and switch it on.

Where it shows. In Desk, when a buyer presses Submit on a purchase order: a refusal in the ERP's words, or the approval by a purchase manager. An import or an API call that submits is answered the same way, with one difference: a submit that runs in the background (an import, a large bulk submit) cannot show an approval, so an over-budget order is refused there; a purchase manager submits it from the form. The till never meets it: a document check is back office only.

What leaves the shop. When a purchase order is submitted: its name, its supplier, its total, each line's item and quantity, the company and the user submitting. Nothing on a draft's save. The manifest names one address; the shop sees it and the consent on the install screen and on the check before it is switched on.

When the service does not answer within 3 seconds, the order is not submitted (did not answer, so this document can't be submitted yet): the declared down answer is refuse, so nothing reaches the ERP unchecked. A shop that would rather submit and look later changes it to allow_and_flag (and reads the note on a copied order below).

What is in the folder

File What it is
manifest.json the field pp_poc_erp_number on Purchase Order and one service: a doccheck subscription on Purchase Order that may fill that field, installed switched off, down answer refuse
po_check.py the pure core: the signature check (verify), the shape check (check_context) and the answer (on_check)
erp.py · erp_standin.json the stand-in ERP: suppliers on hold, each company's monthly purchasing budget and what it has ordered, and the ERP's order numbers. Replace StandIn with a client of your ERP that has the same three methods
service/app.py the service, standard library only: POST /poc/check, GET /health, and the app template's handshake for many shops; one handle answers the web server and the function entry (lambda_handler) alike
Dockerfile · app.json the settings file for hosting ("runs": "function": on CitiXsys hosting it is a function, paid per call) and an image for your own server (built from the kit's root)
tests/ the rules, the service over the wire (one shop and many), every answer against the published contract, the manifest; canaries.py breaks each guarded rule and expects its test to fail

Run it

python3 -m unittest discover -s samples/s34_po_check/tests -p 'test_*.py'
python3 samples/s34_po_check/tests/canaries.py
python3 samples/s34_po_check/service/app.py samples/s34_po_check/service/.env.local

Settings, one shop (service/.env.local, never committed): IVN_CHECK_SECRET (handed back at install as pp_poc:sub:po_check), PORT. Many shops (the app template's handshake): IVN_LIBRARY_APP and a store (IVN_SHOPS_TABLE on CitiXsys hosting, else IVN_SHOPS_FILE); each shop hands over its secret when it connects. POC_PREFIX names the fill field (<prefix>_erp_number, default pp_poc). ERP_STANDIN points at another stand-in file.

Technical notes

What was proven where

Needs this serves

This page in the kit