File size: 6,759 Bytes
a854c1b a499fcb 2705fd6 a499fcb a854c1b 4a4508c a854c1b 4a4508c a854c1b 4a4508c a854c1b 4a4508c a854c1b 4a4508c a499fcb d4f2ca0 4a4508c a854c1b 4a4508c a854c1b a499fcb a854c1b 4a4508c a854c1b a499fcb a854c1b 4a4508c a854c1b 4a4508c a854c1b 4a4508c a854c1b 4a4508c b645b79 4a4508c a499fcb 4a4508c a499fcb 4a4508c a499fcb 4a4508c a499fcb |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
import streamlit as st
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import plotly.express as px
import plotly.graph_objects as go
from datetime import datetime
import time
import io
import os
import json
import base64
from pathlib import Path
# استيراد الوحدات الجديدة من pricing_system
from pricing_system.modules.analysis import smart_price_analysis as analysis_utils
from pricing_system.modules.catalogs import materials_catalog, equipment_catalog
from pricing_system.modules.indirect_support import overheads
from pricing_system.modules.pricing_strategies import balanced_pricing, profit_oriented
class PricingApp:
"""وحدة التسعير"""
def __init__(self):
"""تهيئة وحدة التسعير"""
if 'bill_of_quantities' not in st.session_state:
st.session_state.bill_of_quantities = []
if 'cost_analysis' not in st.session_state:
st.session_state.cost_analysis = []
if 'price_scenarios' not in st.session_state:
st.session_state.price_scenarios = []
if 'local_content_data' not in st.session_state:
st.session_state.local_content_data = {'target_percent': 30, 'actual_percent': 0, 'items': []}
def run(self):
self.render()
def render(self):
st.markdown("<h1 class='module-title'>وحدة التسعير</h1>", unsafe_allow_html=True)
tabs = st.tabs([
"لوحة التحكم",
"جدول الكميات",
"تحليل التكاليف",
"سيناريوهات التسعير",
"المقارنة التنافسية",
"المحتوى المحلي",
"تسعير غير متزن",
"التقارير"
])
with tabs[0]:
self._render_dashboard_tab()
with tabs[1]:
self._render_bill_of_quantities_tab()
with tabs[2]:
self._render_cost_analysis_tab()
with tabs[3]:
self._render_pricing_scenarios_tab()
with tabs[4]:
self._render_competitive_analysis_tab()
with tabs[5]:
self._render_local_content_tab()
with tabs[6]:
self._render_unbalanced_pricing_tab()
with tabs[7]:
self._render_reports_tab()
def _render_dashboard_tab(self):
st.markdown("### لوحة تحكم التسعير")
st.info("سيتم عرض بيانات ملخص التسعير والتحليلات هنا.")
def _render_bill_of_quantities_tab(self):
st.markdown("### جدول الكميات")
boq_df = pd.DataFrame(st.session_state.bill_of_quantities)
if not boq_df.empty:
st.dataframe(
boq_df[['code', 'description', 'unit', 'quantity', 'unit_price', 'total_price', 'category']],
column_config={
'code': 'الكود',
'description': 'الوصف',
'unit': 'الوحدة',
'quantity': 'الكمية',
'unit_price': st.column_config.NumberColumn('سعر الوحدة', format='%d ريال'),
'total_price': st.column_config.NumberColumn('السعر الإجمالي', format='%d ريال'),
'category': 'الفئة'
},
hide_index=True,
use_container_width=True
)
else:
st.warning("لا توجد بيانات في جدول الكميات.")
st.markdown("### إضافة بند جديد")
col1, col2 = st.columns(2)
with col1:
new_code = st.text_input("الكود", key="new_boq_code")
new_description = st.text_input("الوصف", key="new_boq_description")
new_unit = st.selectbox("الوحدة", ["م3", "م2", "طن", "عدد", "متر طولي"], key="new_boq_unit")
with col2:
new_quantity = st.number_input("الكمية", min_value=0.0, step=1.0, key="new_boq_quantity")
new_unit_price = st.number_input("سعر الوحدة", min_value=0.0, step=10.0, key="new_boq_unit_price")
new_category = st.selectbox("الفئة", [
"أعمال ترابية",
"أعمال خرسانية",
"أعمال حديد",
"أعمال بناء",
"أعمال تشطيبات",
"أعمال نجارة",
"أعمال ألمنيوم",
"أعمال كهربائية",
"أعمال ميكانيكية",
"أعمال صحية"
], key="new_boq_category")
if st.button("إضافة البند", key="add_boq_item"):
if new_code and new_description and new_quantity > 0 and new_unit_price > 0:
new_total_price = new_quantity * new_unit_price
new_id = max([item['id'] for item in st.session_state.bill_of_quantities], default=0) + 1
st.session_state.bill_of_quantities.append({
'id': new_id,
'code': new_code,
'description': new_description,
'unit': new_unit,
'quantity': new_quantity,
'unit_price': new_unit_price,
'total_price': new_total_price,
'category': new_category
})
st.success(f"تمت إضافة البند بنجاح: {new_description}")
st.rerun()
else:
st.error("يرجى إدخال جميع البيانات المطلوبة بشكل صحيح")
def _render_cost_analysis_tab(self):
st.markdown("### تحليل التكاليف")
analysis_utils.render_cost_breakdown()
def _render_pricing_scenarios_tab(self):
st.markdown("### سيناريوهات التسعير")
balanced_pricing.render_balanced_strategy()
def _render_competitive_analysis_tab(self):
st.markdown("### المقارنة التنافسية")
st.info("سيتم عرض مقارنة الأسعار والمنافسين هنا.")
def _render_local_content_tab(self):
st.markdown("### المحتوى المحلي")
overheads.render_local_content_ui()
def _render_unbalanced_pricing_tab(self):
st.markdown("### التسعير غير المتزن")
profit_oriented.render_profit_driven_strategy()
def _render_reports_tab(self):
st.markdown("### التقارير")
st.info("يمكنك هنا تنزيل التقارير الخاصة بالتسعير وجدول الكميات.")
|