# 30 — Client Requirements Addendum: Pharma Contract-Manufacturer (Toll / Make-to-Order)

> **Source:** Owner interview, pharmaceutical factory operating **contract / toll manufacturing**
> ("تصنيع للغير بالأوردر" — make-to-order on behalf of a customer). This file formalizes the
> verbatim meeting summary into a numbered, testable requirements specification and maps every
> client statement onto standard contract-manufacturing terminology.
> **Scope of this addendum:** it ADDS the customer-facing front of the lifecycle (exploratory
> quotation, draft BOM, pilot batch, advance-payment gate, stage-gate screens) that the published
> analysis (`md/00..06` spec digests, `md/20` mapping, `md/22` contracts, `md/23` roadmap) did not
> cover. It does NOT re-open the already-ratified decisions on toll/consignment (D-15), reservation
> (A5), the production state machine, or the JE families (`md/22` §4) — it pegs the new requirements
> onto those existing rails.
> **Module identity (binding, D-01):** everything below lands inside the extended
> `Modules/Production` (`production.*` permissions, `mfg_*` new tables) plus the named reuse rails
> (Inventory / Accounting / Sales) already established in `md/20`–`md/22`.

---

## 0. Terminology mapping (client phrasing → standard CM term → Moon ERP anchor)

| # | Client said (Arabic) | Standard contract-manufacturing term | Moon ERP anchor (this addendum) |
|---|---|---|---|
| T-1 | دورة التكلفة الاستكشافية / تسعير مبدئي | **RFQ / quotation costing** (pre-cost estimate) | NEW `mfg_cost_estimates` + `mfg_cost_estimate_versions` (canonical names per `md/34` — this file's earlier provisional `mfg_quotations`/`mfg_quotation_costings` are retired); the customer-facing quote REUSES Sales `SalesQuotation` (D-29) |
| T-2 | تركيبة العميل، R&D تعمل BOM مبدئية | **Draft BOM** (engineering/estimating BOM, not yet released) | `bill_of_materials.bom_type=Engineering` + `status=Draft` (EXTEND already in `md/20` row 2) |
| T-3 | عينة / باتش تجريبي للعميل | **Pilot / sample (trial) batch** | NEW `mfg_trial_batches` — a real, costed production run tagged `order_type=Trial` |
| T-4 | دفعة تحت حساب | **Customer advance / down-payment gate** | NEW `mfg_customer_advances` (keyed to the `mfg_order_cases` case, `md/35`) + a gate blocking Release AND on-behalf purchasing; cash via `ReceiptVoucher`+`ApproveReceiptVoucher` (LA-1/D-33) |
| T-5 | العميل يورّد خامته وتظل ملكه | **Customer-supplied / free-issue (toll) material — consignment, customer property** | `material_ownership=Customer` + `warehouses.is_consignment` (D-15, already ratified) |
| T-6 | حجز الخامات لهذا الأوردر | **Order-pegged material reservation** | `StockService::reserve()/release()` (A5) pegged to the production order |
| T-7 | واجهات لكل مرحلة إنتاجية تنقل الأوردر | **Stage-gate workspaces / operation-stage screens** | NEW `mfg_order_stage_gates` (keyed to `mfg_order_cases.case_id`, `md/35`) driving the CASE stage machine from per-stage FE screens — interpretation of «مرحلة إنتاجية» logged as **OQ-9** (commercial case stages vs manufacturing operation stages) |
| T-8 | كل المستندات مربوطة بأوردر العميل | **Order-pegged document lineage** (everything pegs to the customer order) | `mfg_peggings` (`md/20` row 26) + `source_sales_order_id` stamped on every mfg doc |

---

## 1. Numbered requirements (R-01 .. R-18)

Each requirement: **Actor · Trigger · Inputs · Outputs · Business rule.** Identifiers in `code`.

### Cycle 1 — Exploratory Costing (RFQ / quotation)

**R-01 — Receive customer pricing request (RFQ intake)**
- **Actor:** Sales / front office.
- **Trigger:** customer submits a product with its specification/composition (تركيبته) and asks for a price.
- **Inputs:** customer id (Core `Product`-customer / Sales party), product description, target quantity (optional), customer-supplied spec/composition document (Core `Attachment`).
- **Outputs:** `mfg_cost_estimates` row, `status=Draft`, sequenced via `SequenceService::generateNext(company,'production','cost_estimate')`.
- **Business rule:** a quotation is NOT a sales order and creates NO stock/GL effect. It is the head of an order-pegged lineage (T-8); once it converts (R-08) every downstream document carries its `quotation_id` and resulting `sales_order_id`.

**R-02 — R&D drafts an estimating BOM**
- **Actor:** R&D department.
- **Trigger:** estimate routed to R&D (workflow assignment; estimate stays `Draft` — the lean `md/34` machine, routing is workflow metadata not status).
- **Inputs:** customer composition, Core `products` (raw materials), UoM `product_units`.
- **Outputs:** a **draft BOM** — `bill_of_materials` with `bom_type=Engineering`, `status=Draft`, linked to the estimate via `mfg_cost_estimates.draft_bom_id`.
- **Business rule:** a `Draft`/`Engineering` BOM can never be snapshotted into a production order (only an `Active`/`Production` BOM can be Released — guard reuses the `md/20` row 2 lifecycle), **with the single ratified D-32 carve-out: `order_type=Trial` orders may snapshot a Draft BOM under setting `production.trial_allow_draft_bom` (R-05/R-06); Standard orders never.** Draft BOM may reference not-yet-stocked materials (estimating placeholders).

**R-03 — Accounting computes preliminary (exploratory) costing**
- **Actor:** Accounting / cost engineer.
- **Trigger:** draft BOM ready (`DraftBomReady`; `status: Draft → Estimated` on compute).
- **Inputs:** draft BOM explosion, work-center rates (`production_centers.labor_cost_rate`/`machine_cost_rate`/`overhead_rate`), `cost_driver` (`md/20` row 6), draft routing if any, current material prices (`StockService::getProductCost`).
- **Outputs:** `mfg_cost_estimate_versions` row: `material_cost`, `labor_cost`, `overhead_cost`, `total_unit_cost`, `markup_percent`, `quoted_unit_price`, `valid_until` (price-validity period — see OQ-5/D-34).
- **Business rule:** costing reuses the same roll-up engine as `ComputeStandardCost` (`md/20` row 23) but runs against the **draft** BOM and produces an *estimate*, not a standard cost. No GL posting. Recompute is versioned (keep history; do not mutate — immutability per house rules).

**R-04 — Return preliminary product cost / quote to customer**
- **Actor:** Sales.
- **Trigger:** costing approved (`status: Estimated → Quoted`).
- **Inputs:** `mfg_cost_estimate_versions.quoted_unit_price`, `valid_until`.
- **Outputs:** the customer-facing `SalesQuotation` (REUSE, priced by push via `UpsertQuotationPricing`) + PDF via `print.service`; `status=Quoted`.
- **Business rule:** the quote carries an explicit validity window (`valid_until`); after expiry it must be re-costed (R-03) before it can convert (R-08). Quote is read-only once sent (new version on change).

### Cycle 2 — Production (make-to-order), Stage (a): Trial

**R-05 — Customer requests a trial/sample batch**
- **Actor:** Sales → R&D.
- **Trigger:** customer (post-quote) asks for a sample batch to evaluate, OR converts intent into a trial.
- **Inputs:** estimate id, trial quantity, target evaluation criteria.
- **Outputs:** `mfg_trial_batches` row + a real production order tagged `order_type=Trial`, `production_type=MakeToOrder`, pegged to the estimate/case/sales order.
- **Business rule:** **a trial is a real, costed manufacturing run** — it consumes real materials, accrues real WIP, and posts the normal JE families (`md/22` §4). It is owned/executed by **R&D** (not the line). It is distinguished only by `order_type=Trial` so its cost, scrap and yield are reported separately and excluded from standard-cost baselining until approved.

**R-06 — Execute and cost the trial run**
- **Actor:** R&D / pilot line.
- **Trigger:** trial order Released.
- **Inputs:** draft (or trial-finalized) BOM + routing, materials. (Snapshotting a **Draft** BOM into the Trial order is legal ONLY under the ratified D-32 carve-out, setting `production.trial_allow_draft_bom`.)
- **Outputs:** trial confirmations, trial WIP cost, trial yield/scrap; `mfg_trial_batches.actual_unit_cost`, `result ∈ {Pending, Passed, Failed}`.
- **Business rule:** the trial follows the same Release→Issue→Confirm→Receive→Close rails as a normal order (reuse, no new posting logic). Trial cost is captured so the final quote can be trued-up. **Who bears trial cost and what happens on trial failure are NOT specified by the client — see OQ-1, OQ-3.**

**R-07 — Customer evaluates trial**
- **Actor:** customer (recorded by Sales).
- **Trigger:** trial batch received/handed to customer **via the R-20 sample hand-over document** (trial output sits in the trial/evaluation bucket, never sellable FG).
- **Inputs:** customer decision.
- **Outputs:** `mfg_trial_batches.result` set to `Passed` or `Failed`; on `Passed` the lineage may proceed to R-08.
- **Business rule:** recording the decision is **gated on the R-20 hand-over document existing** (`mfg_trial_batches.sample_delivery_doc_id`). A `Failed` trial blocks formal-order creation until a new trial passes or the customer abandons (lineage closed). Re-trial loops back to R-05.

### Cycle 2 — Stage (b): Formal order → finalize → plan → advance → reserve → manufacture → receive

**R-08 — Convert to formal customer order**
- **Actor:** Sales.
- **Trigger:** customer agreement (after `Quoted` and/or trial `Passed`).
- **Inputs:** quotation, agreed quantity (e.g. 1000 units), agreed price, delivery date.
- **Outputs:** a confirmed Sales order (`Modules\Sales\SalesOrder`); the quotation `status=Converted`; `mfg_peggings` seed prepared.
- **Business rule:** **all structures/documents from here on are pegged to this customer order** (T-8). The formal order is the demand anchor for MPS/pegging (`md/20` rows 9, 26).

**R-09 — R&D finalizes the BOM**
- **Actor:** R&D.
- **Trigger:** formal order created.
- **Inputs:** the draft/trial BOM + trial learnings.
- **Outputs:** the draft BOM is promoted to a **production BOM** — `bom_type=Production`, `status=Active`, one Active version per (product, effectivity window) (`md/20` row 2 rule).
- **Business rule:** only an `Active`/`Production` BOM is eligible for order Release snapshotting. Promotion is a controlled lifecycle transition (Draft→Active), not an edit-in-place.

**R-10 — Planning determines requirements and checks readiness**
- **Actor:** Planning.
- **Trigger:** BOM finalized.
- **Inputs:** finalized BOM explosion × order qty (+scrap%), current stock (`inventory_stock_balances`), open POs/production orders, customer-supplied material on hand (consignment bucket).
- **Outputs:** required-quantity list (gross→net), shortage list, readiness verdict; for own-procured materials, **DRAFT purchase requests prepared but NOT submitted** — `CreatePurchaseRequest` (`md/22` #6) fires only after the advance gate (R-11) is satisfied, because the deposit exists precisely to fund that buying (U-6 rule).
- **Business rule:** readiness must separate **own-procured** materials (factory buys on the customer's behalf) from **customer-supplied** materials (free-issue, customer property, in the consignment warehouse — T-5/D-15, received via R-19). Customer-supplied materials are never purchased and never valued.

**R-11 — Customer advance / down-payment gate**
- **Actor:** Accounting (records receipt); gate enforced by `ReleaseProductionOrder`.
- **Trigger:** Planning ready AND materials need to be procured on the customer's behalf.
- **Inputs:** required advance amount/percentage, customer payment.
- **Outputs:** `mfg_customer_advances` row keyed to the **case** (`case_id`, `amount`, `percent`, `status ∈ {Due, Received, Waived}`, `receipt_voucher_id`, `journal_entry_id`); cash receipt rides **`ReceiptVoucher` + `ApproveReceiptVoucher`** with `reference_type='mfg_order_case'` and line account = Customer Advances — **the voucher engine's own JE (DR Cash/Bank / CR Customer Advances liability, `entry_type='production_customer_advance'`) is the single advance posting (LA-1/D-33; this file's earlier bare-`CreateJournalEntry` design is superseded — `md/32` §2 proved the voucher rail exists).**
- **Business rule:** **the advance gate blocks BOTH `ReleaseProductionOrder` (no reservation, no manufacturing) AND on-behalf purchasing (no `CreatePurchaseRequest` submission for billable-to-customer material) until satisfied** (`Received` or explicitly `Waived` by an authorized role) — the client ties the deposit to procurement, not only to release. The advance is later settled against the final invoice (`production_advance_settlement`, R-16/R-21). **Advance percentage is NOT specified by the client — see OQ-2/D-25.**

**R-12 — Reserve materials for this order (a side-effect OF Release, R-13)**
- **Actor:** `ReleaseProductionOrder` (system — reservation happens INSIDE the Release transition, per the ratified `md/20` row 13; it is never a separate stage that precedes Release).
- **Trigger:** `ReleaseProductionOrder` executing (which itself requires the advance gate, R-11).
- **Inputs:** snapshotted order components, stock balances.
- **Outputs:** `reserved_quantity` written per component (`StockService::reserve()`, A5), pegged to the order; tool reserved.
- **Business rule:** reservation is **order-pegged** (T-6) so two customer orders cannot promise the same stock. Customer-supplied components reserve against the consignment bucket; own components reserve against own stock. Reservation is released on Issue or Cancel.

**R-13 — Create the manufacturing order (Release)**
- **Actor:** Planning / production manager.
- **Trigger:** advance gate satisfied (R-11) and finances OK.
- **Inputs:** Active BOM + routing snapshot, work centers, tool.
- **Outputs:** production order `Planned → Released`; BOM+routing snapshot frozen into `production_order_materials`/`_operations`; reservation executed as a Release side-effect (R-12); `ProductionOrderReleased` event (`md/22` §2).
- **Business rule:** Release is the single point that freezes the snapshot and fires the reservation/inspection-prep side-effects atomically (already defined `md/20` row 13 / `md/22` — this fixes the earlier circular R-12↔R-13 ordering). The advance gate (R-11) sits BEFORE this transition.

**R-14 — Issue materials**
- **Actor:** Store keeper.
- **Trigger:** order Released.
- **Inputs:** reserved components.
- **Outputs:** `mfg_material_issues` → `ApproveIssue` → **DR WIP / CR Raw Materials** (own); customer-owned = tracking-only consignment move, no RM credit (`md/22` §4 toll row).
- **Business rule:** ownership branch per line (`ownership ∈ {Own, Customer}`); customer-supplied issues never credit own RM and never post material cost into WIP (conversion cost only). Reservation consumed here.

**R-15 — Manufacture (operation confirmations)**
- **Actor:** Operators / line.
- **Trigger:** order InProcess.
- **Inputs:** routing operations, labor/machine time, yield, scrap.
- **Outputs:** `mfg_confirmations` (+ labor/OH applied JEs); auto-advance to next operation.
- **Business rule:** reuse the confirmation engine and SFC auto-advance unchanged (`md/20` rows 18–20, `md/22` §2).

**R-16 — Finish & receive into finished-goods warehouse**
- **Actor:** Store keeper / system.
- **Trigger:** final operation confirmed.
- **Inputs:** produced qty/grade, WIP cost.
- **Outputs:** `mfg_goods_receipts` → `ApproveReceipt` → **DR FG / CR WIP** (own) OR toll branch: output to customer ownership + the on-behalf-material WIP relief (`production_toll_material_cogs`, R-21) + the final invoice; order Completed→Closed.
- **Business rule:** on a toll order the FG belongs to the customer; the final invoice — created forward via `Modules\Sales\Actions\CreateServiceInvoice` (net-new thin Action, U-4; never a controller call or direct Sales writes) — carries the **conversion fee** PLUS the **material pass-through line(s) for factory-bought-on-behalf RM** (R-21), and the customer advance (R-11) is settled against it (`production_advance_settlement`: DR Customer Advances / CR AR). Flows to EInvoicing (B18).

### Cross-cutting

**R-17 — Stage-gate screens (واجهات لكل مرحلة)**
- **Actor:** stage owners (R&D, Planning, Accounting, Store, Operators, Supervisor).
- **Trigger:** order present in any stage.
- **Inputs:** order id, current stage, allowed transitions for the actor's role.
- **Outputs:** a per-stage Angular workspace (a screen per stage) showing only that stage's data + the action button(s) that advance the order to the next stage; backed by `mfg_order_stage_gates` (audit of who moved the order, when, from→to).
- **Business rule:** each stage transition is permission-guarded (`production.*`) and maps onto the existing/extended order state machine (`Planned → Released → InProcess → Completed → Closed`) PLUS the customer-front pre-states (`Quotation`, `Trial`, `Awaiting-Advance`). Screens never bypass the state machine — the button calls the same Action the API exposes.

**R-18 — Order-pegged document lineage**
- **Actor:** system.
- **Trigger:** any mfg document created within a customer-order lineage.
- **Inputs:** the originating `quotation_id` / `sales_order_id`.
- **Outputs:** every quotation, trial batch, advance, production order, issue, confirmation, receipt carries the pegging keys; `mfg_peggings` links production↔sales.
- **Business rule:** the customer order is the spine (T-8). A lineage view must reconstruct: RFQ → draft BOM → quote → trial → formal order → finalized BOM → plan → advance → reservation → MO → issues → confirmations → receipt → toll invoice.

**R-19 — Receive & return customer free-issue material (consignment intake document)**
- **Actor:** Store keeper (intake/return); Production Action `ReceiveCustomerMaterial`/`ReturnCustomerMaterial` forward.
- **Trigger:** customer delivers his own raw material for the order; order/case close for the return leg.
- **Inputs:** case id, consignment warehouse (`is_consignment`, D-15), material lines + lot numbers.
- **Outputs:** a real **Inventory receipt document** approved via `ApproveReceipt` running a **tracking-only / no-valuation / no-GL branch** for consignment warehouses (the customer's property is held in bailment, never on our books); on close, unused material returns via the mirror tracking-only `ApproveIssue` document; a case-close reconciliation: received − issued-to-orders − consignment scrap (D-30) = returned.
- **Business rule:** **no stock balance is ever touched outside the Approve* document rails** (`md/22` §1) — the intake/return are first-class documents, not screen-side mutations; lots are written into batch genealogy (md/33 P3).

**R-20 — Trial-sample hand-over to the customer**
- **Actor:** Store keeper / Sales.
- **Trigger:** trial goods receipt completed.
- **Inputs:** trial order output, customer.
- **Outputs:** trial output received into a **trial/evaluation bucket** (warehouse-as-state, non-sellable FG); a **sample delivery document** (tracking-only issue out of the evaluation bucket) recorded on `mfg_trial_batches.sample_delivery_doc_id` + `sample_delivered_at`.
- **Business rule:** the customer evaluation (R-07) cannot be recorded before the hand-over document exists — the sample never "teleports"; ownership/valuation of the trial output follows the trial cost policy (D-23).

**R-21 — Bill back materials purchased on the customer's behalf (pass-through)**
- **Actor:** Accounting / system (with R-16 invoicing).
- **Trigger:** final invoicing of a toll order whose RM the factory bought on behalf of the customer.
- **Inputs:** billable-to-customer tagged POs/issues pegged to the case; contractual handling %.
- **Outputs:** on the toll FG receipt, the on-behalf material portion of WIP relieves via `production_toll_material_cogs` (DR Toll material COGS / CR WIP); the final invoice (R-16) carries a **material pass-through line at cost (+ handling %)** beside the conversion fee.
- **Business rule:** RM bought on the customer's behalf is **factory property until invoiced** (normal own stock, reserved/pegged to the case); title to the material content passes at delivery/invoice. The advance — sized as % of own-procured material cost (D-25) — therefore settles against an invoice that **contains the material it funded**: the cash math closes (closes review gap U-1).

---

## 2. Cycle 1 — Exploratory Costing flow (ordered)

1. Customer submits product + composition + (optional) target qty → Sales opens `mfg_cost_estimates` (`status=Draft`). **[R-01]**
2. Estimate routed to R&D; R&D builds a **draft BOM** (`bom_type=Engineering`, `status=Draft`). **[R-02]**
3. Routed to Accounting; cost engine explodes the draft BOM, applies work-center rates and `cost_driver`, produces a `mfg_cost_estimate_versions` row (`status=Estimated`; material+labor+overhead → unit cost → markup → quoted price → `valid_until`). **[R-03]**
4. Costing approved (`Quoted`); Sales returns the preliminary product cost / quote to the customer as a validity-dated `SalesQuotation`. **[R-04]**
5. END of Cycle 1. No stock, no GL, no commitment. Outcome is a priced offer that, if accepted, seeds Cycle 2.

## 3. Cycle 2 — Production (make-to-order) flow (ordered)

1. **Trial request:** customer asks for a sample batch → `mfg_trial_batches` + production order `order_type=Trial`, executed by **R&D**, pegged to the estimate/case. **[R-05]**
2. **Trial run:** real Release→Issue→Confirm→Receive→Close; trial cost/yield/scrap captured (`actual_unit_cost`); output lands in the trial/evaluation bucket and is handed over via the sample delivery document. **[R-06, R-20]**
3. **Trial evaluation:** customer decides (hand-over document required) → `result = Passed | Failed`. Failed ⇒ re-trial or abandon. **[R-07]**
4. **Formal order:** on agreement, Sales creates the confirmed customer order; **all downstream documents peg to it**. **[R-08]**
5. **Finalize BOM:** R&D promotes draft → `bom_type=Production`, `status=Active` (one Active version per effectivity window). **[R-09]**
6. **Planning & readiness:** required quantities computed (gross→net), shortages identified, own-procured vs customer-supplied materials separated; **draft** PRs prepared (not submitted). **[R-10]**
7. **Advance gate:** because the factory buys raw materials on the customer's behalf, the customer MUST pay a down-payment → `mfg_customer_advances` (`Received` via receipt voucher, LA-1); **Release AND on-behalf purchasing are blocked until satisfied** — PRs submit only now. **[R-11]**
8. **Consignment intake (if any):** customer free-issue material received into the consignment warehouse via the tracking-only receipt document. **[R-19]**
9. **Create MO (Release):** snapshot frozen, reservation executed as a Release side-effect (own stock and/or consignment bucket; tool reserved), `ProductionOrderReleased`. **[R-13, R-12]**
10. **Issue materials:** WIP debited for own materials; customer-supplied issued as tracking-only consignment moves. **[R-14]**
11. **Manufacture:** operation confirmations, labor/OH applied, auto-advance. **[R-15]**
12. **Finish & receive into FG warehouse:** DR FG / CR WIP (own) or toll branch (customer-owned output + final invoice = conversion fee **+ material pass-through line (R-21)**, advance settled against it); unused customer material returned/reconciled (R-19); order Completed→Closed. **[R-16]**
13. Stage-gate screens (**R-17**) move the order between every step above; lineage (**R-18**) keeps it pegged to the customer order throughout.

---

## 4. New / changed Moon ERP objects this addendum introduces

| Object | Verdict | Notes |
|---|---|---|
| `mfg_cost_estimates` | **NEW** | estimate header / RFQ head (canonical name per `md/34`): customer, prospect product, qty, `draft_bom_id`, `sales_quotation_id` (REUSE Sales doc), lean `status ∈ {Draft, Estimated, Quoted, Won, Lost}`, `sales_order_id` (on Won). Seq key `'production'`/`cost_estimate`. |
| `mfg_cost_estimate_versions` | **NEW** | versioned, immutable estimate runs (canonical per `md/34`): material/labor/overhead, `total_unit_cost`, `markup_percent`, `quoted_unit_price`, `valid_until`, `price_basis`. |
| `mfg_order_cases` | **NEW** (per `md/35`) | the Cycle-2 commercial umbrella: 14-stage case machine, deposit fields, `consignment_warehouse_id`, `active_bom_id`; 1 case ↔ N production orders (trial loops + main). The order state machine stays untouched. |
| `mfg_trial_batches` | **NEW** | `case_id`, `cost_estimate_id`, `production_order_id` (the `order_type=Trial` order), `trial_quantity`, `actual_unit_cost`, `result ∈ {Pending, Passed, Failed}`, `evaluated_at`, `sample_delivery_doc_id`/`sample_delivered_at` (R-20). Kept separate from the order (vs `md/32` §4's flag-only lean) because one case spans N re-trial orders each carrying its own verdict/sign-off/hand-over. |
| `mfg_customer_advances` | **NEW** | **`case_id`** (one advance per engagement, `md/35`), `amount`, `percent`, `status ∈ {Due, Received, Waived}`, `receipt_voucher_id`, `journal_entry_id` (the voucher's JE — LA-1), `applied_invoice_id`. |
| `mfg_order_stage_gates` | **NEW** | audit + transition table backing the per-stage screens, keyed to the case (`md/35`): `case_id`, `from_stage`, `to_stage`, `actor_user_id`, `gate_snapshot`, `at`. |
| `bill_of_materials.bom_type/status` | **EXTEND** (already in `md/20` row 2) | `Engineering+Draft` = the exploratory draft BOM; `Production+Active` = finalized. No new column needed beyond the ratified extension. |
| `production_orders.order_type` | **EXTEND** | add `Trial` to the `{Standard, Rework, Repair}` enum (`md/20` row 13) so a trial run is a first-class, separately-reported order. |
| `ReleaseProductionOrder` Action | **EXTEND** | add the advance-payment precondition (R-11) before snapshot/reserve; the same gate also holds back on-behalf `CreatePurchaseRequest` submission. |
| `mfg_peggings` | **REUSE** (`md/20` row 26) | extended lineage anchor; add `cost_estimate_id` + `case_id` to the peg chain. |
| Consignment intake/return documents | **EXTEND** (Inventory docs, R-19) | tracking-only `ApproveReceipt`/`ApproveIssue` branch for `is_consignment` warehouses — the free-issue intake and the unused-material return ride real documents, never direct balance writes. |
| Trial-sample delivery document | **NEW thin doc** (R-20) | tracking-only issue out of the trial/evaluation bucket; referenced from `mfg_trial_batches`. |
| Accounting `entry_type` | **EXTEND** | `production_customer_advance` (the voucher's JE, LA-1/D-33), `production_advance_settlement` (DR Customer Advances / CR AR at invoicing — single canonical name), `production_advance_refund` (D-35), the D-23 trial-policy family (`production_trial_absorb/_defer/_apply/_writeoff`), `production_toll_material_cogs` (R-21); setting key `production.customer_advance_account_id`, seeded via `AutoAccountService`. |

All NEW tables follow the `mfg_*` prefix, `BaseModel` (TenantAware/Auditable), `SequenceService`
numbering, `production.*` permissions, and the Actions-forward / events-backward contract law
(`md/22` §5). No foreign module imports `Modules\Production`.

---

## 5. What the client did NOT specify (open questions — require sign-off before Phase build)

| # | Open question | Why it matters | Proposed default (pending board) |
|---|---|---|---|
| **OQ-1** | **Who pays for the trial batch?** Customer, or factory absorbs it as cost-of-sale? | Determines whether the trial run bills the customer (Sales invoice) or posts to an internal R&D/marketing expense; affects R-06 JE. | Configurable per case: `trial_cost_policy ∈ {Bill, Absorb, CreditOnWin}` with the `md/35` §1.1 posting family (ratified as D-23 — supersedes this file's earlier two-valued `{Customer, Absorbed}` proposal). |
| **OQ-2** | **Deposit / advance percentage?** Fixed %, per-customer, per-order, or cost-of-materials-based? | Drives R-11 gate amount and credit policy. | Configurable `production.default_advance_percent` setting + per-order override; v1 = % of own-procured material cost. |
| **OQ-3** | **What happens if the trial fails?** Re-trial (who pays the re-run?), renegotiate, or abandon? | Affects R-07 loop, cost ownership, and lineage closure. | Re-trial allowed; cost ownership inherits OQ-1 decision; N failed trials ⇒ lineage auto-flagged for review. |
| **OQ-4** | **Scrap ownership for customer-supplied (free-issue) materials.** Who owns scrap/waste of customer property — returned, billed, or written off against the customer? | Toll/consignment scrap is customer property; cannot be valued as own scrap expense. | Track consignment scrap separately (no own-scrap JE); reconcile/return to customer per contract; surface in a consignment movement report. |
| **OQ-5** | **Price validity period** for the quote (`valid_until`). | Stale quotes must be re-costed before conversion (R-04→R-08). | Configurable `production.quote_validity_days` (v1 = 30); expired quote blocks conversion until re-costed. |
| **OQ-6** | Advance refund / forfeiture policy on customer cancellation after advance received. | Liability handling for `Customer Advances` account. | Per-contract; default = applied to incurred cost, balance refundable. |
| **OQ-7** | Are the "stage screens" role-exclusive (each stage one department) or can one user span stages? | Drives permission granularity for R-17. | Per-stage permission slice under `production.*`; supervisor role can span all. |
| **OQ-8** | Minimum/target trial quantity vs full-order quantity relationship. | Trial costing true-up to full order. | Trial qty is independent; full-order cost re-estimated from trial actuals. |
| **OQ-9** | **What does «واجهات لكل مرحلة إنتاجية» actually mean?** Commercial CASE stages (R&D/Planning/deposit/reserve workbenches — the reading designed in `md/35` §4) or per-MANUFACTURING-stage screens (mixing/granulation/compression/packaging — pharma-plausible)? | Determines whether R-17 is satisfied by the case workbenches (Phases 2–2.5) or additionally needs per-operation workbenches over routing operations (Phase 5 SFC). | Ask the client at the Phase-0 gate. Default: case workbenches Phases 2–2.5; if the manufacturing-stage reading is confirmed, per-operation screens ride Phase 5 SFC with an early read-only per-operation monitor in Phase 2.5. |

---

## 6. Roadmap amendments (to `md/23`)

This addendum is **additive** and slots ahead of the order lifecycle without disturbing the
existing phase sequence:

- **Phase 0 (Spec-addenda track):** ratify the open questions via **the authoritative decision
  register `md/36` §4 (D-23..D-36 + OQ-9)** — NOT a positional OQ-x→D-x mapping (this file's
  earlier "OQ-1..OQ-8 = D-23..D-30 in order" is retired; e.g. OQ-1/OQ-3→D-23, OQ-2→D-25,
  OQ-4→D-30, OQ-5→D-34, OQ-6→D-35, OQ-7→D-28, OQ-8→D-36). **Hard gate: no customer-front build
  without these decisions.**
- **New Phase 2.5 — "Customer Front" (M), after Phase 1 (real execution) AND Phase 2
  (routing/confirmations — labor/machine rates + `cost_driver` land there, so exploratory costing
  cannot price conversion before it), before Phase 4 (Planning):** `mfg_cost_estimates` +
  `mfg_cost_estimate_versions`, draft-BOM lifecycle (rides the Phase 1 BOM extension),
  `mfg_trial_batches` + the evaluation bucket/sample hand-over (rides the Phase 1 order rails with
  `order_type=Trial`), and the Cycle-1/case stage screens. The case core, deposit gate
  (`mfg_customer_advances` + the `ReleaseProductionOrder` precondition) and `mfg_order_stage_gates`
  land already in Phase 2 — see `md/36` §3 (which renamed this slot from the provisional "1.5").
- No change to the toll/consignment, reservation, confirmation, or variance phases — this addendum
  consumes them.

---

## 7. Citations

- Toll / `material_ownership=Customer` / consignment, customer property: `md/03-spec-execution.md`
  L27-28, L73-75, L107, L128-130, L274-278; `md/20-mapping.md` rows 13/16/17; `md/22-contracts.md`
  §1 (Inventory row), §4 (toll JE row); D-15 (`md/21-gaps.md` A15).
- Reservation at Release: `md/21-gaps.md` A5 (L55-58); `md/22-contracts.md` §3 #5
  (`StockService::reserve/release`).
- Draft/Engineering BOM lifecycle + Active/Production promotion: `md/20-mapping.md` row 2.
- Standard-cost roll-up engine reused for estimating: `md/20-mapping.md` row 23 (`ComputeStandardCost`).
- Order state machine + Release snapshot/reserve side-effects: `md/20-mapping.md` row 13;
  `md/22-contracts.md` §2 (`ProductionOrderReleased`); `md/23-roadmap.md` §3 (Phase 1 state machine).
- Pegging / demand anchor on customer order: `md/20-mapping.md` row 26; `md/02-spec-planning.md`
  L19, L89, L282-290; `md/22-contracts.md` §1 (Sales row).
- JE families: `md/22-contracts.md` §4; `md/03-spec-execution.md` L305-317. Customer-advance
  cash-in rides `ReceiptVoucher`+`ApproveReceiptVoucher` per `md/32` §2 (LA-1/D-33 — amended from
  this file's original bare-`CreateJournalEntry` design); all other postings stay
  `CreateJournalEntry`-only.
- Toll fee invoicing via Sales→EInvoicing: `md/21-gaps.md` B18; `md/22-contracts.md` §1 (EInvoicing row).
- Module identity / `mfg_*` prefix / Actions-forward law: `md/20-mapping.md` §1; `md/22-contracts.md`
  §0 (D-01), §5.
</content>
