demo seed change 7
This commit is contained in:
@@ -1858,6 +1858,124 @@ class ProductionService:
|
||||
)
|
||||
raise
|
||||
|
||||
async def get_ai_waste_impact(
|
||||
self,
|
||||
tenant_id: UUID,
|
||||
start_date: datetime,
|
||||
end_date: datetime
|
||||
) -> Dict[str, Any]:
|
||||
"""
|
||||
Get AI impact on waste reduction
|
||||
|
||||
Compares waste rates between AI-assisted and manual batches
|
||||
to demonstrate ROI of AI features for sustainability.
|
||||
"""
|
||||
try:
|
||||
async with self.database_manager.get_session() as session:
|
||||
from app.repositories.production_batch_repository import ProductionBatchRepository
|
||||
from sqlalchemy import text
|
||||
|
||||
batch_repo = ProductionBatchRepository(session)
|
||||
|
||||
# Query for AI vs manual batch comparison
|
||||
query = text("""
|
||||
SELECT
|
||||
-- AI-assisted batches
|
||||
COUNT(CASE WHEN is_ai_assisted = true THEN 1 END) as ai_batches,
|
||||
COALESCE(SUM(CASE WHEN is_ai_assisted = true THEN planned_quantity ELSE 0 END), 0) as ai_planned,
|
||||
COALESCE(SUM(CASE WHEN is_ai_assisted = true THEN actual_quantity ELSE 0 END), 0) as ai_actual,
|
||||
COALESCE(SUM(CASE WHEN is_ai_assisted = true THEN waste_quantity ELSE 0 END), 0) as ai_waste,
|
||||
COALESCE(SUM(CASE WHEN is_ai_assisted = true THEN defect_quantity ELSE 0 END), 0) as ai_defects,
|
||||
|
||||
-- Manual batches
|
||||
COUNT(CASE WHEN is_ai_assisted = false THEN 1 END) as manual_batches,
|
||||
COALESCE(SUM(CASE WHEN is_ai_assisted = false THEN planned_quantity ELSE 0 END), 0) as manual_planned,
|
||||
COALESCE(SUM(CASE WHEN is_ai_assisted = false THEN actual_quantity ELSE 0 END), 0) as manual_actual,
|
||||
COALESCE(SUM(CASE WHEN is_ai_assisted = false THEN waste_quantity ELSE 0 END), 0) as manual_waste,
|
||||
COALESCE(SUM(CASE WHEN is_ai_assisted = false THEN defect_quantity ELSE 0 END), 0) as manual_defects
|
||||
FROM production_batches
|
||||
WHERE tenant_id = :tenant_id
|
||||
AND created_at BETWEEN :start_date AND :end_date
|
||||
AND status IN ('COMPLETED', 'QUALITY_CHECK')
|
||||
""")
|
||||
|
||||
result = await session.execute(
|
||||
query,
|
||||
{
|
||||
'tenant_id': tenant_id,
|
||||
'start_date': start_date,
|
||||
'end_date': end_date
|
||||
}
|
||||
)
|
||||
row = result.fetchone()
|
||||
|
||||
# Calculate waste percentages
|
||||
ai_total_waste = float(row.ai_waste or 0) + float(row.ai_defects or 0)
|
||||
manual_total_waste = float(row.manual_waste or 0) + float(row.manual_defects or 0)
|
||||
|
||||
ai_waste_pct = (ai_total_waste / float(row.ai_planned)) * 100 if row.ai_planned > 0 else 0
|
||||
manual_waste_pct = (manual_total_waste / float(row.manual_planned)) * 100 if row.manual_planned > 0 else 0
|
||||
|
||||
# Calculate reduction
|
||||
waste_reduction_pct = 0
|
||||
if manual_waste_pct > 0:
|
||||
waste_reduction_pct = ((manual_waste_pct - ai_waste_pct) / manual_waste_pct) * 100
|
||||
|
||||
# Calculate waste avoided
|
||||
if manual_waste_pct > 0 and row.ai_planned > 0:
|
||||
waste_avoided_kg = (float(row.ai_planned) * (manual_waste_pct / 100)) - ai_total_waste
|
||||
else:
|
||||
waste_avoided_kg = 0
|
||||
|
||||
# Financial impact (€3.50/kg average waste cost)
|
||||
waste_cost_avoided = waste_avoided_kg * 3.50
|
||||
|
||||
ai_impact_data = {
|
||||
'ai_batches': {
|
||||
'count': int(row.ai_batches or 0),
|
||||
'production_kg': float(row.ai_planned or 0),
|
||||
'waste_kg': ai_total_waste,
|
||||
'waste_percentage': round(ai_waste_pct, 2)
|
||||
},
|
||||
'manual_batches': {
|
||||
'count': int(row.manual_batches or 0),
|
||||
'production_kg': float(row.manual_planned or 0),
|
||||
'waste_kg': manual_total_waste,
|
||||
'waste_percentage': round(manual_waste_pct, 2)
|
||||
},
|
||||
'impact': {
|
||||
'waste_reduction_percentage': round(waste_reduction_pct, 1),
|
||||
'waste_avoided_kg': round(waste_avoided_kg, 2),
|
||||
'cost_savings_eur': round(waste_cost_avoided, 2),
|
||||
'annual_projection_eur': round(waste_cost_avoided * 12, 2)
|
||||
},
|
||||
'adoption': {
|
||||
'ai_adoption_rate': round((int(row.ai_batches or 0) / (int(row.ai_batches or 0) + int(row.manual_batches or 1))) * 100, 1),
|
||||
'recommendation': 'increase_ai_usage' if waste_reduction_pct > 10 else 'monitor'
|
||||
},
|
||||
'period': {
|
||||
'start_date': start_date.isoformat(),
|
||||
'end_date': end_date.isoformat()
|
||||
}
|
||||
}
|
||||
|
||||
logger.info(
|
||||
"AI waste impact calculated",
|
||||
tenant_id=str(tenant_id),
|
||||
waste_reduction_pct=waste_reduction_pct,
|
||||
waste_avoided_kg=waste_avoided_kg
|
||||
)
|
||||
|
||||
return ai_impact_data
|
||||
|
||||
except Exception as e:
|
||||
logger.error(
|
||||
"Error calculating AI waste impact",
|
||||
tenant_id=str(tenant_id),
|
||||
error=str(e)
|
||||
)
|
||||
raise
|
||||
|
||||
# ================================================================
|
||||
# NEW: ORCHESTRATOR INTEGRATION
|
||||
# ================================================================
|
||||
|
||||
Reference in New Issue
Block a user