|
"""
|
|
اختبارات تكامل لتصدير التقارير
|
|
"""
|
|
|
|
import unittest
|
|
import pandas as pd
|
|
import os
|
|
import sys
|
|
import tempfile
|
|
import shutil
|
|
from datetime import datetime
|
|
|
|
|
|
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
|
|
|
|
from modules.reports.reports_app import ReportsApp
|
|
from utils.excel_handler import export_to_excel
|
|
|
|
|
|
class TestReportExport(unittest.TestCase):
|
|
"""اختبارات تكامل لتصدير التقارير"""
|
|
|
|
def setUp(self):
|
|
"""إعداد بيئة الاختبار"""
|
|
self.reports_app = ReportsApp()
|
|
|
|
|
|
self.test_dir = tempfile.mkdtemp()
|
|
|
|
|
|
self.projects_data = pd.DataFrame({
|
|
'اسم المشروع': [f'مشروع {i}' for i in range(1, 6)],
|
|
'رقم المناقصة': [f'T-2024{i:03d}' for i in range(1, 6)],
|
|
'العميل': ['وزارة الصحة', 'وزارة التعليم', 'وزارة الصحة', 'شركة أرامكو', 'شركة سابك'],
|
|
'الموقع': ['الرياض', 'جدة', 'الدمام', 'الظهران', 'الجبيل'],
|
|
'الحالة': ['جديد', 'قيد التسعير', 'تم التقديم', 'تمت الترسية', 'قيد التنفيذ'],
|
|
'تاريخ التقديم': ['2024-01-15', '2024-01-28', '2024-02-10', '2024-02-15', '2024-02-20'],
|
|
'نوع المناقصة': ['عامة', 'خاصة', 'عامة', 'عامة', 'خاصة']
|
|
})
|
|
|
|
|
|
self.pricing_data = pd.DataFrame({
|
|
'اسم المشروع': ['مشروع 1', 'مشروع 1', 'مشروع 1', 'مشروع 2', 'مشروع 2'],
|
|
'رقم البند': ['A001', 'A002', 'A003', 'B001', 'B002'],
|
|
'وصف البند': [
|
|
'أعمال الحفر والردم',
|
|
'أعمال الخرسانة المسلحة',
|
|
'أعمال حديد التسليح',
|
|
'أعمال البلوك',
|
|
'أعمال اللياسة'
|
|
],
|
|
'الوحدة': ['م3', 'م3', 'طن', 'م2', 'م2'],
|
|
'الكمية': [1000, 500, 50, 800, 1200],
|
|
'سعر الوحدة': [50, 1200, 5000, 120, 80],
|
|
'الإجمالي': [50000, 600000, 250000, 96000, 96000]
|
|
})
|
|
|
|
|
|
self.risks_data = pd.DataFrame({
|
|
'رمز المخاطرة': [f'R{i:03d}' for i in range(1, 6)],
|
|
'اسم المشروع': ['مشروع 1', 'مشروع 1', 'مشروع 2', 'مشروع 3', 'مشروع 4'],
|
|
'وصف المخاطرة': [
|
|
'غرامة تأخير مرتفعة',
|
|
'مدة تنفيذ قصيرة',
|
|
'متطلبات ضمان بنكي مرتفعة',
|
|
'شروط دفع متأخرة',
|
|
'متطلبات تأمين شاملة ومكلفة'
|
|
],
|
|
'الفئة': [
|
|
'مخاطر مالية',
|
|
'مخاطر زمنية',
|
|
'مخاطر مالية',
|
|
'مخاطر مالية',
|
|
'مخاطر مالية'
|
|
],
|
|
'التأثير': ['عالي', 'متوسط', 'منخفض', 'عالي', 'متوسط'],
|
|
'الاحتمالية': ['محتمل', 'مؤكد', 'غير محتمل', 'محتمل', 'غير محتمل'],
|
|
'درجة المخاطرة': [6, 6, 2, 8, 4]
|
|
})
|
|
|
|
def tearDown(self):
|
|
"""تنظيف بيئة الاختبار"""
|
|
|
|
shutil.rmtree(self.test_dir)
|
|
|
|
def test_export_projects_report_to_excel(self):
|
|
"""اختبار تصدير تقرير المشاريع إلى Excel"""
|
|
|
|
output_file = os.path.join(self.test_dir, 'projects_report.xlsx')
|
|
|
|
|
|
result = export_to_excel(self.projects_data, output_file, sheet_name='المشاريع', title='تقرير المشاريع')
|
|
|
|
|
|
self.assertTrue(result)
|
|
self.assertTrue(os.path.exists(output_file))
|
|
|
|
|
|
imported_data = pd.read_excel(output_file, sheet_name='المشاريع', skiprows=2)
|
|
|
|
|
|
self.assertEqual(len(imported_data), len(self.projects_data))
|
|
self.assertEqual(len(imported_data.columns), len(self.projects_data.columns))
|
|
|
|
def test_export_pricing_report_to_excel(self):
|
|
"""اختبار تصدير تقرير التسعير إلى Excel"""
|
|
|
|
output_file = os.path.join(self.test_dir, 'pricing_report.xlsx')
|
|
|
|
|
|
result = export_to_excel(self.pricing_data, output_file, sheet_name='التسعير', title='تقرير التسعير')
|
|
|
|
|
|
self.assertTrue(result)
|
|
self.assertTrue(os.path.exists(output_file))
|
|
|
|
|
|
imported_data = pd.read_excel(output_file, sheet_name='التسعير', skiprows=2)
|
|
|
|
|
|
self.assertEqual(len(imported_data), len(self.pricing_data))
|
|
self.assertEqual(len(imported_data.columns), len(self.pricing_data.columns))
|
|
|
|
def test_export_multiple_sheets(self):
|
|
"""اختبار تصدير تقرير متعدد الصفحات"""
|
|
|
|
output_file = os.path.join(self.test_dir, 'combined_report.xlsx')
|
|
|
|
|
|
result1 = export_to_excel(self.projects_data, output_file, sheet_name='المشاريع', title='تقرير المشاريع')
|
|
result2 = export_to_excel(self.pricing_data, output_file, sheet_name='التسعير', title='تقرير التسعير', append=True)
|
|
result3 = export_to_excel(self.risks_data, output_file, sheet_name='المخاطر', title='تقرير المخاطر', append=True)
|
|
|
|
|
|
self.assertTrue(result1)
|
|
self.assertTrue(result2)
|
|
self.assertTrue(result3)
|
|
self.assertTrue(os.path.exists(output_file))
|
|
|
|
|
|
excel_file = pd.ExcelFile(output_file)
|
|
self.assertIn('المشاريع', excel_file.sheet_names)
|
|
self.assertIn('التسعير', excel_file.sheet_names)
|
|
self.assertIn('المخاطر', excel_file.sheet_names)
|
|
|
|
|
|
projects_data = pd.read_excel(output_file, sheet_name='المشاريع', skiprows=2)
|
|
pricing_data = pd.read_excel(output_file, sheet_name='التسعير', skiprows=2)
|
|
risks_data = pd.read_excel(output_file, sheet_name='المخاطر', skiprows=2)
|
|
|
|
self.assertEqual(len(projects_data), len(self.projects_data))
|
|
self.assertEqual(len(pricing_data), len(self.pricing_data))
|
|
self.assertEqual(len(risks_data), len(self.risks_data))
|
|
|
|
def test_export_with_formatting(self):
|
|
"""اختبار تصدير تقرير مع التنسيق"""
|
|
|
|
output_file = os.path.join(self.test_dir, 'formatted_report.xlsx')
|
|
|
|
|
|
formatting = {
|
|
'header_format': {
|
|
'bold': True,
|
|
'bg_color': '#4F81BD',
|
|
'font_color': 'white',
|
|
'border': 1,
|
|
'align': 'center'
|
|
},
|
|
'row_formats': [
|
|
{
|
|
'columns': ['الإجمالي'],
|
|
'num_format': '#,##0.00 ريال'
|
|
},
|
|
{
|
|
'columns': ['الكمية'],
|
|
'num_format': '#,##0.00'
|
|
}
|
|
],
|
|
'conditional_formats': [
|
|
{
|
|
'column': 'درجة المخاطرة',
|
|
'criteria': '>',
|
|
'value': 6,
|
|
'format': {'bg_color': '#FF9999'}
|
|
}
|
|
]
|
|
}
|
|
|
|
result = export_to_excel(self.risks_data, output_file, sheet_name='المخاطر',
|
|
title='تقرير المخاطر', formatting=formatting)
|
|
|
|
|
|
self.assertTrue(result)
|
|
self.assertTrue(os.path.exists(output_file))
|
|
|
|
def test_export_with_filters(self):
|
|
"""اختبار تصدير تقرير مع تصفية"""
|
|
|
|
output_file = os.path.join(self.test_dir, 'filtered_report.xlsx')
|
|
|
|
|
|
filtered_data = self.projects_data[self.projects_data['العميل'] == 'وزارة الصحة']
|
|
result = export_to_excel(filtered_data, output_file, sheet_name='مشاريع الصحة',
|
|
title='تقرير مشاريع وزارة الصحة')
|
|
|
|
|
|
self.assertTrue(result)
|
|
self.assertTrue(os.path.exists(output_file))
|
|
|
|
|
|
imported_data = pd.read_excel(output_file, sheet_name='مشاريع الصحة', skiprows=2)
|
|
|
|
|
|
self.assertEqual(len(imported_data), 2)
|
|
self.assertTrue(all(client == 'وزارة الصحة' for client in imported_data['العميل']))
|
|
|
|
def test_export_with_summary(self):
|
|
"""اختبار تصدير تقرير مع ملخص"""
|
|
|
|
output_file = os.path.join(self.test_dir, 'summary_report.xlsx')
|
|
|
|
|
|
summary_data = pd.DataFrame({
|
|
'المؤشر': ['إجمالي المشاريع', 'المشاريع النشطة', 'المشاريع المرساة', 'نسبة النجاح'],
|
|
'القيمة': [5, 4, 2, '40%']
|
|
})
|
|
|
|
|
|
result1 = export_to_excel(summary_data, output_file, sheet_name='الملخص',
|
|
title='ملخص تقرير المشاريع')
|
|
result2 = export_to_excel(self.projects_data, output_file, sheet_name='البيانات',
|
|
title='تفاصيل المشاريع', append=True)
|
|
|
|
|
|
self.assertTrue(result1)
|
|
self.assertTrue(result2)
|
|
self.assertTrue(os.path.exists(output_file))
|
|
|
|
|
|
excel_file = pd.ExcelFile(output_file)
|
|
self.assertIn('الملخص', excel_file.sheet_names)
|
|
self.assertIn('البيانات', excel_file.sheet_names)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main() |