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?