← All manuals Operator Guide for this screen IM2

RO Inbox — Detail

RO Inbox — Detail
Technical Spec Ver 2 Updated 2026-09-06 Matches the live screen

RO Inbox — Detail — Technical Spec

Route: GET /ro/inbox/{inbox_id} in app/ro_import.py.

Data

Reads one ro_inbox row plus all its ro_inbox_line rows, ordered by line_no. No writes happen on page load. A missing inbox_id renders the same template with not_found=True and HTTP 404.

Line columns rendered: line_no, line_type, sku, description, qty, uom, change_type/qty_prior (as New line / Dropped from source (was N) / Qty A → B), would_hold (row highlighted) and hold_reason. The Type dropdown and the three action buttons render only when can_write and the row is non-terminal. [Ver 2, 2026-09-06]

Actions on this screen

Same three POST routes as the list screen (/ro/inbox/{id}/hold, /ro/inbox/{id}/reject, /ro/inbox/{id}/accept), plus POST /ro/inbox/{id}/type (ro_type form field) for setting the operator-chosen type inline. See docs/tech/ro_inbox.md for the full contract of each.

Accept

POST /ro/inbox/{id}/accept:

  1. 400 if ro_type is not set, or the row is already Accepted/Rejected.
  2. Calls promote_inbox_to_ro(inbox_id, user) (implemented in ro_import.py since 2026-09-05), outside any transaction this route holds, in its own transaction: on success it returns an order_no having written ro_header + ro_detail in full; on failure it raises having written nothing. If the source job already produced an RO it refreshes that one via refresh_ro() and returns its existing order_no — so a "successful Accept" does not always mean a new order number. See docs/tech/ro_inbox.md.
  3. On success: ro_inbox.status = 'Accepted', order_no set, ro_audit row written, JSON {"ok": true, "order_no": N} returned. The template redirects the browser to /ro/{order_no}?imported=1.
  4. On the stub raising: ro_inbox.status = 'Error', parse_error set to the exception text, ro_audit row written, HTTP 502 with the error message. The row is untouched otherwise — Accept can be retried once whatever's wrong is fixed.

Review-screen header edit + pre-RO line fix (2026-09-07)

DDL: skills/requirements_orders/scripts/ro_inbox_review_2026-09-07.sql (applied live). New ro_inbox columns: qb_customer_id, qb_customer_name, class_ref, date_required, priority_code, link_system, link_order_no, link_label. ro_inbox.ro_type CHECK widened to match ro_header (Roofing/Administration were offered by the class list but refused on save). ro_detail.line_type CHECK now allows SURPLUS.

Routes (app/ro_import.py):

promote_inbox_to_ro() now carries date_required (header value, else the class lead time), priority_code, class_ref, qb_customer_id/name, entry_source, and the link_system/link_order_no pair as the RO's source system/id. Header date_required seeds every ro_detail.date_required.

Refresh-vs-new fix: the prior-RO lookup matched on source_id alone, so a second BOM on the same FP job refreshed the first BOM's RO instead of creating a second RO. It now matches source_id AND bom_name, per the v3.4 design rule.

Review screen: surplus, BT free text, Fix-now autosave (2026-09-07)