Spaces:
Running
on
T4
Running
on
T4
import os | |
import sys | |
import streamlit as st | |
import logging | |
import pandas as pd | |
import numpy as np | |
from datetime import datetime, timedelta | |
import time | |
import plotly.express as px | |
import plotly.graph_objects as go | |
from plotly.subplots import make_subplots | |
import json | |
import base64 | |
from io import BytesIO | |
# هذا يجب أن يكون أول أمر Streamlit في البرنامج النصي | |
st.set_page_config( | |
page_title="نظام WAHBi-AI-V2", | |
page_icon="📋", | |
layout="wide", | |
initial_sidebar_state="expanded" | |
) | |
# باقي الكود الخاص بك... | |
# إضافة المسار الرئيسي للمشروع إلى PATH | |
sys.path.append(os.path.dirname(os.path.abspath(__file__))) | |
# إضافة CSS للدعم العربي وتحسين المظهر | |
def add_custom_css(): | |
custom_css = """ | |
@import url('https://fonts.googleapis.com/css2?family=Tajawal:wght@400;500;700&display=swap'); | |
* { | |
font-family: 'Tajawal', sans-serif; | |
} | |
html { | |
direction: rtl; | |
} | |
.stApp { | |
direction: rtl; | |
} | |
.css-1d391kg, .css-1cpxqw2 { | |
direction: rtl; | |
text-align: right; | |
} | |
div[data-testid="stVerticalBlock"] { | |
direction: rtl; | |
} | |
button[data-testid="baseButton-secondary"] { | |
background-color: #1e88e5; | |
border-color: #1e88e5; | |
color: white; | |
} | |
button[data-testid="baseButton-primary"] { | |
background-color: #28a745; | |
border-color: #28a745; | |
} | |
div[data-testid="stMetricValue"] { | |
font-size: 1.5rem; | |
font-weight: bold; | |
color: #1e88e5; | |
} | |
div[data-testid="stMetricDelta"] { | |
font-size: 0.9rem; | |
} | |
div[data-testid="stMetricLabel"] { | |
font-weight: 500; | |
} | |
h1, h2, h3, h4, h5, h6 { | |
font-family: 'Tajawal', sans-serif; | |
font-weight: 700; | |
} | |
.dashboard-title { | |
text-align: center; | |
margin-bottom: 2rem; | |
} | |
.insights-box { | |
border: 1px solid #e0e0e0; | |
border-radius: 5px; | |
padding: 1rem; | |
background-color: #f9f9f9; | |
} | |
.stTabs [data-baseweb="tab-list"] { | |
direction: rtl; | |
} | |
.stTabs [data-baseweb="tab"] { | |
direction: rtl; | |
text-align: right; | |
} | |
/* تصحيح مشكلة الجداول */ | |
.stDataFrame { | |
direction: rtl; | |
} | |
/* تصحيح الاتجاه في فلاتر متعدد الاختيار */ | |
div[data-testid="stMultiSelect"] { | |
direction: rtl; | |
text-align: right; | |
} | |
""" | |
st.markdown(f'<style>{custom_css}</style>', unsafe_allow_html=True) | |
# إضافة CSS | |
add_custom_css() | |
# إعداد نظام التسجيل | |
def setup_app_logging(): | |
"""إعداد نظام التسجيل""" | |
try: | |
log_dir = "logs" | |
os.makedirs(log_dir, exist_ok=True) | |
logging.basicConfig( | |
filename=os.path.join(log_dir, f"app_{datetime.now().strftime('%Y%m%d')}.log"), | |
level=logging.INFO, | |
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s" | |
) | |
return logging.getLogger(__name__) | |
except Exception as e: | |
st.error(f"خطأ في إعداد التسجيل: {str(e)}") | |
return logging.getLogger(__name__) | |
logger = setup_app_logging() | |
# دوال ونماذج محاكاة للوحدات الفعلية | |
def get_config(): | |
"""محاكاة لوحدة config.config.get_config""" | |
return { | |
"app": { | |
"name": "نظام WAHBi-AI-V2 لإدارة المناقصات والعقود", | |
"version": "1.2.0", | |
"description": "نظام متكامل لإدارة المناقصات والعقود مدعوم بالذكاء الاصطناعي" | |
}, | |
"paths": { | |
"logs_dir": "logs", | |
"data_dir": "data", | |
"models_dir": "models", | |
"reports_dir": "reports" | |
}, | |
"database": { | |
"host": "localhost", | |
"port": 5432, | |
"name": "wahbi_ai_db", | |
"user": "db_user" | |
}, | |
"api": { | |
"base_url": "https://api.wahbi-ai.org", | |
"version": "v1", | |
"timeout": 30 | |
}, | |
"ai": { | |
"models": { | |
"text_analysis": "ar_nlp_v2", | |
"risk_assessment": "risk_model_v1", | |
"prediction": "tender_prediction_v3" | |
}, | |
"parameters": { | |
"confidence_threshold": 0.75, | |
"batch_size": 16 | |
} | |
} | |
} | |
def load_local_content(): | |
"""محاكاة لوحدة modules.local_content.load_local_content""" | |
logger.info("تحميل بيانات المحتوى المحلي") | |
return True | |
def load_ai_models(): | |
"""محاكاة لوحدة modules.ai_models.load_ai_models""" | |
logger.info("تحميل نماذج الذكاء الاصطناعي") | |
return True | |
def process_document(document_path): | |
"""محاكاة لوحدة modules.document_processor.process_document""" | |
logger.info(f"معالجة المستند: {document_path}") | |
return { | |
"success": True, | |
"pages": 12, | |
"entities": 45, | |
"requirements": 32 | |
} | |
def analyze_requirements(req_text): | |
"""محاكاة لوحدة modules.requirement_analyzer.analyze_requirements""" | |
logger.info("تحليل المتطلبات") | |
return { | |
"functional": [], | |
"non_functional": [], | |
"constraints": [], | |
"risks": [] | |
} | |
def analyze_cost_risk(project_data): | |
"""محاكاة لوحدة modules.cost_risk_analyzer.analyze_cost_risk""" | |
logger.info("تحليل مخاطر التكلفة") | |
return { | |
"total_risk_score": 0.65, | |
"cost_overrun_probability": 0.35, | |
"schedule_delay_probability": 0.42 | |
} | |
def init_database(): | |
"""محاكاة لوحدة utils.database.init_database""" | |
logger.info("تهيئة قاعدة البيانات") | |
return True | |
def setup_logging(): | |
"""محاكاة لوحدة utils.helpers.setup_logging""" | |
logger.info("إعداد نظام التسجيل") | |
return True | |
def handle_uploaded_files(files): | |
"""محاكاة لوحدة utils.file_handler.handle_uploaded_files""" | |
logger.info(f"معالجة الملفات المرفوعة: {len(files)} ملفات") | |
return { | |
"success": True, | |
"processed": len(files) | |
} | |
def setup_api_connections(): | |
"""محاكاة لوحدة utils.api_integrations.setup_api_connections""" | |
logger.info("إعداد اتصالات API") | |
return True | |
def get_procurement_plan(tender_id): | |
"""محاكاة لوحدة supply_chain.procurement_planner.get_procurement_plan""" | |
logger.info(f"الحصول على خطة المشتريات للمناقصة: {tender_id}") | |
return { | |
"phases": [ | |
{"name": "التخطيط", "start": "2024-04-01", "end": "2024-04-15"}, | |
{"name": "طرح المناقصة", "start": "2024-04-16", "end": "2024-05-15"}, | |
{"name": "التقييم", "start": "2024-05-16", "end": "2024-06-01"}, | |
{"name": "الترسية", "start": "2024-06-02", "end": "2024-06-10"}, | |
{"name": "التعاقد", "start": "2024-06-11", "end": "2024-06-25"} | |
], | |
"estimated_cost": 3500000, | |
"local_content_target": 60 | |
} | |
def analyze_project_requirements(req_file): | |
"""محاكاة لوحدة analysis.requirement_analyzer.analyze_project_requirements""" | |
logger.info(f"تحليل متطلبات المشروع: {req_file}") | |
return { | |
"total_requirements": 32, | |
"functional_requirements": 24, | |
"non_functional_requirements": 8, | |
"complexity": "متوسطة", | |
"effort_estimate": "85 يوم عمل" | |
} | |
def analyze_risks(project_data): | |
"""محاكاة لوحدة analysis.risk_analyzer.analyze_risks""" | |
logger.info("تحليل المخاطر") | |
return { | |
"risk_count": 12, | |
"high_risks": 3, | |
"medium_risks": 5, | |
"low_risks": 4 | |
} | |
def estimate_costs(project_scope): | |
"""محاكاة لوحدة analysis.cost_estimator.estimate_costs""" | |
logger.info("تقدير التكاليف") | |
return { | |
"total_cost": 4250000, | |
"labor_cost": 2800000, | |
"material_cost": 850000, | |
"overhead_cost": 600000 | |
} | |
def analyze_local_content(supply_chain_data): | |
"""محاكاة لوحدة analysis.local_content_analyzer.analyze_local_content""" | |
logger.info("تحليل المحتوى المحلي") | |
return { | |
"average_local_content": 62.5, | |
"potential_increase": 15.8, | |
"suppliers_count": { | |
"local": 12, | |
"foreign": 5, | |
"joint": 3 | |
} | |
} | |
# تحميل بيانات العرض التوضيحي | |
def load_demo_data(): | |
"""تحميل بيانات توضيحية للعرض""" | |
# بيانات المناقصات | |
tenders_data = { | |
"رقم المناقصة": [f"RFP-2024-{i:03d}" for i in range(1, 21)], | |
"العنوان": [ | |
"توريد معدات تقنية", "خدمات صيانة", "تطوير نظام إلكتروني", | |
"توريد أجهزة طبية", "خدمات استشارية", "تنفيذ مشروع بنية تحتية", | |
"خدمات أمن المعلومات", "توريد أثاث مكتبي", "تطوير تطبيقات موبايل", | |
"خدمات تدريب", "توريد وتركيب أنظمة مراقبة", "صيانة مباني", | |
"تطوير محتوى تعليمي", "خدمات نظافة", "توريد سيارات", | |
"تنفيذ حملة إعلامية", "تطوير موقع إلكتروني", "خدمات لوجستية", | |
"توريد مستلزمات مكتبية", "تركيب أنظمة تكييف" | |
], | |
"تاريخ الإعلان": [ | |
(datetime.now() - timedelta(days=np.random.randint(1, 60))).strftime('%Y-%m-%d') | |
for _ in range(20) | |
], | |
"تاريخ الإغلاق": [ | |
(datetime.now() + timedelta(days=np.random.randint(5, 45))).strftime('%Y-%m-%d') | |
for _ in range(20) | |
], | |
"القيمة التقديرية": [ | |
round(np.random.uniform(100000, 5000000), -3) | |
for _ in range(20) | |
], | |
"الحالة": np.random.choice( | |
["جديدة", "مفتوحة", "قيد التقييم", "معلقة", "مغلقة", "ملغاة"], | |
size=20, | |
p=[0.15, 0.25, 0.25, 0.1, 0.2, 0.05] | |
), | |
"نسبة النجاح المتوقعة": [ | |
round(np.random.uniform(30, 95), 1) | |
for _ in range(20) | |
] | |
} | |
# بيانات العقود | |
contracts_data = { | |
"رقم العقد": [f"CONT-2024-{i:03d}" for i in range(1, 16)], | |
"رقم المناقصة": [f"RFP-2024-{i:03d}" for i in range(1, 16)], | |
"المورد": [ | |
"شركة التقنية المتطورة", "مؤسسة الحلول الذكية", "شركة الخدمات المتكاملة", | |
"مجموعة الإبداع التقني", "شركة التطوير الرقمي", "مؤسسة الجودة الشاملة", | |
"شركة الاتصالات المتقدمة", "مؤسسة البناء الحديث", "شركة التقنيات الذكية", | |
"مجموعة الخدمات الاستشارية", "شركة الحلول الهندسية", "مؤسسة التطوير والابتكار", | |
"شركة الأنظمة المتكاملة", "مجموعة الخدمات اللوجستية", "شركة المشاريع التقنية" | |
], | |
"تاريخ البدء": [ | |
(datetime.now() - timedelta(days=np.random.randint(1, 120))).strftime('%Y-%m-%d') | |
for _ in range(15) | |
], | |
"تاريخ الانتهاء": [ | |
(datetime.now() + timedelta(days=np.random.randint(30, 365))).strftime('%Y-%m-%d') | |
for _ in range(15) | |
], | |
"القيمة": [ | |
round(np.random.uniform(80000, 4500000), -3) | |
for _ in range(15) | |
], | |
"نسبة الإنجاز": [ | |
round(np.random.uniform(0, 100), 1) | |
for _ in range(15) | |
], | |
"المحتوى المحلي": [ | |
round(np.random.uniform(20, 95), 1) | |
for _ in range(15) | |
], | |
"مستوى المخاطر": np.random.choice( | |
["منخفض", "متوسط", "عالي"], | |
size=15, | |
p=[0.4, 0.4, 0.2] | |
) | |
} | |
# بيانات المخاطر | |
risks_data = { | |
"الرمز": [f"RISK-{i:02d}" for i in range(1, 13)], | |
"الوصف": [ | |
"تأخر في تسليم المواد", "تجاوز الميزانية المخططة", "مشاكل في جودة المنتجات", | |
"تغيير في المتطلبات", "مشاكل في توفر الموارد", "تضارب في الجدول الزمني", | |
"مشاكل فنية غير متوقعة", "تغييرات في الأنظمة واللوائح", "تأخر في الموافقات", | |
"مشاكل مع الموردين الفرعيين", "صعوبات في الحصول على التصاريح", "نقص في المهارات المطلوبة" | |
], | |
"التأثير": np.random.choice( | |
["منخفض", "متوسط", "عالي", "حرج"], | |
size=12, | |
p=[0.2, 0.4, 0.3, 0.1] | |
), | |
"الاحتمالية": np.random.choice( | |
["منخفضة", "متوسطة", "عالية"], | |
size=12, | |
p=[0.3, 0.5, 0.2] | |
), | |
"المعالجة": np.random.choice( | |
["تجنب", "تخفيف", "نقل", "قبول"], | |
size=12 | |
), | |
"المسؤول": [ | |
"مدير المشروع", "مدير المشتريات", "مدير الجودة", "مدير المالية", | |
"مدير تقنية المعلومات", "مدير الموارد البشرية", "مدير العمليات", | |
"المستشار القانوني", "مدير المشروع", "مدير المشتريات", | |
"مدير الجودة", "مدير المالية" | |
], | |
"الحالة": np.random.choice( | |
["جديدة", "قيد المعالجة", "معالجة", "مغلقة"], | |
size=12, | |
p=[0.25, 0.4, 0.25, 0.1] | |
) | |
} | |
# بيانات المحتوى المحلي | |
local_content_data = { | |
"الفئة": ["توظيف", "توطين التقنية", "سلاسل التوريد", "البحث والتطوير", "التدريب"], | |
"النسبة المستهدفة": [60, 40, 55, 25, 45], | |
"النسبة الحالية": [53.2, 35.8, 48.7, 18.4, 42.1], | |
"التغير السنوي": ["+8.2%", "+5.5%", "+3.2%", "+7.1%", "+9.3%"] | |
} | |
# بيانات التحليل المالي | |
financial_data = { | |
"الشهر": [f"شهر {i}" for i in range(1, 13)], | |
"المخطط": [ | |
round(np.random.uniform(1000000, 1500000), -3) | |
for _ in range(12) | |
], | |
"الفعلي": [ | |
round(np.random.uniform(800000, 1600000), -3) | |
for _ in range(12) | |
] | |
} | |
financial_df = pd.DataFrame(financial_data) | |
financial_df["الفرق"] = financial_df["الفعلي"] - financial_df["المخطط"] | |
financial_df["نسبة الانحراف"] = (financial_df["الفرق"] / financial_df["المخطط"] * 100).round(1) | |
return pd.DataFrame(tenders_data), pd.DataFrame(contracts_data), pd.DataFrame(risks_data), pd.DataFrame(local_content_data), financial_df | |
def initialize_app(): | |
"""تهيئة التطبيق وتحميل المتطلبات الأساسية""" | |
try: | |
# إعداد متغيرات الجلسة | |
if 'is_initialized' not in st.session_state: | |
st.session_state.is_initialized = False | |
config = get_config() | |
st.session_state.app_name = config["app"]["name"] | |
st.session_state.app_version = config["app"]["version"] | |
st.session_state.user_role = "مدير النظام" | |
# محاكاة تهيئة النظام | |
init_database() | |
load_local_content() | |
load_ai_models() | |
setup_api_connections() | |
# تحميل البيانات التوضيحية وتخزينها في الجلسة | |
tenders_df, contracts_df, risks_df, local_content_df, financial_df = load_demo_data() | |
st.session_state.tenders_df = tenders_df | |
st.session_state.contracts_df = contracts_df | |
st.session_state.risks_df = risks_df | |
st.session_state.local_content_df = local_content_df | |
st.session_state.financial_df = financial_df | |
st.session_state.is_initialized = True | |
# تسجيل بدء تشغيل التطبيق | |
logger.info(f"تم بدء تشغيل {st.session_state.app_name} v{st.session_state.app_version}") | |
return True | |
except Exception as e: | |
logger.error(f"خطأ في تهيئة التطبيق: {str(e)}") | |
st.error(f"خطأ في تهيئة التطبيق: {str(e)}") | |
return False | |
def render_sidebar(): | |
"""عرض القائمة الجانبية""" | |
with st.sidebar: | |
# عنوان التطبيق | |
st.title(f"📋 {st.session_state.app_name}") | |
st.caption(f"الإصدار: {st.session_state.app_version}") | |
st.markdown("---") | |
# القائمة الرئيسية | |
selected_page = st.radio( | |
"القائمة الرئيسية:", | |
["الرئيسية", "المناقصات والعقود", "تحليل المتطلبات", "تخطيط سلسلة التوريد", "تحليل المخاطر", "توقع النجاح", "المحتوى المحلي", "التقارير", "لوحة المؤشرات"] | |
) | |
st.markdown("---") | |
# إحصائيات سريعة | |
st.subheader("إحصائيات سريعة") | |
# عرض بعض الإحصائيات | |
col1, col2 = st.columns(2) | |
with col1: | |
active_tenders = len(st.session_state.tenders_df[st.session_state.tenders_df['الحالة'].isin(['جديدة', 'مفتوحة', 'قيد التقييم'])]) | |
st.metric(label="المناقصات النشطة", value=active_tenders) | |
with col2: | |
active_contracts = len(st.session_state.contracts_df[pd.to_datetime(st.session_state.contracts_df['تاريخ الانتهاء']) > datetime.now()]) | |
st.metric(label="العقود الجارية", value=active_contracts) | |
st.markdown("---") | |
# معلومات المستخدم | |
st.subheader("معلومات المستخدم") | |
st.write(f"**المستخدم:** {st.session_state.user_role}") | |
st.write(f"**تاريخ الدخول:** {datetime.now().strftime('%Y-%m-%d %H:%M')}") | |
st.markdown("---") | |
# معلومات النظام | |
st.caption("© 2024 جميع الحقوق محفوظة") | |
st.caption("فريق تطوير البرمجيات") | |
return selected_page | |
def render_header(): | |
"""عرض رأس الصفحة""" | |
col1, col2, col3 = st.columns([2, 5, 2]) | |
with col1: | |
st.write("## 📋") | |
with col2: | |
st.title("نظام WAHBi-AI-V2") | |
st.caption("منصة متكاملة لإدارة المناقصات والعقود مدعومة بالذكاء الاصطناعي") | |
with col3: | |
st.write(f"**التاريخ:** {datetime.now().strftime('%Y-%m-%d')}") | |
st.write(f"**المستخدم:** {st.session_state.user_role}") | |
st.markdown("---") | |
def home_page(): | |
"""صفحة الرئيسية""" | |
# العنوان الرئيسي | |
st.markdown("<h1 style='text-align: center;'>نظام WAHBi-AI-V2 لإدارة المناقصات والعقود</h1>", unsafe_allow_html=True) | |
st.markdown("<p style='text-align: center; font-size: 1.2em;'>مدعوم بتقنيات الذكاء الاصطناعي والتحليل المتقدم</p>", unsafe_allow_html=True) | |
# مؤشرات الأداء الرئيسية | |
st.markdown("## 📊 مؤشرات الأداء الرئيسية") | |
col1, col2, col3, col4 = st.columns(4) | |
with col1: | |
active_tenders = len(st.session_state.tenders_df[st.session_state.tenders_df['الحالة'].isin(['جديدة', 'مفتوحة', 'قيد التقييم'])]) | |
st.metric( | |
"المناقصات النشطة", | |
active_tenders, | |
"+3" | |
) | |
with col2: | |
active_contracts = len(st.session_state.contracts_df[pd.to_datetime(st.session_state.contracts_df['تاريخ الانتهاء']) > datetime.now()]) | |
st.metric( | |
"العقود الجارية", | |
active_contracts, | |
"+1" | |
) | |
with col3: | |
avg_success = round(st.session_state.tenders_df['نسبة النجاح المتوقعة'].mean(), 1) | |
st.metric( | |
"متوسط نسبة النجاح المتوقعة", | |
f"{avg_success}%", | |
"+2.5%" | |
) | |
with col4: | |
avg_local_content = round(st.session_state.contracts_df['المحتوى المحلي'].mean(), 1) | |
st.metric( | |
"متوسط المحتوى المحلي", | |
f"{avg_local_content}%", | |
"+5.3%" | |
) | |
# رسوم بيانية | |
st.markdown("## 📈 تحليل البيانات") | |
tab1, tab2, tab3 = st.tabs(["📑 المناقصات", "📝 العقود", "⚠️ المخاطر"]) | |
with tab1: | |
col1, col2 = st.columns(2) | |
with col1: | |
# توزيع المناقصات حسب الحالة | |
status_counts = st.session_state.tenders_df['الحالة'].value_counts().reset_index() | |
status_counts.columns = ['الحالة', 'العدد'] | |
fig = px.pie( | |
status_counts, | |
values='العدد', | |
names='الحالة', | |
title='توزيع المناقصات حسب الحالة', | |
color_discrete_sequence=px.colors.qualitative.Bold | |
) | |
fig.update_layout( | |
title_font_size=20, | |
title_font_family="Tajawal", | |
title_x=0.5, | |
legend_title_font_size=16 | |
) | |
st.plotly_chart(fig, use_container_width=True) | |
with col2: | |
# نسب النجاح المتوقعة للمناقصات النشطة | |
active_tenders = st.session_state.tenders_df[st.session_state.tenders_df['الحالة'].isin(['جديدة', 'مفتوحة', 'قيد التقييم'])] | |
active_tenders = active_tenders.sort_values('نسبة النجاح المتوقعة', ascending=False).head(8) | |
fig = px.bar( | |
active_tenders, | |
x='نسبة النجاح المتوقعة', | |
y='رقم المناقصة', | |
title='نسب النجاح المتوقعة للمناقصات النشطة', | |
color='نسبة النجاح المتوقعة', | |
color_continuous_scale='Viridis', | |
orientation='h' | |
) | |
fig.update_layout( | |
title_font_size=20, | |
title_font_family="Tajawal", | |
title_x=0.5, | |
yaxis={'categoryorder':'total ascending'} | |
) | |
st.plotly_chart(fig, use_container_width=True) | |
with tab2: | |
col1, col2 = st.columns(2) | |
with col1: | |
# توزيع قيم العقود | |
fig = px.histogram( | |
st.session_state.contracts_df, | |
x='القيمة', | |
nbins=10, | |
title='توزيع قيم العقود', | |
color_discrete_sequence=['#3498db'] | |
) | |
fig.update_layout( | |
title_font_size=20, | |
title_font_family="Tajawal", | |
title_x=0.5, | |
xaxis_title="القيمة (ريال)", | |
yaxis_title="عدد العقود" | |
) | |
st.plotly_chart(fig, use_container_width=True) | |
with col2: | |
# نسب المحتوى المحلي | |
fig = px.scatter( | |
st.session_state.contracts_df, | |
x='القيمة', | |
y='المحتوى المحلي', | |
size='نسبة الإنجاز', | |
color='مستوى المخاطر', | |
hover_name='رقم العقد', | |
title='نسب المحتوى المحلي للعقود', | |
color_discrete_map={ | |
'منخفض': '#2ecc71', | |
'متوسط': '#f39c12', | |
'عالي': '#e74c3c' | |
} | |
) | |
fig.update_layout( | |
title_font_size=20, | |
title_font_family="Tajawal", | |
title_x=0.5, | |
xaxis_title="القيمة (ريال)", | |
yaxis_title="نسبة المحتوى المحلي (%)" | |
) | |
st.plotly_chart(fig, use_container_width=True) | |
with tab3: | |
col1, col2 = st.columns(2) | |
with col1: | |
# مصفوفة المخاطر | |
risk_matrix = pd.crosstab( | |
st.session_state.risks_df['التأثير'], | |
st.session_state.risks_df['الاحتمالية'], | |
margins=False | |
) | |
# تحويل القيم إلى حرارية | |
risk_severity = { | |
('منخفض', 'منخفضة'): 1, | |
('منخفض', 'متوسطة'): 2, | |
('منخفض', 'عالية'): 3, | |
('متوسط', 'منخفضة'): 2, | |
('متوسط', 'متوسطة'): 4, | |
('متوسط', 'عالية'): 6, | |
('عالي', 'منخفضة'): 3, | |
('عالي', 'متوسطة'): 6, | |
('عالي', 'عالية'): 9, | |
('حرج', 'منخفضة'): 4, | |
('حرج', 'متوسطة'): 8, | |
('حرج', 'عالية'): 12 | |
} | |
# تحضير بيانات المصفوفة | |
impact_order = ['منخفض', 'متوسط', 'عالي', 'حرج'] | |
probability_order = ['منخفضة', 'متوسطة', 'عالية'] | |
# إنشاء مصفوفة حرارية | |
heat_values = [] | |
annotations = [] | |
for impact in impact_order: | |
heat_row = [] | |
for prob in probability_order: | |
try: | |
value = risk_matrix.loc[impact, prob] | |
except: | |
value = 0 | |
heat_row.append(risk_severity.get((impact, prob), 0)) | |
annotations.append(dict( | |
text=str(value), | |
x=prob, | |
y=impact, | |
showarrow=False | |
)) | |
heat_values.append(heat_row) | |
# إنشاء الرسم البياني | |
fig = go.Figure(data=go.Heatmap( | |
z=heat_values, | |
x=probability_order, | |
y=impact_order, | |
colorscale=[ | |
[0.0, "#2ecc71"], # أخضر للمخاطر المنخفضة | |
[0.33, "#f1c40f"], # أصفر للمخاطر المتوسطة | |
[0.66, "#e67e22"], # برتقالي للمخاطر العالية | |
[1.0, "#e74c3c"] # أحمر للمخاطر الحرجة | |
], | |
showscale=False | |
)) | |
# إضافة النصوص | |
for annotation in annotations: | |
fig.add_annotation(annotation) | |
fig.update_layout( | |
title='مصفوفة المخاطر', | |
title_font_size=20, | |
title_font_family="Tajawal", | |
title_x=0.5, | |
xaxis_title="الاحتمالية", | |
yaxis_title="التأثير" | |
) | |
st.plotly_chart(fig, use_container_width=True) | |
with col2: | |
# توزيع المخاطر حسب استراتيجية المعالجة | |
treatment_counts = st.session_state.risks_df['المعالجة'].value_counts().reset_index() | |
treatment_counts.columns = ['المعالجة', 'العدد'] | |
fig = px.bar( | |
treatment_counts, | |
x='المعالجة', | |
y='العدد', | |
title='استراتيجيات معالجة المخاطر', | |
color='المعالجة', | |
color_discrete_sequence=px.colors.qualitative.Pastel | |
) | |
fig.update_layout( | |
title_font_size=20, | |
title_font_family="Tajawal", | |
title_x=0.5, | |
xaxis_title="استراتيجية المعالجة", | |
yaxis_title="عدد المخاطر" | |
) | |
st.plotly_chart(fig, use_container_width=True) | |
# قسم المناقصات القادمة | |
st.markdown("## 📅 المناقصات القادمة للإغلاق") | |
upcoming_tenders = st.session_state.tenders_df[ | |
(pd.to_datetime(st.session_state.tenders_df['تاريخ الإغلاق']) > datetime.now()) & | |
(pd.to_datetime(st.session_state.tenders_df['تاريخ الإغلاق']) <= datetime.now() + timedelta(days=14)) | |
] | |
upcoming_tenders = upcoming_tenders.sort_values('تاريخ الإغلاق') | |
if not upcoming_tenders.empty: | |
# عرض المناقصات في جدول | |
upcoming_display = upcoming_tenders[['رقم المناقصة', 'العنوان', 'تاريخ الإغلاق', 'القيمة التقديرية', 'نسبة النجاح المتوقعة']] | |
upcoming_display['أيام متبقية'] = (pd.to_datetime(upcoming_display['تاريخ الإغلاق']) - datetime.now()).dt.days | |
upcoming_display['القيمة التقديرية'] = upcoming_display['القيمة التقديرية'].apply(lambda x: f"{x:,.0f} ريال") | |
upcoming_display['نسبة النجاح المتوقعة'] = upcoming_display['نسبة النجاح المتوقعة'].apply(lambda x: f"{x}%") | |
st.dataframe( | |
upcoming_display, | |
hide_index=True, | |
use_container_width=True | |
) | |
else: | |
st.info("لا توجد مناقصات ستغلق خلال الأسبوعين القادمين") | |
# قسم تحليل الذكاء الاصطناعي | |
st.markdown("## 🤖 تحليلات الذكاء الاصطناعي") | |
col1, col2 = st.columns(2) | |
with col1: | |
st.markdown("### التنبؤ بنجاح المناقصات") | |
st.markdown(""" | |
تستخدم خوارزميات الذكاء الاصطناعي لتحليل البيانات التاريخية وتحديد العوامل المؤثرة في نجاح المناقصات. | |
يمكن للنظام التنبؤ بنسب النجاح المتوقعة للمناقصات الجديدة بناءً على خصائصها ومتطلباتها. | |
""") | |
if st.button("تحليل مناقصة جديدة", key="analyze_new_tender"): | |
with st.spinner("جاري تحليل المناقصة..."): | |
time.sleep(2) # محاكاة وقت المعالجة | |
st.success("تم التحليل بنجاح!") | |
st.info("نسبة النجاح المتوقعة للمناقصة: 78.5%") | |
st.markdown(""" | |
**العوامل المؤثرة في النتيجة:** | |
- قدرة عالية على تلبية المتطلبات الفنية (+15%) | |
- توافق المنتج مع المعايير المطلوبة (+12%) | |
- خبرة سابقة مع نفس الجهة (+10%) | |
- المنافسة المتوقعة قوية (-7%) | |
""") | |
with col2: | |
st.markdown("### تحليل المتطلبات") | |
st.markdown(""" | |
يقوم النظام بتحليل وثائق المتطلبات باستخدام تقنيات معالجة اللغة الطبيعية لاستخراج البنود المهمة والمخاطر المحتملة. | |
يساعد هذا التحليل في تقييم مدى تعقيد المتطلبات وتحديد النقاط التي تحتاج إلى اهتمام خاص. | |
""") | |
uploaded_file = st.file_uploader("رفع ملف متطلبات للتحليل", type=['pdf', 'docx', 'txt']) | |
if uploaded_file is not None: | |
with st.spinner("جاري تحليل المتطلبات..."): | |
time.sleep(3) # محاكاة وقت المعالجة | |
st.success("تم تحليل المتطلبات بنجاح!") | |
# عرض نتائج التحليل | |
col1, col2 = st.columns(2) | |
with col1: | |
st.metric("عدد المتطلبات", "27") | |
st.metric("المتطلبات الوظيفية", "19") | |
st.metric("المتطلبات غير الوظيفية", "8") | |
with col2: | |
st.metric("درجة التعقيد", "متوسطة") | |
st.metric("المخاطر المحتملة", "4") | |
st.metric("البنود الغامضة", "3") | |
def dashboard_page(): | |
"""صفحة لوحة المؤشرات""" | |
st.markdown("# 📊 لوحة المؤشرات") | |
st.markdown(""" | |
## لوحة مؤشرات الأداء الرئيسية | |
استخدم هذه اللوحة لمراقبة أداء المؤشرات الرئيسية للنظام واستعراض الإحصائيات والاتجاهات. | |
""") | |
# المؤشرات الرئيسية | |
col1, col2, col3, col4 = st.columns(4) | |
with col1: | |
avg_success = round(st.session_state.tenders_df['نسبة النجاح المتوقعة'].mean(), 1) | |
st.metric( | |
"متوسط نسبة النجاح", | |
f"{avg_success}%", | |
"+2.5%" | |
) | |
with col2: | |
avg_local_content = round(st.session_state.contracts_df['المحتوى المحلي'].mean(), 1) | |
st.metric( | |
"متوسط المحتوى المحلي", | |
f"{avg_local_content}%", | |
"+5.3%" | |
) | |
with col3: | |
active_contracts = len(st.session_state.contracts_df[pd.to_datetime(st.session_state.contracts_df['تاريخ الانتهاء']) > datetime.now()]) | |
avg_contract_value = round(st.session_state.contracts_df['القيمة'].mean() / 1000000, 2) | |
st.metric( | |
"متوسط قيمة العقود", | |
f"{avg_contract_value} مليون", | |
"+0.8 مليون" | |
) | |
with col4: | |
high_risks = len(st.session_state.risks_df[st.session_state.risks_df['التأثير'].isin(['عالي', 'حرج']) & st.session_state.risks_df['الاحتمالية'].isin(['متوسطة', 'عالية'])]) | |
st.metric( | |
"المخاطر العالية", | |
high_risks, | |
"-2" | |
) | |
# الرسوم البيانية الرئيسية | |
st.markdown("## تحليلات رئيسية") | |
col1, col2 = st.columns(2) | |
with col1: | |
# توزيع المناقصات حسب الحالة | |
status_counts = st.session_state.tenders_df['الحالة'].value_counts().reset_index() | |
status_counts.columns = ['الحالة', 'العدد'] | |
fig = px.pie( | |
status_counts, | |
values='العدد', | |
names='الحالة', | |
title='توزيع المناقصات حسب الحالة', | |
color_discrete_sequence=px.colors.qualitative.Bold | |
) | |
fig.update_layout( | |
title_font_size=20, | |
title_font_family="Tajawal", | |
title_x=0.5, | |
legend_title_font_size=16 | |
) | |
st.plotly_chart(fig, use_container_width=True) | |
with col2: | |
# تحليل المحتوى المحلي | |
local_df = st.session_state.local_content_df | |
fig = go.Figure() | |
fig.add_trace(go.Bar( | |
x=local_df['الفئة'], | |
y=local_df['النسبة الحالية'], | |
name='النسبة الحالية', | |
marker_color='#3498db' | |
)) | |
fig.add_trace(go.Bar( | |
x=local_df['الفئة'], | |
y=local_df['النسبة المستهدفة'], | |
name='النسبة المستهدفة', | |
marker_color='#2ecc71' | |
)) | |
fig.update_layout( | |
barmode='group', | |
title_text='تحليل المحتوى المحلي', | |
title_font_size=20, | |
title_font_family="Tajawal", | |
title_x=0.5, | |
xaxis_title="الفئة", | |
yaxis_title="النسبة المئوية (%)", | |
legend_title="النسبة", | |
height=400 | |
) | |
st.plotly_chart(fig, use_container_width=True) | |
# تحليل المالي | |
st.markdown("## التحليل المالي والموازنة") | |
financial_df = st.session_state.financial_df | |
fig = go.Figure() | |
fig.add_trace(go.Scatter( | |
x=financial_df['الشهر'], | |
y=financial_df['المخطط'], | |
name='المخطط', | |
line=dict(color='#3498db', width=2) | |
)) | |
fig.add_trace(go.Scatter( | |
x=financial_df['الشهر'], | |
y=financial_df['الفعلي'], | |
name='الفعلي', | |
line=dict(color='#e74c3c', width=2) | |
)) | |
fig.update_layout( | |
title_text='مقارنة التكاليف المخططة والفعلية', | |
title_font_size=20, | |
title_font_family="Tajawal", | |
title_x=0.5, | |
xaxis_title="الشهر", | |
yaxis_title="التكلفة (ريال)", | |
legend_title="النوع", | |
height=400 | |
) | |
st.plotly_chart(fig, use_container_width=True) | |
# المشاريع القادمة | |
st.markdown("## المشاريع والمناقصات القادمة") | |
upcoming_tenders = st.session_state.tenders_df[ | |
(pd.to_datetime(st.session_state.tenders_df['تاريخ الإغلاق']) > datetime.now()) & | |
(pd.to_datetime(st.session_state.tenders_df['تاريخ الإغلاق']) <= datetime.now() + timedelta(days=30)) | |
] | |
if not upcoming_tenders.empty: | |
upcoming_display = upcoming_tenders[['رقم المناقصة', 'العنوان', 'تاريخ الإغلاق', 'القيمة التقديرية', 'نسبة النجاح المتوقعة']] | |
upcoming_display['أيام متبقية'] = (pd.to_datetime(upcoming_display['تاريخ الإغلاق']) - datetime.now()).dt.days | |
upcoming_display['القيمة التقديرية'] = upcoming_display['القيمة التقديرية'].apply(lambda x: f"{x:,.0f} ريال") | |
upcoming_display['نسبة النجاح المتوقعة'] = upcoming_display['نسبة النجاح المتوقعة'].apply(lambda x: f"{x}%") | |
st.dataframe(upcoming_display, hide_index=True, use_container_width=True) | |
else: | |
st.info("لا توجد مناقصات قادمة خلال الثلاثين يوماً القادمة.") | |
def procurement_page(): | |
"""صفحة المناقصات والعقود""" | |
st.markdown("# 📑 المناقصات والعقود") | |
tab1, tab2 = st.tabs(["المناقصات", "العقود"]) | |
with tab1: | |
st.markdown("## إدارة المناقصات") | |
# أزرار الإجراءات | |
col1, col2, col3, col4 = st.columns(4) | |
with col1: | |
if st.button("🆕 إضافة مناقصة جديدة"): | |
st.session_state.show_add_tender = True | |
with col2: | |
st.button("🔍 بحث متقدم") | |
with col3: | |
st.button("📊 تصدير التقرير") | |
with col4: | |
st.button("🔄 تحديث البيانات") | |
# عرض جدول المناقصات | |
st.markdown("### قائمة المناقصات") | |
# فلاتر | |
col1, col2, col3 = st.columns(3) | |
with col1: | |
status_filter = st.multiselect( | |
"الحالة:", | |
["الكل"] + list(st.session_state.tenders_df['الحالة'].unique()), | |
default=["الكل"] | |
) | |
with col2: | |
date_range = st.date_input( | |
"تاريخ الإعلان:", | |
value=( | |
(datetime.now() - timedelta(days=60)).date(), | |
datetime.now().date() | |
) | |
) | |
with col3: | |
min_value, max_value = st.slider( | |
"القيمة التقديرية (ريال):", | |
0, | |
int(st.session_state.tenders_df['القيمة التقديرية'].max()), | |
(0, int(st.session_state.tenders_df['القيمة التقديرية'].max())), | |
step=100000 | |
) | |
# تطبيق الفلاتر | |
filtered_df = st.session_state.tenders_df.copy() | |
# فلتر الحالة | |
if "الكل" not in status_filter: | |
filtered_df = filtered_df[filtered_df['الحالة'].isin(status_filter)] | |
# فلتر التاريخ | |
filtered_df = filtered_df[ | |
(pd.to_datetime(filtered_df['تاريخ الإعلان']) >= pd.Timestamp(date_range[0])) & | |
(pd.to_datetime(filtered_df['تاريخ الإعلان']) <= pd.Timestamp(date_range[1])) | |
] | |
# فلتر القيمة | |
filtered_df = filtered_df[ | |
(filtered_df['القيمة التقديرية'] >= min_value) & | |
(filtered_df['القيمة التقديرية'] <= max_value) | |
] | |
# عرض الجدول | |
st.dataframe( | |
filtered_df, | |
use_container_width=True, | |
hide_index=True | |
) | |
# نموذج إضافة مناقصة جديدة | |
if 'show_add_tender' in st.session_state and st.session_state.show_add_tender: | |
st.markdown("### إضافة مناقصة جديدة") | |
with st.form("add_tender_form"): | |
col1, col2 = st.columns(2) | |
with col1: | |
tender_id = st.text_input("رقم المناقصة", f"RFP-2024-{len(st.session_state.tenders_df) + 1:03d}") | |
title = st.text_input("عنوان المناقصة", "") | |
start_date = st.date_input("تاريخ الإعلان", datetime.now()) | |
with col2: | |
end_date = st.date_input("تاريخ الإغلاق", datetime.now() + timedelta(days=30)) | |
estimated_value = st.number_input("القيمة التقديرية", min_value=0, value=1000000, step=100000) | |
status = st.selectbox("الحالة", ["جديدة", "مفتوحة", "قيد التقييم", "معلقة", "مغلقة", "ملغاة"]) | |
submitted = st.form_submit_button("حفظ المناقصة") | |
cancel = st.form_submit_button("إلغاء") | |
if submitted: | |
st.success("تم إضافة المناقصة بنجاح") | |
st.session_state.show_add_tender = False | |
if cancel: | |
st.session_state.show_add_tender = False | |
with tab2: | |
st.markdown("## إدارة العقود") | |
# أزرار الإجراءات | |
col1, col2, col3, col4 = st.columns(4) | |
with col1: | |
st.button("🆕 إضافة عقد جديد") | |
with col2: | |
st.button("🔍 بحث متقدم", key="search_contracts") | |
with col3: | |
st.button("📊 تصدير التقرير", key="export_contracts") | |
with col4: | |
st.button("🔄 تحديث البيانات", key="refresh_contracts") | |
# عرض جدول العقود | |
st.markdown("### قائمة العقود") | |
# فلاتر | |
col1, col2 = st.columns(2) | |
with col1: | |
risk_filter = st.multiselect( | |
"مستوى المخاطر:", | |
["الكل"] + list(st.session_state.contracts_df['مستوى المخاطر'].unique()), | |
default=["الكل"] | |
) | |
with col2: | |
local_content_range = st.slider( | |
"نسبة المحتوى المحلي (%):", | |
0, 100, | |
(0, 100), | |
step=10 | |
) | |
# تطبيق الفلاتر | |
filtered_df = st.session_state.contracts_df.copy() | |
# فلتر مستوى المخاطر | |
if "الكل" not in risk_filter: | |
filtered_df = filtered_df[filtered_df['مستوى المخاطر'].isin(risk_filter)] | |
# فلتر المحتوى المحلي | |
filtered_df = filtered_df[ | |
(filtered_df['المحتوى المحلي'] >= local_content_range[0]) & | |
(filtered_df['المحتوى المحلي'] <= local_content_range[1]) | |
] | |
# عرض الجدول | |
st.dataframe( | |
filtered_df, | |
use_container_width=True, | |
hide_index=True | |
) | |
def requirements_analysis_page(): | |
"""صفحة تحليل المتطلبات""" | |
st.markdown("# 🔍 تحليل المتطلبات") | |
st.markdown(""" | |
## نظام تحليل المتطلبات بالذكاء الاصطناعي | |
يقوم هذا النظام بتحليل وثائق المتطلبات باستخدام تقنيات معالجة اللغة الطبيعية والذكاء الاصطناعي لاستخراج: | |
- المتطلبات الوظيفية وغير الوظيفية | |
- التبعيات بين المتطلبات | |
- المخاطر المحتملة | |
- الشروط والقيود | |
- تقدير الجهد والتكلفة | |
""") | |
col1, col2 = st.columns(2) | |
with col1: | |
st.markdown("### تحميل وثائق المتطلبات") | |
uploaded_file = st.file_uploader("اختر ملف", type=['pdf', 'docx', 'txt']) | |
if uploaded_file is not None: | |
st.success(f"تم تحميل الملف: {uploaded_file.name}") | |
if st.button("بدء التحليل"): | |
with st.spinner("جاري تحليل المتطلبات..."): | |
time.sleep(3) # محاكاة وقت المعالجة | |
st.success("تم تحليل المستند بنجاح!") | |
# عرض نتائج التحليل في الجانب الآخر | |
st.session_state.show_analysis_results = True | |
with col2: | |
if 'show_analysis_results' in st.session_state and st.session_state.show_analysis_results: | |
st.markdown("### نتائج التحليل") | |
tab1, tab2, tab3 = st.tabs(["ملخص", "المتطلبات المستخرجة", "المخاطر"]) | |
with tab1: | |
col1, col2 = st.columns(2) | |
with col1: | |
st.metric("إجمالي المتطلبات", "34") | |
st.metric("المتطلبات الوظيفية", "26") | |
st.metric("المتطلبات غير الوظيفية", "8") | |
with col2: | |
st.metric("تقدير الجهد", "87 يوم عمل") | |
st.metric("التكلفة التقديرية", "435,000 ريال") | |
st.metric("درجة التعقيد", "متوسطة") | |
with tab2: | |
requirements_demo = pd.DataFrame({ | |
"المعرف": [f"REQ-{i:03d}" for i in range(1, 11)], | |
"النوع": ["وظيفي", "وظيفي", "غير وظيفي", "وظيفي", "وظيفي", "غير وظيفي", "وظيفي", "وظيفي", "غير وظيفي", "وظيفي"], | |
"الوصف": [ | |
"يجب أن يوفر النظام واجهة لإدارة المستخدمين", | |
"يجب أن يتيح النظام إمكانية إضافة مناقصات جديدة", | |
"يجب أن يدعم النظام اللغة العربية", | |
"يجب أن يوفر النظام تقارير عن حالة المناقصات", | |
"يجب أن يقوم النظام بحساب نسبة المحتوى المحلي", | |
"يجب أن يستجيب النظام في أقل من 3 ثواني", | |
"يجب أن يدعم النظام تحميل المستندات", | |
"يجب أن يوفر النظام واجهة لإدارة العقود", | |
"يجب أن يعمل النظام على متصفحات الويب الحديثة", | |
"يجب أن يوفر النظام نظام تنبيهات للمواعيد النهائية" | |
], | |
"الأولوية": ["عالية", "عالية", "متوسطة", "عالية", "عالية", "منخفضة", "متوسطة", "عالية", "متوسطة", "متوسطة"], | |
"التعقيد": ["متوسط", "بسيط", "بسيط", "متوسط", "معقد", "بسيط", "متوسط", "معقد", "بسيط", "متوسط"] | |
}) | |
st.dataframe(requirements_demo, use_container_width=True, hide_index=True) | |
with tab3: | |
risks_demo = pd.DataFrame({ | |
"المعرف": [f"RISK-{i:03d}" for i in range(1, 6)], | |
"الوصف": [ | |
"غموض في متطلبات حساب المحتوى المحلي", | |
"تعارض بين متطلبات الأداء والوظائف المطلوبة", | |
"عدم وضوح آلية تكامل النظام مع الأنظمة الخارجية", | |
"تعقيد في متطلبات التقارير", | |
"متطلبات أمنية غير محددة بوضوح" | |
], | |
"المتطلبات المتأثرة": [ | |
"REQ-005", | |
"REQ-006, REQ-003", | |
"REQ-010", | |
"REQ-004", | |
"REQ-001, REQ-007" | |
], | |
"الخطورة": ["عالية", "متوسطة", "عالية", "متوسطة", "عالية"], | |
"التوصية": [ | |
"طلب توضيح تفصيلي من العميل", | |
"إعادة تحديد أولويات المتطلبات", | |
"عقد ورشة عمل للتكامل", | |
"طلب نماذج للتقارير المطلوبة", | |
"إضافة متطلبات أمنية تفصيلية" | |
] | |
}) | |
st.dataframe(risks_demo, use_container_width=True, hide_index=True) | |
else: | |
st.markdown("### ملخص المتطلبات") | |
st.info("قم بتحميل ملف المتطلبات وبدء التحليل لعرض النتائج هنا") | |
def supply_chain_page(): | |
"""صفحة تخطيط سلسلة التوريد""" | |
st.markdown("# 🔄 تخطيط سلسلة التوريد") | |
tab1, tab2, tab3 = st.tabs(["تحليل المحتوى المحلي", "إدارة الموردين", "التخطيط للمشتريات"]) | |
with tab1: | |
st.markdown("## تحليل وتحسين المحتوى المحلي") | |
col1, col2 = st.columns(2) | |
with col1: | |
st.markdown("### نسب المحتوى المحلي حسب الفئة") | |
# الرسم البياني | |
fig = go.Figure() | |
local_df = st.session_state.local_content_df | |
# إضافة الأعمدة | |
fig.add_trace(go.Bar( | |
x=local_df['الفئة'], | |
y=local_df['النسبة الحالية'], | |
name='النسبة الحالية', | |
marker_color='#3498db' | |
)) | |
fig.add_trace(go.Bar( | |
x=local_df['الفئة'], | |
y=local_df['النسبة المستهدفة'], | |
name='النسبة المستهدفة', | |
marker_color='#2ecc71' | |
)) | |
# تخصيص الرسم البياني | |
fig.update_layout( | |
barmode='group', | |
title_text='مقارنة المحتوى المحلي الحالي والمستهدف', | |
title_font_size=16, | |
xaxis_title="الفئة", | |
yaxis_title="النسبة المئوية (%)", | |
legend_title="النسبة", | |
height=400 | |
) | |
st.plotly_chart(fig, use_container_width=True) | |
with col2: | |
st.markdown("### فرص تحسين المحتوى المحلي") | |
for i, row in local_df.iterrows(): | |
gap = row['النسبة المستهدفة'] - row['النسبة الحالية'] | |
if gap > 5: | |
st.markdown(f""" | |
**تحسين {row['الفئة']}** | |
- الفجوة الحالية: {gap:.1f}% | |
- التغير السنوي: {row['التغير السنوي']} | |
- توصية: زيادة الاعتماد على الموردين المحليين في هذه الفئة | |
""") | |
st.markdown("### تقدير التأثير الاقتصادي") | |
st.metric( | |
"القيمة المضافة المحلية المتوقعة", | |
"3.2 مليون ريال", | |
"+12.5%" | |
) | |
with tab2: | |
st.markdown("## إدارة الموردين") | |
# أزرار الإجراءات | |
col1, col2, col3 = st.columns(3) | |
with col1: | |
st.button("إضافة مورد جديد") | |
with col2: | |
st.button("تصدير قائمة الموردين") | |
with col3: | |
st.button("تقييم الموردين") | |
# بيانات الموردين التوضيحية | |
suppliers_data = { | |
"اسم المورد": [ | |
"شركة التقنية المتطورة", "مؤسسة الحلول الذكية", "شركة الخدمات المتكاملة", | |
"مجموعة الإبداع التقني", "شركة التطوير الرقمي", "مؤسسة الجودة الشاملة", | |
"شركة الاتصالات المتقدمة", "مؤسسة البناء الحديث" | |
], | |
"التصنيف": [ | |
"محلي", "محلي", "أجنبي", | |
"محلي", "محلي مشترك", "محلي", | |
"أجنبي", "محلي" | |
], | |
"المنتجات/الخدمات": [ | |
"أنظمة تقنية", "خدمات استشارية", "معدات وأجهزة", | |
"برمجيات", "حلول تقنية", "خدمات صيانة", | |
"أنظمة اتصالات", "إنشاءات" | |
], | |
"درجة التقييم": [ | |
"A", "A", "B", | |
"B", "A", "C", | |
"B", "A" | |
], | |
"المحتوى المحلي": [ | |
"87%", "92%", "34%", | |
"79%", "63%", "95%", | |
"28%", "91%" | |
], | |
"تاريخ آخر تعامل": [ | |
"2024-01-15", "2024-02-20", "2023-11-05", | |
"2024-03-10", "2024-02-25", "2023-09-18", | |
"2024-01-30", "2024-03-05" | |
] | |
} | |
suppliers_df = pd.DataFrame(suppliers_data) | |
# تصفية البيانات | |
local_filter = st.multiselect( | |
"التصنيف:", | |
["الكل"] + list(suppliers_df['التصنيف'].unique()), | |
default=["الكل"] | |
) | |
filtered_suppliers = suppliers_df.copy() | |
if "الكل" not in local_filter: | |
filtered_suppliers = filtered_suppliers[filtered_suppliers['التصنيف'].isin(local_filter)] | |
# عرض الجدول | |
st.dataframe(filtered_suppliers, use_container_width=True, hide_index=True) | |
with tab3: | |
st.markdown("## التخطيط للمشتريات") | |
st.markdown(""" | |
### التخطيط الاستراتيجي للمشتريات | |
استخدم هذا القسم لتخطيط المشتريات المستقبلية وتحليل الاحتياجات وفرص توفير التكاليف. | |
""") | |
col1, col2 = st.columns(2) | |
with col1: | |
st.markdown("### توزيع المشتريات حسب الفئة") | |
categories = ["أجهزة ومعدات", "خدمات استشارية", "برمجيات", "خدمات صيانة", "مستلزمات مكتبية"] | |
values = [45, 25, 15, 10, 5] | |
fig = px.pie( | |
names=categories, | |
values=values, | |
title="توزيع المشتريات حسب الفئة", | |
color_discrete_sequence=px.colors.qualitative.Pastel | |
) | |
fig.update_layout( | |
title_font_size=16, | |
legend_title="" | |
) | |
st.plotly_chart(fig, use_container_width=True) | |
with col2: | |
st.markdown("### التكاليف الشهرية المتوقعة") | |
# بيانات مالية توضيحية | |
financial_df = st.session_state.financial_df | |
# تحويل البيانات المالية إلى صيغة مناسبة للرسم البياني | |
fig = go.Figure() | |
fig.add_trace(go.Scatter( | |
x=financial_df['الشهر'], | |
y=financial_df['المخطط'], | |
name='المخطط', | |
line=dict(color='#3498db', width=2) | |
)) | |
fig.add_trace(go.Scatter( | |
x=financial_df['الشهر'], | |
y=financial_df['الفعلي'], | |
name='الفعلي', | |
line=dict(color='#e74c3c', width=2) | |
)) | |
fig.update_layout( | |
title_text='مقارنة التكاليف المخططة والفعلية', | |
title_font_size=16, | |
xaxis_title="الشهر", | |
yaxis_title="التكلفة (ريال)", | |
legend_title="النوع", | |
height=400 | |
) | |
st.plotly_chart(fig, use_container_width=True) | |
def risk_analysis_page(): | |
"""صفحة تحليل المخاطر""" | |
st.markdown("# ⚠️ تحليل المخاطر") | |
st.markdown(""" | |
## نظام تحليل وإدارة المخاطر | |
يقوم هذا النظام بتحديد وتقييم وإدارة المخاطر المرتبطة بالمناقصات والعقود. | |
يمكنك من خلاله تحليل المخاطر المختلفة وتحديد استراتيجيات الاستجابة المناسبة. | |
""") | |
col1, col2 = st.columns([1, 2]) | |
with col1: | |
st.markdown("### تصنيف المخاطر") | |
risk_options = [ | |
"مخاطر قانونية", | |
"مخاطر مالية", | |
"مخاطر تشغيلية", | |
"مخاطر فنية", | |
"مخاطر تعاقدية", | |
"مخاطر خارجية" | |
] | |
selected_risk = st.radio("اختر نوع المخاطر:", risk_options) | |
st.markdown("### تحليل ذكي") | |
if st.button("تحليل المخاطر بالذكاء الاصطناعي"): | |
with st.spinner("جاري التحليل..."): | |
time.sleep(2) | |
st.success("تم التحليل بنجاح!") | |
ai_results = { | |
"مخاطر قانونية": """ | |
- احتمالية عالية لتغير اللوائح التنظيمية خلال فترة المشروع | |
- مخاطر متوسطة لوجود ثغرات في صياغة العقد | |
- مخاطر منخفضة لنزاعات قضائية | |
""", | |
"مخاطر مالية": """ | |
- مخاطر عالية لتقلبات أسعار المواد الخام | |
- مخاطر متوسطة لتغير أسعار الصرف | |
- مخاطر عالية للتأخر في السداد | |
""", | |
"مخاطر تشغيلية": """ | |
- مخاطر متوسطة لتأخر جدول المشروع | |
- مخاطر عالية لنقص الكوادر المؤهلة | |
- مخاطر منخفضة للأعطال التقنية | |
""", | |
"مخاطر فنية": """ | |
- مخاطر عالية لعدم وضوح المتطلبات الفنية | |
- مخاطر متوسطة لتعارض تقني مع أنظمة قائمة | |
- مخاطر منخفضة لأداء النظام | |
""", | |
"مخاطر تعاقدية": """ | |
- مخاطر عالية لغموض نطاق العمل | |
- مخاطر متوسطة لتغيير متطلبات العميل | |
- مخاطر متوسطة لمعايير القبول | |
""", | |
"مخاطر خارجية": """ | |
- مخاطر منخفضة للعوامل البيئية | |
- مخاطر متوسطة للعوامل السياسية | |
- مخاطر منخفضة للكوارث الطبيعية | |
""" | |
} | |
st.info(ai_results[selected_risk]) | |
with col2: | |
st.markdown("### سجل المخاطر") | |
# عرض جدول المخاطر | |
st.dataframe( | |
st.session_state.risks_df, | |
use_container_width=True, | |
hide_index=True | |
) | |
# مصفوفة المخاطر | |
st.markdown("### مصفوفة المخاطر") | |
risk_matrix = pd.crosstab( | |
st.session_state.risks_df['التأثير'], | |
st.session_state.risks_df['الاحتمالية'], | |
margins=False | |
) | |
# تحويل القيم إلى حرارية | |
risk_severity = { | |
('منخفض', 'منخفضة'): 1, | |
('منخفض', 'متوسطة'): 2, | |
('منخفض', 'عالية'): 3, | |
('متوسط', 'منخفضة'): 2, | |
('متوسط', 'متوسطة'): 4, | |
('متوسط', 'عالية'): 6, | |
('عالي', 'منخفضة'): 3, | |
('عالي', 'متوسطة'): 6, | |
('عالي', 'عالية'): 9, | |
('حرج', 'منخفضة'): 4, | |
('حرج', 'متوسطة'): 8, | |
('حرج', 'عالية'): 12 | |
} | |
# تحضير بيانات المصفوفة | |
impact_order = ['منخفض', 'متوسط', 'عالي', 'حرج'] | |
probability_order = ['منخفضة', 'متوسطة', 'عالية'] | |
# إنشاء مصفوفة حرارية | |
heat_values = [] | |
annotations = [] | |
for impact in impact_order: | |
heat_row = [] | |
for prob in probability_order: | |
try: | |
value = risk_matrix.loc[impact, prob] | |
except: | |
value = 0 | |
heat_row.append(risk_severity.get((impact, prob), 0)) | |
annotations.append(dict( | |
text=str(value), | |
x=prob, | |
y=impact, | |
showarrow=False | |
)) | |
heat_values.append(heat_row) | |
# إنشاء الرسم البياني | |
fig = go.Figure(data=go.Heatmap( | |
z=heat_values, | |
x=probability_order, | |
y=impact_order, | |
colorscale=[ | |
[0.0, "#2ecc71"], # أخضر للمخاطر المنخفضة | |
[0.33, "#f1c40f"], # أصفر للمخاطر المتوسطة | |
[0.66, "#e67e22"], # برتقالي للمخاطر العالية | |
[1.0, "#e74c3c"] # أحمر للمخاطر الحرجة | |
], | |
showscale=False | |
)) | |
# إضافة النصوص | |
for annotation in annotations: | |
fig.add_annotation(annotation) | |
fig.update_layout( | |
title_font_size=16, | |
title_x=0.5, | |
xaxis_title="الاحتمالية", | |
yaxis_title="التأثير" | |
) | |
st.plotly_chart(fig, use_container_width=True) | |
def local_content_page(): | |
"""صفحة المحتوى المحلي""" | |
st.markdown("# 🏠 المحتوى المحلي") | |
st.markdown(""" | |
## قياس وتحسين المحتوى المحلي | |
يتيح النظام إمكانية قياس نسبة المحتوى المحلي في المشاريع والمناقصات وتحديد فرص التحسين. | |
""") | |
tab1, tab2 = st.tabs(["تحليل المحتوى المحلي", "فرص التحسين"]) | |
with tab1: | |
# تحليل المحتوى المحلي حسب الفئة | |
local_df = st.session_state.local_content_df | |
col1, col2 = st.columns([2, 1]) | |
with col1: | |
fig = go.Figure() | |
fig.add_trace(go.Bar( | |
x=local_df['الفئة'], | |
y=local_df['النسبة الحالية'], | |
name='النسبة الحالية', | |
marker_color='#3498db' | |
)) | |
fig.add_trace(go.Bar( | |
x=local_df['الفئة'], | |
y=local_df['النسبة المستهدفة'], | |
name='النسبة المستهدفة', | |
marker_color='#2ecc71' | |
)) | |
fig.update_layout( | |
barmode='group', | |
title_text='تحليل المحتوى المحلي حسب الفئة', | |
title_font_size=20, | |
title_x=0.5, | |
xaxis_title="الفئة", | |
yaxis_title="النسبة المئوية (%)", | |
legend_title="النسبة" | |
) | |
st.plotly_chart(fig, use_container_width=True) | |
with col2: | |
total_current = local_df['النسبة الحالية'].mean() | |
total_target = local_df['النسبة المستهدفة'].mean() | |
gap = total_target - total_current | |
st.markdown("### المحتوى المحلي الإجمالي") | |
st.metric( | |
"النسبة الحالية", | |
f"{total_current:.1f}%", | |
delta=None | |
) | |
st.metric( | |
"النسبة المستهدفة", | |
f"{total_target:.1f}%", | |
delta=None | |
) | |
st.metric( | |
"الفجوة", | |
f"{gap:.1f}%", | |
delta=None | |
) | |
# تحليل المحتوى المحلي حسب العقود | |
st.markdown("### تحليل المحتوى المحلي في العقود") | |
sorted_contracts = st.session_state.contracts_df.sort_values('المحتوى المحلي', ascending=False) | |
fig = px.bar( | |
sorted_contracts.head(10), | |
x='رقم العقد', | |
y='المحتوى المحلي', | |
color='المحتوى المحلي', | |
color_continuous_scale=px.colors.sequential.Viridis, | |
title="أعلى 10 عقود من حيث المحتوى المحلي" | |
) | |
fig.update_layout( | |
title_font_size=16, | |
title_x=0.5, | |
xaxis_title="رقم العقد", | |
yaxis_title="نسبة المحتوى المحلي (%)" | |
) | |
st.plotly_chart(fig, use_container_width=True) | |
with tab2: | |
st.markdown("### فرص تحسين المحتوى المحلي") | |
col1, col2 = st.columns(2) | |
with col1: | |
st.markdown(""" | |
#### مجالات التحسين | |
1. **توظيف الكوادر المحلية** | |
- توظيف مهندسين محليين | |
- التعاقد مع خبراء محليين للاستشارات | |
- برامج تدريب للكوادر المحلية | |
2. **شراء المواد والمعدات المحلية** | |
- تفضيل الموردين المحليين | |
- دعم المصنعين المحليين | |
- تطوير سلاسل التوريد المحلية | |
3. **نقل التقنية** | |
- توطين التقنيات الحديثة | |
- تطوير الخبرات المحلية | |
- الشراكة مع الجامعات المحلية | |
""") | |
with col2: | |
st.markdown("### أكبر الفجوات في المحتوى المحلي") | |
# البيانات | |
categories = [] | |
gaps = [] | |
for i, row in local_df.iterrows(): | |
gap = row['النسبة المستهدفة'] - row['النسبة الحالية'] | |
categories.append(row['الفئة']) | |
gaps.append(gap) | |
# ترتيب البيانات | |
gap_df = pd.DataFrame({ | |
'الفئة': categories, | |
'الفجوة': gaps | |
}) | |
sorted_gap_df = gap_df.sort_values('الفجوة', ascending=False) | |
fig = px.bar( | |
sorted_gap_df, | |
x='الفئة', | |
y='الفجوة', | |
color='الفجوة', | |
color_continuous_scale=px.colors.sequential.Reds, | |
title="الفجوات في المحتوى المحلي حسب الفئة" | |
) | |
fig.update_layout( | |
title_font_size=16, | |
title_x=0.5, | |
xaxis_title="الفئة", | |
yaxis_title="الفجوة (%)" | |
) | |
st.plotly_chart(fig, use_container_width=True) | |
def success_prediction_page(): | |
"""صفحة توقع احتمالية النجاح""" | |
st.markdown("# 🎯 توقع احتمالية النجاح") | |
st.markdown(""" | |
## نظام التنبؤ بنجاح المناقصات | |
يستخدم هذا النظام خوارزميات الذكاء الاصطناعي لتحليل عوامل نجاح المناقصات وتوقع احتمالية الفوز بها. | |
""") | |
col1, col2 = st.columns([1, 2]) | |
with col1: | |
st.markdown("### تحليل مناقصة جديدة") | |
with st.form("prediction_form"): | |
tender_type = st.selectbox( | |
"نوع المناقصة:", | |
["مناقصة عامة", "مناقصة محدودة", "منافسة محدودة", "شراء مباشر"] | |
) | |
tender_sector = st.selectbox( | |
"القطاع:", | |
["حكومي", "شبه حكومي", "خاص"] | |
) | |
tender_value = st.number_input( | |
"القيمة التقديرية (ريال):", | |
min_value=100000, | |
max_value=100000000, | |
value=1000000, | |
step=100000 | |
) | |
competitors_count = st.slider( | |
"عدد المنافسين المتوقع:", | |
min_value=1, | |
max_value=20, | |
value=5 | |
) | |
technical_weight = st.slider( | |
"وزن التقييم الفني (%):", | |
min_value=0, | |
max_value=100, | |
value=60 | |
) | |
previous_experience = st.checkbox("خبرة سابقة مع نفس الجهة") | |
local_content_value = st.slider( | |
"نسبة المحتوى المحلي المقدمة (%):", | |
min_value=0, | |
max_value=100, | |
value=65 | |
) | |
submit_button = st.form_submit_button("توقع احتمالية النجاح") | |
if submit_button: | |
with st.spinner("جاري تحليل المناقصة..."): | |
time.sleep(2) # محاكاة وقت المعالجة | |
# حساب احتمالية النجاح (محاكاة) | |
base_probability = 70 # احتمالية أساسية | |
# العوامل المؤثرة | |
factors = {} | |
# نوع المناقصة | |
if tender_type == "مناقصة عامة": | |
factors["نوع المناقصة"] = -5 # منافسة أكبر | |
elif tender_type == "مناقصة محدودة": | |
factors["نوع المناقصة"] = 5 | |
elif tender_type == "منافسة محدودة": | |
factors["نوع المناقصة"] = 10 | |
else: # شراء مباشر | |
factors["نوع المناقصة"] = 15 | |
# القطاع | |
if tender_sector == "حكومي": | |
factors["القطاع"] = 0 | |
elif tender_sector == "شبه حكومي": | |
factors["القطاع"] = 5 | |
else: # خاص | |
factors["القطاع"] = -5 | |
# القيمة التقديرية | |
if tender_value < 500000: | |
factors["القيمة"] = 5 | |
elif tender_value < 2000000: | |
factors["القيمة"] = 0 | |
elif tender_value < 10000000: | |
factors["القيمة"] = -5 | |
else: | |
factors["القيمة"] = -10 | |
# عدد المنافسين | |
if competitors_count <= 3: | |
factors["المنافسين"] = 10 | |
elif competitors_count <= 7: | |
factors["المنافسين"] = 0 | |
else: | |
factors["المنافسين"] = -10 | |
# وزن التقييم الفني | |
if technical_weight >= 70: | |
factors["التقييم الفني"] = 10 | |
elif technical_weight >= 50: | |
factors["التقييم الفني"] = 5 | |
else: | |
factors["التقييم الفني"] = 0 | |
# خبرة سابقة | |
if previous_experience: | |
factors["خبرة سابقة"] = 15 | |
else: | |
factors["خبرة سابقة"] = 0 | |
# المحتوى المحلي | |
if local_content_value >= 80: | |
factors["المحتوى المحلي"] = 10 | |
elif local_content_value >= 60: | |
factors["المحتوى المحلي"] = 5 | |
elif local_content_value >= 40: | |
factors["المحتوى المحلي"] = 0 | |
else: | |
factors["المحتوى المحلي"] = -5 | |
# حساب الاحتمالية النهائية | |
final_probability = base_probability + sum(factors.values()) | |
# تعديل النتيجة ضمن النطاق المقبول | |
final_probability = max(min(final_probability, 99), 1) | |
# عرض النتيجة | |
st.success(f"احتمالية النجاح في المناقصة: {final_probability}%") | |
# عرض تفاصيل التحليل | |
st.markdown("### تفاصيل التحليل") | |
for factor, value in factors.items(): | |
icon = "🔼" if value > 0 else "🔽" if value < 0 else "◀▶" | |
st.text(f"{icon} {factor}: {value:+d}%") | |
with col2: | |
st.markdown("### العوامل المؤثرة في نجاح المناقصات") | |
# بيانات توضيحية للعوامل المؤثرة | |
factors_df = pd.DataFrame({ | |
"العامل": [ | |
"المحتوى المحلي", | |
"السعر التنافسي", | |
"الخبرة السابقة", | |
"الحلول التقنية", | |
"القدرات الفنية", | |
"سرعة التنفيذ", | |
"جودة المقترح الفني", | |
"الامتثال للمتطلبات" | |
], | |
"تأثير إيجابي": [ | |
0.85, 0.78, 0.72, 0.65, 0.62, 0.58, 0.52, 0.48 | |
] | |
}) | |
fig = px.bar( | |
factors_df, | |
x="تأثير إيجابي", | |
y="العامل", | |
orientation='h', | |
color="تأثير إيجابي", | |
color_continuous_scale=px.colors.sequential.Viridis, | |
title="تأثير العوامل المختلفة على احتمالية النجاح" | |
) | |
fig.update_layout( | |
title_font_size=16, | |
title_x=0.5, | |
xaxis_title="مستوى التأثير الإيجابي", | |
yaxis_title="" | |
) | |
st.plotly_chart(fig, use_container_width=True) | |
st.markdown("### إحصائيات المناقصات السابقة") | |
# بيانات توضيحية للمناقصات السابقة | |
historical_df = pd.DataFrame({ | |
"الشهر": [ | |
"يناير", "فبراير", "مارس", "أبريل", "مايو", | |
"يونيو", "يوليو", "أغسطس", "سبتمبر", "أكتوبر" | |
], | |
"عدد المناقصات": [5, 7, 4, 6, 9, 8, 6, 7, 10, 8], | |
"معدل النجاح": [0.6, 0.57, 0.75, 0.67, 0.44, 0.5, 0.67, 0.71, 0.6, 0.75] | |
}) | |
fig = make_subplots(specs=[[{"secondary_y": True}]]) | |
fig.add_trace( | |
go.Bar( | |
x=historical_df["الشهر"], | |
y=historical_df["عدد المناقصات"], | |
name="عدد المناقصات", | |
marker_color="#3498db" | |
), | |
secondary_y=False | |
) | |
fig.add_trace( | |
go.Scatter( | |
x=historical_df["الشهر"], | |
y=historical_df["معدل النجاح"], | |
name="معدل النجاح", | |
mode="lines+markers", | |
marker_color="#e74c3c", | |
line=dict(width=3) | |
), | |
secondary_y=True | |
) | |
fig.update_layout( | |
title_text="إحصائيات المناقصات السابقة", | |
title_font_size=16, | |
title_x=0.5, | |
legend_title="", | |
xaxis_title="الشهر" | |
) | |
fig.update_yaxes(title_text="عدد المناقصات", secondary_y=False) | |
fig.update_yaxes(title_text="معدل النجاح", secondary_y=True) | |
st.plotly_chart(fig, use_container_width=True) | |
def settings_page(): | |
"""صفحة الإعدادات""" | |
st.markdown("# ⚙️ الإعدادات") | |
st.markdown(""" | |
## إعدادات النظام | |
يمكنك من خلال هذه الصفحة تخصيص إعدادات النظام بما يتناسب مع احتياجاتك. | |
""") | |
tab1, tab2, tab3 = st.tabs(["إعدادات عامة", "إعدادات الحساب", "الدعم والمساعدة"]) | |
with tab1: | |
st.markdown("### الإعدادات العامة") | |
st.markdown("#### إعدادات اللغة") | |
lang = st.radio( | |
"اللغة الافتراضية للنظام:", | |
["العربية", "English"], | |
index=0 | |
) | |
st.markdown("#### إعدادات العرض") | |
theme = st.selectbox( | |
"السمة:", | |
["السمة الافتراضية", "الوضع الداكن", "الوضع الفاتح"], | |
index=0 | |
) | |
st.markdown("#### إعدادات الإشعارات") | |
st.checkbox("تفعيل الإشعارات داخل النظام", value=True) | |
st.checkbox("تفعيل الإشعارات عبر البريد الإلكتروني", value=True) | |
if st.button("حفظ الإعدادات العامة"): | |
st.success("تم حفظ الإعدادات بنجاح") | |
with tab2: | |
st.markdown("### إعدادات الحساب") | |
st.markdown("#### البيانات الشخصية") | |
col1, col2 = st.columns(2) | |
with col1: | |
st.text_input("الاسم:", value="محمد أحمد") | |
st.text_input("البريد الإلكتروني:", value="[email protected]") | |
with col2: | |
st.text_input("المسمى الوظيفي:", value="مدير مشاريع") | |
st.text_input("رقم الهاتف:", value="0555555555") | |
st.markdown("#### تغيير كلمة المرور") | |
st.password_input("كلمة المرور الحالية:") | |
st.password_input("كلمة المرور الجديدة:") | |
st.password_input("تأكيد كلمة المرور الجديدة:") | |
if st.button("تحديث البيانات"): | |
st.success("تم تحديث البيانات بنجاح") | |
st.markdown("#### إعدادات الأمان") | |
st.checkbox("تفعيل المصادقة الثنائية", value=False) | |
with tab3: | |
st.markdown("### الدعم والمساعدة") | |
st.markdown(""" | |
#### كيفية استخدام النظام | |
يوفر النظام مجموعة من الأدوات والتحليلات التي تساعدك في إدارة المناقصات والعقود وتحليل المخاطر. | |
يمكنك الاطلاع على دليل الاستخدام للحصول على شرح تفصيلي لكافة الوظائف. | |
""") | |
st.download_button( | |
"تحميل دليل الاستخدام", | |
data="محتوى دليل الاستخدام", | |
file_name="user_guide.pdf", | |
mime="application/pdf" | |
) | |
st.markdown("#### التواصل مع الدعم الفني") | |
with st.form("support_form"): | |
st.text_input("العنوان:") | |
st.text_area("الرسالة:") | |
st.selectbox( | |
"نوع المشكلة:", | |
["استفسار عام", "مشكلة فنية", "اقتراح تحسين", "أخرى"] | |
) | |
st.file_uploader("إرفاق ملف (اختياري):") | |
submit_support = st.form_submit_button("إرسال") | |
if submit_support: | |
st.success("تم إرسال رسالتك بنجاح، سيتم التواصل معك قريباً") | |
def about_page(): | |
"""صفحة حول النظام""" | |
st.markdown("# ℹ️ حول النظام") | |
st.markdown(""" | |
## نظام إدارة المناقصات والعقود | |
### نبذة عن النظام | |
نظام متكامل لإدارة المناقصات والعقود يعتمد على أحدث التقنيات والذكاء الاصطناعي لتحسين كفاءة العمليات وزيادة فرص النجاح. | |
يوفر النظام مجموعة من الأدوات والتحليلات التي تساعد في اتخاذ القرارات وإدارة المخاطر وتحسين المحتوى المحلي. | |
### المميزات الرئيسية | |
* إدارة المناقصات والفرص التجارية | |
* تحليل وإدارة المخاطر | |
* قياس وتحسين المحتوى المحلي | |
* توقع احتمالية النجاح في المناقصات | |
* إدارة وتحليل العقود | |
* تخطيط سلسلة التوريد | |
* تحليل المتطلبات | |
### فريق التطوير | |
تم تطوير هذا النظام بواسطة فريق من الخبراء المتخصصين في مجالات البرمجة والذكاء الاصطناعي وإدارة المشاريع والعقود. | |
### التواصل | |
للمزيد من المعلومات أو الاستفسارات، يرجى التواصل عبر: | |
* البريد الإلكتروني: [email protected] | |
* رقم الهاتف: 0123456789 | |
""") | |
col1, col2, col3 = st.columns(3) | |
with col1: | |
st.info("إصدار النظام: 1.0.0") | |
with col2: | |
st.info("تاريخ الإطلاق: 2024/03/15") | |
with col3: | |
st.info("آخر تحديث: 2024/03/18") | |
# تكوين القائمة الجانبية | |
def setup_sidebar(): | |
"""إعداد القائمة الجانبية""" | |
with st.sidebar: | |
st.image("images/logo.png", width=150) | |
st.title("نظام إدارة المناقصات") | |
# معلومات المستخدم | |
st.markdown("### أهلاً م تامر الجوهري ") | |
st.markdown("مدير المناقصات والعقود") | |
st.markdown("---") | |
# القائمة الرئيسية | |
page = st.radio( | |
"القائمة الرئيسية", | |
[ | |
"📊 الرئيسية", | |
"📋 المناقصات", | |
"📑 العقود", | |
"🔍 تحليل المتطلبات", | |
"🔄 تخطيط سلسلة التوريد", | |
"⚠️ تحليل المخاطر", | |
"🏠 المحتوى المحلي", | |
"🎯 توقع احتمالية النجاح", | |
"⚙️ الإعدادات", | |
"ℹ️ حول النظام" | |
] | |
) | |
st.markdown("---") | |
# الإحصائيات | |
st.markdown("### إحصائيات سريعة") | |
col1, col2 = st.columns(2) | |
with col1: | |
st.metric("المناقصات", "28") | |
with col2: | |
st.metric("العقود", "14") | |
col1, col2 = st.columns(2) | |
with col1: | |
st.metric("قيد الدراسة", "7") | |
with col2: | |
st.metric("معدل النجاح", "64%") | |
return page | |
# ... باقي الكود بدون تغيير ... | |
# الدالة الرئيسية للتطبيق | |
def main(): | |
# التأكد من وجود بيانات الجلسة | |
initialize_app() # تم تغيير اسم الدالة هنا | |
# إعداد القائمة الجانبية | |
page = setup_sidebar() | |
# عرض الصفحة المناسبة | |
if page == "📊 الرئيسية": | |
home_page() | |
elif page == "🔍 تحليل المتطلبات": | |
requirements_analysis_page() | |
elif page == "🔄 تخطيط سلسلة التوريد": | |
supply_chain_page() | |
elif page == "⚠️ تحليل المخاطر": | |
risk_analysis_page() | |
elif page == "🏠 المحتوى المحلي": | |
local_content_page() | |
elif page == "🎯 توقع احتمالية النجاح": | |
success_prediction_page() | |
elif page == "⚙️ الإعدادات": | |
settings_page() | |
elif page == "ℹ️ حول النظام": | |
about_page() | |
if __name__ == "__main__": | |
main() |