MANUFACTURING MODULE SPEC

03 β€” Execution Layer

Reality. Translates plans into actual recorded events. The gap between planned and actual = variances (file 04). Inherits all rules from 00. Four sequential components.

Production Order β†’ Material Issue β†’ Confirmation β†’ Goods Receipt

3.1 Component: Production Order (PO)

Purpose: The internal contract authorizing production of a specific quantity. Everything after (issue, confirm, receipt) links to a specific order.

Critical concept β€” Frozen Snapshot

On Planned β†’ Released, the order snapshots the active BOM and Routing. Later master-data changes do NOT affect this order. Protects historical cost & audit trail.

Production_Order entities

Production_Order_Header:
  - order_no (PK)
  - order_type ∈ { Standard, Rework, Repair }
  - product_id, quantity
  - production_type ∈ { MakeToStock, MakeToOrder, TollManufacturing }
  - material_ownership ∈ { Own, Customer }
  - start_date, finish_date
  - status ∈ { Planned, Released, InProcess, Completed, Closed }
  - bom_snapshot_id, routing_snapshot_id
  - tool_id                 (assigned mold/die)
  - source_orders []        (Pegging β€” which sales orders this serves)
  - wip_account

Order_Component:   (snapshot copy of BOM lines)
  - component_id, required_quantity, issued_quantity, reserved_quantity, operation_seq
  # required_quantity = bom_qty Γ— order_qty Γ— (1 + scrap%)

Order_Operation:   (snapshot copy of Routing operations)
  - operation_no, work_center_id, tool_id
  - planned_setup_time, planned_run_time
  - actual_setup_time, actual_run_time
  - status ∈ { Waiting, Ready, InProgress, Completed }   ← used by SFC (file 05)
  - actual_start_time, actual_end_time
  - confirmed_quantity, scrap_quantity

Status state machine

Planned β†’ Released:   snapshot BOM+Routing; reserve materials; reserve tool & capacity
Released β†’ InProcess: first issue/confirmation begins; time tracking starts
InProcess β†’ Completed: all operations done; confirmed_qty β‰ˆ order_qty
Completed β†’ Closed:   close WIP; compute final variances; block further postings

Generic-design notes

Toll branch

if production_type == TollManufacturing:
  on Released:  do NOT reserve/purchase customer material; verify consignment sufficiency
  on Closed:    output goes to CUSTOMER ownership (not own FG); cost = conversion only

3.2 Component: Material Issue

Purpose: First real accounting movement. Material moves from Raw Materials (RM) to Work-In-Process (WIP).

Entities

Material_Issue_Header:
  - issue_no, issue_date
  - issue_type ∈ { Manual, Backflush, AutoIssue }
  - issue_level ∈ { PerOrder, PerShift, PerOperation }
  - order_no, operation_no, issuer_id, warehouse_from
  - status ∈ { Draft, Posted, Reversed }

Material_Issue_Line:
  - material_code, quantity, batch_no/lot_no
  - cost_price (per costing_method), total_cost, bin_location
  - ownership ∈ { Own, Customer }   ← consignment tracking

Issue types (timing differs)

Manual:    worker issues explicitly, when needed, actual qty. Most accurate, slowest.
Backflush: system auto-issues at confirmation; qty = produced Γ— BOM. Diff β†’ variance.
AutoIssue: all materials issued at Release, in one shot. Suits small orders.

Algorithm

Material_Issue(target, material, qty):
  validate: order Released/InProcess; available β‰₯ qty; material in BOM snapshot
  cost_price = get_cost(material, costing_method)   # FIFO/LIFO/Standard/Average
  on_hand[material] -= qty; reserved[material] -= qty
  WIP[order] += qty Γ— cost_price
  POST: Debit WIP / Credit Raw Materials   (qty Γ— cost_price)
  order_component[material].issued += qty

Toll branch

if material.ownership == Customer:
  issue from separate customer (consignment) stock, NOT own stock
  accounting differs: no "Credit Raw Materials" at your cost (not your asset)
  record a "customer material consumption" movement for tracking only

Generic-design notes

Melamine test case

Shift-level manual issue of powder: worker draws 16kg; produces 300 dishes.
Theoretical = 300 Γ— 0.15 Γ— 1.03 = 46.4kg... (per-shift reconciliation):
issued βˆ’ (produced Γ— BOM) = Material Usage Variance β†’ surfaces powder waste
without per-piece tracking.

3.3 Component: Confirmation

Purpose: Records that part of an order actually executed (per operation): how much produced, labor/machine used, scrap. The true source of actuals compared against standards.

Entities

Confirmation_Header:
  - confirmation_no, order_no, operation_no
  - confirmation_type ∈ { Partial, Final, Reversal }
  - operator_id, work_center_id, shift, timestamp

Confirmation_Yield:   (GENERALIZED β€” a distribution, not a scalar)
  - grade_code        (A/B/C... or single grade for normal factories)
  - quantity
  - unit_sale_price   (for joint-products NRV allocation)

Confirmation_Detail:
  - scrap_quantity, rework_quantity
  - setup_time_actual, run_time_actual
  - labor_hours, machine_hours
  - reason_code       (for scrap/delay β†’ Pareto analysis)

Core rule

Ξ£(grade quantities) + scrap = total_input
yield% = Ξ£grades / input ; first_pass% = grade_A / input   (key quality KPI)

Algorithm (with backflush & postings)

Confirmation(order, operation, results):
  validate: order InProcess; operation open
  # backflush if configured
  if operation has backflush materials:
      consumed = total_input Γ— BOM_qty ; auto Material_Issue
  # cost posting β€” labor depends on labor_calc
  labor_cost  = (labor_calc==Hourly) ? labor_hours Γ— labor_rate
                                     : produced Γ— piece_rate
  machine_cost = machine_hours Γ— machine_rate
  overhead     = (labor_hours + machine_hours) Γ— overhead_rate   # or qty Γ— oh_rate
  POST:
    Debit  WIP                 (labor+machine+overhead)
    Credit Labor Applied       (labor_cost)
    Credit Machine Applied     (machine_cost)
    Credit Overhead Applied    (overhead)
  # scrap
  POST: Debit Scrap Expense / Credit WIP   (scrap Γ— unit_cost)
  # advance
  if Final: close operation; if not last: mark next operation Ready (β†’ SFC)

Joint-products cost allocation (at confirmation/receipt)

total_sale_value = Ξ£(grade.qty Γ— grade.price)
for each grade:
  grade.allocated_cost = total_cost Γ— (grade.qty Γ— grade.price) / total_sale_value
  grade.unit_cost = grade.allocated_cost / grade.qty

Higher-priced grade absorbs more cost (NRV method). Normal factories use a single grade β†’ collapses to standard behaviour.

Generic-design notes


3.4 Component: Goods Receipt (GR)

Purpose: Last step β€” finished product enters inventory. Closes WIP, opens FG. Converts accumulated cost into ready-to-sell product cost.

Entities

Goods_Receipt_Header:
  - gr_no, gr_date, order_no
  - receipt_type ∈ { Full, Partial }
  - warehouse_to, receiver_id
  - status ∈ { Draft, Posted, Reversed }

Goods_Receipt_Line:   (One-to-Many β€” a line per grade)
  - item_id, received_quantity, grade_code
  - batch_no/lot_no, bin_location
  - cost_per_unit (= allocated WIP / qty)
  - quality_status ∈ { Released, OnHold, Rejected }

Algorithm

Goods_Receipt(order, received_qty):
  Total_WIP = Ξ£(material + labor + machine + overhead)
  # multi-grade: split into lines, each with allocated cost (see 3.3)
  for grade line: FG_Inventory[item, grade] += qty (at allocated unit cost)
  POST (standard costing):
    Debit  FG Inventory   (standard_cost Γ— qty)
    Debit  Variance Acct  (difference)
    Credit WIP            (total_actual_cost)
  if Full: order β†’ Completed
  if pegged to sales orders: allocate quantities to customers
  compute final variances; order β†’ Closed

Multi-grade receipt (Melamine)

One press order 100 dishes β†’ 3 receipt lines + scrap:
  A: 70 @ 11.77, B: 18 @ 7.06, C: 7 @ 3.53, scrap 5
POST:
  Debit FG-A 824 / FG-B 127 / FG-C 25 / Scrap 24 ; Credit WIP 1000

Toll branch

if production_type == TollManufacturing:
  output β†’ CUSTOMER ownership (not own FG inventory)
  revenue = conversion fee only:
    Debit Customer (receivable)  / Credit Toll-service revenue
  close conversion-WIP (labor+machine+overhead, NO material)

Final variance gate

At close, compute and decompose variances (price/usage/labor/overhead) β€” this is the entry point to Costing (file 04).