import streamlit as st import pandas as pd import plotly.express as px from streamlit_option_menu import option_menu import numpy as np from datetime import datetime, timedelta # Import our modules from data.synthetic_data import SAPDataGenerator from agents.procurement_agent import ProcurementAgent from utils.charts import ProcurementCharts # Page configuration st.set_page_config( page_title="🚀 SAP S/4HANA Procurement AI", page_icon="🚀", layout="wide", initial_sidebar_state="expanded" ) # Custom CSS for beautiful UI st.markdown(""" """, unsafe_allow_html=True) # Initialize session state if 'data_loaded' not in st.session_state: st.session_state.data_loaded = False st.session_state.po_data = None st.session_state.supplier_data = None st.session_state.spend_data = None @st.cache_data def load_synthetic_data(): """Load and cache synthetic data""" generator = SAPDataGenerator() po_data = generator.generate_purchase_orders(1000) supplier_data = generator.generate_supplier_performance() spend_data = generator.generate_spend_analysis() return po_data, supplier_data, spend_data def main(): # Main header st.markdown('

🚀 SAP S/4HANA Procurement AI Assistant

', unsafe_allow_html=True) st.markdown('

Intelligent Procurement Analytics with AI-Powered Insights

', unsafe_allow_html=True) # Load data if not st.session_state.data_loaded: with st.spinner("🔄 Loading SAP S/4HANA Data..."): po_data, supplier_data, spend_data = load_synthetic_data() st.session_state.po_data = po_data st.session_state.supplier_data = supplier_data st.session_state.spend_data = spend_data st.session_state.data_loaded = True # Sidebar navigation with st.sidebar: st.image("https://via.placeholder.com/200x80/667eea/white?text=SAP+S/4HANA", width=200) selected = option_menu( menu_title="Navigation", options=["🏠 Dashboard", "📊 Analytics", "🤖 AI Insights", "🔍 Deep Dive", "⚙️ Settings"], icons=["house", "graph-up", "robot", "search", "gear"], menu_icon="cast", default_index=0, styles={ "container": {"padding": "0!important", "background-color": "#fafafa"}, "icon": {"color": "#667eea", "font-size": "18px"}, "nav-link": {"font-size": "16px", "text-align": "left", "margin": "0px", "--hover-color": "#eee"}, "nav-link-selected": {"background-color": "#667eea"}, } ) # Initialize AI agent agent = ProcurementAgent() charts = ProcurementCharts() # Main content based on selection if selected == "🏠 Dashboard": show_dashboard(st.session_state.po_data, st.session_state.supplier_data, charts) elif selected == "📊 Analytics": show_analytics(st.session_state.po_data, st.session_state.spend_data, charts) elif selected == "🤖 AI Insights": show_ai_insights(st.session_state.po_data, st.session_state.supplier_data, agent) elif selected == "🔍 Deep Dive": show_deep_dive(st.session_state.po_data, st.session_state.supplier_data) elif selected == "⚙️ Settings": show_settings() def show_dashboard(po_data, supplier_data, charts): st.subheader("📈 Executive Dashboard") # KPI Metrics col1, col2, col3, col4 = st.columns(4) total_spend = po_data['Total_Value'].sum() total_pos = len(po_data) avg_delivery = po_data['Delivery_Performance'].mean() top_supplier = po_data.groupby('Supplier')['Total_Value'].sum().idxmax() with col1: st.markdown(f"""

💰 Total Spend

${total_spend:,.0f}

""", unsafe_allow_html=True) with col2: st.markdown(f"""

📋 Purchase Orders

{total_pos:,}

""", unsafe_allow_html=True) with col3: st.markdown(f"""

🎯 Avg Delivery

{avg_delivery:.1f}%

""", unsafe_allow_html=True) with col4: st.markdown(f"""

🏆 Top Supplier

{top_supplier}

""", unsafe_allow_html=True) st.markdown("---") # Charts col1, col2 = st.columns(2) with col1: fig_trend = charts.create_spend_trend_chart(po_data) st.plotly_chart(fig_trend, use_container_width=True) with col2: fig_category = charts.create_category_pie_chart(po_data) st.plotly_chart(fig_category, use_container_width=True) # Status and Performance col1, col2 = st.columns(2) with col1: fig_status = charts.create_status_donut_chart(po_data) st.plotly_chart(fig_status, use_container_width=True) with col2: fig_supplier = charts.create_supplier_performance_chart(po_data) st.plotly_chart(fig_supplier, use_container_width=True) def show_analytics(po_data, spend_data, charts): st.subheader("📊 Advanced Analytics") # Filter controls col1, col2, col3 = st.columns(3) with col1: selected_suppliers = st.multiselect( "Select Suppliers:", options=po_data['Supplier'].unique(), default=po_data['Supplier'].unique()[:5] ) with col2: selected_categories = st.multiselect( "Select Categories:", options=po_data['Category'].unique(), default=po_data['Category'].unique()[:5] ) with col3: date_range = st.date_input( "Date Range:", value=(po_data['PO_Date'].min(), po_data['PO_Date'].max()), min_value=po_data['PO_Date'].min(), max_value=po_data['PO_Date'].max() ) # Filter data filtered_data = po_data[ (po_data['Supplier'].isin(selected_suppliers)) & (po_data['Category'].isin(selected_categories)) ] st.markdown("---") # Advanced Charts tab1, tab2, tab3 = st.tabs(["📈 Trends", "🏢 Suppliers", "📦 Categories"]) with tab1: col1, col2 = st.columns(2) with col1: # Monthly trend fig_trend = charts.create_spend_trend_chart(filtered_data) st.plotly_chart(fig_trend, use_container_width=True) with col2: # Delivery performance over time monthly_delivery = filtered_data.groupby(filtered_data['PO_Date'].dt.to_period('M'))['Delivery_Performance'].mean().reset_index() monthly_delivery['PO_Date'] = monthly_delivery['PO_Date'].astype(str) fig = px.bar(monthly_delivery, x='PO_Date', y='Delivery_Performance', title='🚚 Monthly Delivery Performance', color='Delivery_Performance', color_continuous_scale='RdYlGn') fig.update_layout(height=400, plot_bgcolor='rgba(0,0,0,0)') st.plotly_chart(fig, use_container_width=True) with tab2: # Supplier analysis supplier_summary = filtered_data.groupby('Supplier').agg({ 'Total_Value': ['sum', 'mean', 'count'], 'Delivery_Performance': 'mean' }).round(2) supplier_summary.columns = ['Total Spend', 'Avg PO Value', 'PO Count', 'Delivery %'] supplier_summary = supplier_summary.reset_index() st.dataframe( supplier_summary.style.highlight_max(axis=0), use_container_width=True, height=400 ) with tab3: # Category deep dive category_analysis = filtered_data.groupby('Category').agg({ 'Total_Value': 'sum', 'Quantity': 'sum', 'Unit_Price': 'mean', 'Delivery_Performance': 'mean' }).round(2) st.dataframe( category_analysis.style.highlight_max(axis=0), use_container_width=True, height=400 ) def show_ai_insights(po_data, supplier_data, agent): st.subheader("🤖 AI-Powered Procurement Insights") # Generate insights with st.spinner("🧠 AI Agent is analyzing your procurement data..."): insights = agent.generate_insights(po_data, supplier_data) # Executive Summary st.markdown(f"""

📋 Executive Summary

{insights['summary']}
""", unsafe_allow_html=True) # Tabs for different insights tab1, tab2, tab3 = st.tabs(["💰 Spend Analysis", "🏢 Supplier Intelligence", "⚠️ Risk Alerts"]) with tab1: spend_insights = insights['spend_analysis'] col1, col2 = st.columns(2) with col1: st.metric("Total Spend", f"${spend_insights.get('total_spend', 0):,.2f}") st.metric("Avg PO Value", f"${spend_insights.get('avg_po_value', 0):,.2f}") with col2: st.metric("Spending Trend", spend_insights.get('monthly_trend', 'N/A').title()) st.metric("Top Category", spend_insights.get('top_category', 'N/A')) st.subheader("🎯 AI Recommendations") for recommendation in spend_insights.get('recommendations', []): st.markdown(f"""
{recommendation}
""", unsafe_allow_html=True) with tab2: supplier_insights = insights['supplier_analysis'] col1, col2 = st.columns(2) with col1: best = supplier_insights.get('best_performer', {}) st.success(f"🏆 Best Performer: {best.get('name', 'N/A')} ({best.get('performance', 0):.1f}%)") with col2: worst = supplier_insights.get('worst_performer', {}) st.error(f"⚠️ Needs Improvement: {worst.get('name', 'N/A')} ({worst.get('performance', 0):.1f}%)") st.subheader("📈 Supplier Recommendations") for recommendation in supplier_insights.get('recommendations', []): st.markdown(f"""
{recommendation}
""", unsafe_allow_html=True) with tab3: anomalies = insights['anomalies'] if anomalies: st.subheader(f"🚨 {len(anomalies)} Critical Issues Detected") for anomaly in anomalies: risk_color = {"High": "🔴", "Medium": "🟡", "Low": "🟢"} st.markdown(f"""
{risk_color.get(anomaly.get('risk_level', 'Medium'), '🟡')} {anomaly['type']}
PO: {anomaly.get('po_number', 'N/A')} | Supplier: {anomaly.get('supplier', 'N/A')}
Risk Level: {anomaly.get('risk_level', 'Unknown')}
""", unsafe_allow_html=True) else: st.success("🎉 No critical issues detected in your procurement data!") def show_deep_dive(po_data, supplier_data): st.subheader("🔍 Deep Dive Analysis") # Data explorer st.subheader("📊 Purchase Orders Data Explorer") # Search and filter col1, col2, col3 = st.columns(3) with col1: search_po = st.text_input("🔍 Search PO Number:") with col2: filter_status = st.selectbox("Filter by Status:", ['All'] + list(po_data['Status'].unique())) with col3: min_value = st.number_input("Min PO Value:", min_value=0, value=0) # Apply filters filtered_po = po_data.copy() if search_po: filtered_po = filtered_po[filtered_po['PO_Number'].str.contains(search_po, case=False)] if filter_status != 'All': filtered_po = filtered_po[filtered_po['Status'] == filter_status] if min_value > 0: filtered_po = filtered_po[filtered_po['Total_Value'] >= min_value] # Display filtered data st.dataframe( filtered_po.style.highlight_max(axis=0), use_container_width=True, height=400 ) # Download data csv = filtered_po.to_csv(index=False) st.download_button( label="📥 Download Filtered Data", data=csv, file_name=f"procurement_data_{datetime.now().strftime('%Y%m%d_%H%M%S')}.csv", mime="text/csv" ) def show_settings(): st.subheader("⚙️ Application Settings") st.info("🚀 **Demo Configuration**") col1, col2 = st.columns(2) with col1: st.markdown("### 📊 Data Settings") data_refresh = st.button("🔄 Refresh Synthetic Data") if data_refresh: st.session_state.data_loaded = False st.rerun() st.markdown("### 🎨 Theme Settings") theme = st.selectbox("Choose Theme:", ["Default", "Dark", "Light"]) with col2: st.markdown("### 🤖 AI Settings") ai_model = st.selectbox("AI Model:", ["GPT-4", "Claude", "Local Model"]) confidence = st.slider("Confidence Threshold:", 0.0, 1.0, 0.8) st.markdown("### 📈 Chart Settings") chart_style = st.selectbox("Chart Style:", ["Modern", "Classic", "Minimal"]) st.markdown("---") st.markdown("### 📋 Application Info") st.json({ "version": "1.0.0", "framework": "Streamlit", "data_source": "Synthetic SAP S/4HANA", "ai_agent": "Custom Procurement Agent", "last_updated": datetime.now().strftime("%Y-%m-%d %H:%M:%S") }) if __name__ == "__main__": main()