File size: 6,784 Bytes
a854c1b d9e7bdd 71b02bf a499fcb 71b02bf a499fcb a854c1b d9e7bdd 71b02bf d9e7bdd 71b02bf d9e7bdd 71b02bf d9e7bdd a499fcb b00d24d d4f2ca0 d9e7bdd 4a4508c d9e7bdd 4a4508c a854c1b d9e7bdd a854c1b 4a4508c a854c1b d9e7bdd a854c1b d9e7bdd a854c1b d9e7bdd a499fcb 4a4508c d9e7bdd 4a4508c d9e7bdd 4a4508c d9e7bdd 4a4508c d9e7bdd 4a4508c d9e7bdd 4a4508c d9e7bdd 4a4508c d9e7bdd 4a4508c a854c1b d9e7bdd a854c1b d9e7bdd 4a4508c d9e7bdd 4a4508c d9e7bdd 4a4508c d9e7bdd 4a4508c a499fcb d9e7bdd |
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 165 166 167 168 169 170 171 172 173 174 |
from pathlib import Path
import streamlit as st
import pandas as pd
from datetime import datetime
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 'project_data' not in st.session_state:
st.session_state.project_data = {}
if 'bill_of_quantities' not in st.session_state:
st.session_state.bill_of_quantities = []
# Maintain existing session state for indirect costs and risks if available.
if 'indirect_costs' not in st.session_state:
st.session_state.indirect_costs = {
'overhead': 0.10, # نسبة المصاريف العمومية والإدارية
'profit': 0.15, # نسبة الربح
'contingency': 0.05, # نسبة الطوارئ
'bonds': 0.02, # نسبة الضمانات
'insurance': 0.03 # نسبة التأمين
}
if 'risks' not in st.session_state:
st.session_state.risks = []
def run(self):
"""تشغيل وحدة التسعير"""
st.title("وحدة التسعير")
# اختيار المشروع
self._select_project()
tabs = st.tabs([
"جدول الكميات",
"تحليل التكاليف",
"سيناريوهات التسعير",
"المحتوى المحلي"
])
with tabs[0]:
self._render_bill_of_quantities_tab()
with tabs[1]:
self._render_cost_analysis_tab()
with tabs[2]:
self._render_pricing_scenarios_tab()
with tabs[3]:
self._render_local_content_tab()
def _select_project(self):
"""اختيار المشروع"""
st.sidebar.markdown("### اختيار المشروع")
# جلب المشاريع من قاعدة البيانات
projects = self._get_projects_from_db()
if projects:
project_names = [p['name'] for p in projects]
selected_project = st.sidebar.selectbox(
"اختر المشروع",
project_names
)
# تحديث بيانات المشروع المحدد
project = next((p for p in projects if p['name'] == selected_project), None)
if project:
st.session_state.current_project = project
st.session_state.bill_of_quantities = project.get('boq_items', [])
else:
st.sidebar.warning("لا توجد مشاريع متاحة")
def _get_projects_from_db(self):
"""جلب المشاريع من قاعدة البيانات"""
# هنا يتم جلب المشاريع من قاعدة البيانات
# هذه بيانات تجريبية للتوضيح
return [
{
'id': 1,
'name': 'مشروع تطوير الطريق',
'client': 'وزارة النقل',
'boq_items': [
{
'code': 'A-001',
'description': 'أعمال الحفر',
'unit': 'م3',
'quantity': 1000,
'unit_price': 50,
'total_price': 50000
}
]
}
]
def _render_bill_of_quantities_tab(self):
"""عرض تبويب جدول الكميات"""
st.markdown("### جدول الكميات")
# عرض البنود الحالية
if st.session_state.bill_of_quantities:
df = pd.DataFrame(st.session_state.bill_of_quantities)
st.dataframe(df, use_container_width=True)
# إضافة بند جديد
st.markdown("### إضافة بند جديد")
col1, col2 = st.columns(2)
with col1:
code = st.text_input("كود البند")
description = st.text_area("وصف البند")
with col2:
unit = st.selectbox("الوحدة", ["م3", "م2", "متر طولي", "عدد"])
quantity = st.number_input("الكمية", min_value=0.0)
unit_price = st.number_input("سعر الوحدة", min_value=0.0)
if st.button("إضافة البند"):
if code and description and quantity > 0 and unit_price > 0:
new_item = {
'code': code,
'description': description,
'unit': unit,
'quantity': quantity,
'unit_price': unit_price,
'total_price': quantity * unit_price
}
st.session_state.bill_of_quantities.append(new_item)
st.success("تم إضافة البند بنجاح")
st.rerun()
def _render_cost_analysis_tab(self):
st.markdown("### تحليل التكاليف")
if len(st.session_state.bill_of_quantities) > 0:
# تحليل التكاليف حسب الفئة
category_costs = {}
total_cost = 0
for item in st.session_state.bill_of_quantities:
category = item.get('category', 'غير مصنف') # Handle missing category gracefully
cost = item['total_price']
if category in category_costs:
category_costs[category] += cost
else:
category_costs[category] = cost
total_cost += cost
# عرض إجمالي التكاليف
st.metric("إجمالي التكاليف", f"{total_cost:,.2f} ريال")
# عرض التكاليف حسب الفئة
st.markdown("#### التكاليف حسب الفئة")
for category, cost in category_costs.items():
percentage = (cost / total_cost) * 100
st.write(f"- {category}: {cost:,.2f} ريال ({percentage:.1f}%)")
else:
st.warning("لا توجد بنود في جدول الكميات")
def _render_pricing_scenarios_tab(self):
st.markdown("### سيناريوهات التسعير")
balanced_pricing.render_balanced_strategy()
def _render_local_content_tab(self):
st.markdown("### المحتوى المحلي")
overheads.render_local_content_ui() |