Lifecycle & Evaluation Flow
This page explains when and how Buying Policies are evaluated, the order of checks, and how blocking reasons and unblock workflows work.
Quick orientation
- Policy families are toggled independently (Credit Control, Quotas).
- Evaluation is ordered and deterministic: Credit Control → Quotas.
- If any policy blocks, the order becomes blocked with one or more reasons that you can retrieve and audit.
- Operators may force validation (unblock) with a recorded audit trail.
🧪 End-to-end evaluation
graph LR %% ---------- Flow ---------- IN[Incoming order] --> T[Policies enabled?<br>Credit Control, Quotas] T -->|No| PASS[Pass through<br>no policy checks] T -->|Yes| CRED[Credit Control<br>exposure, holds, grace] CRED -->|Block| R1[Collect reasons] CRED -->|OK| QUO[Quotas<br>min thresholds, rules] QUO -->|Block| R2[Collect reasons] QUO -->|OK| OK[Allow order] R1 --> OUT[Result: Blocked<br>with reasons] R2 --> OUT %% ---------- Styles ---------- classDef total fill:#e8f1ff,stroke:#2f6feb,stroke-width:2px,color:#0b3d91; classDef diff fill:#fff4e5,stroke:#f59e0b,stroke-width:2px,color:#7a3e00; classDef inter fill:#fee2e2,stroke:#ef4444,stroke-width:2px,color:#7f1d1d; classDef visible fill:#ecfdf5,stroke:#10b981,stroke-width:2px,color:#064e3b; class IN,T total; class CRED,QUO diff; class R1,R2,OUT inter; class OK visible; class PASS visible; style IN rx:8,ry:8 style T rx:8,ry:8 style PASS rx:8,ry:8 style CRED rx:8,ry:8 style QUO rx:8,ry:8 style R1 rx:8,ry:8 style R2 rx:8,ry:8 style OK rx:8,ry:8 style OUT rx:8,ry:8 linkStyle 2 stroke:#ef4444,stroke-width:2px linkStyle 4 stroke:#ef4444,stroke-width:2px
When it runs Policies are evaluated during order processing. If a policy blocks, the order appears in the blocked orders view and exposes blocking reasons that can be fetched via API.
💳 Credit Control — decision flow
graph LR
%% ---------- Flow ----------
A[Start Credit Control] --> H{Credit Hold active<br>per account}
H -->|Yes| BLK1[Block<br>reason: credit_hold_active]
H -->|No| E[Exposure check<br>against credit limit]
E -->|Within limit| OK2[Allow]
E -->|Over limit within grace| OK1[Allow<br>consume grace amount]
E -->|Over limit beyond grace| BLK2[Block<br>reason: credit_limit_exceeded]
%% ---------- Styles ----------
classDef total fill:#e8f1ff,stroke:#2f6feb,stroke-width:2px,color:#0b3d91;
classDef diff fill:#fff4e5,stroke:#f59e0b,stroke-width:2px,color:#7a3e00;
classDef inter fill:#fee2e2,stroke:#ef4444,stroke-width:2px,color:#7f1d1d;
classDef visible fill:#ecfdf5,stroke:#10b981,stroke-width:2px,color:#064e3b;
class A,E,H diff;
class BLK1,BLK2 inter;
class OK1,OK2 visible;
style A rx:8,ry:8
style H rx:8,ry:8
style E rx:8,ry:8
style BLK1 rx:8,ry:8
style BLK2 rx:8,ry:8
style OK1 rx:8,ry:8
style OK2 rx:8,ry:8
What’s considered
- Manual Credit Holds (account-level blocks).
- Exposure vs credit limit, with Grace Amount tolerance per account.
- Admins configure policy toggle, default credit limit, and per-account grace.
📊 Quotas — decision flow
graph LR %% ---------- Flow ---------- Q[Start Quotas] --> EN[Quotas enabled?] EN -->|No| PASS[Skip quotas] EN -->|Yes| SCOPE[Resolve applicable rules<br>default min + overrides] SCOPE --> GRP[Co-validation groups?<br>sum bucket if configured] GRP --> CMP[Compare order metrics<br>against min thresholds] CMP -->|Below min| BLK[Block<br>reason: quota_min_not_met] CMP -->|Meets min| OK[Allow] %% ---------- Styles ---------- classDef total fill:#e8f1ff,stroke:#2f6feb,stroke-width:2px,color:#0b3d91; classDef diff fill:#fff4e5,stroke:#f59e0b,stroke-width:2px,color:#7a3e00; classDef inter fill:#fee2e2,stroke:#ef4444,stroke-width:2px,color:#7f1d1d; classDef visible fill:#ecfdf5,stroke:#10b981,stroke-width:2px,color:#064e3b; class Q,EN,SCOPE,GRP,CMP diff; class BLK inter; class OK,PASS visible; style Q rx:8,ry:8 style EN rx:8,ry:8 style SCOPE rx:8,ry:8 style GRP rx:8,ry:8 style CMP rx:8,ry:8 style BLK rx:8,ry:8 style OK rx:8,ry:8 style PASS rx:8,ry:8
What’s considered
- Policy toggle and Default minimum.
- Specific rules per Account, Supplier, or Store.
- Co-validation groups (shared quota buckets across configurations).
- Mono-supplier platforms: quota logic still applies; rules typically scope to the single supplier.
🧾 Blocking reasons & audit (unblock)
graph LR %% ---------- Flow ---------- B[Order blocked by policy] --> R[Fetch reasons<br>GET /v1/buying-policies/blocking-reasons<br>ADM-BUYING-POLICY-552] B --> V[View in UI<br>Blocked orders page] B --> F[Force validation<br>POST /v1/logistic-orders/unblock<br>ADM-ORDER-150] F --> H[Audit history<br>GET /v1/logistic-orders/logisticOrderId/unblock-history<br>ADM-ORDER-550] R --> H %% ---------- Styles ---------- classDef total fill:#e8f1ff,stroke:#2f6feb,stroke-width:2px,color:#0b3d91; classDef inter fill:#fee2e2,stroke:#ef4444,stroke-width:2px,color:#7f1d1d; classDef visible fill:#ecfdf5,stroke:#10b981,stroke-width:2px,color:#064e3b; classDef resp fill:#f2f4f7,stroke:#475569,stroke-width:2px,color:#111827; class B inter; class R,F,H visible; class V resp; style B rx:8,ry:8 style R rx:8,ry:8 style V rx:8,ry:8 style F rx:8,ry:8 style H rx:8,ry:8
“Force validation” (unblock) is an operator action with a persistent audit trail.
⚙️ Admin settings (where these checks are configured)
Credit Control
- GET /v1/buying-policies/credit-control — ADM-BUYING-POLICY-500
- PATCH /v1/buying-policies/credit-control — ADM-BUYING-POLICY-200
- PATCH /v1/buying-policies/credit-control/credit-limit — ADM-BUYING-POLICY-201
- GET /v1/buying-policies/credit-control/grace-amounts — ADM-BUYING-POLICY-551
- POST /v1/buying-policies/credit-control/grace-amounts — ADM-BUYING-POLICY-151
- PUT /v1/buying-policies/credit-control/grace-amounts/:graceAmountId — ADM-BUYING-POLICY-203
- DELETE /v1/buying-policies/credit-control/grace-amounts/:graceAmountId — ADM-BUYING-POLICY-301
- GET /v1/buying-policies/credit-control/holds — ADM-BUYING-POLICY-550
- POST /v1/buying-policies/credit-control/holds — ADM-BUYING-POLICY-150
- PUT /v1/buying-policies/credit-control/holds/:creditHoldId — ADM-BUYING-POLICY-202
- DELETE /v1/buying-policies/credit-control/holds/:creditHoldId — ADM-BUYING-POLICY-300
Quotas
- GET /v1/buying-policies/quotas — ADM-BUYING-POLICY-501
- PATCH /v1/buying-policies/quotas — ADM-BUYING-POLICY-204
- PATCH /v1/buying-policies/quotas/min-value — ADM-BUYING-POLICY-205
- POST /v1/buying-policies/quotas/rules — ADM-BUYING-POLICY-152
- GET /v1/buying-policies/quotas/rules — ADM-BUYING-POLICY-553
- PUT /v1/buying-policies/quotas/rules/:ruleId — ADM-BUYING-POLICY-206
- DELETE /v1/buying-policies/quotas/rules/:ruleId — ADM-BUYING-POLICY-302
- POST /v1/buying-policies/quotas/groups — ADM-BUYING-POLICY-153
- GET /v1/buying-policies/quotas/groups — ADM-BUYING-POLICY-554
- PUT /v1/buying-policies/quotas/groups/:groupId — ADM-BUYING-POLICY-207
- DELETE /v1/buying-policies/quotas/groups/:groupId — ADM-BUYING-POLICY-303
Blocking reasons & Unblock
- GET /v1/buying-policies/blocking-reasons — ADM-BUYING-POLICY-552
- POST /v1/logistic-orders/unblock — ADM-ORDER-150
- GET /v1/logistic-orders/:logisticOrderId/unblock-history — ADM-ORDER-550
✅ What to check when behavior seems off
- Is the policy enabled (Credit Control or Quotas)?
- For Credit Control: any Manual Hold active? Is Grace Amount configured?
- For Quotas: do specific rules or co-validation groups apply that override defaults?
- Are you fetching reasons to see the exact blocking codes?
Updated 22 days ago
