1+ """
2+ app.py
3+ The Web Interface for the Digital Capacity Optimizer.
4+ Run with: streamlit run app.py
5+ """
6+ import streamlit as st
7+ import pandas as pd
8+ from inventory_math import calculate_newsvendor_target , calculate_required_inventory
9+ from forecaster import generate_forecast
10+ from visualizer import plot_forecast
11+ import config
12+
13+ # --- 1. Page Configuration ---
14+ st .set_page_config (page_title = "Digital Capacity Optimizer" , page_icon = "🏭" )
15+
16+ st .title ("🏭 Digital Capacity Optimizer" )
17+ st .markdown ("""
18+ **AI-Powered Supply Chain Planning** Upload your demand logs to generate forecasts and optimized procurement plans.
19+ """ )
20+
21+ # --- 2. Sidebar (Settings) ---
22+ st .sidebar .header ("⚙️ Configuration" )
23+ holding_cost = st .sidebar .number_input ("Holding Cost ($/Unit/Year)" , value = config .HOLDING_COST )
24+ stockout_cost = st .sidebar .number_input ("Stockout Cost ($/Unit)" , value = config .STOCKOUT_COST )
25+
26+ # --- 3. File Upload ---
27+ uploaded_file = st .file_uploader ("Upload CSV Usage Logs" , type = ["csv" ])
28+
29+ if uploaded_file is not None :
30+ # Load Data
31+ df = pd .read_csv (uploaded_file )
32+ st .success (f"✅ Loaded { len (df )} months of data." )
33+
34+ # Show Raw Data (Expandable)
35+ with st .expander ("View Raw Data" ):
36+ st .dataframe (df )
37+
38+ # --- 4. Run Forecasting Engine ---
39+ st .subheader ("🔮 Demand Forecast" )
40+
41+ months_to_predict = st .slider ("Months to Forecast" , min_value = 1 , max_value = 6 , value = 3 )
42+
43+ with st .spinner ("Training AI Model..." ):
44+ forecast_result = generate_forecast (df , months_ahead = months_to_predict )
45+ forecast_values = forecast_result ['forecast_values' ]
46+
47+ # Display Chart
48+ fig = plot_forecast (df , forecast_values )
49+ st .pyplot (fig )
50+
51+ # --- 5. Optimization Results ---
52+ st .subheader ("📦 Procurement Recommendation" )
53+
54+ # Get Next Month's Prediction
55+ next_month_demand = forecast_values .iloc [0 ]
56+ std_dev_demand = df ['demand' ].std ()
57+
58+ # Calculate Math
59+ optimal_sla = calculate_newsvendor_target (holding_cost , stockout_cost )
60+ required_inventory = calculate_required_inventory (next_month_demand , std_dev_demand , optimal_sla )
61+
62+ # Display Key Metrics in Columns
63+ col1 , col2 , col3 = st .columns (3 )
64+ col1 .metric ("Predicted Demand" , f"{ int (next_month_demand )} units" , delta = "Next Month" )
65+ col2 .metric ("Optimal Service Level" , f"{ optimal_sla * 100 :.1f} %" , help = "Based on Cost Ratio" )
66+ col3 .metric ("Recommended Order" , f"{ int (required_inventory )} units" , delta = "Final Decision" )
67+
68+ st .info (
69+ f"💡 **Insight:** To maintain a { optimal_sla * 100 :.1f} % Service Level with current volatility, you need **{ int (required_inventory )} units** in stock." )
70+
71+ else :
72+ st .info ("👆 Please upload a CSV file to begin simulation. (Use 'mock_data.csv')" )
0 commit comments