EGYADMIN commited on
Commit
97503d3
·
verified ·
1 Parent(s): 7050b01

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +222 -199
app.py CHANGED
@@ -603,147 +603,250 @@ def home_page():
603
  legend_title_font_size=16
604
  )
605
  st.plotly_chart(fig, use_container_width=True)
606
-
607
- def settings_page():
608
- """صفحة الإعدادات"""
609
- st.markdown("# ⚙️ الإعدادات")
610
-
611
- st.markdown("""
612
- ## إعدادات النظام
613
-
614
- يمكنك من خلال هذه الصفحة تخصيص إعدادات النظام بما يتناسب مع احتياجاتك.
615
- """)
616
-
617
- tab1, tab2, tab3 = st.tabs(["إعدادات عامة", "إعدادات الحساب", "الدعم والمساعدة"])
618
-
619
- with tab1:
620
- st.markdown("### الإعدادات العامة")
621
 
622
- st.markdown("#### إعدادات اللغة")
623
- lang = st.radio(
624
- "اللغة الافتراضية للنظام:",
625
- ["العربية", "English"],
626
- index=0
627
- )
628
-
629
- st.markdown("#### إعدادات العرض")
630
- theme = st.selectbox(
631
- "السمة:",
632
- ["السمة الافتراضية", "الوضع الداكن", "الوضع الفاتح"],
633
- index=0
634
- )
635
-
636
- st.markdown("#### إعدادات الإشعارات")
637
- st.checkbox("تفعيل الإشعارات داخل النظام", value=True)
638
- st.checkbox("تفعيل الإشعارات عبر البريد الإلكتروني", value=True)
639
-
640
- if st.button("حفظ الإعدادات العامة"):
641
- st.success("تم حفظ الإعدادات بنجاح")
 
642
 
643
  with tab2:
644
- st.markdown("### إعدادات الحساب")
645
-
646
- st.markdown("#### البيانات الشخصية")
647
-
648
  col1, col2 = st.columns(2)
649
 
650
  with col1:
651
- st.text_input("الاسم:", value="محمد أحمد")
652
- st.text_input("البريد الإلكتروني:", value="mohammed@example.com")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
653
 
654
  with col2:
655
- st.text_input("المسمى الوظيفي:", value="مدير مشاريع")
656
- st.text_input("رقم الهاتف:", value="0555555555")
657
-
658
- st.markdown("#### تغيير كلمة المرور")
659
- st.password_input("كلمة المرور الحالية:")
660
- st.password_input("كلمة المرور الجديدة:")
661
- st.password_input("تأكيد كلمة المرور الجديدة:")
662
-
663
- if st.button("تحديث البيانات"):
664
- st.success("تم تحديث البيانات بنجاح")
665
-
666
- st.markdown("#### إعدادات الأمان")
667
- st.checkbox("تفعيل المصادقة الثنائية", value=False)
 
 
 
 
 
 
 
 
 
 
668
 
669
  with tab3:
670
- st.markdown("### الدعم والمساعدة")
671
-
672
- st.markdown("""
673
- #### كيفية استخدام النظام
674
-
675
- يوفر النظام مجموعة من الأدوات والتحليلات التي تساعدك في إدارة المناقصات والعقود وتحليل المخاطر.
676
- يمكنك الاطلاع على دليل الاستخدام للحصول على شرح تفصيلي لكافة الوظائف.
677
- """)
678
-
679
- st.download_button(
680
- "تحميل دليل الاستخدام",
681
- data="محتوى دليل الاستخدام",
682
- file_name="user_guide.pdf",
683
- mime="application/pdf"
684
- )
685
-
686
- st.markdown("#### التواصل مع الدعم الفني")
687
 
688
- with st.form("support_form"):
689
- st.text_input("العنوان:")
690
- st.text_area("الرسالة:")
691
- st.selectbox(
692
- "نوع المشكلة:",
693
- ["استفسار عام", "مشكلة فنية", "اقتراح تحسين", "أخرى"]
694
  )
695
- st.file_uploader("إرفاق ملف (اختياري):")
696
 
697
- submit_support = st.form_submit_button("إرسال")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
698
 
699
- if submit_support:
700
- st.success("تم إرسال رسالتك بنجاح، سيتم التواصل معك قريباً")
701
-
702
- def about_page():
703
- """صفحة حول النظام"""
704
- st.markdown("# ℹ️ حول النظام")
705
-
706
- st.markdown("""
707
- ## نظام إدارة المناقصات والعقود
708
-
709
- ### نبذة عن النظام
710
-
711
- نظام متكامل لإدارة المناقصات والعقود يعتمد على أحدث التقنيات والذكاء الاصطناعي لتحسين كفاءة العمليات وزيادة فرص النجاح.
712
- يوفر النظام مجموعة من الأدوات والتحليلات التي تساعد في اتخاذ القرارات وإدارة المخاطر وتحسين المحتوى المحلي.
713
-
714
- ### المميزات الرئيسية
715
-
716
- * إدارة المناقصات والفرص التجارية
717
- * تحليل وإدارة المخاطر
718
- * قياس وتحسين المحتوى المحلي
719
- * توقع احتمالية النجاح في المناقصات
720
- * إدارة وتحليل العقود
721
- * تخطيط سلسلة التوريد
722
- * تحليل المتطلبات
723
-
724
- ### فريق التطوير
725
-
726
- تم تطوير هذا النظام بواسطة فريق من الخبراء المتخصصين في مجالات البرمجة والذكاء الاصطناعي وإدارة المشاريع والعقود.
727
 
728
- ### التواصل
 
 
 
 
 
 
729
 
730
- للمزيد من المعلومات أو الاستفسارات، يرجى التواصل عبر:
 
 
 
 
 
 
 
 
 
 
 
 
 
731
 
732
- * البريد الإلكتروني: [email protected]
733
- * رقم الهاتف: 0123456789
734
- """)
735
 
736
- col1, col2, col3 = st.columns(3)
737
 
738
  with col1:
739
- st.info("إصدار النظام: 1.0.0")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
740
 
741
  with col2:
742
- st.info("تاريخ الإطلاق: 2024/03/15")
743
-
744
- with col3:
745
- st.info("آخر تحديث: 2024/03/18")
 
746
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
747
  def dashboard_page():
748
  """صفحة لوحة المؤشرات"""
749
  st.markdown("# 📊 لوحة المؤشرات")
@@ -900,86 +1003,6 @@ def dashboard_page():
900
  st.dataframe(upcoming_display, hide_index=True, use_container_width=True)
901
  else:
902
  st.info("لا توجد مناقصات قادمة خلال الثلاثين يوماً القادمة.")
903
-
904
- def procurement_page():
905
- """صفحة المناقصات والعقود"""
906
- st.markdown("# 📑 المناقصات والعقود")
907
-
908
- tab1, tab2 = st.tabs(["المناقصات", "العقود"])
909
-
910
- with tab1:
911
- st.markdown("## إدارة المناقصات")
912
-
913
- # أزرار الإجراءات
914
- col1, col2, col3, col4 = st.columns(4)
915
- with col1:
916
- if st.button("🆕 إضافة مناقصة جديدة"):
917
- st.session_state.show_add_tender = True
918
-
919
- with col2:
920
- st.button("🔍 بحث متقدم")
921
-
922
- with col3:
923
- st.button("📊 تصدير التقرير")
924
-
925
- with col4:
926
- st.button("🔄 تحديث البيانات")
927
-
928
- # عرض جدول المناقصات
929
- st.markdown("### قائمة المناقصات")
930
-
931
- # فلاتر
932
- col1, col2, col3 = st.columns(3)
933
- with col1:
934
- status_filter = st.multiselect(
935
- "الحالة:",
936
- ["الكل"] + list(st.session_state.tenders_df['الحالة'].unique()),
937
- default=["الكل"]
938
- )
939
-
940
- with col2:
941
- date_range = st.date_input(
942
- "تاريخ الإعلان:",
943
- value=(
944
- (datetime.now() - timedelta(days=60)).date(),
945
- datetime.now().date()
946
- )
947
- )
948
-
949
- with col3:
950
- min_value, max_value = st.slider(
951
- "القيمة التقديرية (ريال):",
952
- 0,
953
- int(st.session_state.tenders_df['القيمة التقديرية'].max()),
954
- (0, int(st.session_state.tenders_df['القيمة التقديرية'].max())),
955
- step=100000
956
- )
957
-
958
- # تطبيق الفلاتر
959
- filtered_df = st.session_state.tenders_df.copy()
960
-
961
- # فلتر الحالة
962
- if "الكل" not in status_filter:
963
- filtered_df = filtered_df[filtered_df['الحالة'].isin(status_filter)]
964
-
965
- # فلتر التاريخ
966
- filtered_df = filtered_df[
967
- (pd.to_datetime(filtered_df['تاريخ الإعلان']) >= pd.Timestamp(date_range[0])) &
968
- (pd.to_datetime(filtered_df['تاريخ الإعلان']) <= pd.Timestamp(date_range[1]))
969
- ]
970
-
971
- # فلتر القيمة
972
- filtered_df = filtered_df[
973
- (filtered_df['القيمة التقد��رية'] >= min_value) &
974
- (filtered_df['القيمة التقديرية'] <= max_value)
975
- ]
976
-
977
- # عرض الجدول
978
- st.dataframe(
979
- filtered_df,
980
- use_container_width=True,
981
- hide_index=True
982
- )
983
 
984
  def procurement_page():
985
  """صفحة المناقصات والعقود"""
@@ -1194,7 +1217,7 @@ def requirements_analysis_page():
1194
  st.metric("التكلفة التقديرية", "435,000 ريال")
1195
  st.metric("درجة التعقيد", "متوسطة")
1196
 
1197
- with tab2:
1198
  requirements_demo = pd.DataFrame({
1199
  "المعرف": [f"REQ-{i:03d}" for i in range(1, 11)],
1200
  "النوع": ["وظيفي", "وظيفي", "غير وظيفي", "وظيفي", "وظيفي", "غير وظيفي", "وظيفي", "وظيفي", "غير وظيفي", "وظيفي"],
 
603
  legend_title_font_size=16
604
  )
605
  st.plotly_chart(fig, use_container_width=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
606
 
607
+ with col2:
608
+ # نسب النجاح المتوقعة للمناقصات النشطة
609
+ active_tenders = st.session_state.tenders_df[st.session_state.tenders_df['الحالة'].isin(['جديدة', 'مفتوحة', 'قيد التقييم'])]
610
+ active_tenders = active_tenders.sort_values('نسبة النجاح المتوقعة', ascending=False).head(8)
611
+
612
+ fig = px.bar(
613
+ active_tenders,
614
+ x='نسبة النجاح المتوقعة',
615
+ y='رقم المناقصة',
616
+ title='نسب النجاح المتوقعة للمناقصات النشطة',
617
+ color='نسبة النجاح المتوقعة',
618
+ color_continuous_scale='Viridis',
619
+ orientation='h'
620
+ )
621
+ fig.update_layout(
622
+ title_font_size=20,
623
+ title_font_family="Tajawal",
624
+ title_x=0.5,
625
+ yaxis={'categoryorder':'total ascending'}
626
+ )
627
+ st.plotly_chart(fig, use_container_width=True)
628
 
629
  with tab2:
 
 
 
 
630
  col1, col2 = st.columns(2)
631
 
632
  with col1:
633
+ # توزيع قيم العقود
634
+ fig = px.histogram(
635
+ st.session_state.contracts_df,
636
+ x='القيمة',
637
+ nbins=10,
638
+ title='توزيع قيم العقود',
639
+ color_discrete_sequence=['#3498db']
640
+ )
641
+ fig.update_layout(
642
+ title_font_size=20,
643
+ title_font_family="Tajawal",
644
+ title_x=0.5,
645
+ xaxis_title="القيمة (ريال)",
646
+ yaxis_title="عدد العقود"
647
+ )
648
+ st.plotly_chart(fig, use_container_width=True)
649
 
650
  with col2:
651
+ # نسب المحتوى المحلي
652
+ fig = px.scatter(
653
+ st.session_state.contracts_df,
654
+ x='القيمة',
655
+ y='المحتوى المحلي',
656
+ size='نسبة الإنجاز',
657
+ color='مستوى المخاطر',
658
+ hover_name='رقم العقد',
659
+ title='نسب المحتوى المحلي للعقود',
660
+ color_discrete_map={
661
+ 'منخفض': '#2ecc71',
662
+ 'متوسط': '#f39c12',
663
+ 'عالي': '#e74c3c'
664
+ }
665
+ )
666
+ fig.update_layout(
667
+ title_font_size=20,
668
+ title_font_family="Tajawal",
669
+ title_x=0.5,
670
+ xaxis_title="القيمة (ريال)",
671
+ yaxis_title="نسبة المحتوى المحلي (%)"
672
+ )
673
+ st.plotly_chart(fig, use_container_width=True)
674
 
675
  with tab3:
676
+ col1, col2 = st.columns(2)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
677
 
678
+ with col1:
679
+ # مصفوفة المخاطر
680
+ risk_matrix = pd.crosstab(
681
+ st.session_state.risks_df['التأثير'],
682
+ st.session_state.risks_df['الاحتمالية'],
683
+ margins=False
684
  )
 
685
 
686
+ # تحويل القيم إلى حرارية
687
+ risk_severity = {
688
+ ('منخفض', 'منخفضة'): 1,
689
+ ('منخفض', 'متوسطة'): 2,
690
+ ('منخفض', 'عالية'): 3,
691
+ ('متوسط', 'منخفضة'): 2,
692
+ ('متوسط', 'متوسطة'): 4,
693
+ ('متوسط', 'عالية'): 6,
694
+ ('عالي', 'منخفضة'): 3,
695
+ ('عالي', 'متوسطة'): 6,
696
+ ('عالي', 'عالية'): 9,
697
+ ('حرج', 'منخفضة'): 4,
698
+ ('حرج', 'متوسطة'): 8,
699
+ ('حرج', 'عالية'): 12
700
+ }
701
+
702
+ # تحضير بيانات المصفوفة
703
+ impact_order = ['منخفض', 'متوسط', 'عالي', 'حرج']
704
+ probability_order = ['منخفضة', 'متوسطة', 'عالية']
705
+
706
+ # إنشاء مصفوفة حرارية
707
+ heat_values = []
708
+ annotations = []
709
+
710
+ for impact in impact_order:
711
+ heat_row = []
712
+ for prob in probability_order:
713
+ try:
714
+ value = risk_matrix.loc[impact, prob]
715
+ except:
716
+ value = 0
717
+ heat_row.append(risk_severity.get((impact, prob), 0))
718
+ annotations.append(dict(
719
+ text=str(value),
720
+ x=prob,
721
+ y=impact,
722
+ showarrow=False
723
+ ))
724
+ heat_values.append(heat_row)
725
+
726
+ # إنشاء الرسم البياني
727
+ fig = go.Figure(data=go.Heatmap(
728
+ z=heat_values,
729
+ x=probability_order,
730
+ y=impact_order,
731
+ colorscale=[
732
+ [0.0, "#2ecc71"], # أخضر للمخاطر المنخفضة
733
+ [0.33, "#f1c40f"], # أصفر للمخاطر المتوسطة
734
+ [0.66, "#e67e22"], # برتقالي للمخاطر العالية
735
+ [1.0, "#e74c3c"] # أحمر للمخاطر الحرجة
736
+ ],
737
+ showscale=False
738
+ ))
739
+
740
+ # إضافة النصوص
741
+ for annotation in annotations:
742
+ fig.add_annotation(annotation)
743
+
744
+ fig.update_layout(
745
+ title='مصفوفة المخاطر',
746
+ title_font_size=20,
747
+ title_font_family="Tajawal",
748
+ title_x=0.5,
749
+ xaxis_title="الاحتمالية",
750
+ yaxis_title="التأثير"
751
+ )
752
+
753
+ st.plotly_chart(fig, use_container_width=True)
754
 
755
+ with col2:
756
+ # توزيع المخاطر حسب استراتيجية المعالجة
757
+ treatment_counts = st.session_state.risks_df['المعالجة'].value_counts().reset_index()
758
+ treatment_counts.columns = ['المعالجة', 'العدد']
759
+
760
+ fig = px.bar(
761
+ treatment_counts,
762
+ x='المعالجة',
763
+ y='العدد',
764
+ title='استراتيجيات معالجة المخاطر',
765
+ color='المعالجة',
766
+ color_discrete_sequence=px.colors.qualitative.Pastel
767
+ )
768
+ fig.update_layout(
769
+ title_font_size=20,
770
+ title_font_family="Tajawal",
771
+ title_x=0.5,
772
+ xaxis_title="استراتيجية المعالجة",
773
+ yaxis_title="عدد المخاطر"
774
+ )
775
+ st.plotly_chart(fig, use_container_width=True)
 
 
 
 
 
 
 
776
 
777
+ # قسم المناقصات القادمة
778
+ st.markdown("## 📅 المناقصات القادمة للإغلاق")
779
+ upcoming_tenders = st.session_state.tenders_df[
780
+ (pd.to_datetime(st.session_state.tenders_df['تاريخ الإغلاق']) > datetime.now()) &
781
+ (pd.to_datetime(st.session_state.tenders_df['تاريخ الإغلاق']) <= datetime.now() + timedelta(days=14))
782
+ ]
783
+ upcoming_tenders = upcoming_tenders.sort_values('تاريخ الإغلاق')
784
 
785
+ if not upcoming_tenders.empty:
786
+ # عرض المناقصات في جدول
787
+ upcoming_display = upcoming_tenders[['رقم المناقصة', 'العنوان', 'تاريخ الإغلاق', 'القيمة التقديرية', 'نسبة النجاح المتوقعة']]
788
+ upcoming_display['أيام متبقية'] = (pd.to_datetime(upcoming_display['تاريخ الإغلاق']) - datetime.now()).dt.days
789
+ upcoming_display['القيمة التقديرية'] = upcoming_display['القيمة التقديرية'].apply(lambda x: f"{x:,.0f} ريال")
790
+ upcoming_display['نسبة النجاح المتوقعة'] = upcoming_display['نسبة النجاح المتوقعة'].apply(lambda x: f"{x}%")
791
+
792
+ st.dataframe(
793
+ upcoming_display,
794
+ hide_index=True,
795
+ use_container_width=True
796
+ )
797
+ else:
798
+ st.info("لا توجد مناقصات ستغلق خلال الأسبوعين القادمين")
799
 
800
+ # قسم تحليل الذكاء الاصطناعي
801
+ st.markdown("## 🤖 تحليلات الذكاء الاصطناعي")
 
802
 
803
+ col1, col2 = st.columns(2)
804
 
805
  with col1:
806
+ st.markdown("### التنبؤ بنجاح المناقصات")
807
+ st.markdown("""
808
+ تستخدم خوارزميات الذكاء الاصطناعي لتحليل البيانات التاريخية وتحديد العوامل المؤثرة في نجاح المناقصات.
809
+ يمكن للنظام التنبؤ بنسب النجاح المتوقعة للمناقصات الجديدة بناءً على خصائصها ومتطلباتها.
810
+ """)
811
+
812
+ if st.button("تحليل مناقصة جديدة", key="analyze_new_tender"):
813
+ with st.spinner("جاري تحليل المناقصة..."):
814
+ time.sleep(2) # محاكاة وقت المعالجة
815
+ st.success("تم التحليل بنجاح!")
816
+ st.info("نسبة النجاح المتوقعة للمناق��ة: 78.5%")
817
+ st.markdown("""
818
+ **العوامل المؤثرة في النتيجة:**
819
+ - قدرة عالية على تلبية المتطلبات الفنية (+15%)
820
+ - توافق المنتج مع المعايير المطلوبة (+12%)
821
+ - خبرة سابقة مع نفس الجهة (+10%)
822
+ - المنافسة المتوقعة قوية (-7%)
823
+ """)
824
 
825
  with col2:
826
+ st.markdown("### تحليل المتطلبات")
827
+ st.markdown("""
828
+ يقوم النظام بتحليل وثائق المتطلبات باستخدام تقنيات معالجة اللغة الطبيعية لاستخراج البنود المهمة والمخاطر المحتملة.
829
+ يساعد هذا التحليل في تقييم مدى تعقيد المتطلبات وتحديد النقاط التي تحتاج إلى اهتمام خاص.
830
+ """)
831
 
832
+ uploaded_file = st.file_uploader("رفع ملف متطلبات للتحليل", type=['pdf', 'docx', 'txt'])
833
+ if uploaded_file is not None:
834
+ with st.spinner("جاري تحليل المتطلبات..."):
835
+ time.sleep(3) # محاكاة وقت المعالجة
836
+ st.success("تم تحليل المتطلبات بنجاح!")
837
+
838
+ # عرض نتائج التحليل
839
+ col1, col2 = st.columns(2)
840
+ with col1:
841
+ st.metric("عدد المتطلبات", "27")
842
+ st.metric("المتطلبات الوظيفية", "19")
843
+ st.metric("المتطلبات غير الوظيفية", "8")
844
+
845
+ with col2:
846
+ st.metric("درجة التعقيد", "متوسطة")
847
+ st.metric("المخاطر المحتملة", "4")
848
+ st.metric("البنود الغامضة", "3")
849
+
850
  def dashboard_page():
851
  """صفحة لوحة المؤشرات"""
852
  st.markdown("# 📊 لوحة المؤشرات")
 
1003
  st.dataframe(upcoming_display, hide_index=True, use_container_width=True)
1004
  else:
1005
  st.info("لا توجد مناقصات قادمة خلال الثلاثين يوماً القادمة.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1006
 
1007
  def procurement_page():
1008
  """صفحة المناقصات والعقود"""
 
1217
  st.metric("التكلفة التقديرية", "435,000 ريال")
1218
  st.metric("درجة التعقيد", "متوسطة")
1219
 
1220
+ with tab2:
1221
  requirements_demo = pd.DataFrame({
1222
  "المعرف": [f"REQ-{i:03d}" for i in range(1, 11)],
1223
  "النوع": ["وظيفي", "وظيفي", "غير وظيفي", "وظيفي", "وظيفي", "غير وظيفي", "وظيفي", "وظيفي", "غير وظيفي", "وظيفي"],