Manufacturing Module
Manage the complete production lifecycle — from Bill of Materials to finished goods, with intelligent scheduling and real-time tracking.
What is the Manufacturing Module?
The Manufacturing module helps you plan and track production from start to finish. You can define how products are made (Bill of Materials), assign work to machines (Work Centers), and monitor every step of the production process through Manufacturing Orders and Job Orders.
The core_manuf module implements a multi-level manufacturing workflow built on Django models with HMX framework extensions. It depends on base, core_product, core_hr, and webx_widget. Key capabilities include hierarchical BoM with multi-operation support, finite-capacity WC scheduling (08:00–16:00 Mon–Fri), async scheduling via Celery with sync fallback, priority-based queue management, and job order splitting with material redistribution.
Bill of Materials
Define product recipes — materials, operations, and outputs
Work Centers
Set up machines and areas where production happens
Manufacturing Orders
Create and track production orders from start to finish
Job Orders
Track each operation step on the production floor
Scheduling
Automatic scheduling across work centers
Production Records
Record output quantities, quality, and time
Bom
BoM with operations, materials, byproducts, cost summary
WorkCenter
WC with service/labor/molding costs, capacity, OEE
ManufOrder
MO with auto-sequence, priority, Celery scheduling
ManufJobOrder
MJO with start/pause/done, split, Gantt aliases
ManufWcSchedule
Finite-capacity scheduling engine, 480min/day
ManufMjoOperator
Operator assignment with conflict detection
Production Process Flow
MO Status Flow
Cancel is available from any status (except Done/Closed)
MJO Status Flow
Getting Started
Follow these steps to set up your manufacturing environment for the first time.
Prerequisites
- Products must be created in the Inventory module first (raw materials and finished goods)
- At least one Work Center must be configured
- If using operator tracking, employees must be registered in HR module
- Your user account must have a Manufacturing role assigned (Super User, Manager, Production Planner, or Operator)
First-Time Setup Steps
Set Up Work Centers
Go to Manufacturing > Master Data > Work Centers. Create at least one Work Center (e.g., your main production machine). Set its capacity, setup time, and efficiency.
Define Work Center Costs
On each Work Center, add service costs and labor costs in the cost tabs. Choose whether each cost is based on quantity produced or duration of work.
| Service Product | Cost Basis | Cost/Unit |
|---|---|---|
| Electricity | Duration | IDR 15,000/hr |
Create a Bill of Materials
Go to Manufacturing > Bill of Materials > Create. Add your finished goods in the Output tab, define operations with their work centers and durations, and assign materials to each operation.
Create a Manufacturing Order
Go to Manufacturing > Manufacturing Orders > Create. Select your BoM, set the planned quantity, and specify the requested start date. The system will auto-populate materials and job orders.
Confirm & Start Production
Click "Confirm" on the Manufacturing Order. The system will automatically schedule Job Orders across Work Centers. Operators can then start, pause, and complete each Job Order.
| JO | Operation | Work Center | Status |
|---|---|---|---|
| JO-0200 | Cutting | WC-002 | Planned |
| JO-0201 | Welding | WC-005 | Planned |
Technical Setup
Module Dependencies
# __hmx__.py manifest
{
"name": "Core_Manuf",
"depends": ["base", "core_product", "core_hr", "webx_widget"],
"data": [
"security/manuf_groups.xml",
"security/base.model.access.csv",
"data/manuf_order_sequence_data.xml",
...
]
}
Auto-Sequences
| Model | Sequence Code | Example |
|---|---|---|
| ManufOrder | manuf.order | MO/2026/0001 |
| ManufRecord | manuf.record | MRC/2026/0001 |
| ManufWcSchedule | manuf.wc.schedule | WCS/2026/0001 |
| ManufSplitJobOrder | manuf.split.job.order | SJO/2026/0001 |
Key Computed Fields
| Model | Field | Depends On |
|---|---|---|
| ManufOrder | expected_duration | bom_id.operation_ids.duration |
| ManufOrder | date_scheduled_start | MJO scheduled starts (min) |
| ManufOrder | date_scheduled_end | MJO scheduled ends (max) |
| ManufOrder | delay_flag | scheduled_start vs requested_start |
| ManufJobOrder | name | MO code + operation name |
| ManufJobOrder | start_date/end_date | Gantt aliases for scheduled dates |
| HrEmployee | availability_status | Active operator assignments |
Bill of Materials (BoM)
Define the recipe for manufacturing a product — what materials are needed, which operations to perform, and what finished goods are produced.
What is a Bill of Materials?
A Bill of Materials (BoM) is like a recipe for making a product. It tells the system: what raw materials are needed, what steps (operations) to follow, which machines (work centers) to use, and what finished products come out at the end.
How to Create a BoM
Open Bill of Materials
Navigate to Manufacturing > Master Data > Bill of Materials, then click "Create".
| Code | Name | Version | Forecast Cost | Exec. Mode |
|---|---|---|---|---|
| BOM-0042 | Steel Frame Assembly | v2 | IDR 1,250,000 | Sequential |
| BOM-0038 | PCB Controller Board | v1 | IDR 850,000 | Sequential |
| BOM-0055 | Hydraulic Cylinder HX-200 | v1 | IDR 3,200,000 | Parallel |
Fill in Basic Information
Enter the BoM Code, BoM Name, and Version number. Select your Branch and Company.
Configure Production Rules
Set the Production Start Rule (when can production begin?), Operation Execution Mode (sequential or parallel), and Material Consumption Policy.
Add Finished Goods (Output Tab)
In the Output tab, add the products that will be produced. Specify the quantity and optionally set a rejected product variant for quality control.
| # | Product | Quantity | UoM | Allocated Cost | Reject Product |
|---|---|---|---|---|---|
| 1 | Steel Frame Assembly A1 | 1 | pcs | IDR 1,250,000 | Steel Frame A1 — Reject |
Define Operations
Add operations — each operation has a name, a Work Center, and an estimated duration in minutes.
| Seq | Operation Name | Work Center | Duration (min) |
|---|---|---|---|
| 10 | Cutting | WC-002 — Laser Cutting Station | 120 |
| 20 | Welding | WC-005 — Welding Station A | 240 |
| 30 | Assembly | WC-003 — Assembly Line A | 180 |
| 40 | Coating | WC-004 — Paint Booth #2 | 90 |
Assign Materials to Operations
For each operation, add the raw materials needed. Specify the product and quantity. The unit of measure is automatically pulled from the product.
| # | Operation | Material | Quantity | UoM | Unit Cost |
|---|---|---|---|---|---|
| 1 | Cutting | Steel Rod 10mm | 5 | pcs | IDR 45,000 |
| 2 | Welding | Welding Wire 1.2mm | 0.1 | kg | IDR 180,000 |
| 3 | Assembly | Bolt M8x25 | 8 | pcs | IDR 2,500 |
| 4 | Coating | Anti-Rust Coating | 0.24 | liter | IDR 85,000 |
Add Byproducts (Optional)
If any operation produces secondary products, add them as byproducts with their quantities and allocated costs.
| # | Operation | Product | Quantity | UoM | Allocated Cost |
|---|---|---|---|---|---|
| 1 | Cutting | Steel Scrap | 0.5 | kg | IDR 5,000 |
Production Rules Explained
| Rule | Options | When to Use |
|---|---|---|
| Production Start Rule | All Materials Available / At Least One Available / Start Immediately | Controls when production can begin relative to material availability |
| Operation Execution Mode | Sequential / Parallel | Sequential: operations run one after another. Parallel: all operations start at the same time. |
| Material Consumption | Block / Allow With Warning / Allow Without Warning | Controls what happens when consumed quantity differs from planned |
| Reject Cost Allocation | Recorded / Transferred to Finished Good | How rejected product costs are handled |
BoM Technical Reference
Model: bom
| Field | Type | Details |
|---|---|---|
| code | CharField(255) | BoM Code |
| name | CharField(255) | BoM Name |
| version | CharField(50) | Version string |
| forecast_cost | Decimal(16,2) | Estimated total cost |
| product_start_rule | CharField(50) | all_material_available | at_least_one_available | start_immediately |
| operation_execution_mode | CharField(50) | sequential | parallel |
| material_consumption_policy | CharField(50) | block | allow_with_warning | allow_without_warning |
| reject_cost_allocation | CharField(50) | recorded | transferred_to_finished_good |
| branch / company | FK | Multi-company support |
Related Models
| Model | Key | Relation | Key Fields |
|---|---|---|---|
bom_output | output_ids | BoM → Finished Goods | product_fg, quantity, allocated_cost, rejected_product |
operation | operation_ids | BoM → Operations | name, duration, work_center |
material | material_ids | Operation → Materials | product, quantity, uom (computed). Unique product per operation constraint. |
byproduct | byproduct_ids | Operation → Byproducts | product, quantity, allocated_cost |
Cost Summary Engine
The _compute_summary_widget_json method builds a comprehensive cost breakdown as JSON, including:
- Finished goods costs with allocated_cost_percent per output line
- Material costs:
quantity × product.standard_price - WC costs: resolved via
_find_workcenter_by_label, thenservice_cost_idsandlabor_cost_idsare iterated with duration/quantity-based calculation - Byproduct costs deducted from total
- Linked BoM navigation via
product_bom_cache
manuf_order_bom_ids exists (referenced by any MO).ERD
Work Centers
Work Centers represent machines or production areas where manufacturing operations are performed.
What is a Work Center?
A Work Center is a machine, production line, or work area where manufacturing operations happen. Each Work Center has its own capacity, costs, and schedule. The system uses this information to plan when and where each operation will be performed.
How to Create a Work Center
Open Work Centers
Navigate to Manufacturing > Master Data > Work Centers, then click "Create".
| Code | Name | Type | Capacity | Efficiency | OEE Target |
|---|---|---|---|---|---|
| WC-001 | CNC Milling Machine #1 | Machine | 1 | 95% | 85% |
| WC-003 | Assembly Line A | Area | 8 | 78% | 75% |
| WC-005 | Welding Station A | Machine | 3 | 91% | 85% |
Enter Basic Details
Fill in the Work Center Code (must be unique), Name, and Type (Machine or Area). You can also upload an image and link an asset product.
Set Capacity & Efficiency
Set the Capacity (parallel units, minimum 1), Efficiency percentage (0–100%), OEE Target, and Setup/Teardown times in minutes.
Add Service Costs
In the Service Costs tab, add cost items. For each, select a service product, choose whether the cost is based on quantity or duration, and enter the cost per unit.
| # | Service Product | Cost Basis | Cost per Unit |
|---|---|---|---|
| 1 | Electricity — Welding | Duration | IDR 15,000 /hour |
| 2 | Gas Supply — Argon | Quantity | IDR 8,500 /unit |
Add Labor Costs
In the Labor Costs tab, add labor cost lines with cost rates. These will be used to calculate manufacturing costs in the BoM summary.
| # | Description | Cost Rate |
|---|---|---|
| 1 | Welder — Senior | IDR 75,000 /hour |
| 2 | Welder — Junior | IDR 45,000 /hour |
WorkCenter Technical Reference
Model: workcenter
| Field | Type | Constraints |
|---|---|---|
| code | CharField(255) | Unique across all WCs |
| name | CharField(255) | Required |
| type | CharField | machine | area |
| capacity | Float | Must be ≥ 1.0 |
| efficiency | Float | 0 < value ≤ 100 |
| oee_target | Float | 0 ≤ value ≤ 100 |
| setup_time | Float | Minutes |
| teardown_time | Float | Minutes |
| image | ImageField | Optional |
Cost Models
| Model | Fields | Purpose |
|---|---|---|
service_cost_workcenter | product_service_id (service type), based_on (quantity|duration), cost | Machine operation costs |
labor_cost_workcenter | product_service_id, based_on, cost, labor_id | Labor costs per worker/role |
molding_workcenter | product_service_id | Molding/tooling costs |
Performance Metrics (Read-only)
oee_percentage, lost_percentage, load_percentage, performance_percentage — stored fields for OEE dashboard display.
Manufacturing Orders
Manufacturing Orders (MO) are the central document for planning and tracking production runs.
What is a Manufacturing Order?
A Manufacturing Order (MO) is your instruction to produce a specific quantity of a product. It links to a Bill of Materials and automatically generates the Job Orders (one per operation) needed to complete the production.
How to Create a Manufacturing Order
Open Manufacturing Orders
Navigate to Manufacturing > Manufacturing Orders, then click "Create". The system will automatically assign an MO code.
| MO Number | Product | BoM | Qty | Priority | Status | Progress |
|---|---|---|---|---|---|---|
| MO-2026-0089 | Steel Frame Assembly A1 | BOM-0042 v2 | 500 | Critical | In Progress | 72% |
| MO-2026-0088 | PCB Controller Board Rev.3 | BOM-0038 v1 | 1,200 | High | Done | 100% |
| MO-2026-0087 | Hydraulic Cylinder HX-200 | BOM-0055 v1 | 80 | Normal | In Progress | 35% |
| MO-2026-0086 | Aluminum Enclosure C-Type | BOM-0061 v3 | 300 | Normal | Draft | 0% |
Select Bill of Materials
Choose the BoM for the product you want to manufacture. The system will automatically populate the planned quantity, materials list, and job orders based on the BoM.
Adjust Quantity
Modify the planned quantity if needed. Material quantities and job order durations will automatically recalculate based on the ratio from the BoM output.
| Material | Per Unit | Total Qty | UoM |
|---|---|---|---|
| Steel Rod 10mm | 5 | 2,500 | pcs |
| Welding Wire 1.2mm | 0.1 | 50 | kg |
| Bolt M8x25 | 8 | 4,000 | pcs |
Set Schedule Date
Enter the Requested Start Date. The system will calculate the Requested End Date based on the total operation durations and working hours (8 AM – 4 PM, Mon–Fri).
Set Priority
Choose a priority level: Critical, High, Normal, or Low. Priority affects scheduling order — higher priority orders are scheduled first.
Confirm the Order
Click "Confirm" to lock in the order. The system will automatically schedule all Job Orders across the assigned Work Centers.
ManufOrder Technical Reference
Model: manuforder
| Field | Type | Details |
|---|---|---|
| name | CharField(255) | Auto-sequence via manuf.order |
| status | CharField | draft | confirm | in_progress | partial | done | close | cancel |
| priority | CharField(20) | critical | high | normal (default) | low. Tracking enabled. |
| scheduling_status | CharField(20) | pending_schedule | scheduled |
| delay_flag | CharField(20) | Computed: earlier | on_schedule | delayed |
| bom_id | FK → bom | RESTRICT on delete |
| planned_quantity | Decimal | Drives material scaling |
| date_requested_start/end | DateTime | end computed via add_working_minutes |
| date_scheduled_start/end | DateTime | Computed from MJO min/max |
| started_at / completed_at | DateTime | Computed from MJO actual times |
| expected_duration | Float | Sum of operation durations |
Key Methods
| Method | Description |
|---|---|
action_confirm() | Sets status=confirm, scheduling_status=pending_schedule, calls _run_schedule() |
_run_schedule() | Decorated with @use_task — runs async via Celery, falls back to sync. Calls ManufWcSchedule.compute_schedule() |
action_cancel() | Cancels all MJOs, calls handle_mo_cancel() to cascade reschedule |
write() | Priority changes on confirmed MOs require role check via _check_priority_access(), triggers handle_priority_change() |
_onchange_bom_id() | Auto-populates mo_materials and job orders |
_onchange_planned_quantity() | Recalculates materials and job orders with qty scaling |
Priority Access Control
# Roles allowed to change priority on confirmed MOs:
- core_manuf.manuf_group_super_user
- core_manuf.manuf_group_manager
- core_manuf.manuf_group_production_planner
- base.group_system
Material Scaling Logic
# _prepare_material_values()
to_consume_quantity = material.quantity × planned_quantity
# _prepare_workorder_values()
scaled_duration = compute_duration(operation, planned_qty, default_qty)
# where default_qty = sum(bom.output_ids.quantity)
Job Orders
Job Orders represent individual operation steps within a Manufacturing Order, assigned to specific Work Centers.
What is a Job Order?
A Job Order (also called Work Order) is a single operation step in the manufacturing process. When you confirm a Manufacturing Order, the system automatically creates one Job Order for each operation defined in the Bill of Materials. Each Job Order is assigned to a specific Work Center.
Executing Job Orders
Find Your Job Orders
Go to Manufacturing > Job Orders. You can filter by Work Center, status, or Manufacturing Order to find the jobs assigned to you.
| JO Number | MO | Operation | Work Center | Qty | Status |
|---|---|---|---|---|---|
| JO-2026-0201 | MO-2026-0089 | Frame Welding | WC-005 Welding Station A | 500 | In Progress |
| JO-2026-0202 | MO-2026-0089 | Assembly | WC-003 Assembly Line A | 500 | Waiting Material |
| JO-2026-0203 | MO-2026-0087 | CNC Machining | WC-001 CNC Milling #1 | 80 | Ready |
| JO-2026-0200 | MO-2026-0089 | Cutting | WC-002 Laser Cutting | 500 | Done |
Start the Job Order
Open the Job Order and click "Start". The status changes to "In Progress" and the system begins tracking the actual start time.
Pause if Needed
If you need to stop work temporarily, click "Pause". You can resume later by clicking "Start" again. Pause time is tracked separately.
| Type | Start | End | Duration |
|---|---|---|---|
| Work | 08:15 | 12:00 | 3h 45m |
| Pause | 12:00 | 13:00 | 1h 00m |
| Work | 13:00 | — | Running... |
Complete the Job Order
When the operation is finished, click "Done". A Production Record form will open automatically for you to enter the produced quantities, quality results, and any remarks.
| Material | Planned | Consumed | UoM |
|---|---|---|---|
| Steel Rod 10mm | 2,500 | 2,500 | pcs |
| Welding Wire 1.2mm | 50 | 48 | kg |
Delay Indicator
Each Job Order shows a delay flag: "Earlier" (ahead of schedule), "On Schedule", or "Delayed". This helps you prioritize which jobs need immediate attention.
ManufJobOrder Technical Reference
Model: manufjoborder
Uses active_name = "active" for soft-delete support (voided by split).
| Field | Type | Details |
|---|---|---|
| name | CharField (computed) | "{MO.name}/{operation.name}" |
| status | CharField | planned | waiting_material | waiting_mjo | ready | in_progress | paused | done | cancelled | voided |
| active | Boolean | False when voided by split |
| sequence | Integer | Operation order within MO |
| manuf_order_id | FK → manuforder | Parent MO |
| workcenter_id | FK → workcenter | Assigned WC |
| operation | FK → operation | BoM operation reference |
| produce_quantity | Decimal | Target quantity |
| duration_planned | Integer | Scaled: setup + estimated × qty_factor |
| start_date / end_date | DateTime (computed) | Gantt view aliases for scheduled dates |
| split_ref_id | FK → manufsplitjoborder | Set on child JOs from split |
| parent_mjo_id | FK → self | Back-pointer to voided source JO |
Action Methods
action_start() → status = 'in_progress' (from planned/ready/paused)
action_pause() → status = 'paused' (from in_progress)
action_done() → creates ManufRecord, status = 'done', opens record form
Production Record Creation
_create_production_record() creates a ManufRecord with draft status. _is_last_job_order() checks if this is the last active JO in the MO (no other non-done/cancelled/voided active JOs).
Production Records
Production Records capture the actual output, quality results, and consumption data for each completed Job Order.
What is a Production Record?
When you complete a Job Order (click "Done"), the system automatically creates a Production Record. This is where you enter the actual quantities produced, consumed materials, quality check results, and any notes about the production run.
Review Auto-Filled Information
The record will show the MO code, Job Order, operation, work center, and planned quantity. Verify these are correct.
Enter Production Data
Fill in the Material tab (consumed quantities), By Products tab (if any), Quality Check tab, and Labor tab. Add any remarks in the notes section.
| Material | Planned | Consumed | Variance | UoM |
|---|---|---|---|---|
| Steel Rod 10mm | 2,500 | 2,500 | 0 | pcs |
| Welding Wire 1.2mm | 50 | 48 | -2 | kg |
Confirm the Record
Click "Confirm" to finalize the production record. This action cannot be undone — the record becomes permanent.
ManufRecord Technical Reference
Model: manufrecord
| Field | Type | Details |
|---|---|---|
| name | CharField(255) | Auto-sequence: manuf.record |
| mjo_id | FK → manufjoborder | CASCADE |
| mo_id | FK → manuforder | CASCADE |
| workcenter_id | FK → workcenter | RESTRICT |
| status | CharField | draft | confirm |
| related_mjo_is_last_manuf_job_order | Boolean | True if this is the last active JO |
| material_ids, by_product_ids, quality_check_ids, labor_ids | TextField | Temporary JSON/text fields for tabs |
| remarks | TextField | Free-text notes |
action_confirm() sets status to 'confirm' and returns baseactwindowclose to close the dialog.
Work Center Scheduling
The scheduling engine automatically assigns time slots to Job Orders based on Work Center availability, priority, and working calendar.
How Scheduling Works
When you confirm a Manufacturing Order, the system automatically schedules each Job Order on its assigned Work Center. The scheduler respects working hours (8 AM to 4 PM, Monday to Friday) and ensures no two jobs overlap on the same Work Center.
- Sequential Mode: Operations run one after another — the next operation starts only after the previous one finishes.
- Parallel Mode: All operations can start at the same time, each on their assigned Work Center.
- Priority: Higher priority orders (Critical > High > Normal > Low) are scheduled first.
- Duration Calculation: Setup Time + (Operation Duration × Quantity Factor)
Understanding Delay Flags
| Flag | Meaning | Action Needed |
|---|---|---|
| ● Earlier | Scheduled start is before the requested start date | No action needed — production is ahead of schedule |
| ● On Schedule | Scheduled start matches the requested start date | On track — proceed as planned |
| ● Delayed | Scheduled start is after the requested start date | Consider increasing priority or splitting the job order |
Scheduling Engine Reference
Models
manufwcschedule — one header per WC per date (UNIQUE constraint on workcenter_id + schedule_date).
manufwcscheduleline — one line per MJO (UNIQUE on mjo_id).
Duration Computation
def compute_duration(operation, planned_qty, default_qty, workcenter=None):
wc = workcenter or operation.work_center
setup_time = wc.setup_time or 0
scaling_factor = planned_qty / default_qty
op_duration = operation.duration * scaling_factor
return setup_time + op_duration
Working Calendar
SHIFT_START = time(8, 0)
SHIFT_END = time(16, 0)
WORKING_MINUTES_PER_DAY = 480
# add_working_minutes(): spans across days, skips weekends
# snap_to_working_start(): snaps to next valid work hour
# _is_working_day(): Mon-Fri only
compute_schedule(mo) Flow
- Get all MJOs sorted by sequence
- For each MJO: compute scaled duration
- Determine anchor: sequential mode uses prev_finish; parallel mode uses MO requested start
- Check WC last finish — if WC is busy, anchor moves forward
- Snap to working start, compute finish via add_working_minutes
- Create/get schedule header for the date, create schedule line
- Sync dates back to MJO
Cascade Operations
| Trigger | Method | Effect |
|---|---|---|
| MO Cancel | handle_mo_cancel() | Cancel all MJOs + lines, recalculate affected WCs |
| Priority Change | handle_priority_change() | Re-sort all WC lines by priority + created_at, recalculate from pos 1 |
| Split MJO | schedule_single_mjo() | Schedule individual child MJO independently |
| Void MJO | handle_mjo_void() | Cancel schedule line, cascade recalculate |
Split Job Order
Split a Job Order into multiple smaller jobs across different Work Centers to balance load or speed up production.
When to Split a Job Order
You can split a Job Order when you want to distribute work across multiple Work Centers, or when a single Work Center can't handle the full quantity in time. For example, if you need to produce 1000 units and have 2 machines available, you can split the job into 500 + 500.
How to Split a Job Order
Open the Split Wizard
On the Manufacturing Order, click "Split Job Order". The wizard will show all eligible Job Orders.
| Select | JO | Operation | Work Center | Qty | Status |
|---|---|---|---|---|---|
| ☐ | JO-2026-0201 | Frame Welding | WC-005 | 500 | In Progress |
| ☐ | JO-2026-0202 | Assembly | WC-003 | 500 | Planned |
Select the Job Order
Choose which Job Order to split. The wizard will display the original quantity and the splittable quantity.
Define Split Lines
Add at least 2 split lines. For each line, set the quantity and select a Work Center. The system will recommend the best Work Centers based on availability.
| # | Quantity | Work Center | Recommended |
|---|---|---|---|
| 1 | 300 pcs | WC-005 — Welding Station A | Best Avail. |
| 2 | 200 pcs | WC-006 — Welding Station B | Available |
Review & Confirm
Verify that the total of all split quantities equals the splittable quantity exactly. Click "Confirm" to execute the split. The original Job Order will be voided and new ones created.
| Action | Job Order | Qty | Work Center |
|---|---|---|---|
| Void | JO-2026-0201 | 500 | WC-005 |
| New | JO-2026-0210 | 300 | WC-005 |
| New | JO-2026-0211 | 200 | WC-006 |
Work Center Recommendations
The system scores Work Centers by availability. A Work Center with no queue and immediate availability will be ranked "Best", while busy ones are ranked lower. Already-selected Work Centers are deprioritized to encourage load distribution.
Split Job Order Technical Reference
Business Rules
| Rule | Check |
|---|---|
| BR-001 | Eligibility: status in (planned, ready, paused). In Progress must pause first. No recursive split (split_ref_id must be null). |
| BR-002 | Sum of split quantities must equal splittable_qty exactly (tolerance: 0.001) |
| BR-004 | Each line min qty: 1. Minimum 2 lines per split. |
| BR-008 | WC scoring: score = nextFree_minutes + (queue_length × 10). Already selected WCs get +999 penalty. |
Execution Flow (action_confirm)
- Validate via
_check_split() - Create audit document (
ManufSplitJobOrder) - Void source MJO: set
active=False,status=voided,voided_by_split_id - Cancel source schedule line via
handle_mjo_void() - Create child MJOs from split lines with
split_ref_idandparent_mjo_id - Schedule each child via
schedule_single_mjo() - Redistribute MO materials proportionally via
_redistribute_materials() - Confirm the audit doc (becomes read-only)
Material Redistribution
# _redistribute_materials():
# For each MO material linked to the voided MJO:
# total_split_qty = sum(child.produce_quantity)
# for each child MJO:
# ratio = child.produce_quantity / total_split_qty
# new_mo_material.to_consume_quantity = original × ratio
Models
manufsplitjoborder — audit document, read-only after confirmation (write raises ValidationError on confirmed state).
manufsplitjoline — split lines with planned_qty, workcenter_id, assigned_mode (auto/manual), duration_planned, resulting_mjo_id.
Operator Management
Assign operators to Job Orders, track their work time, and manage conflicts.
Assigning Operators
Operators are employees marked as "Manufacturing Labor" in the HR system. You can assign one or more operators to each Job Order with Primary or Secondary roles. The system tracks their availability — an operator currently working on an active job will show as "Busy".
Open a Job Order
Navigate to the Job Order you want to assign operators to.
Add Operator Assignments
In the Operators tab, click "Add" and select an employee. Only employees marked as "Manufacturing Labor" will appear. Set their role (Primary or Secondary).
| Employee | Role | Status |
|---|---|---|
| EMP-0034 — Ahmad Fauzi | Primary | Confirmed |
| EMP-0041 — Budi Santoso | Secondary | Confirmed |
Check for Conflicts
If an operator is already assigned to another active job, a conflict will be flagged. A manager can acknowledge the conflict to proceed.
Time Tracking
The system automatically logs work time for each operator through the Labor Time Log. It records actual start and end times, pause durations, and calculates total actual duration. Time logs can be auto-generated from job order actions or entered manually.
Operator Assignment Technical Reference
Model: manufmjooperator
| Field | Type | Details |
|---|---|---|
| mjo_id | FK → manufjoborder | CASCADE |
| labor_id | FK → hremployee | Domain: is_manufacturing_labor=True |
| role | CharField(20) | primary | secondary |
| status | CharField(20) | assigned | confirmed | replaced | voided |
| has_conflict | Boolean | Set when operator has overlapping assignment |
| conflict_acknowledged_by/at | FK/DateTime | Manager who acknowledged |
| replaced_by_id | FK → self | For replacement chains |
HrEmployee Extension
class HrEmployee(models.Model):
class Meta:
inherit = "hremployee"
is_manufacturing_labor = models.BooleanField(default=False)
availability_status = computed:
"Busy" if any active assignment on non-done MJO
"Available" otherwise
Labor Time Log: manuflabortimelog
Per-operator time tracking with pause sub-lines (manuflabortimelogpause). Source field: auto (system-generated) or manual.
Time Tracking: manuftimetracking
Per-MJO time entries with type (work/pause), start/end times, duration, and optional reason for pauses.
Role-Based Access Control
The Manufacturing module has 4 security roles with different permission levels.
Security Roles
Super User
Full access to all manufacturing features. Can create, edit, and delete everything.
Manager
Full access to most features. Cannot delete production records or time logs.
Production Planner
Can read, create, and edit. Cannot delete any records.
Operator
Read-only on most features. Can create and edit Production Records.
Permission Matrix
| Model | Super User | Manager | Planner | Operator |
|---|---|---|---|---|
| Bill of Materials | CRUD | CRUD | CRU | R |
| BoM Output | CRUD | CRUD | CRU | R |
| Operation | CRUD | CRUD | CRU | R |
| Material | CRUD | CRUD | CRU | R |
| ByProduct | CRUD | CRUD | CRU | R |
| Work Center | CRUD | CRUD | CRU | R |
| WC Service Cost | CRUD | CRUD | CRU | R |
| WC Labor Cost | CRUD | CRUD | CRU | R |
| Manufacturing Order | CRUD | CRUD | CRU | R |
| Job Order | CRUD | CRUD | CRU | R |
| MO Material | CRUD | CRUD | CRU | R |
| Production Record | CRUD | CRU | CRU | CRU |
| WC Schedule | CRUD | CRUD | CRU | R |
| Time Tracking | CRUD | CRUD | CRU | R |
| Operator Assignment | RU | RU | RU | R |
| Labor Timelog | RU | RU | RU | R |
| Split Job Order | CRUD | CRUD | CRU | R |
C = Create, R = Read, U = Update, D = Delete
Troubleshooting
Common issues and how to resolve them.
Common Issues
Cannot delete a Bill of Materials
Cannot delete a Work Center
Cannot change priority on a Manufacturing Order
Cannot split a Job Order
Scheduling shows "Delayed" status
Operator shows as "Busy"
Technical Troubleshooting
Celery Task Failures
The scheduling task (_run_schedule) is decorated with @use_task(fallback_to_sync=True). If Celery is unavailable, it falls back to synchronous execution. Check Celery worker logs if scheduling seems delayed.
Schedule Integrity
If schedule data becomes inconsistent, you can trigger a full recalculation for a Work Center:
schedule_model = env['manufwcschedule']
schedule_model.recalculate_sequences(wc_id, from_position=1)
Unique Constraint Violations
workcenter.code— unique across all Work Centersmanufwcschedule (workcenter_id, schedule_date)— one schedule per WC per datemanufwcscheduleline.mjo_id— one schedule line per MJOmaterial (operation, product)— unique product per operation