import streamlit as st import pandas as pd import re import plotly.express as px st.set_page_config(page_title="گزارش خرید کالا و داشبورد تصویری", layout="wide", initial_sidebar_state="expanded") # --- بارگذاری فونت Vazirmatn از CDN --- st.markdown( """ """, unsafe_allow_html=True ) # --- بارگذاری فایل CSS --- with open("src/style.css") as f: st.markdown(f"", unsafe_allow_html=True) st.title("📊 گزارش خرید کالا و داشبورد تصویری") # --- سایدبار --- with st.sidebar: st.header("تنظیمات") uploaded_file = st.file_uploader("📂 فایل اکسل Book.xlsx را بارگذاری کنید", type=["xlsx"]) if uploaded_file is not None: df = pd.read_excel(uploaded_file) # --- تمیزکاری ستون‌ها --- def clean_col(col): col = str(col) col = re.sub(r'[\n\r]+', ' ', col) col = re.sub(r'[\u200c\u200f\u202a-\u202e\ufeff]', '', col) col = re.sub(r'\s+', ' ', col).strip() return col df.columns = [clean_col(c) for c in df.columns] # --- پیدا کردن ستون تعداد و مبلغ --- qty_col = next((c for c in df.columns if re.search(r'خالص.*تعداد', c)), None) amt_col = next((c for c in df.columns if re.search(r'خالص.*مبلغ(?!.*تخفیف)', c)), None) if not qty_col or not amt_col: st.error("❌ ستون‌های مربوط به «خالص تعداد» یا «خالص مبلغ» پیدا نشدند!") st.write("📑 ستون‌های موجود در فایل (بعد از تمیزکاری):") st.write(list(df.columns)) else: # اطمینان از اینکه ستون مبلغ عددی است و NaN ندارد df[amt_col] = pd.to_numeric(df[amt_col], errors='coerce').fillna(0) # --- نگاشت ماه‌ها --- month_order = ['فروردین','اردیبهشت','خرداد','تیر','مرداد','شهریور', 'مهر','آبان','آذر','دی','بهمن','اسفند'] month_dict = { "01": "فروردین", "02": "اردیبهشت", "03": "خرداد", "04": "تیر", "05": "مرداد", "06": "شهریور", "07": "مهر", "08": "آبان", "09": "آذر", "10": "دی", "11": "بهمن", "12": "اسفند" } df['کدماه'] = df['نام ماه'].astype(str).str[:2] df['ماه'] = df['کدماه'].map(month_dict) # --- Pivot مشتری --- grouped = df.groupby(['کد کالا','نام کالا','طرف حساب','ماه']).agg({ qty_col:'sum', amt_col:'sum' }).reset_index() pivot_qty = grouped.pivot_table( index=['کد کالا','نام کالا','طرف حساب'], columns='ماه', values=qty_col, fill_value=0 ).reindex(columns=month_order, fill_value=0) total_amount = grouped.groupby(['کد کالا','نام کالا','طرف حساب'])[amt_col].sum() pivot_qty['مجموع مبلغ خرید'] = total_amount report_customer = pivot_qty.reset_index() tab1, tab2, tab3, tab4 = st.tabs(["گزارش مشتری", "گزارش تجمیعی تعداد", "گزارش تجمیعی مبلغ", "داشبورد تصویری"]) with tab1: st.subheader("📋 گزارش خرید هر شخص برای هر کالا") st.dataframe(report_customer, use_container_width=True) st.download_button("⬇️ دانلود گزارش مشتری (CSV)", report_customer.to_csv(index=False, encoding='utf-8-sig'), "Sales_Report_ByCustomer.csv", "text/csv", use_container_width=True) # --- Pivot تجمیعی --- grouped_total = df.groupby(['کد کالا','نام کالا','ماه']).agg({qty_col:'sum', amt_col:'sum'}).reset_index() pivot_qty_total = grouped_total.pivot_table( index=['کد کالا','نام کالا'], columns='ماه', values=qty_col, fill_value=0 ).reindex(columns=month_order, fill_value=0) pivot_amt_total = grouped_total.pivot_table( index=['کد کالا','نام کالا'], columns='ماه', values=amt_col, fill_value=0 ).reindex(columns=month_order, fill_value=0) # جمع کل pivot_qty_total['جمع کل تعداد'] = pivot_qty_total.sum(axis=1) pivot_amt_total['جمع کل مبلغ'] = pivot_amt_total.sum(axis=1) with tab2: st.subheader("📦 گزارش تجمیعی تعداد فروش کل کالاها") st.dataframe(pivot_qty_total.reset_index(), use_container_width=True) st.download_button("⬇️ دانلود گزارش تجمیعی تعداد (CSV)", pivot_qty_total.reset_index().to_csv(index=False, encoding='utf-8-sig'), "Total_Quantity_Report.csv", "text/csv", use_container_width=True) with tab3: st.subheader("💰 گزارش تجمیعی مبلغ فروش کل کالاها") st.dataframe(pivot_amt_total.reset_index(), use_container_width=True) st.download_button("⬇️ دانلود گزارش تجمیعی مبلغ (CSV)", pivot_amt_total.reset_index().to_csv(index=False, encoding='utf-8-sig'), "Total_Amount_Report.csv", "text/csv", use_container_width=True) with tab4: st.header("📊 نمودارهای فروش") # --- Top مشتری‌ها --- sales_by_customer = df.groupby('طرف حساب')[amt_col].sum().sort_values(ascending=False).head(10).reset_index() sales_by_customer.columns = ['طرف حساب', 'مبلغ فروش'] fig1 = px.bar(sales_by_customer, x='طرف حساب', y='مبلغ فروش', title="🏆 برترین مشتری‌ها", color='مبلغ فروش') st.plotly_chart(fig1, use_container_width=True) # --- Top کالاها --- sales_by_product = df.groupby('نام کالا')[amt_col].sum().sort_values(ascending=False).head(10).reset_index() sales_by_product.columns = ['نام کالا', 'مبلغ فروش'] fig2 = px.bar(sales_by_product, x='نام کالا', y='مبلغ فروش', title="📦 برترین کالاها", color='مبلغ فروش') st.plotly_chart(fig2, use_container_width=True) # 3. فروش ماهانه sales_by_month = df.groupby('ماه')[amt_col].sum().reindex(month_order, fill_value=0) fig3 = px.bar(x=sales_by_month.index, y=sales_by_month.values, title="📅 فروش ماهانه", labels={'y':'مبلغ فروش', 'x':'ماه'}) st.plotly_chart(fig3, use_container_width=True) # 4. سهم مشتری‌ها top_5_customers = sales_by_customer.head(5) fig4 = px.pie(top_5_customers, values='مبلغ فروش', names='طرف حساب', title="🥧 سهم مشتری‌ها از کل فروش (Top 5)") st.plotly_chart(fig4, use_container_width=True) # 5. سهم کالاها top_5_products = sales_by_product.head(5) fig5 = px.pie(top_5_products, values='مبلغ فروش', names='نام کالا', title="🥧 سهم کالاها از کل فروش (Top 5)") st.plotly_chart(fig5, use_container_width=True) # 6. Trend فروش ماهانه fig6 = px.line(sales_by_month, title="📈 روند فروش در طول سال", labels={'value':'مبلغ فروش', 'index':'ماه'}, markers=True) st.plotly_chart(fig6, use_container_width=True)