Improve the frontend and fix TODOs

This commit is contained in:
Urtzi Alfaro
2025-10-24 13:05:04 +02:00
parent 07c33fa578
commit 61376b7a9f
100 changed files with 8284 additions and 3419 deletions

View File

@@ -4,7 +4,7 @@ Main business logic for production operations
"""
from typing import Optional, List, Dict, Any
from datetime import datetime, date, timedelta
from datetime import datetime, date, timedelta, timezone
from uuid import UUID
import structlog
@@ -369,12 +369,46 @@ class ProductionService:
str(tenant_id), week_ago, today
)
# Calculate capacity utilization from actual data
from app.models.production import QualityCheck
from sqlalchemy import select, func, and_
# Calculate capacity utilization: (Total planned quantity / Total capacity) * 100
# Assuming 8-hour workday with standard capacity per hour
STANDARD_HOURLY_CAPACITY = 100 # units per hour (configurable)
WORKING_HOURS_PER_DAY = 8
total_daily_capacity = STANDARD_HOURLY_CAPACITY * WORKING_HOURS_PER_DAY
total_planned_today = sum(b.planned_quantity or 0 for b in todays_batches)
capacity_utilization = min((total_planned_today / total_daily_capacity * 100) if total_daily_capacity > 0 else 0, 100)
# Calculate average quality score from quality checks
quality_query = select(func.avg(QualityCheck.quality_score)).where(
and_(
QualityCheck.tenant_id == tenant_id,
QualityCheck.check_time >= datetime.now(timezone.utc).replace(hour=0, minute=0, second=0, microsecond=0)
)
)
quality_result = await batch_repo.session.execute(quality_query)
average_quality_score = quality_result.scalar() or 0.0
# If no checks today, use recent average (last 7 days)
if average_quality_score == 0:
recent_quality_query = select(func.avg(QualityCheck.quality_score)).where(
and_(
QualityCheck.tenant_id == tenant_id,
QualityCheck.check_time >= datetime.now(timezone.utc) - timedelta(days=7)
)
)
recent_quality_result = await batch_repo.session.execute(recent_quality_query)
average_quality_score = recent_quality_result.scalar() or 8.5 # Default fallback
return ProductionDashboardSummary(
active_batches=len(active_batches),
todays_production_plan=todays_plan,
capacity_utilization=85.0, # TODO: Calculate from actual capacity data
capacity_utilization=round(capacity_utilization, 1),
on_time_completion_rate=weekly_metrics.get("on_time_completion_rate", 0),
average_quality_score=8.5, # TODO: Get from quality checks
average_quality_score=round(average_quality_score, 1),
total_output_today=sum(b.actual_quantity or 0 for b in todays_batches),
efficiency_percentage=weekly_metrics.get("average_yield_percentage", 0)
)

View File

@@ -241,12 +241,32 @@ class QualityTemplateService:
tenant_id=tenant_id)
return False
# TODO: Business Rule - Check if template is in use before deletion
# For now, allow deletion. In production you might want to:
# 1. Soft delete by setting is_active = False
# 2. Check for dependent quality checks
# 3. Prevent deletion if actively used
# Business Rule: Check if template is in use before deletion
# Check for quality checks using this template
from app.models.production import QualityCheck
from sqlalchemy import select, func
usage_query = select(func.count(QualityCheck.id)).where(
QualityCheck.template_id == template_id
)
usage_result = await self.repository.session.execute(usage_query)
usage_count = usage_result.scalar() or 0
if usage_count > 0:
logger.warning("Cannot delete template in use",
template_id=str(template_id),
tenant_id=tenant_id,
usage_count=usage_count)
# Instead of deleting, soft delete by setting is_active = False
template.is_active = False
await self.repository.session.commit()
logger.info("Quality template soft deleted (set to inactive)",
template_id=str(template_id),
tenant_id=tenant_id,
usage_count=usage_count)
return True
# Template is not in use, safe to delete
success = await self.repository.delete(template_id)
if success: