Automatic Order Validation

Djust OMS supports automatic validation of orders through a scheduled background job, configured via the Djust Data Hub. This feature allows delayed or programmatic progression of orders from Draft, On Hold, or Blocked by Policy to Created status, based on a configured validation date.


⚙️ How It Works

A recurring job in the Data Hub automatically scans eligible orders and validates them when the conditions below are met.

🔄 Job Behavior

  • The job runs at regular intervals (e.g., every 15 minutes).
  • It looks for orders currently in status Draft, On Hold, or Blocked by Policy.
  • For each order, it checks for a custom field of type DATE linked to the role Automatic order validation date.

📅 Custom Field Requirement

To be eligible for automatic validation, an order must include a DATE custom field associated with the following role:

🗒️

Configuration of order custom field role :

Role: Automatic order validation date
Location: https://your.tenant.name.djust-app.com/settings/custom-field-roles

Only one custom field with this role should be assigned per tenant. The field must be of type DATE.


🕒 Validation Criteria

When the job runs, it attempts to validate an order if:

  • The associated custom field contains a date equal to or earlier than the current job execution timestamp.

If this condition is met, the order is automatically transitioned to Created.


🔀 Behavior by Order Status

The automatic validation applies to three order statuses, with a specific handling for orders blocked by a buying policy:

Source statusBehavior
DraftDirectly validated to Created (standard validation checks apply).
On HoldDirectly validated to Created (standard validation checks apply).
Blocked by PolicyThe order is first transitioned back to Draft, then validated to Created. This means the buying policy block is overridden by the automatic validation.
⚠️

For orders in Blocked by Policy, the automatic validation acts as a programmatic forced validation. Make sure this behavior is expected before enabling the job on tenants using buying policies (credit control, quotas, manual validation).

For more information on buying policies and manual forced validation, see Buying Policies and Forced Validation Audit History.


❗ Validation Errors & Controls

Before updating the order status, the job performs standard order validation checks:

Blocking conditionDetail
Inactive productProduct status is not ACTIVE
Inactive variantVariant status is not ACTIVE
Inactive offer inventoryInventory status is not ACTIVE
Inactive offer priceOffer price status is not ACTIVE
Inactive supplierSupplier is inactive
Insufficient stockAvailable stock < requested quantity
Unknown offer priceOffer price ID not found
Invalid quantityQuantity ≤ 0
Missing required custom fieldsRequired product or shipping custom fields are empty
Min/Max quantity not metRequested quantity is outside defined bounds
Missing shipping informationShipping address, time slot, or other delivery data is missing or invalid

These checks are performed line by line. If a single order line fails, the entire order is not validated.

If an error occurs during validation:

  • By default, the order remains in its current state.
  • The error is logged and can be reviewed by the operations team.

🛠️ Feature Flag: CONTROLLED_AUTOMATIC_ORDER_VALIDATION

To override standard validation controls, a feature flag is available:

  • If CONTROLLED_AUTOMATIC_ORDER_VALIDATION is set to false:
    • The job bypasses all standard validation controls listed above.
    • The only remaining condition is the presence of a valid date in the custom field.
    • Orders with a valid date are forcibly transitioned to Created, even if some lines are inconsistent.
⚠️

This setting should only be used with caution in controlled environments.


🧩 Example Flow

flowchart LR
  %% Styles (Readme)
  classDef create   fill:#e8f1ff,stroke:#2f6feb,stroke-width:2px,color:#0b3d91;
  classDef read     fill:#ede9fe,stroke:#7c3aed,stroke-width:2px,color:#1e1b4b;
  classDef update   fill:#e0f7fa,stroke:#06b6d4,stroke-width:2px,color:#0c4a6e;
  classDef add      fill:#ecfdf5,stroke:#10b981,stroke-width:2px,color:#064e3b;
  classDef remove   fill:#fee2e2,stroke:#ef4444,stroke-width:2px,color:#7f1d1d;
  classDef decision fill:#fff4e5,stroke:#f59e0b,stroke-width:2px,color:#7a3e00;
  classDef place    fill:#dcfce7,stroke:#16a34a,stroke-width:2px,color:#14532d;
  classDef sys      fill:#f2f4f7,stroke:#475569,stroke-width:2px,color:#111827;
  classDef ok       fill:#ecfdf5,stroke:#10b981,stroke-width:2px,color:#064e3b;
  classDef stop     fill:#fee2e2,stroke:#ef4444,stroke-width:2px,color:#7f1d1d;

  A[📦 Order<br>Draft / On Hold /<br>Blocked by Policy]:::read
  B{📅 Has DATE CF<br>with validation role?}:::decision
  C{🕒 Date <= Now?}:::decision
  D{🔀 Blocked<br>by Policy?}:::decision
  E[🔄 Reset to Draft]:::update
  F[✅ Attempt validation]:::create
  G{Validation OK?}:::decision
  H[✅ Status = Created]:::place
  I{🛠️ Feature flag OFF?}:::decision
  J[⛔ Keep as-is<br>Log error]:::stop
  Z[⏭️ Skip]:::stop

  style A rx:8,ry:8
  style B rx:8,ry:8
  style C rx:8,ry:8
  style D rx:8,ry:8
  style E rx:8,ry:8
  style F rx:8,ry:8
  style G rx:8,ry:8
  style H rx:8,ry:8
  style I rx:8,ry:8
  style J rx:8,ry:8
  style Z rx:8,ry:8

  A --> B
  B -->|No| Z
  B -->|Yes| C
  C -->|No| Z
  C -->|Yes| D
  D -->|Yes| E --> F
  D -->|No| F
  F --> G
  G -->|Yes| H
  G -->|No| I
  I -->|Yes| H
  I -->|No| J

✅ Best Practices

  • Always test the job frequency in a staging environment before deploying to production. A too-frequent interval on a large order volume can generate unnecessary load.
  • Use a dedicated custom field for the validation date. Do not reuse a custom field that serves another business purpose (e.g., delivery date), as this may trigger unintended validations.
  • Monitor job execution reports regularly. Orders that fail validation remain in their current status silently — review the Data Hub execution logs to catch recurring issues (inactive products, missing shipping info, etc.).
  • Be cautious with Blocked by Policy orders. If buying policies are active on your tenant, understand that automatic validation will override the policy block. Coordinate with the team responsible for credit control or manual approval workflows.
  • Keep the feature flag CONTROLLED_AUTOMATIC_ORDER_VALIDATION enabled (default) in production. Disabling validation controls should be reserved for exceptional recovery scenarios.

⚠️ Common Mistakes

  • Forgetting to assign the custom field role. The job does nothing if no custom field is associated with the Automatic order validation date role. The job will complete with status NOTHING_TO_PROCESS.
  • Using a non-DATE custom field. If the custom field linked to the role is not of type DATE, orders are silently skipped. No error is raised.
  • Setting a date without a time component. If the custom field value contains only a date (e.g., 2026-04-08) without hours/minutes, it is interpreted as 2026-04-08T00:00:00Z. This means the order becomes eligible at midnight UTC — which may be earlier than expected depending on your timezone.
  • Disabling validation controls and forgetting to re-enable them. When CONTROLLED_AUTOMATIC_ORDER_VALIDATION is set to false, all business checks are skipped. This is useful for recovery, but leaving it disabled long-term can result in inconsistent orders reaching suppliers.
  • Not accounting for buying policy interactions. If a tenant uses both automatic validation and buying policies, orders blocked by a policy will be automatically unblocked and validated when the date condition is met. This may bypass approval workflows that the business expects to remain enforced.

🔧 Configuration Summary

ElementValue / Location
Custom field roleAutomatic order validation date configured in Backoffice config path /settings/custom-field-roles
Allowed custom field typeDATE
Eligible order statusesDraft, On Hold, Blocked by Policy
Target statusCreated (not configurable)
Validation job frequencyConfigured in Data Hub
Feature flag (bypass checks)CONTROLLED_AUTOMATIC_ORDER_VALIDATION (Boolean)