Overview
The Production Workflow module orchestrates the furniture manufacturing process, tracking production orders from creation through material allocation, manufacturing stages, and completion.
This feature is planned for future implementation as part of the complete production management system.
Purpose
The production workflow provides:
Production order management
Material requirement planning (MRP)
Work-in-progress (WIP) tracking
Production stage monitoring
Resource allocation and scheduling
Quality control checkpoints
Integration with inventory systems
Production Process Flow
┌───────────────────────┐
│ 1. Order Creation │
│ Define product & qty │
└───────────────────────┘
│
↓
┌───────────────────────┐
│ 2. Material Planning │
│ Calculate needs │
└───────────────────────┘
│
↓
┌───────────────────────┐
│ 3. Material Issuing │
│ Allocate from stock │
└───────────────────────┘
│
↓
┌───────────────────────┐
│ 4. Manufacturing │
│ Production stages │
└───────────────────────┘
│
↓
┌───────────────────────┐
│ 5. Quality Control │
│ Inspection │
└───────────────────────┘
│
↓
┌───────────────────────┐
│ 6. Completion │
│ Add to inventory │
└───────────────────────┘
Data Model Design
ProductionOrder Model
class ProductionOrder ( db . Model ):
__tablename__ = 'production_orders'
id_order = db.Column(db.Integer, primary_key = True )
order_number = db.Column(db.String( 50 ), unique = True , nullable = False )
order_date = db.Column(db.Date, nullable = False )
# Product information
product_id = db.Column(db.Integer, db.ForeignKey( 'finished_products.id_product' ))
quantity_ordered = db.Column(db.Integer, nullable = False )
quantity_completed = db.Column(db.Integer, default = 0 )
# Scheduling
start_date = db.Column(db.Date, nullable = True )
due_date = db.Column(db.Date, nullable = True )
completion_date = db.Column(db.Date, nullable = True )
# Status tracking
status = db.Column(db.String( 20 ), default = 'PENDING' )
# Statuses: PENDING, PLANNED, IN_PROGRESS, COMPLETED, CANCELLED
# Assignment
assigned_to = db.Column(db.String( 100 ), nullable = True )
priority = db.Column(db.Integer, default = 5 ) # 1-10, 1=highest
notes = db.Column(db.Text, nullable = True )
created_at = db.Column(db. TIMESTAMP , server_default = func.current_timestamp())
created_by = db.Column(db.String( 100 ), nullable = True )
# Relationships
product = db.relationship( 'FinishedProduct' , backref = 'production_orders' )
MaterialRequirement Model
Defines materials needed for products:
class MaterialRequirement ( db . Model ):
__tablename__ = 'material_requirements'
id_requirement = db.Column(db.Integer, primary_key = True )
product_id = db.Column(db.Integer, db.ForeignKey( 'finished_products.id_product' ))
material_id = db.Column(db.Integer, db.ForeignKey( 'raw_materials.id_material' ))
quantity_required = db.Column(db.Numeric( 10 , 2 ), nullable = False )
unit_id = db.Column(db.Integer, db.ForeignKey( 'unit_of_measures.id_unit_of_measure' ))
waste_percentage = db.Column(db.Numeric( 5 , 2 ), default = 0.00 ) # Expected waste
notes = db.Column(db.Text, nullable = True )
# Relationships
product = db.relationship( 'FinishedProduct' , backref = 'material_requirements' )
material = db.relationship( 'RawMaterial' , backref = 'required_by_products' )
unit = db.relationship( 'UnitOfMeasure' )
MaterialIssue Model
Tracks material allocation to production:
class MaterialIssue ( db . Model ):
__tablename__ = 'material_issues'
id_issue = db.Column(db.Integer, primary_key = True )
issue_date = db.Column(db.DateTime, server_default = func.current_timestamp())
production_order_id = db.Column(db.Integer, db.ForeignKey( 'production_orders.id_order' ))
material_id = db.Column(db.Integer, db.ForeignKey( 'raw_materials.id_material' ))
quantity_issued = db.Column(db.Numeric( 10 , 2 ), nullable = False )
quantity_returned = db.Column(db.Numeric( 10 , 2 ), default = 0.00 )
quantity_wasted = db.Column(db.Numeric( 10 , 2 ), default = 0.00 )
issued_by = db.Column(db.String( 100 ), nullable = True )
notes = db.Column(db.Text, nullable = True )
# Relationships
production_order = db.relationship( 'ProductionOrder' , backref = 'material_issues' )
material = db.relationship( 'RawMaterial' , backref = 'issues' )
ProductionStage Model
Tracks progress through manufacturing stages:
class ProductionStage ( db . Model ):
__tablename__ = 'production_stages'
id_stage = db.Column(db.Integer, primary_key = True )
production_order_id = db.Column(db.Integer, db.ForeignKey( 'production_orders.id_order' ))
stage_name = db.Column(db.String( 50 ), nullable = False )
# Examples: CUTTING, ASSEMBLY, SANDING, FINISHING, QC
stage_order = db.Column(db.Integer, nullable = False ) # Sequence
status = db.Column(db.String( 20 ), default = 'PENDING' )
# Statuses: PENDING, IN_PROGRESS, COMPLETED
start_time = db.Column(db.DateTime, nullable = True )
end_time = db.Column(db.DateTime, nullable = True )
worker_name = db.Column(db.String( 100 ), nullable = True )
notes = db.Column(db.Text, nullable = True )
# Relationships
production_order = db.relationship( 'ProductionOrder' , backref = 'stages' )
Planned Architecture
app/production/workflow/
├── routes.py
│ ├── Create production order
│ ├── View order status
│ ├── Update stage progress
│ └── Complete order
├── services.py
│ ├── Order management
│ ├── Material planning (MRP)
│ ├── Stock allocation
│ └── Progress tracking
└── forms.py
├── ProductionOrderForm
├── MaterialIssueForm
└── StageUpdateForm
Key Features
Order Management Create and track production orders from start to finish
Material Planning Automatic calculation of material requirements
Stage Tracking Monitor progress through manufacturing stages
Resource Scheduling Assign workers and plan production timeline
Planned Service Methods
ProductionOrderService
class ProductionOrderService :
@ staticmethod
def create_order ( data : dict ) -> dict :
"""Create new production order."""
# Generates unique order number
# Validates product exists
# Checks material availability
# Creates order record
# Initializes production stages
pass
@ staticmethod
def get_active_orders () -> list[ProductionOrder]:
"""Get all non-completed orders."""
return ProductionOrder.query.filter(
ProductionOrder.status.in_([ 'PENDING' , 'PLANNED' , 'IN_PROGRESS' ])
).all()
@ staticmethod
def calculate_material_needs ( product_id : int , quantity : int ) -> dict :
"""Calculate materials needed for production."""
# Gets material requirements for product
# Multiplies by quantity
# Adds waste percentage
# Returns dict of {material_id: quantity_needed}
pass
@ staticmethod
def check_material_availability ( order_id : int ) -> bool :
"""Verify materials available for order."""
# Compares requirements against stock
# Returns True if all materials available
pass
@ staticmethod
def start_order ( order_id : int ) -> None :
"""Begin production on order."""
# Updates status to IN_PROGRESS
# Sets start_date
# Creates material issues
pass
@ staticmethod
def complete_order ( order_id : int , quantity_completed : int , quantity_defective : int ) -> None :
"""Complete production order."""
# Updates order status
# Creates ProductionCompletion record
# Updates finished product inventory
# Records material waste
pass
MaterialIssueService
class MaterialIssueService :
@ staticmethod
def issue_materials ( order_id : int ) -> list[ dict ]:
"""Issue materials to production order."""
# Gets material requirements
# Creates issue records
# Reduces raw material stock
# Creates stock movement records
pass
@ staticmethod
def record_waste ( issue_id : int , quantity_wasted : float , notes : str ) -> None :
"""Record material waste."""
# Updates material issue
# Tracks waste for analysis
pass
@ staticmethod
def return_unused ( issue_id : int , quantity_returned : float ) -> None :
"""Return unused materials to stock."""
# Updates issue record
# Increases raw material stock
# Creates stock movement
pass
ProductionStageService
class ProductionStageService :
@ staticmethod
def start_stage ( stage_id : int , worker_name : str ) -> None :
"""Begin work on production stage."""
# Updates status to IN_PROGRESS
# Records start_time
# Assigns worker
pass
@ staticmethod
def complete_stage ( stage_id : int , notes : str = None ) -> None :
"""Complete production stage."""
# Updates status to COMPLETED
# Records end_time
# Calculates duration
# Starts next stage if applicable
pass
@ staticmethod
def get_order_progress ( order_id : int ) -> dict :
"""Calculate order completion percentage."""
# Counts completed vs total stages
# Returns percentage complete
pass
Manufacturing Stages
Typical furniture production stages:
Material Cutting
Cut wood and materials to required dimensions
Component Assembly
Assemble individual furniture components
Joining
Join components using fasteners, glue, or joinery
Sanding
Sand surfaces to smooth finish
Staining/Painting
Apply color finish as specified
Finishing
Apply protective coatings (varnish, lacquer, wax)
Quality Inspection
Inspect for defects and quality standards
Packaging
Prepare for storage or shipment
Example Workflow
Creating a Production Order
# Create order for 10 dining tables
order_data = {
"order_number" : "PO-2024-0315-001" , # Auto-generated
"order_date" : "2024-03-15" ,
"product_id" : 10 , # Oak Dining Table
"quantity_ordered" : 10 ,
"due_date" : "2024-03-30" ,
"priority" : 3 ,
"assigned_to" : "Production Team A"
}
# Service handles:
# 1. Create order record
# 2. Calculate material needs (10 tables × requirements)
# 3. Check material availability
# 4. Create production stages
# 5. Set status to PLANNED
order = ProductionOrderService.create_order(order_data)
Material Requirements Calculation
# For Oak Dining Table (product_id=10)
# Material requirements defined:
# - Oak Plywood: 2.5 m² per table
# - Wood Glue: 0.5 L per table
# - Finish: 0.3 L per table
quantity = 10
materials = ProductionOrderService.calculate_material_needs(
product_id = 10 ,
quantity = 10
)
# Returns:
# {
# 5: {"material": "Oak Plywood", "needed": 25.0, "unit": "m²", "available": 30.0},
# 8: {"material": "Wood Glue", "needed": 5.0, "unit": "L", "available": 10.0},
# 12: {"material": "Finish", "needed": 3.0, "unit": "L", "available": 2.5}
# }
# Shows Finish is short by 0.5 L
Starting Production
# Start production order
ProductionOrderService.start_order( order_id = 100 )
# Service handles:
# 1. Update status to IN_PROGRESS
# 2. Set start_date to today
# 3. Issue materials from stock:
# - Oak Plywood: -25.0 m²
# - Wood Glue: -5.0 L
# - Finish: -3.0 L
# 4. Create MaterialIssue records
# 5. Create StockMovement records (OUT)
Tracking Progress
# Worker updates stage completion
ProductionStageService.start_stage(
stage_id = 1 , # Cutting stage
worker_name = "Juan Pérez"
)
# Later...
ProductionStageService.complete_stage(
stage_id = 1 ,
notes = "All pieces cut to specification"
)
# Check overall progress
progress = ProductionStageService.get_order_progress( order_id = 100 )
# Returns: {"completed": 1, "total": 7, "percentage": 14.3}
Integration Points
With Raw Materials Inventory
When production starts:
Materials issued from Raw Materials Inventory
Stock levels reduced automatically
Movement records created for traceability
Waste tracked and recorded
With Finished Products Inventory
With Catalogs
Production uses catalog data:
Reports and Analytics
Planned reporting capabilities:
Production Schedule Active and planned orders by due date
Efficiency Report Time per stage, completion rates, delays
Material Usage Actual vs. planned consumption, waste analysis
Worker Performance Orders completed, stages per worker, quality
Best Practices
Use priority levels effectively:
1-3: High priority (rush orders, customer deadlines)
4-6: Normal priority (standard production)
7-10: Low priority (stock building, non-urgent)
Best practices for MRP:
Include waste percentage in calculations (typically 5-10%)
Check availability before starting orders
Maintain safety stock of common materials
Plan orders based on material lead times
Effective progress monitoring:
Update stages in real-time
Record actual worker time
Note any issues or delays
Use notes field for important details