diff --git a/frontend/src/components/dashboard/UnifiedActionQueueCard.tsx b/frontend/src/components/dashboard/UnifiedActionQueueCard.tsx index f9b9cfc3..90c07ebe 100644 --- a/frontend/src/components/dashboard/UnifiedActionQueueCard.tsx +++ b/frontend/src/components/dashboard/UnifiedActionQueueCard.tsx @@ -110,6 +110,71 @@ function EscalationBadge({ alert }: { alert: EnrichedAlert }) { ); } +/** + * Map action type to i18n translation key with extracted parameters + */ +function getActionLabelKey(actionType: string, metadata?: Record): { key: string; params: Record } { + const actionTypeMap: Record) => Record }> = { + 'approve_po': { + key: 'alerts:actions.approve_po', + extractParams: (meta) => ({ amount: meta.amount || meta.po_amount || 0 }) + }, + 'reject_po': { + key: 'alerts:actions.reject_po', + extractParams: () => ({}) + }, + 'call_supplier': { + key: 'alerts:actions.call_supplier', + extractParams: (meta) => ({ supplier: meta.supplier || meta.name || 'Supplier', phone: meta.phone || '' }) + }, + 'open_reasoning': { + key: 'alerts:actions.see_reasoning', + extractParams: () => ({}) + }, + 'complete_stock_receipt': { + key: 'alerts:actions.complete_receipt', + extractParams: () => ({}) + }, + 'mark_delivery_received': { + key: 'alerts:actions.mark_received', + extractParams: () => ({}) + }, + 'adjust_production': { + key: 'alerts:actions.adjust_production', + extractParams: () => ({}) + }, + 'navigate': { + key: 'alerts:actions.navigate', + extractParams: () => ({}) + }, + 'notify_customer': { + key: 'alerts:actions.notify_customer', + extractParams: (meta) => ({ customer: meta.customer_name || meta.customer || 'Customer' }) + }, + 'snooze': { + key: 'alerts:actions.snooze', + extractParams: (meta) => ({ hours: meta.duration_hours || meta.hours || 4 }) + }, + 'dismiss': { + key: 'alerts:actions.dismiss', + extractParams: () => ({}) + }, + 'mark_read': { + key: 'alerts:actions.mark_read', + extractParams: () => ({}) + }, + 'cancel_auto_action': { + key: 'alerts:actions.cancel_auto_action', + extractParams: () => ({}) + }, + }; + + const config = actionTypeMap[actionType] || { key: 'alerts:actions.navigate', extractParams: () => ({}) }; + const params = config.extractParams ? config.extractParams(metadata || {}) : {}; + + return { key: config.key, params }; +} + function ActionCard({ alert, showEscalationBadge = false, onActionSuccess, onActionError }: ActionCardProps) { const [expanded, setExpanded] = useState(false); const [loadingAction, setLoadingAction] = useState(null); @@ -305,7 +370,10 @@ function ActionCard({ alert, showEscalationBadge = false, onActionSuccess, onAct }} className={`${isPrimary ? 'font-semibold' : ''} sm:w-auto w-full`} > - {action.label} + {(() => { + const { key, params } = getActionLabelKey(action.type, action.metadata); + return String(t(key, params)); + })()} {action.estimated_time_minutes && !isLoading && ( ({action.estimated_time_minutes}m) )} diff --git a/frontend/src/locales/en/alerts.json b/frontend/src/locales/en/alerts.json new file mode 100644 index 00000000..b2c04867 --- /dev/null +++ b/frontend/src/locales/en/alerts.json @@ -0,0 +1,299 @@ +{ + "priority": { + "critical": "Critical", + "important": "Important", + "standard": "Standard", + "info": "Info" + }, + "type_class": { + "action_needed": "Action Needed", + "prevented_issue": "Issue Prevented", + "trend_warning": "Trend Warning", + "escalation": "Escalation", + "information": "Information" + }, + "context": { + "already_addressed": "AI already handled this", + "financial_impact": "€{amount} at risk", + "time_until": "Needs decision in {time}", + "can_user_fix": "You can fix this", + "requires_supplier": "Requires {supplier}", + "prevented_savings": "Saved €{amount}", + "grouped_count": "{count} grouped" + }, + "actions": { + "approve_po": "Approve €{amount} order", + "reject_po": "Reject order", + "call_supplier": "Call {supplier} ({phone})", + "see_reasoning": "See full reasoning", + "complete_receipt": "Complete stock receipt", + "mark_received": "Mark as received", + "adjust_production": "Adjust production schedule", + "snooze": "Snooze {hours}h", + "mark_read": "Mark as read", + "dismiss": "Dismiss", + "navigate": "View details", + "notify_customer": "Notify {customer}", + "cancel_auto_action": "Cancel auto-action" + }, + "orchestration": { + "reasoning_title": "🤖 Daily Orchestrator Reasoning", + "analyzed_title": "This morning, I analyzed:", + "actions_taken": "So I scheduled:", + "prevented_issues": "✅ Issues Prevented", + "estimated_impact": "Estimated Impact", + "impact_description": "Savings from prevented rush orders, stockouts, and waste", + "last_run": "Last run", + "what_ai_did": "What AI did for you" + }, + "metrics": { + "hours": "{count, plural, =1 {# hour} other {# hours}}", + "minutes": "{count, plural, =1 {# minute} other {# minutes}}", + "days": "{count, plural, =1 {# day} other {# days}}" + }, + "escalated": "Escalated", + "action_success": "Action completed successfully", + "action_error": "Action failed. Please try again.", + "hub": { + "tab_list_label": "Alert categories", + "tabs": { + "all": "All Alerts", + "all_description": "Every alert for your bakery", + "for_me": "For Me", + "for_me_description": "Alerts assigned to you or requiring your action", + "archived": "Archived", + "archived_description": "Resolved and dismissed alerts" + }, + "toggle_filters": "Toggle filters", + "filters": "Filters", + "active": "Active" + }, + "auto_action": { + "title": "Auto-action Pending", + "remaining": "remaining", + "financial_impact": "Impact:", + "cancel_button": "Cancel Auto-action", + "cancelling": "Cancelling...", + "cancelled_title": "Auto-action Cancelled", + "cancelled_message": "The automatic action has been prevented. You can now handle this manually.", + "completed_title": "Auto-action Executed", + "help_text": "AI will automatically execute this action when the timer expires. Click \"Cancel\" to prevent it and handle manually.", + "urgency": { + "critical": "URGENT", + "warning": "SOON", + "info": "SCHEDULED" + } + }, + "priority_explainer": { + "title": "Understanding Priority Scores", + "subtitle": "How AI calculates what needs your attention first", + "overview": { + "title": "The Priority Score (0-100)", + "description": "Every alert receives a priority score from 0-100 based on four weighted components. This helps you focus on what truly matters for your bakery." + }, + "example_alert": "Example Alert Priority", + "level": { + "critical": "CRITICAL", + "important": "IMPORTANT", + "standard": "STANDARD", + "info": "INFO" + }, + "components_title": "Score Components", + "weight": "weight", + "business_impact": { + "name": "Business Impact", + "description": "Financial consequences, affected orders, customer satisfaction", + "example1": "€500 in potential revenue at risk", + "example2": "10 customer orders affected", + "example3": "High customer satisfaction impact" + }, + "urgency": { + "name": "Urgency", + "description": "Time sensitivity, deadlines, escalation potential", + "example1": "Deadline in 2 hours", + "example2": "Stockout imminent (4 hours)", + "example3": "Production window closing soon" + }, + "agency": { + "name": "User Agency", + "description": "Can you take action? Do you have control over the outcome?", + "example1": "Requires approval from you", + "example2": "One-click action available", + "example3": "Decision needed within your authority" + }, + "confidence": { + "name": "AI Confidence", + "description": "How certain is the AI about this alert's validity?", + "example1": "Based on historical patterns (95% match)", + "example2": "Data quality: High", + "example3": "Prediction accuracy validated" + }, + "formula_title": "The Formula", + "footer": "This scoring helps AI prioritize alerts, ensuring you see the most important issues first.", + "got_it": "Got it!" + }, + "trend": { + "near_threshold": "Near threshold" + }, + "action_preview": { + "title": "Action Preview", + "outcome": "What will happen", + "financial_impact": "Financial Impact", + "affected_systems": "Affected Systems", + "reversible": "This action can be undone", + "not_reversible": "This action cannot be undone", + "confidence": "AI Confidence: {{confidence}}%", + "cancel": "Cancel", + "confirm": "Confirm Action" + }, + "response_time": { + "title": "Response Time Performance", + "subtitle": "How quickly you respond to alerts", + "on_time": "On Time", + "alerts": "alerts", + "average": "Average", + "target": "Target", + "on_time_responses": "On-Time Responses", + "needs_improvement": "Needs improvement", + "benchmark_title": "Performance Perspective", + "excellent": "Excellent! You're responding faster than 80% of bakeries. Keep it up!", + "good": "Good job! Try responding to critical alerts within target time to improve further.", + "needs_work": "Faster responses to critical alerts can prevent issues and save money. Try meeting target times.", + "tip": "Tip: Enable mobile notifications to respond faster to critical alerts" + }, + "alerts": { + "critical_stock_shortage": { + "title": "🚨 Critical Stock: {{ingredient_name}}", + "message_with_po_pending": "Only {{current_stock}}kg of {{ingredient_name}} (need {{required_stock}}kg). Already created {{po_id}} for delivery on {{delivery_day_name}}. Please approve €{{po_amount}}.", + "message_with_po_created": "Only {{current_stock}}kg of {{ingredient_name}} (need {{required_stock}}kg). Already created {{po_id}}. Review and approve €{{po_amount}}.", + "message_with_hours": "Only {{current_stock}}kg of {{ingredient_name}} available (need {{required_stock}}kg in {{hours_until}} hours).", + "message_with_date": "Only {{current_stock}}kg of {{ingredient_name}} available (need {{required_stock}}kg for production on {{production_day_name}}).", + "message_generic": "Only {{current_stock}}kg of {{ingredient_name}} available (need {{required_stock}}kg)." + }, + "low_stock": { + "title": "⚠️ Low Stock: {{ingredient_name}}", + "message_with_po": "{{ingredient_name}} stock: {{current_stock}}kg (minimum: {{minimum_stock}}kg). Already scheduled PO for replenishment.", + "message_generic": "{{ingredient_name}} stock: {{current_stock}}kg (minimum: {{minimum_stock}}kg). Consider placing an order." + }, + "stock_depleted": { + "title": "📦 Stock Depleted by Order", + "message_with_supplier": "Order #{{order_id}} requires {{ingredient_name}} but it's depleted. Contact {{supplier_name}} ({{supplier_phone}}).", + "message_generic": "Order #{{order_id}} requires {{ingredient_name}} but it's depleted. Immediate action required." + }, + "ingredient_shortage": { + "title": "⚠️ Ingredient Shortage in Production", + "message_with_customers": "{{ingredient_name}} insufficient for batches in progress. {{affected_orders}} orders affected ({{customer_names}}). Current stock: {{current_stock}}kg, required: {{required_stock}}kg.", + "message_generic": "{{ingredient_name}} insufficient for batches in progress. Current stock: {{current_stock}}kg, required: {{required_stock}}kg." + }, + "expired_products": { + "title": "🚫 Expired or Expiring Products", + "message_with_names": "{{count}} products expiring: {{product_names}}. Total value: €{{total_value}}.", + "message_generic": "{{count}} products expiring. Total value: €{{total_value}}." + }, + "production_delay": { + "title": "⏰ Production Delay: {{batch_name}}", + "message_with_customers": "Batch {{batch_name}} delayed {{delay_minutes}} minutes. Affected customers: {{customer_names}}. Original delivery time: {{scheduled_time}}.", + "message_with_orders": "Batch {{batch_name}} delayed {{delay_minutes}} minutes. {{affected_orders}} orders affected. Original delivery time: {{scheduled_time}}.", + "message_generic": "Batch {{batch_name}} delayed {{delay_minutes}} minutes. Original delivery time: {{scheduled_time}}." + }, + "equipment_failure": { + "title": "🔧 Equipment Failure: {{equipment_name}}", + "message_with_batches": "{{equipment_name}} failed. {{affected_batches}} batches in production affected ({{batch_names}}).", + "message_generic": "{{equipment_name}} failed. Requires immediate repair." + }, + "maintenance_required": { + "title": "🔧 Maintenance Required: {{equipment_name}}", + "message_with_hours": "{{equipment_name}} requires maintenance in {{hours_until}} hours. Schedule now to prevent disruptions.", + "message_with_days": "{{equipment_name}} requires maintenance in {{days_until}} days. Schedule before {{maintenance_date}}." + }, + "low_equipment_efficiency": { + "title": "📉 Low Efficiency: {{equipment_name}}", + "message": "{{equipment_name}} operating at {{efficiency_percent}}% efficiency (expected: >{{threshold_percent}}%). Consider maintenance." + }, + "order_overload": { + "title": "📊 Order Overload", + "message_with_orders": "Capacity overloaded by {{overload_percent}}%. {{total_orders}} orders scheduled, capacity: {{capacity_orders}}. Consider adjusting schedule.", + "message_generic": "Capacity overloaded by {{overload_percent}}%. Consider adjusting production schedule." + }, + "supplier_delay": { + "title": "🚚 Supplier Delay: {{supplier_name}}", + "message": "{{supplier_name}} delayed delivery of {{ingredient_name}} (PO: {{po_id}}). New date: {{new_delivery_date}}. Original: {{original_delivery_date}}." + }, + "temperature_breach": { + "title": "🌡️ Temperature Breach", + "message": "Temperature {{location}}: {{current_temp}}°C (range: {{min_temp}}°C-{{max_temp}}°C). Duration: {{duration_minutes}} minutes." + }, + "demand_surge_weekend": { + "title": "📈 Demand Surge: Weekend", + "message": "Expected demand {{surge_percent}}% higher for {{weekend_date}}. Affected products: {{products}}. Consider increasing production." + }, + "weather_impact_alert": { + "title": "🌦️ Expected Weather Impact", + "message": "{{weather_condition}} expected {{date}}. Demand impact: {{impact_percent}}%. Affected products: {{products}}." + }, + "holiday_preparation": { + "title": "🎉 Holiday Preparation: {{holiday_name}}", + "message": "{{holiday_name}} in {{days_until}} days ({{holiday_date}}). Expected demand {{expected_increase}}% higher. Key products: {{products}}." + }, + "severe_weather_impact": { + "title": "⛈️ Severe Weather Impact", + "message": "Severe {{weather_condition}} expected {{date}}. Demand impact: {{impact_percent}}%. Consider adjusting delivery schedules." + }, + "unexpected_demand_spike": { + "title": "📊 Unexpected Demand Spike", + "message": "Demand increased {{spike_percent}}% for {{products}}. Current stock may run out in {{hours_until_stockout}} hours." + }, + "demand_pattern_optimization": { + "title": "💡 Demand Pattern Optimization", + "message": "Pattern detected: {{pattern_description}}. Recommend adjusting production of {{products}} to optimize efficiency." + }, + "inventory_optimization": { + "title": "📦 Inventory Optimization", + "message": "{{ingredient_name}} consistently over-stocked by {{excess_percent}}%. Recommend reducing order to {{recommended_amount}}kg." + }, + "production_efficiency": { + "title": "⚡ Production Efficiency Opportunity", + "message": "{{product_name}} more efficient at {{suggested_time}}. Production time {{time_saved}} minutes shorter ({{savings_percent}}% savings)." + }, + "sales_opportunity": { + "title": "💰 Sales Opportunity", + "message": "High demand for {{products}} detected. Consider additional production. Potential revenue: €{{potential_revenue}}." + }, + "seasonal_adjustment": { + "title": "🍂 Seasonal Adjustment Recommended", + "message": "{{season}} season approaching. Adjust production of {{products}} based on historical trends ({{adjustment_percent}}% {{adjustment_direction}})." + }, + "cost_reduction": { + "title": "💵 Cost Reduction Opportunity", + "message": "Switching to {{alternative_ingredient}} can save €{{savings_amount}}/month. Similar quality, lower cost." + }, + "waste_reduction": { + "title": "♻️ Waste Reduction Opportunity", + "message": "{{product_name}} waste high ({{waste_percent}}%). Recommend reducing batch to {{recommended_quantity}} units." + }, + "quality_improvement": { + "title": "⭐ Quality Improvement Recommended", + "message": "{{issue_description}} detected in {{product_name}}. Recommended action: {{recommended_action}}." + }, + "customer_satisfaction": { + "title": "😊 Customer Satisfaction Opportunity", + "message": "Customer {{customer_name}} consistently orders {{product_name}}. Consider special offer or loyalty program." + }, + "energy_optimization": { + "title": "⚡ Energy Optimization", + "message": "Energy usage for {{equipment_name}} peaks at {{peak_time}}. Shifting to {{off_peak_start}}-{{off_peak_end}} can save €{{savings_amount}}/month." + }, + "staff_optimization": { + "title": "👥 Staff Optimization", + "message": "{{shift_name}} over-staffed by {{excess_percent}}%. Consider adjusting staff levels to reduce labor costs." + }, + "po_approval_needed": { + "title": "Purchase Order #{{po_number}} requires approval", + "message": "Purchase order for {{supplier_name}} totaling {{currency}} {{total_amount}} is pending approval. Delivery required by {{required_delivery_date}}." + }, + "production_batch_start": { + "title": "Production Batch Ready: {{product_name}}", + "message": "Batch #{{batch_number}} ({{quantity_planned}} {{unit}} of {{product_name}}) is ready to start. Priority: {{priority}}." + } + } +} diff --git a/frontend/src/locales/es/alerts.json b/frontend/src/locales/es/alerts.json new file mode 100644 index 00000000..a0ed44d1 --- /dev/null +++ b/frontend/src/locales/es/alerts.json @@ -0,0 +1,297 @@ +{ + "priority": { + "critical": "Crítico", + "important": "Importante", + "standard": "Estándar", + "info": "Info" + }, + "type_class": { + "action_needed": "Acción Requerida", + "prevented_issue": "Problema Prevenido", + "trend_warning": "Aviso de Tendencia", + "escalation": "Escalación", + "information": "Información" + }, + "context": { + "already_addressed": "La IA ya gestionó esto", + "financial_impact": "€{amount} en riesgo", + "time_until": "Necesita decisión en {time}", + "can_user_fix": "Puedes solucionarlo", + "requires_supplier": "Requiere {supplier}", + "prevented_savings": "Ahorrado €{amount}", + "grouped_count": "{count} agrupadas" + }, + "actions": { + "approve_po": "Aprobar pedido €{amount}", + "reject_po": "Rechazar pedido", + "call_supplier": "Llamar a {supplier} ({phone})", + "see_reasoning": "Ver razonamiento completo", + "complete_receipt": "Completar recepción de stock", + "mark_received": "Marcar como recibido", + "adjust_production": "Ajustar calendario de producción", + "snooze": "Posponer {hours}h", + "mark_read": "Marcar como leído", + "dismiss": "Descartar", + "navigate": "Ver detalles", + "notify_customer": "Notificar a {customer}", + "cancel_auto_action": "Cancelar acción automática" + }, + "orchestration": { + "reasoning_title": "🤖 Razonamiento del Orquestador Diario", + "analyzed_title": "Esta mañana, analicé:", + "actions_taken": "Así que programé:", + "prevented_issues": "✅ Problemas Prevenidos", + "estimated_impact": "Impacto Estimado", + "impact_description": "Ahorros por prevención de pedidos urgentes, faltas de stock y desperdicios", + "last_run": "Última ejecución", + "what_ai_did": "Lo que hizo la IA por ti" + }, + "metrics": { + "hours": "{count, plural, =1 {# hora} other {# horas}}", + "minutes": "{count, plural, =1 {# minuto} other {# minutos}}", + "days": "{count, plural, =1 {# día} other {# días}}" + }, + "escalated": "Escalado", + "hub": { + "tab_list_label": "Categorías de alertas", + "tabs": { + "all": "Todas las Alertas", + "all_description": "Todas las alertas de tu panadería", + "for_me": "Para Mí", + "for_me_description": "Alertas asignadas a ti o que requieren tu acción", + "archived": "Archivadas", + "archived_description": "Alertas resueltas y descartadas" + }, + "toggle_filters": "Activar/desactivar filtros", + "filters": "Filtros", + "active": "Activos" + }, + "auto_action": { + "title": "Acción Automática Pendiente", + "remaining": "restante", + "financial_impact": "Impacto:", + "cancel_button": "Cancelar Acción Automática", + "cancelling": "Cancelando...", + "cancelled_title": "Acción Automática Cancelada", + "cancelled_message": "La acción automática ha sido prevenida. Ahora puedes gestionarlo manualmente.", + "completed_title": "Acción Automática Ejecutada", + "help_text": "La IA ejecutará automáticamente esta acción cuando expire el temporizador. Haz clic en \"Cancelar\" para prevenirlo y gestionarlo manualmente.", + "urgency": { + "critical": "URGENTE", + "warning": "PRONTO", + "info": "PROGRAMADO" + } + }, + "priority_explainer": { + "title": "Entendiendo las Puntuaciones de Prioridad", + "subtitle": "Cómo la IA calcula qué necesita tu atención primero", + "overview": { + "title": "La Puntuación de Prioridad (0-100)", + "description": "Cada alerta recibe una puntuación de prioridad de 0-100 basada en cuatro componentes ponderados. Esto te ayuda a enfocarte en lo que realmente importa para tu panadería." + }, + "example_alert": "Prioridad de Alerta de Ejemplo", + "level": { + "critical": "CRÍTICO", + "important": "IMPORTANTE", + "standard": "ESTÁNDAR", + "info": "INFO" + }, + "components_title": "Componentes de la Puntuación", + "weight": "peso", + "business_impact": { + "name": "Impacto Empresarial", + "description": "Consecuencias financieras, pedidos afectados, satisfacción del cliente", + "example1": "€500 en ingresos potenciales en riesgo", + "example2": "10 pedidos de clientes afectados", + "example3": "Alto impacto en la satisfacción del cliente" + }, + "urgency": { + "name": "Urgencia", + "description": "Sensibilidad temporal, plazos, potencial de escalada", + "example1": "Plazo en 2 horas", + "example2": "Falta de stock inminente (4 horas)", + "example3": "Ventana de producción cerrándose pronto" + }, + "agency": { + "name": "Capacidad de Acción del Usuario", + "description": "¿Puedes tomar acción? ¿Tienes control sobre el resultado?", + "example1": "Requiere tu aprobación", + "example2": "Acción con un clic disponible", + "example3": "Decisión necesaria dentro de tu autoridad" + }, + "confidence": { + "name": "Confianza de la IA", + "description": "¿Qué tan segura está la IA sobre la validez de esta alerta?", + "example1": "Basado en patrones históricos (95% coincidencia)", + "example2": "Calidad de datos: Alta", + "example3": "Precisión de predicción validada" + }, + "formula_title": "La Fórmula", + "footer": "Esta puntuación ayuda a la IA a priorizar alertas, asegurando que veas los problemas más importantes primero.", + "got_it": "¡Entendido!" + }, + "trend": { + "near_threshold": "Cerca del umbral" + }, + "action_preview": { + "title": "Vista Previa de Acción", + "outcome": "Qué sucederá", + "financial_impact": "Impacto Financiero", + "affected_systems": "Sistemas Afectados", + "reversible": "Esta acción se puede deshacer", + "not_reversible": "Esta acción no se puede deshacer", + "confidence": "Confianza de IA: {{confidence}}%", + "cancel": "Cancelar", + "confirm": "Confirmar Acción" + }, + "response_time": { + "title": "Rendimiento de Tiempo de Respuesta", + "subtitle": "Qué tan rápido respondes a las alertas", + "on_time": "A Tiempo", + "alerts": "alertas", + "average": "Promedio", + "target": "Objetivo", + "on_time_responses": "Respuestas a Tiempo", + "needs_improvement": "Necesita mejora", + "benchmark_title": "Perspectiva de Rendimiento", + "excellent": "¡Excelente! Estás respondiendo más rápido que el 80% de las panaderías. ¡Sigue así!", + "good": "¡Buen trabajo! Intenta responder a alertas críticas dentro del tiempo objetivo para mejorar aún más.", + "needs_work": "Respuestas más rápidas a alertas críticas pueden prevenir problemas y ahorrar dinero. Intenta cumplir los tiempos objetivo.", + "tip": "Consejo: Activa las notificaciones móviles para responder más rápido a alertas críticas" + }, + "alerts": { + "critical_stock_shortage": { + "title": "🚨 Stock Crítico: {{ingredient_name}}", + "message_with_po_pending": "Solo {{current_stock}}kg de {{ingredient_name}} (necesitas {{required_stock}}kg). Ya creé {{po_id}} para entrega el {{delivery_day_name}}. Por favor aprueba €{{po_amount}}.", + "message_with_po_created": "Solo {{current_stock}}kg de {{ingredient_name}} (necesitas {{required_stock}}kg). Ya creé {{po_id}}. Revisa y aprueba €{{po_amount}}.", + "message_with_hours": "Solo {{current_stock}}kg de {{ingredient_name}} disponibles (necesitas {{required_stock}}kg en {{hours_until}} horas).", + "message_with_date": "Solo {{current_stock}}kg de {{ingredient_name}} disponibles (necesitas {{required_stock}}kg para producción del {{production_day_name}}).", + "message_generic": "Solo {{current_stock}}kg de {{ingredient_name}} disponibles (necesitas {{required_stock}}kg)." + }, + "low_stock": { + "title": "⚠️ Stock Bajo: {{ingredient_name}}", + "message_with_po": "Stock de {{ingredient_name}}: {{current_stock}}kg (mínimo: {{minimum_stock}}kg). Ya programé PO para reposición.", + "message_generic": "Stock de {{ingredient_name}}: {{current_stock}}kg (mínimo: {{minimum_stock}}kg). Considera hacer un pedido." + }, + "stock_depleted": { + "title": "📦 Stock Agotado por Pedido", + "message_with_supplier": "Pedido #{{order_id}} requiere {{ingredient_name}} pero está agotado. Contacta a {{supplier_name}} ({{supplier_phone}}).", + "message_generic": "Pedido #{{order_id}} requiere {{ingredient_name}} pero está agotado. Acción inmediata requerida." + }, + "ingredient_shortage": { + "title": "⚠️ Falta de Ingrediente en Producción", + "message_with_customers": "{{ingredient_name}} insuficiente para lotes en curso. {{affected_orders}} pedidos afectados ({{customer_names}}). Stock actual: {{current_stock}}kg, necesario: {{required_stock}}kg.", + "message_generic": "{{ingredient_name}} insuficiente para lotes en curso. Stock actual: {{current_stock}}kg, necesario: {{required_stock}}kg." + }, + "expired_products": { + "title": "🚫 Productos Caducados o por Caducar", + "message_with_names": "{{count}} productos caducando: {{product_names}}. Valor total: €{{total_value}}.", + "message_generic": "{{count}} productos caducando. Valor total: €{{total_value}}." + }, + "production_delay": { + "title": "⏰ Retraso en Producción: {{batch_name}}", + "message_with_customers": "Lote {{batch_name}} retrasado {{delay_minutes}} minutos. Clientes afectados: {{customer_names}}. Hora entrega original: {{scheduled_time}}.", + "message_with_orders": "Lote {{batch_name}} retrasado {{delay_minutes}} minutos. {{affected_orders}} pedidos afectados. Hora entrega original: {{scheduled_time}}.", + "message_generic": "Lote {{batch_name}} retrasado {{delay_minutes}} minutos. Hora entrega original: {{scheduled_time}}." + }, + "equipment_failure": { + "title": "🔧 Fallo de Equipo: {{equipment_name}}", + "message_with_batches": "{{equipment_name}} falló. {{affected_batches}} lotes en producción afectados ({{batch_names}}).", + "message_generic": "{{equipment_name}} falló. Requiere reparación inmediata." + }, + "maintenance_required": { + "title": "🔧 Mantenimiento Requerido: {{equipment_name}}", + "message_with_hours": "{{equipment_name}} requiere mantenimiento en {{hours_until}} horas. Programa ahora para evitar interrupciones.", + "message_with_days": "{{equipment_name}} requiere mantenimiento en {{days_until}} días. Programa antes del {{maintenance_date}}." + }, + "low_equipment_efficiency": { + "title": "📉 Baja Eficiencia: {{equipment_name}}", + "message": "{{equipment_name}} operando a {{efficiency_percent}}% eficiencia (esperado: >{{threshold_percent}}%). Considera mantenimiento." + }, + "order_overload": { + "title": "📊 Sobrecarga de Pedidos", + "message_with_orders": "Capacidad sobrecargada en {{overload_percent}}%. {{total_orders}} pedidos programados, capacidad: {{capacity_orders}}. Considera ajustar el calendario.", + "message_generic": "Capacidad sobrecargada en {{overload_percent}}%. Considera ajustar el calendario de producción." + }, + "supplier_delay": { + "title": "🚚 Retraso de Proveedor: {{supplier_name}}", + "message": "{{supplier_name}} retrasó entrega de {{ingredient_name}} (PO: {{po_id}}). Nueva fecha: {{new_delivery_date}}. Original: {{original_delivery_date}}." + }, + "temperature_breach": { + "title": "🌡️ Violación de Temperatura", + "message": "Temperatura {{location}}: {{current_temp}}°C (rango: {{min_temp}}°C-{{max_temp}}°C). Duración: {{duration_minutes}} minutos." + }, + "demand_surge_weekend": { + "title": "📈 Aumento de Demanda: Fin de Semana", + "message": "Demanda esperada {{surge_percent}}% mayor para {{weekend_date}}. Productos afectados: {{products}}. Considera aumentar producción." + }, + "weather_impact_alert": { + "title": "🌦️ Impacto Climático Esperado", + "message": "{{weather_condition}} esperado {{date}}. Impacto en demanda: {{impact_percent}}%. Productos afectados: {{products}}." + }, + "holiday_preparation": { + "title": "🎉 Preparación para Festivo: {{holiday_name}}", + "message": "{{holiday_name}} en {{days_until}} días ({{holiday_date}}). Demanda esperada {{expected_increase}}% mayor. Productos clave: {{products}}." + }, + "severe_weather_impact": { + "title": "⛈️ Impacto Climático Severo", + "message": "{{weather_condition}} severo esperado {{date}}. Impacto en demanda: {{impact_percent}}%. Considera ajustar horarios de entrega." + }, + "unexpected_demand_spike": { + "title": "📊 Pico de Demanda Inesperado", + "message": "Demanda aumentó {{spike_percent}}% para {{products}}. Stock actual podría agotarse en {{hours_until_stockout}} horas." + }, + "demand_pattern_optimization": { + "title": "💡 Optimización de Patrón de Demanda", + "message": "Patrón detectado: {{pattern_description}}. Recomienda ajustar producción de {{products}} para optimizar eficiencia." + }, + "inventory_optimization": { + "title": "📦 Optimización de Inventario", + "message": "{{ingredient_name}} consistentemente sobre-stock por {{excess_percent}}%. Recomienda reducir pedido a {{recommended_amount}}kg." + }, + "production_efficiency": { + "title": "⚡ Oportunidad de Eficiencia en Producción", + "message": "{{product_name}} más eficiente a las {{suggested_time}}. Tiempo de producción {{time_saved}} minutos menor ({{savings_percent}}% ahorro)." + }, + "sales_opportunity": { + "title": "💰 Oportunidad de Ventas", + "message": "Alta demanda de {{products}} detectada. Considera producción adicional. Ingresos potenciales: €{{potential_revenue}}." + }, + "seasonal_adjustment": { + "title": "🍂 Ajuste Estacional Recomendado", + "message": "Temporada {{season}} acercándose. Ajusta producción de {{products}} basado en tendencias históricas ({{adjustment_percent}}% {{adjustment_direction}})." + }, + "cost_reduction": { + "title": "💵 Oportunidad de Reducción de Costos", + "message": "Cambiando a {{alternative_ingredient}} puede ahorrar €{{savings_amount}}/mes. Calidad similar, menor costo." + }, + "waste_reduction": { + "title": "♻️ Oportunidad de Reducción de Desperdicio", + "message": "{{product_name}} desperdicio alto ({{waste_percent}}%). Recomienda reducir lote a {{recommended_quantity}} unidades." + }, + "quality_improvement": { + "title": "⭐ Mejora de Calidad Recomendada", + "message": "{{issue_description}} detectado en {{product_name}}. Acción recomendada: {{recommended_action}}." + }, + "customer_satisfaction": { + "title": "😊 Oportunidad de Satisfacción del Cliente", + "message": "Cliente {{customer_name}} consistentemente ordena {{product_name}}. Considera oferta especial o programa de lealtad." + }, + "energy_optimization": { + "title": "⚡ Optimización de Energía", + "message": "Uso de energía para {{equipment_name}} pico a las {{peak_time}}. Cambiando a {{off_peak_start}}-{{off_peak_end}} puede ahorrar €{{savings_amount}}/mes." + }, + "staff_optimization": { + "title": "👥 Optimización de Personal", + "message": "{{shift_name}} sobrestimado por {{excess_percent}}%. Considera ajustar niveles de personal para reducir costos laborales." + }, + "po_approval_needed": { + "title": "Orden de Compra #{{po_number}} requiere aprobación", + "message": "Orden de compra para {{supplier_name}} por un total de {{currency}} {{total_amount}} pendiente de aprobación. Entrega requerida para {{required_delivery_date}}." + }, + "production_batch_start": { + "title": "Lote de Producción Listo: {{product_name}}", + "message": "Lote #{{batch_number}} ({{quantity_planned}} {{unit}} de {{product_name}}) está listo para comenzar. Prioridad: {{priority}}." + } + } +} diff --git a/frontend/src/locales/eu/alerts.json b/frontend/src/locales/eu/alerts.json new file mode 100644 index 00000000..edbae8a2 --- /dev/null +++ b/frontend/src/locales/eu/alerts.json @@ -0,0 +1,297 @@ +{ + "priority": { + "critical": "Kritikoa", + "important": "Garrantzitsua", + "standard": "Estandarra", + "info": "Informazioa" + }, + "type_class": { + "action_needed": "Ekintza Behar Da", + "prevented_issue": "Arazoa Saihestua", + "trend_warning": "Joera Abisua", + "escalation": "Eskalazio", + "information": "Informazioa" + }, + "context": { + "already_addressed": "AIak dagoeneko kudeatu du hau", + "financial_impact": "€{amount} arriskuan", + "time_until": "Erabakia behar da {time}n", + "can_user_fix": "Konpon dezakezu hau", + "requires_supplier": "{supplier} behar da", + "prevented_savings": "Aurreztua €{amount}", + "grouped_count": "{count} bilduta" + }, + "actions": { + "approve_po": "Onartu €{amount} eskaera", + "reject_po": "Baztertu eskaera", + "call_supplier": "Deitu {supplier}ri ({phone})", + "see_reasoning": "Ikusi arrazoibide osoa", + "complete_receipt": "Osatu stockaren harrera", + "mark_received": "Markatu jasota gisa", + "adjust_production": "Doitu ekoizpen egutegia", + "snooze": "Atzeratu {hours}h", + "mark_read": "Markatu irakurrita gisa", + "dismiss": "Baztertu", + "navigate": "Ikusi xehetasunak", + "notify_customer": "Jakinarazi {customer}ri", + "cancel_auto_action": "Ezeztatu ekintza automatikoa" + }, + "orchestration": { + "reasoning_title": "🤖 Eguneko Orkestatzailearen Arrazoibidea", + "analyzed_title": "Goiz honetan, aztertu dut:", + "actions_taken": "Beraz, antolatu dut:", + "prevented_issues": "✅ Arazoak Saihestuta", + "estimated_impact": "Aurreikusitako Eragina", + "impact_description": "Aurrezkiak eskabide presagarriak, stock falta eta hondakinak saihestuz", + "last_run": "Azken exekuzioa", + "what_ai_did": "AIak zuretzat egin duena" + }, + "metrics": { + "hours": "{count, plural, =1 {# ordu} other {# ordu}}", + "minutes": "{count, plural, =1 {# minutu} other {# minutu}}", + "days": "{count, plural, =1 {# egun} other {# egun}}" + }, + "escalated": "Eskalatuta", + "hub": { + "tab_list_label": "Alerta kategoriak", + "tabs": { + "all": "Alerta Guztiak", + "all_description": "Zure ogi-dendan dauden alerta guztiak", + "for_me": "Niretzat", + "for_me_description": "Zuri esleitutako alertak edo zure ekintza behar dutenak", + "archived": "Artxibatuta", + "archived_description": "Konpondutako eta baztertutako alertak" + }, + "toggle_filters": "Aktibatu/desaktibatu iragazkiak", + "filters": "Iragazkiak", + "active": "Aktiboak" + }, + "auto_action": { + "title": "Ekintza Automatiko Zain", + "remaining": "geratzen da", + "financial_impact": "Eragina:", + "cancel_button": "Ezeztatu Ekintza Automatikoa", + "cancelling": "Ezeztatzen...", + "cancelled_title": "Ekintza Automatikoa Ezeztatuta", + "cancelled_message": "Ekintza automatikoa saihestu da. Orain eskuz kudea dezakezu.", + "completed_title": "Ekintza Automatikoa Exekutatuta", + "help_text": "AIak automatikoki exekutatuko du ekintza hau tenporizadorea amaitzen denean. Egin klik \"Ezeztatu\"n saihestu eta eskuz kudeatzeko.", + "urgency": { + "critical": "PRESAZKOA", + "warning": "LASTER", + "info": "PROGRAMATUTA" + } + }, + "priority_explainer": { + "title": "Lehentasun Puntuazioak Ulertzea", + "subtitle": "Nola kalkulatzen duen AIak zerk behar duen zure arreta lehenik", + "overview": { + "title": "Lehentasun Puntuazioa (0-100)", + "description": "Alerta bakoitzak 0-100 bitarteko lehentasun puntuazioa jasotzen du lau osagai ponderatuen arabera. Honek zure ogi-dendarako benetan garrantzitsua denean zentratzea laguntzen dizu." + }, + "example_alert": "Alerta Adibidearen Lehentasuna", + "level": { + "critical": "KRITIKOA", + "important": "GARRANTZITSUA", + "standard": "ESTANDARRA", + "info": "INFORMAZIOA" + }, + "components_title": "Puntuazioaren Osagaiak", + "weight": "pisua", + "business_impact": { + "name": "Negozio Eragina", + "description": "Finantza ondorioak, eskaerak eraginduta, bezeroaren gogobetetasuna", + "example1": "€500 sarrera potentzialean arriskuan", + "example2": "10 bezero eskabide eraginda", + "example3": "Bezeroaren gogobetetasunean eragin handia" + }, + "urgency": { + "name": "Premura", + "description": "Denbora sentikortasuna, epe-mugak, eskalazio potentziala", + "example1": "Epe-muga 2 ordutan", + "example2": "Stock falta gertu (4 ordu)", + "example3": "Ekoizpen leihoa laster ixten" + }, + "agency": { + "name": "Erabiltzailearen Ekintza Gaitasuna", + "description": "Ekintza har dezakezu? Emaitzaren gaineko kontrola duzu?", + "example1": "Zure onespena behar du", + "example2": "Klik bakarreko ekintza erabilgarri", + "example3": "Zure autoritatearen barruko erabakia behar da" + }, + "confidence": { + "name": "AIaren Konfiantza", + "description": "Zenbat ziur dago AIa alerta honen baliozkotasunaz?", + "example1": "Historian oinarritutako patroietan (95% bat etortzea)", + "example2": "Datu kalitatea: Altua", + "example3": "Iragarpen zehaztasuna balioztatua" + }, + "formula_title": "Formula", + "footer": "Puntuazio honek AIari alertak lehentasunez ipintzen laguntzen dio, garrantzitsuenak lehenik ikusten dituzula ziurtatuz.", + "got_it": "Ulertu dut!" + }, + "trend": { + "near_threshold": "Atalasearen ondoan" + }, + "action_preview": { + "title": "Ekintzaren Aurrebista", + "outcome": "Zer gertatuko da", + "financial_impact": "Finantza Eragina", + "affected_systems": "Sistema Eragindak", + "reversible": "Ekintza hau desegin daiteke", + "not_reversible": "Ekintza hau ezin da desegin", + "confidence": "AIaren Konfiantza: {{confidence}}%", + "cancel": "Ezeztatu", + "confirm": "Berretsi Ekintza" + }, + "response_time": { + "title": "Erantzun Denboraren Errendimendua", + "subtitle": "Zenbat azkar erantzuten diozun alertei", + "on_time": "Garaiz", + "alerts": "alertak", + "average": "Batez Bestekoa", + "target": "Helburua", + "on_time_responses": "Garaiz Erantzunak", + "needs_improvement": "Hobetzea behar du", + "benchmark_title": "Errendimenduaren Ikuspegia", + "excellent": "Bikaina! Ogi-denda %80 baino azkarrago erantzuten ari zara. Jarraitu horrela!", + "good": "Lan ona! Saiatu alerta kritikoei helburu denboran erantzuten gehiago hobetzeko.", + "needs_work": "Alerta kritikoei erantzun azkarragoak arazoak sahiestu eta dirua aurreztu dezakete. Saiatu helburu denborak betetzen.", + "tip": "Aholkua: Gaitu mugikorretako jakinarazpenak alerta kritikoei azkarrago erantzuteko" + }, + "alerts": { + "critical_stock_shortage": { + "title": "🚨 Stock Kritikoa: {{ingredient_name}}", + "message_with_po_pending": "{{ingredient_name}}-ren {{current_stock}}kg bakarrik ({{required_stock}}kg behar dituzu). Dagoeneko {{po_id}} sortu dut {{delivery_day_name}}rako entregarako. Mesedez onartu €{{po_amount}}.", + "message_with_po_created": "{{ingredient_name}}-ren {{current_stock}}kg bakarrik ({{required_stock}}kg behar dituzu). Dagoeneko {{po_id}} sortu dut. Berrikusi eta onartu €{{po_amount}}.", + "message_with_hours": "{{ingredient_name}}-ren {{current_stock}}kg bakarrik eskuragarri ({{required_stock}}kg behar dituzu {{hours_until}} ordutan).", + "message_with_date": "{{ingredient_name}}-ren {{current_stock}}kg bakarrik eskuragarri ({{required_stock}}kg behar dituzu {{production_day_name}}ko ekoizpenerako).", + "message_generic": "{{ingredient_name}}-ren {{current_stock}}kg bakarrik eskuragarri ({{required_stock}}kg behar dituzu)." + }, + "low_stock": { + "title": "⚠️ Stock Baxua: {{ingredient_name}}", + "message_with_po": "{{ingredient_name}} stocka: {{current_stock}}kg (gutxienekoa: {{minimum_stock}}kg). Dagoeneko PO programatu dut osatzeko.", + "message_generic": "{{ingredient_name}} stocka: {{current_stock}}kg (gutxienekoa: {{minimum_stock}}kg). Eskaera egitea kontuan hartu." + }, + "stock_depleted": { + "title": "📦 Eskaeragatik Stocka Agortu Da", + "message_with_supplier": "#{{order_id}} eskaerak {{ingredient_name}} behar du baina agortu da. Jarri harremanetan {{supplier_name}}rekin ({{supplier_phone}}).", + "message_generic": "#{{order_id}} eskaerak {{ingredient_name}} behar du baina agortu da. Berehala ekintza behar da." + }, + "ingredient_shortage": { + "title": "⚠️ Osagaien Falta Ekoizpenean", + "message_with_customers": "{{ingredient_name}} nahikoa ez abian dauden loteentzat. {{affected_orders}} eskabide eraginda ({{customer_names}}). Oraingo stocka: {{current_stock}}kg, beharrezkoa: {{required_stock}}kg.", + "message_generic": "{{ingredient_name}} nahikoa ez abian dauden loteentzat. Oraingo stocka: {{current_stock}}kg, beharrezkoa: {{required_stock}}kg." + }, + "expired_products": { + "title": "🚫 Iraungitako edo Iraungitzear Dauden Produktuak", + "message_with_names": "{{count}} produktu iraungitzen: {{product_names}}. Balio osoa: €{{total_value}}.", + "message_generic": "{{count}} produktu iraungitzen. Balio osoa: €{{total_value}}." + }, + "production_delay": { + "title": "⏰ Ekoizpen Atzerapena: {{batch_name}}", + "message_with_customers": "{{batch_name}} lotea {{delay_minutes}} minutu atzeratu da. Bezeroak eraginda: {{customer_names}}. Jatorrizko entrega ordua: {{scheduled_time}}.", + "message_with_orders": "{{batch_name}} lotea {{delay_minutes}} minutu atzeratu da. {{affected_orders}} eskabide eraginda. Jatorrizko entrega ordua: {{scheduled_time}}.", + "message_generic": "{{batch_name}} lotea {{delay_minutes}} minutu atzeratu da. Jatorrizko entrega ordua: {{scheduled_time}}." + }, + "equipment_failure": { + "title": "🔧 Ekipamendu Matxura: {{equipment_name}}", + "message_with_batches": "{{equipment_name}} huts egin du. {{affected_batches}} ekoizpeneko lote eraginda ({{batch_names}}).", + "message_generic": "{{equipment_name}} huts egin du. Berehala konponketa behar du." + }, + "maintenance_required": { + "title": "🔧 Mantentze-lanak Behar Dira: {{equipment_name}}", + "message_with_hours": "{{equipment_name}}(e)k mantentze-lanak behar ditu {{hours_until}} ordutan. Programatu orain etetenak saihesteko.", + "message_with_days": "{{equipment_name}}(e)k mantentze-lanak behar ditu {{days_until}} egunetan. Programatu {{maintenance_date}} baino lehen." + }, + "low_equipment_efficiency": { + "title": "📉 Eraginkortasun Baxua: {{equipment_name}}", + "message": "{{equipment_name}} %{{efficiency_percent}} eraginkortasunarekin funtzionatzen (esperoa: >{{threshold_percent}}%). Mantentze-lanak kontuan hartu." + }, + "order_overload": { + "title": "📊 Eskabideen Gainzama", + "message_with_orders": "Gaitasuna %{{overload_percent}}z gainzamatuta. {{total_orders}} eskabide programatuta, gaitasuna: {{capacity_orders}}. Egutegia doitzea kontuan hartu.", + "message_generic": "Gaitasuna %{{overload_percent}}z gainzamatuta. Ekoizpen egutegia doitzea kontuan hartu." + }, + "supplier_delay": { + "title": "🚚 Hornitzaile Atzerapena: {{supplier_name}}", + "message": "{{supplier_name}}(e)k {{ingredient_name}} entrega atzeratu du (PO: {{po_id}}). Data berria: {{new_delivery_date}}. Jatorrizkoa: {{original_delivery_date}}." + }, + "temperature_breach": { + "title": "🌡️ Tenperatura Haustea", + "message": "Tenperatura {{location}}: {{current_temp}}°C (tartea: {{min_temp}}°C-{{max_temp}}°C). Iraupena: {{duration_minutes}} minutu." + }, + "demand_surge_weekend": { + "title": "📈 Eskariaren Igoera: Asteburua", + "message": "Eskatutako eskaria %{{surge_percent}} handiagoa {{weekend_date}}rako. Produktu eragindak: {{products}}. Ekoizpena handitzea kontuan hartu." + }, + "weather_impact_alert": { + "title": "🌦️ Espero den Eguraldiaren Eragina", + "message": "{{weather_condition}} esperotzen da {{date}}. Eskarian eragina: %{{impact_percent}}. Produktu eragindak: {{products}}." + }, + "holiday_preparation": { + "title": "🎉 Jai Prestaketa: {{holiday_name}}", + "message": "{{holiday_name}} {{days_until}} egunetan ({{holiday_date}}). Eskatutako eskaria %{{expected_increase}} handiagoa. Funtsezko produktuak: {{products}}." + }, + "severe_weather_impact": { + "title": "⛈️ Eguraldi Larriaren Eragina", + "message": "{{weather_condition}} larria esperotzen da {{date}}. Eskarian eragina: %{{impact_percent}}. Entrega ordutegiak doitzea kontuan hartu." + }, + "unexpected_demand_spike": { + "title": "📊 Ustekabeko Eskariaren Igoera", + "message": "Eskaria %{{spike_percent}} igo da {{products}}entzat. Oraingo stocka agor daiteke {{hours_until_stockout}} ordutan." + }, + "demand_pattern_optimization": { + "title": "💡 Eskari Ereduaren Optimizazioa", + "message": "Eredua detektatua: {{pattern_description}}. Gomendatzen da {{products}} ekoizpena doitzea eraginkortasuna optimizatzeko." + }, + "inventory_optimization": { + "title": "📦 Inbentarioaren Optimizazioa", + "message": "{{ingredient_name}} etengabe gehiegizko stockarekin %{{excess_percent}}z. Gomendatzen da eskaera {{recommended_amount}}kg-ra murriztea." + }, + "production_efficiency": { + "title": "⚡ Ekoizpen Eraginkortasunaren Aukera", + "message": "{{product_name}} eraginkorragoa da {{suggested_time}}etan. Ekoizpen denbora {{time_saved}} minutu laburragoa (%{{savings_percent}} aurrezkia)." + }, + "sales_opportunity": { + "title": "💰 Salmenten Aukera", + "message": "{{products}}entzako eskari handia detektatuta. Ekoizpen gehigarria kontuan hartu. Sarrera potentziala: €{{potential_revenue}}." + }, + "seasonal_adjustment": { + "title": "🍂 Sasoiko Doikuntza Gomendatua", + "message": "{{season}} sasoia hurbiltzen. Doitu {{products}} ekoizpena historia joerei oinarrituta (%{{adjustment_percent}} {{adjustment_direction}})." + }, + "cost_reduction": { + "title": "💵 Kostu Murrizketa Aukera", + "message": "{{alternative_ingredient}}ra aldatzeak €{{savings_amount}}/hilabetean aurreztu dezake. Antzeko kalitatea, kostu txikiagoa." + }, + "waste_reduction": { + "title": "♻️ Hondakin Murrizketa Aukera", + "message": "{{product_name}} hondakin handia (%{{waste_percent}}). Gomendatzen da lotea {{recommended_quantity}} unitatetara murriztea." + }, + "quality_improvement": { + "title": "⭐ Kalitate Hobekuntza Gomendatua", + "message": "{{issue_description}} detektatuta {{product_name}}n. Gomendatutako ekintza: {{recommended_action}}." + }, + "customer_satisfaction": { + "title": "😊 Bezeroaren Gogobetetasun Aukera", + "message": "{{customer_name}} bezeroak etengabe eskatzen du {{product_name}}. Eskaintza berezia edo leialtasun programa kontuan hartu." + }, + "energy_optimization": { + "title": "⚡ Energia Optimizazioa", + "message": "{{equipment_name}}rako energia erabilera gailurra {{peak_time}}etan. {{off_peak_start}}-{{off_peak_end}}ra aldatzeak €{{savings_amount}}/hilabetean aurreztu dezake." + }, + "staff_optimization": { + "title": "👥 Langile Optimizazioa", + "message": "{{shift_name}} langileak gehiegi %{{excess_percent}}z. Langile mailak doitzea kontuan hartu lan kostuak murrizteko." + }, + "po_approval_needed": { + "title": "Erosketa Agindua #{{po_number}} onarpenaren beharra", + "message": "{{supplier_name}}-(r)entzako erosketa agindua {{currency}} {{total_amount}} onarpenaren zain. Entreaga {{required_delivery_date}}-(e)rako behar da." + }, + "production_batch_start": { + "title": "Ekoizpen Lote Prest: {{product_name}}", + "message": "#{{batch_number}} lotea ({{quantity_planned}} {{unit}} {{product_name}}) hasteko prest. Lehentasuna: {{priority}}." + } + } +}