New alert system and panel de control page 2
This commit is contained in:
@@ -164,137 +164,137 @@
|
||||
},
|
||||
"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)."
|
||||
"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."
|
||||
"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."
|
||||
"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."
|
||||
"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}}."
|
||||
"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}}."
|
||||
"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."
|
||||
"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}}."
|
||||
"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."
|
||||
"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."
|
||||
"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}}."
|
||||
"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."
|
||||
"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."
|
||||
"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}}."
|
||||
"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}}."
|
||||
"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."
|
||||
"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."
|
||||
"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."
|
||||
"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."
|
||||
"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)."
|
||||
"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}}."
|
||||
"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}})."
|
||||
"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."
|
||||
"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."
|
||||
"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}}."
|
||||
"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."
|
||||
"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."
|
||||
"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."
|
||||
"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}}."
|
||||
"title": "Production Batch Ready: {product_name}",
|
||||
"message": "Batch #{batch_number} ({quantity_planned} {unit} of {product_name}) is ready to start. Priority: {priority}."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,7 +140,7 @@
|
||||
"affected_systems": "Sistema Eragindak",
|
||||
"reversible": "Ekintza hau desegin daiteke",
|
||||
"not_reversible": "Ekintza hau ezin da desegin",
|
||||
"confidence": "AIaren Konfiantza: {{confidence}}%",
|
||||
"confidence": "AIaren Konfiantza: {confidence}%",
|
||||
"cancel": "Ezeztatu",
|
||||
"confirm": "Berretsi Ekintza"
|
||||
},
|
||||
@@ -161,137 +161,137 @@
|
||||
},
|
||||
"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)."
|
||||
"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."
|
||||
"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."
|
||||
"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."
|
||||
"message_with_customers": "{ingredient_name} nahikoa ez abian dauden loteentzat. {affected_orders} eskabide eraginda ({customer_names}). Stock orain: {current_stock}kg, beharrezkoa: {required_stock}kg.",
|
||||
"message_generic": "{ingredient_name} nahikoa ez abian dauden loteentzat. Stock orain: {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}}."
|
||||
"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}}."
|
||||
"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."
|
||||
"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."
|
||||
"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."
|
||||
"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."
|
||||
"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}}."
|
||||
"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."
|
||||
"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."
|
||||
"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}}."
|
||||
"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}}."
|
||||
"title": "🎉 Jai Prestaketa: {holiday_name}",
|
||||
"message": "{holiday_name} {days_until} egunetan ({holiday_date}). Eskatutako eskaria %{expected_increase} handiagoa. Produktu gakoak: {products}."
|
||||
},
|
||||
"severe_weather_impact": {
|
||||
"title": "⛈️ Eguraldi Larriaren Eragina",
|
||||
"message": "{{weather_condition}} larria esperotzen da {{date}}. Eskarian eragina: %{{impact_percent}}. Entrega ordutegiak doitzea kontuan hartu."
|
||||
"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."
|
||||
"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."
|
||||
"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."
|
||||
"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)."
|
||||
"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}}."
|
||||
"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}})."
|
||||
"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."
|
||||
"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."
|
||||
"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}}."
|
||||
"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."
|
||||
"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."
|
||||
"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."
|
||||
"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."
|
||||
"message": "Erosketa agindua {supplier_name}-(r)entzako {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}}."
|
||||
"title": "Ekoizpen Lote Prest: {product_name}",
|
||||
"message": "Lote #{batch_number} ({quantity_planned} {unit} {product_name}) hasierarako prest dago. Lehentasuna: {priority}."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -417,7 +417,7 @@
|
||||
"header": {
|
||||
"main_navigation": "Nabigazio nagusia",
|
||||
"notifications": "Jakinarazpenak",
|
||||
"unread_count": "{{count}} jakinarazpen irakurri gabeak",
|
||||
"unread_count": "{count} jakinarazpen irakurri gabeak",
|
||||
"login": "Hasi Saioa",
|
||||
"start_free": "Hasi Doan",
|
||||
"register": "Erregistratu",
|
||||
|
||||
@@ -1,183 +0,0 @@
|
||||
"""
|
||||
Test script to verify i18n ICU format parameters are properly structured
|
||||
for PO approval alerts in the bakery-ia system.
|
||||
"""
|
||||
|
||||
import uuid
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
def test_raw_alert_structure():
|
||||
"""Test that raw alerts contain proper message_params for ICU format"""
|
||||
print("Testing Raw Alert Structure...")
|
||||
|
||||
# Simulate the structure that should be created by _emit_po_approval_alert
|
||||
raw_alert_data = {
|
||||
'id': str(uuid.uuid4()),
|
||||
'tenant_id': str(uuid.uuid4()),
|
||||
'service': 'procurement',
|
||||
'type': 'po_approval_needed',
|
||||
'alert_type': 'po_approval_needed',
|
||||
'type_class': 'action_needed',
|
||||
'severity': 'high',
|
||||
'title': '', # Empty - will be generated by frontend with i18n
|
||||
'message': '', # Empty - will be generated by frontend with i18n
|
||||
'timestamp': datetime.utcnow().isoformat(),
|
||||
'metadata': {
|
||||
'po_id': str(uuid.uuid4()),
|
||||
'po_number': 'PO-12345',
|
||||
'supplier_id': str(uuid.uuid4()),
|
||||
'supplier_name': 'ABC Supplier',
|
||||
'total_amount': 1500.00,
|
||||
'currency': 'EUR',
|
||||
'priority': 'high',
|
||||
'required_delivery_date': '2024-01-15',
|
||||
'created_at': datetime.utcnow().isoformat(),
|
||||
'financial_impact': 1500.00,
|
||||
'urgency_score': 85,
|
||||
'reasoning_data': {
|
||||
'type': 'po_creation_approval',
|
||||
'parameters': {
|
||||
'po_number': 'PO-12345',
|
||||
'supplier_name': 'ABC Supplier',
|
||||
'total_amount': 1500.00,
|
||||
'currency': 'EUR',
|
||||
'required_delivery_date': '2024-01-15',
|
||||
'items_count': 5,
|
||||
'priority': 'high',
|
||||
'reason': 'automated_replenishment',
|
||||
'triggering_event': 'low_stock_detected',
|
||||
'financial_impact_if_delayed': 2000.00,
|
||||
'production_batches_affected': ['BATCH-001', 'BATCH-002']
|
||||
},
|
||||
'consequence': {
|
||||
'severity': 'high',
|
||||
'affects': ['production_delay', 'stockout_risk']
|
||||
}
|
||||
}
|
||||
},
|
||||
'message_params': {
|
||||
'po_number': 'PO-12345',
|
||||
'supplier_name': 'ABC Supplier',
|
||||
'total_amount': 1500.00,
|
||||
'currency': 'EUR',
|
||||
'priority': 'high',
|
||||
'required_delivery_date': '2024-01-15',
|
||||
'items_count': 5,
|
||||
'created_at': datetime.utcnow().isoformat()
|
||||
},
|
||||
'actions': ['approve_po', 'reject_po', 'modify_po'],
|
||||
'item_type': 'alert'
|
||||
}
|
||||
|
||||
print(f"✓ Raw alert contains message_params: {raw_alert_data['message_params']}")
|
||||
print(f"✓ Message params structure: {list(raw_alert_data['message_params'].keys())}")
|
||||
|
||||
# Verify ICU format compatibility
|
||||
icu_compatible = all(isinstance(v, (str, int, float, bool)) for k, v in raw_alert_data['message_params'].items()
|
||||
if k != 'created_at') # created_at is datetime string
|
||||
print(f"✓ ICU format compatible: {icu_compatible}")
|
||||
|
||||
return raw_alert_data
|
||||
|
||||
|
||||
def test_enriched_alert_structure(raw_alert_data):
|
||||
"""Test that enriched alerts preserve and enhance message_params"""
|
||||
print("\nTesting Enriched Alert Structure...")
|
||||
|
||||
# Simulate the enriched alert structure (simplified version)
|
||||
enriched_alert_data = {
|
||||
'id': raw_alert_data['id'],
|
||||
'tenant_id': raw_alert_data['tenant_id'],
|
||||
'service': raw_alert_data['service'],
|
||||
'alert_type': raw_alert_data['alert_type'],
|
||||
'type_class': raw_alert_data['type_class'],
|
||||
'priority_score': 85,
|
||||
'priority_level': 'important',
|
||||
'message_params': raw_alert_data['message_params'], # Preserved from raw alert
|
||||
'reasoning_data': raw_alert_data['metadata']['reasoning_data'],
|
||||
'actions': raw_alert_data['actions'],
|
||||
'business_impact': {'financial_impact_eur': 1500.00},
|
||||
'urgency_context': {'time_until_consequence_hours': 24},
|
||||
'user_agency': {'can_user_fix': True},
|
||||
'created_at': datetime.utcnow(),
|
||||
'alert_metadata': {
|
||||
**raw_alert_data['metadata'],
|
||||
'message_params': raw_alert_data['message_params'], # Preserved in metadata
|
||||
'i18n': {
|
||||
'title_key': f'alerts.{raw_alert_data["alert_type"]}.title',
|
||||
'message_key': f'alerts.{raw_alert_data["alert_type"]}.message',
|
||||
'message_params': raw_alert_data['message_params'] # ICU format params
|
||||
}
|
||||
},
|
||||
'status': 'active'
|
||||
}
|
||||
|
||||
print(f"✓ Enriched alert preserves message_params: {enriched_alert_data['message_params']}")
|
||||
print(f"✓ ICU params in metadata: {enriched_alert_data['alert_metadata']['i18n']['message_params']}")
|
||||
print(f"✓ All ICU params preserved: {set(enriched_alert_data['message_params'].keys()) == set(raw_alert_data['message_params'].keys())}")
|
||||
|
||||
return enriched_alert_data
|
||||
|
||||
|
||||
def test_i18n_icu_usage():
|
||||
"""Test how frontend would use ICU format parameters"""
|
||||
print("\nTesting ICU Format Usage...")
|
||||
|
||||
# Simulate frontend i18n usage
|
||||
message_params = {
|
||||
'po_number': 'PO-12345',
|
||||
'supplier_name': 'ABC Supplier',
|
||||
'total_amount': 1500.00,
|
||||
'currency': 'EUR',
|
||||
'priority': 'high',
|
||||
'required_delivery_date': '2024-01-15',
|
||||
'items_count': 5
|
||||
}
|
||||
|
||||
# Simulate ICU format translation strings
|
||||
title_template = "{po_number} needs approval"
|
||||
message_template = "Purchase order for {supplier_name} ({currency}{total_amount}) requires your approval. {items_count} items included. Required by {required_delivery_date}."
|
||||
|
||||
# Simulate i18n.t() function replacement
|
||||
title = title_template.format(**message_params)
|
||||
message = message_template.format(**message_params)
|
||||
|
||||
print(f"✓ ICU title: {title}")
|
||||
print(f"✓ ICU message: {message}")
|
||||
|
||||
# Verify ICU format compatibility
|
||||
expected_title = "PO-12345 needs approval"
|
||||
expected_message = "Purchase order for ABC Supplier (EUR150.0) requires your approval. 5 items included. Required by 2024-01-15."
|
||||
|
||||
print(f"✓ Title matches expected: {title == expected_title}")
|
||||
print(f"✓ Message matches expected: {message == expected_message}")
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def main():
|
||||
"""Main test function"""
|
||||
print("Testing i18n ICU Format Implementation for PO Approval Alerts")
|
||||
print("=" * 60)
|
||||
|
||||
# Test 1: Raw alert structure
|
||||
raw_alert = test_raw_alert_structure()
|
||||
|
||||
# Test 2: Enriched alert structure
|
||||
enriched_alert = test_enriched_alert_structure(raw_alert)
|
||||
|
||||
# Test 3: ICU format usage
|
||||
icu_test = test_i18n_icu_usage()
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("All tests passed! ✓")
|
||||
print("\nSummary:")
|
||||
print("- Raw alerts now contain structured message_params for ICU format")
|
||||
print("- Enriched alerts preserve and enhance message_params")
|
||||
print("- ICU format supports {param} syntax for i18n translation")
|
||||
print("- Parameters are compatible with frontend i18n libraries")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user