Add improved production UI 3
This commit is contained in:
@@ -35,6 +35,22 @@ class ProductionPriority(str, enum.Enum):
|
||||
URGENT = "URGENT"
|
||||
|
||||
|
||||
class EquipmentStatus(str, enum.Enum):
|
||||
"""Equipment status enumeration"""
|
||||
OPERATIONAL = "operational"
|
||||
MAINTENANCE = "maintenance"
|
||||
DOWN = "down"
|
||||
WARNING = "warning"
|
||||
|
||||
|
||||
class EquipmentType(str, enum.Enum):
|
||||
"""Equipment type enumeration"""
|
||||
OVEN = "oven"
|
||||
MIXER = "mixer"
|
||||
PROOFER = "proofer"
|
||||
FREEZER = "freezer"
|
||||
PACKAGING = "packaging"
|
||||
OTHER = "other"
|
||||
|
||||
|
||||
class ProductionBatch(Base):
|
||||
@@ -56,16 +72,22 @@ class ProductionBatch(Base):
|
||||
planned_end_time = Column(DateTime(timezone=True), nullable=False)
|
||||
planned_quantity = Column(Float, nullable=False)
|
||||
planned_duration_minutes = Column(Integer, nullable=False)
|
||||
|
||||
|
||||
# Actual production tracking
|
||||
actual_start_time = Column(DateTime(timezone=True), nullable=True)
|
||||
actual_end_time = Column(DateTime(timezone=True), nullable=True)
|
||||
actual_quantity = Column(Float, nullable=True)
|
||||
actual_duration_minutes = Column(Integer, nullable=True)
|
||||
|
||||
|
||||
# Status and priority
|
||||
status = Column(SQLEnum(ProductionStatus), nullable=False, default=ProductionStatus.PENDING, index=True)
|
||||
priority = Column(SQLEnum(ProductionPriority), nullable=False, default=ProductionPriority.MEDIUM)
|
||||
|
||||
# Process stage tracking
|
||||
current_process_stage = Column(SQLEnum(ProcessStage), nullable=True, index=True)
|
||||
process_stage_history = Column(JSON, nullable=True) # Track stage transitions with timestamps
|
||||
pending_quality_checks = Column(JSON, nullable=True) # Required quality checks for current stage
|
||||
completed_quality_checks = Column(JSON, nullable=True) # Completed quality checks by stage
|
||||
|
||||
# Cost tracking
|
||||
estimated_cost = Column(Float, nullable=True)
|
||||
@@ -307,48 +329,138 @@ class ProductionCapacity(Base):
|
||||
}
|
||||
|
||||
|
||||
class ProcessStage(str, enum.Enum):
|
||||
"""Production process stages where quality checks can occur"""
|
||||
MIXING = "mixing"
|
||||
PROOFING = "proofing"
|
||||
SHAPING = "shaping"
|
||||
BAKING = "baking"
|
||||
COOLING = "cooling"
|
||||
PACKAGING = "packaging"
|
||||
FINISHING = "finishing"
|
||||
|
||||
|
||||
class QualityCheckTemplate(Base):
|
||||
"""Quality check templates for tenant-specific quality standards"""
|
||||
__tablename__ = "quality_check_templates"
|
||||
|
||||
# Primary identification
|
||||
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||
tenant_id = Column(UUID(as_uuid=True), nullable=False, index=True)
|
||||
|
||||
# Template identification
|
||||
name = Column(String(255), nullable=False)
|
||||
template_code = Column(String(100), nullable=True, index=True)
|
||||
check_type = Column(String(50), nullable=False) # visual, measurement, temperature, weight, boolean
|
||||
category = Column(String(100), nullable=True) # appearance, structure, texture, etc.
|
||||
|
||||
# Template configuration
|
||||
description = Column(Text, nullable=True)
|
||||
instructions = Column(Text, nullable=True)
|
||||
parameters = Column(JSON, nullable=True) # Dynamic check parameters
|
||||
thresholds = Column(JSON, nullable=True) # Pass/fail criteria
|
||||
scoring_criteria = Column(JSON, nullable=True) # Scoring methodology
|
||||
|
||||
# Configurability settings
|
||||
is_active = Column(Boolean, default=True)
|
||||
is_required = Column(Boolean, default=False)
|
||||
is_critical = Column(Boolean, default=False) # Critical failures block production
|
||||
weight = Column(Float, default=1.0) # Weight in overall quality score
|
||||
|
||||
# Measurement specifications
|
||||
min_value = Column(Float, nullable=True)
|
||||
max_value = Column(Float, nullable=True)
|
||||
target_value = Column(Float, nullable=True)
|
||||
unit = Column(String(20), nullable=True)
|
||||
tolerance_percentage = Column(Float, nullable=True)
|
||||
|
||||
# Process stage applicability
|
||||
applicable_stages = Column(JSON, nullable=True) # List of ProcessStage values
|
||||
|
||||
# Metadata
|
||||
created_by = Column(UUID(as_uuid=True), nullable=False)
|
||||
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
||||
updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
"""Convert to dictionary following shared pattern"""
|
||||
return {
|
||||
"id": str(self.id),
|
||||
"tenant_id": str(self.tenant_id),
|
||||
"name": self.name,
|
||||
"template_code": self.template_code,
|
||||
"check_type": self.check_type,
|
||||
"category": self.category,
|
||||
"description": self.description,
|
||||
"instructions": self.instructions,
|
||||
"parameters": self.parameters,
|
||||
"thresholds": self.thresholds,
|
||||
"scoring_criteria": self.scoring_criteria,
|
||||
"is_active": self.is_active,
|
||||
"is_required": self.is_required,
|
||||
"is_critical": self.is_critical,
|
||||
"weight": self.weight,
|
||||
"min_value": self.min_value,
|
||||
"max_value": self.max_value,
|
||||
"target_value": self.target_value,
|
||||
"unit": self.unit,
|
||||
"tolerance_percentage": self.tolerance_percentage,
|
||||
"applicable_stages": self.applicable_stages,
|
||||
"created_by": str(self.created_by),
|
||||
"created_at": self.created_at.isoformat() if self.created_at else None,
|
||||
"updated_at": self.updated_at.isoformat() if self.updated_at else None,
|
||||
}
|
||||
|
||||
|
||||
class QualityCheck(Base):
|
||||
"""Quality check model for tracking production quality metrics"""
|
||||
"""Quality check model for tracking production quality metrics with stage support"""
|
||||
__tablename__ = "quality_checks"
|
||||
|
||||
|
||||
# Primary identification
|
||||
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||
tenant_id = Column(UUID(as_uuid=True), nullable=False, index=True)
|
||||
batch_id = Column(UUID(as_uuid=True), nullable=False, index=True) # FK to ProductionBatch
|
||||
|
||||
template_id = Column(UUID(as_uuid=True), nullable=True, index=True) # FK to QualityCheckTemplate
|
||||
|
||||
# Check information
|
||||
check_type = Column(String(50), nullable=False) # visual, weight, temperature, etc.
|
||||
process_stage = Column(SQLEnum(ProcessStage), nullable=True, index=True) # Stage when check was performed
|
||||
check_time = Column(DateTime(timezone=True), nullable=False)
|
||||
checker_id = Column(String(100), nullable=True) # Staff member who performed check
|
||||
|
||||
|
||||
# Quality metrics
|
||||
quality_score = Column(Float, nullable=False) # 1-10 scale
|
||||
pass_fail = Column(Boolean, nullable=False)
|
||||
defect_count = Column(Integer, nullable=False, default=0)
|
||||
defect_types = Column(JSON, nullable=True) # List of defect categories
|
||||
|
||||
|
||||
# Measurements
|
||||
measured_weight = Column(Float, nullable=True)
|
||||
measured_temperature = Column(Float, nullable=True)
|
||||
measured_moisture = Column(Float, nullable=True)
|
||||
measured_dimensions = Column(JSON, nullable=True)
|
||||
|
||||
stage_specific_data = Column(JSON, nullable=True) # Stage-specific measurements
|
||||
|
||||
# Standards comparison
|
||||
target_weight = Column(Float, nullable=True)
|
||||
target_temperature = Column(Float, nullable=True)
|
||||
target_moisture = Column(Float, nullable=True)
|
||||
tolerance_percentage = Column(Float, nullable=True)
|
||||
|
||||
|
||||
# Results
|
||||
within_tolerance = Column(Boolean, nullable=True)
|
||||
corrective_action_needed = Column(Boolean, default=False)
|
||||
corrective_actions = Column(JSON, nullable=True)
|
||||
|
||||
|
||||
# Template-based results
|
||||
template_results = Column(JSON, nullable=True) # Results from template-based checks
|
||||
criteria_scores = Column(JSON, nullable=True) # Individual criteria scores
|
||||
|
||||
# Notes and documentation
|
||||
check_notes = Column(Text, nullable=True)
|
||||
photos_urls = Column(JSON, nullable=True) # URLs to quality check photos
|
||||
certificate_url = Column(String(500), nullable=True)
|
||||
|
||||
|
||||
# Timestamps
|
||||
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
||||
updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())
|
||||
@@ -385,3 +497,81 @@ class QualityCheck(Base):
|
||||
}
|
||||
|
||||
|
||||
class Equipment(Base):
|
||||
"""Equipment model for tracking production equipment"""
|
||||
__tablename__ = "equipment"
|
||||
|
||||
# Primary identification
|
||||
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||
tenant_id = Column(UUID(as_uuid=True), nullable=False, index=True)
|
||||
|
||||
# Equipment identification
|
||||
name = Column(String(255), nullable=False)
|
||||
type = Column(SQLEnum(EquipmentType), nullable=False)
|
||||
model = Column(String(100), nullable=True)
|
||||
serial_number = Column(String(100), nullable=True)
|
||||
location = Column(String(255), nullable=True)
|
||||
|
||||
# Status tracking
|
||||
status = Column(SQLEnum(EquipmentStatus), nullable=False, default=EquipmentStatus.OPERATIONAL)
|
||||
|
||||
# Dates
|
||||
install_date = Column(DateTime(timezone=True), nullable=True)
|
||||
last_maintenance_date = Column(DateTime(timezone=True), nullable=True)
|
||||
next_maintenance_date = Column(DateTime(timezone=True), nullable=True)
|
||||
maintenance_interval_days = Column(Integer, nullable=True) # Maintenance interval in days
|
||||
|
||||
# Performance metrics
|
||||
efficiency_percentage = Column(Float, nullable=True) # Current efficiency
|
||||
uptime_percentage = Column(Float, nullable=True) # Overall equipment effectiveness
|
||||
energy_usage_kwh = Column(Float, nullable=True) # Current energy usage
|
||||
|
||||
# Specifications
|
||||
power_kw = Column(Float, nullable=True) # Power in kilowatts
|
||||
capacity = Column(Float, nullable=True) # Capacity (units depend on equipment type)
|
||||
weight_kg = Column(Float, nullable=True) # Weight in kilograms
|
||||
|
||||
# Temperature monitoring
|
||||
current_temperature = Column(Float, nullable=True) # Current temperature reading
|
||||
target_temperature = Column(Float, nullable=True) # Target temperature
|
||||
|
||||
# Status
|
||||
is_active = Column(Boolean, default=True)
|
||||
|
||||
# Notes
|
||||
notes = Column(Text, nullable=True)
|
||||
|
||||
# Timestamps
|
||||
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
||||
updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
"""Convert to dictionary following shared pattern"""
|
||||
return {
|
||||
"id": str(self.id),
|
||||
"tenant_id": str(self.tenant_id),
|
||||
"name": self.name,
|
||||
"type": self.type.value if self.type else None,
|
||||
"model": self.model,
|
||||
"serial_number": self.serial_number,
|
||||
"location": self.location,
|
||||
"status": self.status.value if self.status else None,
|
||||
"install_date": self.install_date.isoformat() if self.install_date else None,
|
||||
"last_maintenance_date": self.last_maintenance_date.isoformat() if self.last_maintenance_date else None,
|
||||
"next_maintenance_date": self.next_maintenance_date.isoformat() if self.next_maintenance_date else None,
|
||||
"maintenance_interval_days": self.maintenance_interval_days,
|
||||
"efficiency_percentage": self.efficiency_percentage,
|
||||
"uptime_percentage": self.uptime_percentage,
|
||||
"energy_usage_kwh": self.energy_usage_kwh,
|
||||
"power_kw": self.power_kw,
|
||||
"capacity": self.capacity,
|
||||
"weight_kg": self.weight_kg,
|
||||
"current_temperature": self.current_temperature,
|
||||
"target_temperature": self.target_temperature,
|
||||
"is_active": self.is_active,
|
||||
"notes": self.notes,
|
||||
"created_at": self.created_at.isoformat() if self.created_at else None,
|
||||
"updated_at": self.updated_at.isoformat() if self.updated_at else None,
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user