#Stable version for Maruti Suzuki import streamlit as st import pandas as pd import numpy as np import plotly.express as px import plotly.graph_objects as go from datetime import datetime, timedelta import random # Page configuration st.set_page_config( page_title="Maruti Suzuki - Complete Supply Chain Hub", page_icon="🚗", layout="wide", initial_sidebar_state="expanded" ) # Custom CSS (same as before) st.markdown(""" """, unsafe_allow_html=True) # Initialize session state if 'executed_mitigations' not in st.session_state: st.session_state.executed_mitigations = [] if 'external_signals' not in st.session_state: st.session_state.external_signals = [] # UPDATED: Generate 8-week forward-looking demand data for Maruti components @st.cache_data def generate_8week_demand_data(): today = datetime(2025, 9, 24) # Current date dates = [today + timedelta(days=x) for x in range(56)] # 8 weeks = 56 days # Maruti-specific materials/components based on actual product lineup materials = [ 'ENG001-K15C Engine Assembly', 'TRX001-CVT Transmission', 'STR001-Electric Power Steering', 'BRK001-ABS Brake System', 'SUS001-MacPherson Strut' ] all_data = [] for material in materials: np.random.seed(hash(material) % 1000) # Generate base demand patterns (higher volumes for Maruti scale) base_demand = np.random.normal(180, 20, 56) # First 14 days: FIRM DEMAND from production schedule firm_demand = np.clip(base_demand[:14], 120, 250).astype(int) # Days 15-56: Customer shared demand (dealer network forecast) customer_shared = np.clip(base_demand[14:] * (1 + 0.08 * np.sin(np.linspace(0, 3.14, 42))), 100, 280).astype(int) # Days 15-56: AI-corrected demand (with market signals) external_factors = np.zeros(42) # Festive season impact (weeks 3-4) external_factors[0:14] += np.random.normal(0, 8, 14) # EV transition impact (weeks 5-8) - negative for ICE components if 'ENG001' in material or 'TRX001' in material: external_factors[14:] -= 5 # New model launch boost (weeks 6-7) external_factors[28:42] += 12 corrected_demand = np.clip(customer_shared + external_factors, 80, 320).astype(int) # Generate supply plan for 56 days supply_capacity = np.random.normal(185, 15, 56) supply_plan = np.clip(supply_capacity, 140, 280).astype(int) # Apply disruptions to supply (monsoon impact on days 15-18) supply_actual = supply_plan.copy() supply_actual[15:19] = (supply_actual[15:19] * 0.75).astype(int) for i, date in enumerate(dates): # Determine which demand to use if i < 14: demand_used = firm_demand[i] firm_val = firm_demand[i] customer_val = None corrected_val = None demand_type = "Production Schedule" else: demand_used = corrected_demand[i-14] firm_val = None customer_val = customer_shared[i-14] corrected_val = corrected_demand[i-14] demand_type = "AI-Corrected Forecast" # Calculate shortfall shortfall = max(0, demand_used - supply_actual[i]) all_data.append({ 'Date': date, 'Week': f"Week {(i//7)+1}", 'Day': i + 1, 'Material': material, 'Firm_Demand': firm_val, 'Customer_Demand': customer_val, 'Corrected_Demand': corrected_val, 'Demand_Used': demand_used, 'Supply_Plan': supply_plan[i], 'Supply_Projected': supply_actual[i], 'Shortfall': shortfall, 'Demand_Type': demand_type, 'Gap': supply_actual[i] - demand_used }) return pd.DataFrame(all_data) # UPDATED: Maruti Tier-1 suppliers data based on actual suppliers @st.cache_data def get_tier1_suppliers(): return { 'Motherson Automotive': { 'location': 'Noida', 'materials': ['STR001-Electric Power Steering', 'ENG001-K15C Engine Assembly'], 'capacity': 250, 'reliability': 96, 'lead_time': 2, 'risk_factors': ['Component shortage', 'Transportation delays', 'Quality issues'] }, 'Bosch India': { 'location': 'Bangalore', 'materials': ['BRK001-ABS Brake System', 'ENG001-K15C Engine Assembly'], 'capacity': 220, 'reliability': 98, 'lead_time': 3, 'risk_factors': ['Semiconductor shortage', 'Supplier strikes', 'Raw material costs'] }, 'Valeo India': { 'location': 'Chennai', 'materials': ['SUS001-MacPherson Strut', 'TRX001-CVT Transmission'], 'capacity': 200, 'reliability': 94, 'lead_time': 2, 'risk_factors': ['Monsoon flooding', 'Port congestion', 'Currency fluctuation'] }, 'AISIN India': { 'location': 'Haryana', 'materials': ['TRX001-CVT Transmission', 'STR001-Electric Power Steering'], 'capacity': 180, 'reliability': 95, 'lead_time': 4, 'risk_factors': ['Technology delays', 'Capacity bottlenecks', 'Logistics issues'] } } # UPDATED: Generate ecosystem data for Maruti suppliers @st.cache_data def generate_ecosystem_data(): today = datetime(2025, 9, 24) dates = [today + timedelta(days=x) for x in range(14)] suppliers = get_tier1_suppliers() all_data = [] for supplier_name, supplier_info in suppliers.items(): for material in supplier_info['materials']: np.random.seed(hash(supplier_name + material) % 1000) base_capacity = supplier_info['capacity'] normal_supply = np.full(14, base_capacity, dtype=int) disrupted_supply = normal_supply.copy() if supplier_name == 'Motherson Automotive': disrupted_supply[3:6] = (disrupted_supply[3:6] * 0.4).astype(int) disruption_cause = "Component shortage from Tier-2 suppliers" disruption_days = list(range(3, 6)) elif supplier_name == 'Bosch India': disrupted_supply[6:9] = (disrupted_supply[6:9] * 0.3).astype(int) disruption_cause = "Semiconductor chip shortage" disruption_days = list(range(6, 9)) elif supplier_name == 'Valeo India': disrupted_supply[4:8] = (disrupted_supply[4:8] * 0.5).astype(int) disruption_cause = "Monsoon flooding in Chennai" disruption_days = list(range(4, 8)) elif supplier_name == 'AISIN India': disrupted_supply[9:12] = (disrupted_supply[9:12] * 0.2).astype(int) disruption_cause = "Production line automation failure" disruption_days = list(range(9, 12)) else: disruption_cause = "Normal Operations" disruption_days = [] lead_time = supplier_info['lead_time'] maruti_supply = np.full(14, base_capacity, dtype=int) for disruption_day in disruption_days: arrival_day = disruption_day + lead_time if arrival_day < 14: reduction = normal_supply[disruption_day] - disrupted_supply[disruption_day] maruti_supply[arrival_day] = max(maruti_supply[arrival_day] - reduction, 0) for i, date in enumerate(dates): all_data.append({ 'Date': date, 'Supplier': supplier_name, 'Material': material, 'Tier1_Normal_Supply': int(normal_supply[i]), 'Tier1_Disrupted_Supply': int(disrupted_supply[i]), 'Tier1_Impact': int(normal_supply[i] - disrupted_supply[i]), 'Maruti_Normal_Supply': int(normal_supply[i]), 'Maruti_Impacted_Supply': int(maruti_supply[i]), 'Maruti_Impact': int(normal_supply[i] - maruti_supply[i]), 'Disruption_Cause': disruption_cause if i in disruption_days else "Normal Operations", 'Lead_Time_Days': lead_time, 'Is_Disrupted': i in disruption_days, 'Is_Maruti_Impacted': maruti_supply[i] < normal_supply[i] }) return pd.DataFrame(all_data) # UPDATED: External signals for Maruti market context @st.cache_data def get_external_signals(): return [ {'Source': 'Weather API', 'Signal': 'Heavy monsoon expected in Chennai for next 4 days', 'Impact': 'Supply Risk', 'Confidence': 96}, {'Source': 'Market Intelligence', 'Signal': 'Festive season demand surge - historically 20% increase', 'Impact': 'Demand Spike', 'Confidence': 94}, {'Source': 'Government Policy', 'Signal': 'New EV incentive scheme announced - ICE demand may soften', 'Impact': 'Demand Shift', 'Confidence': 89}, {'Source': 'Supplier Network', 'Signal': 'Semiconductor supply improving by 15% next quarter', 'Impact': 'Supply Recovery', 'Confidence': 92}, {'Source': 'Social Media Analytics', 'Signal': 'High anticipation for new Maruti hybrid models', 'Impact': 'Future Demand', 'Confidence': 78}, {'Source': 'Industry Reports', 'Signal': 'Rural market recovery driving small car demand', 'Impact': 'Volume Growth', 'Confidence': 87}, {'Source': 'Dealer Network', 'Signal': 'Inventory clearance promotions planned for month-end', 'Impact': 'Short-term Boost', 'Confidence': 98} ] # UPDATED: Generate alerts for 8-week data def generate_detailed_alerts(df): alerts = [] for material in df['Material'].unique(): material_data = df[df['Material'] == material] shortage_days = material_data[material_data['Shortfall'] > 5] if not shortage_days.empty: for _, row in shortage_days.iterrows(): root_causes = [] if row['Day'] > 14: if row['Corrected_Demand'] and row['Customer_Demand']: diff = row['Corrected_Demand'] - row['Customer_Demand'] if diff > 10: root_causes.append(f"AI detected {diff} units additional demand from market signals") if row['Day'] >= 15 and row['Day'] <= 18: root_causes.append("Monsoon disruption affecting supplier delivery") else: root_causes.append("Production schedule demand exceeding supplier capacity") if not root_causes: root_causes.append("Base demand exceeding current supply capacity") mitigation_options = [ {"option": "Activate backup production line at Haryana plant", "impact": "+40 units/day", "cost": "High", "timeline": "24 hours"}, {"option": "Expedite air freight from alternate suppliers", "impact": "+20 units/day", "cost": "Medium", "timeline": "12 hours"}, {"option": "Emergency sourcing from Suzuki Japan", "impact": "+60 units/day", "cost": "Very High", "timeline": "48 hours"}, {"option": "Reallocate inventory from Gurgaon warehouse", "impact": "+25 units/day", "cost": "Low", "timeline": "18 hours"} ] if row['Shortfall'] > 40: best_option = mitigation_options[2] elif row['Shortfall'] > 20: best_option = mitigation_options[0] else: best_option = mitigation_options[1] alerts.append({ 'material': material, 'date': row['Date'].strftime('%Y-%m-%d'), 'week': row['Week'], 'shortage': int(row['Shortfall']), 'demand_type': row['Demand_Type'], 'severity': 'Critical' if row['Shortfall'] > 40 else 'High' if row['Shortfall'] > 20 else 'Medium', 'root_causes': root_causes, 'mitigation_options': mitigation_options, 'best_option': best_option }) return alerts # Keep mitigation strategies for ecosystem (updated for Maruti context) def generate_mitigation_strategies(supplier, material, impact_amount, impact_days): base_strategies = [ { 'strategy': 'Activate Alternate Supplier Network', 'description': f'Engage backup Tier-1 supplier for {material}', 'timeline': '24-48 hours', 'cost': 'High (+12% unit cost)', 'effectiveness': '92%', 'capacity': f'+{impact_amount * 0.9:.0f} units/day', }, { 'strategy': 'Emergency Suzuki Japan Import', 'description': f'Air freight {material} from Suzuki Corporation', 'timeline': '48-72 hours', 'cost': 'Very High (+35% logistics cost)', 'effectiveness': '85%', 'capacity': f'+{impact_amount * 0.85:.0f} units/day', }, { 'strategy': 'Cross-Plant Inventory Transfer', 'description': f'Transfer {material} stock from other Maruti plants', 'timeline': '12-24 hours', 'cost': 'Medium (+6% handling cost)', 'effectiveness': '70%', 'capacity': f'+{impact_amount * 0.7:.0f} units/day', } ] if impact_amount > 150: recommended = [0, 1] elif impact_amount > 75: recommended = [0, 2] else: recommended = [2] return base_strategies, recommended # Load data df_demand = generate_8week_demand_data() df_ecosystem = generate_ecosystem_data() external_signals = get_external_signals() suppliers = get_tier1_suppliers() # Updated title for Maruti Suzuki st.title("🚗 Maruti Suzuki Supply Chain Command Center") # Tab Navigation (same as before) st.sidebar.title("🎯 Dashboard Navigation") dashboard_tab = st.sidebar.radio( "Select Dashboard:", ["📊 Demand & Supply Forecast", "🌐 Ecosystem Supplier Impact", "🛡️ Buffer Optimizer"], index=0 ) # TAB 1: 8-WEEK DEMAND & SUPPLY FORECAST (Updated for Maruti) if dashboard_tab == "📊 Demand & Supply Forecast": st.markdown("""

📊 8-Week Maruti Suzuki Demand & Supply Forecast

8-Week Production Planning | Production Schedule (Days 1-14) | AI-Enhanced Market Forecast (Days 15-56)

""", unsafe_allow_html=True) # Material selection selected_materials_demand = st.sidebar.multiselect( "Focus Components:", df_demand['Material'].unique(), default=df_demand['Material'].unique()[:3] ) # Week filter week_filter = st.sidebar.selectbox( "Focus on Weeks:", ["All 8 Weeks", "Weeks 1-2 (Production Schedule)", "Weeks 3-4", "Weeks 5-6", "Weeks 7-8"], index=0 ) # Filter data filtered_df_demand = df_demand[df_demand['Material'].isin(selected_materials_demand)] if week_filter != "All 8 Weeks": if week_filter == "Weeks 1-2 (Production Schedule)": filtered_df_demand = filtered_df_demand[filtered_df_demand['Day'] <= 14] elif week_filter == "Weeks 3-4": filtered_df_demand = filtered_df_demand[(filtered_df_demand['Day'] > 14) & (filtered_df_demand['Day'] <= 28)] elif week_filter == "Weeks 5-6": filtered_df_demand = filtered_df_demand[(filtered_df_demand['Day'] > 28) & (filtered_df_demand['Day'] <= 42)] else: # Weeks 7-8 filtered_df_demand = filtered_df_demand[filtered_df_demand['Day'] > 42] # Generate and display alerts st.subheader("🚨 8-Week Maruti Supply Chain Alerts") alerts = generate_detailed_alerts(filtered_df_demand) if alerts: for i, alert in enumerate(alerts[:3]): st.markdown(f"""

⚠️ {alert['material']} - {alert['severity']} Shortage Alert

Date: {alert['date']} ({alert['week']}) | Shortage: {alert['shortage']} units | Type: {alert['demand_type']}

""", unsafe_allow_html=True) st.markdown("**🔍 Root Cause Analysis:**") for cause in alert['root_causes']: st.markdown(f"""
🎯 {cause}
""", unsafe_allow_html=True) st.markdown("**⚡ Mitigation Options:**") for option in alert['mitigation_options']: is_best = option == alert['best_option'] option_class = "best-option" if is_best else "mitigation" best_indicator = "🏆 **RECOMMENDED** " if is_best else "" st.markdown(f"""
{best_indicator}{option['option']}
📈 Impact: {option['impact']} | 💰 Cost: {option['cost']} | ⏱️ Timeline: {option['timeline']}
""", unsafe_allow_html=True) col1, col2, col3 = st.columns([2, 1, 1]) with col1: if st.button(f"✅ Implement Solution", key=f"demand_implement_{i}"): st.success(f"Implementing: {alert['best_option']['option']}") st.markdown("---") else: st.markdown("""
All Systems Green! No critical supply shortages detected in the 8-week horizon.
""", unsafe_allow_html=True) # Continue with the rest of the TAB 1 code (planning table, charts, external signals)... # [Rest of TAB 1 implementation remains the same structure] # TAB 2: ECOSYSTEM SUPPLIER IMPACT (Updated for Maruti suppliers) elif dashboard_tab == "🌐 Ecosystem Supplier Impact": st.markdown("""

🌐 Maruti Suzuki Tier-1 Supplier Impact Dashboard

Tier-1 Supplier Disruption Analysis | Cascading Impact on Production | Automated Response Systems

""", unsafe_allow_html=True) selected_suppliers = st.sidebar.multiselect( "Monitor Suppliers:", list(suppliers.keys()), default=list(suppliers.keys()) ) st.subheader("🚨 Live Supplier Network Alerts") ecosystem_alerts = [] for supplier in selected_suppliers: supplier_data = df_ecosystem[df_ecosystem['Supplier'] == supplier] disrupted_data = supplier_data[supplier_data['Is_Disrupted'] == True] if not disrupted_data.empty: for material in disrupted_data['Material'].unique(): material_disruptions = disrupted_data[disrupted_data['Material'] == material] total_impact = material_disruptions['Tier1_Impact'].sum() impact_days = len(material_disruptions) first_impact_date = material_disruptions['Date'].min() maruti_impacted = supplier_data[ (supplier_data['Material'] == material) & (supplier_data['Is_Maruti_Impacted'] == True) ] if not maruti_impacted.empty: maruti_impact_start = maruti_impacted['Date'].min() maruti_impact_days = len(maruti_impacted) maruti_total_impact = maruti_impacted['Maruti_Impact'].sum() ecosystem_alerts.append({ 'supplier': supplier, 'material': material, 'disruption_cause': material_disruptions.iloc[0]['Disruption_Cause'], 'tier1_impact_start': first_impact_date, 'tier1_impact_days': impact_days, 'tier1_total_impact': total_impact, 'maruti_impact_start': maruti_impact_start, 'maruti_impact_days': maruti_impact_days, 'maruti_total_impact': maruti_total_impact, 'lead_time': material_disruptions.iloc[0]['Lead_Time_Days'] }) # Continue with ecosystem alerts display... # [Rest of TAB 2 implementation with Maruti-specific context] # TAB 3: BUFFER OPTIMIZER (Updated with Maruti volumes) elif dashboard_tab == "🛡️ Buffer Optimizer": st.markdown("""

🛡️ Maruti Multi-Echelon Buffer Optimizer

AI-driven safety stock recommendations across Maruti's production network

""", unsafe_allow_html=True) # Continue with buffer optimization logic... # [Rest of TAB 3 implementation remains similar with Maruti context] # Performance summary (Updated for Maruti metrics) st.subheader("📊 Maruti Performance Summary") # [Performance metrics implementation] # Footer st.markdown("---") st.markdown("""

🚗 Maruti Suzuki 8-Week Supply Chain Command Center | Production Schedule + AI-Enhanced Forecast | Tier-1 Supplier Intelligence + Buffer Optimization
Powered by Agentic AI | 8-Week Planning Horizon | Comprehensive Automotive Supply Chain Resilience

""", unsafe_allow_html=True)