""" خدمة حاسبة تكاليف البناء تقوم هذه الخدمة بحساب تكاليف البناء بشكل تفصيلي بناءً على المكونات المختلفة: - المواد الخام - العمالة - المعدات - المصاريف الإدارية - هامش الربح """ import pandas as pd import numpy as np from datetime import datetime import os import json import sys from typing import Dict, List, Optional, Union, Any # إضافة مسار النظام للوصول لملفات التكوين sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "../../../"))) try: import config except ImportError: # إذا لم يتم العثور على ملف التكوين، نستخدم قيم افتراضية class DefaultConfig: DATA_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "../../../data")) config = DefaultConfig # إنشاء مجلد البيانات إذا لم يكن موجودًا if not os.path.exists(config.DATA_DIR): os.makedirs(config.DATA_DIR) class ConstructionCostCalculator: """خدمة حاسبة تكاليف البناء""" def __init__(self): """تهيئة حاسبة تكاليف البناء""" # تحميل بيانات المواد والأسعار المرجعية self.material_rates = self._load_material_rates() self.labor_rates = self._load_labor_rates() self.equipment_rates = self._load_equipment_rates() # النسب الافتراضية للمصاريف الإدارية وهامش الربح self.default_admin_expenses_percentage = 0.05 # 5% self.default_profit_margin_percentage = 0.10 # 10% # معاملات التعديل الافتراضية self.default_adjustment_factors = { 'location_factor': 1.0, # معامل الموقع 'time_factor': 1.0, # معامل الوقت 'risk_factor': 1.0, # معامل المخاطر 'market_factor': 1.0 # معامل السوق } def _load_material_rates(self) -> Dict[str, Dict[str, Any]]: """تحميل أسعار المواد""" # محاكاة تحميل البيانات من مصدر بيانات material_rates = { # مواد الخرسانة 'خرسانة جاهزة': { 'وحدة': 'م3', 'سعر_الوحدة': 750.0, 'وصف': 'خرسانة جاهزة بقوة 350 كجم/سم2', 'فئة': 'أعمال خرسانية' }, 'حديد تسليح': { 'وحدة': 'طن', 'سعر_الوحدة': 5500.0, 'وصف': 'حديد تسليح قطر 8-32 مم', 'فئة': 'أعمال خرسانية' }, 'أسمنت': { 'وحدة': 'كيس', 'سعر_الوحدة': 30.0, 'وصف': 'أسمنت بورتلاندي عادي', 'فئة': 'أعمال خرسانية' }, 'رمل': { 'وحدة': 'م3', 'سعر_الوحدة': 120.0, 'وصف': 'رمل خشن للخرسانة', 'فئة': 'أعمال خرسانية' }, 'زلط': { 'وحدة': 'م3', 'سعر_الوحدة': 150.0, 'وصف': 'زلط مقاس 10-20 مم للخرسانة', 'فئة': 'أعمال خرسانية' }, # مواد البناء 'طوب أحمر': { 'وحدة': '1000 قطعة', 'سعر_الوحدة': 900.0, 'وصف': 'طوب أحمر مقاس 25×12×6 سم', 'فئة': 'أعمال بناء' }, 'طوب أسمنتي': { 'وحدة': 'قطعة', 'سعر_الوحدة': 4.5, 'وصف': 'بلوك أسمنتي مقاس 20×20×40 سم', 'فئة': 'أعمال بناء' }, 'مونة بناء': { 'وحدة': 'م3', 'سعر_الوحدة': 350.0, 'وصف': 'مونة أسمنتية للبناء', 'فئة': 'أعمال بناء' }, # مواد التشطيبات 'بلاط سيراميك': { 'وحدة': 'م2', 'سعر_الوحدة': 120.0, 'وصف': 'بلاط سيراميك للأرضيات مقاس 40×40 سم', 'فئة': 'تشطيبات' }, 'بلاط بورسلين': { 'وحدة': 'م2', 'سعر_الوحدة': 180.0, 'وصف': 'بلاط بورسلين للأرضيات مقاس 60×60 سم', 'فئة': 'تشطيبات' }, 'دهانات بلاستيك': { 'وحدة': 'لتر', 'سعر_الوحدة': 35.0, 'وصف': 'دهان بلاستيك أساس وتشطيب', 'فئة': 'تشطيبات' }, 'جبس بورد': { 'وحدة': 'م2', 'سعر_الوحدة': 95.0, 'وصف': 'ألواح جبس بورد سمك 12 مم', 'فئة': 'تشطيبات' }, # مواد العزل 'عزل مائي': { 'وحدة': 'م2', 'سعر_الوحدة': 45.0, 'وصف': 'عزل مائي من البيتومين المؤكسد', 'فئة': 'أعمال عزل' }, 'عزل حراري': { 'وحدة': 'م2', 'سعر_الوحدة': 65.0, 'وصف': 'ألواح عزل حراري من البوليسترين سمك 5 سم', 'فئة': 'أعمال عزل' } } # محاولة تحميل البيانات من ملف إذا كان متاحًا try: file_path = os.path.join(config.DATA_DIR, 'material_rates.json') if os.path.exists(file_path): with open(file_path, 'r', encoding='utf-8') as f: loaded_data = json.load(f) material_rates.update(loaded_data) except Exception as e: print(f"خطأ في تحميل بيانات أسعار المواد: {str(e)}") return material_rates def _load_labor_rates(self) -> Dict[str, Dict[str, Any]]: """تحميل أسعار العمالة""" # محاكاة تحميل البيانات من مصدر بيانات labor_rates = { # عمالة الخرسانات 'نجار مسلح': { 'وحدة': 'يوم', 'سعر_الوحدة': 250.0, 'وصف': 'نجار مسلح لأعمال الشدات والفرم', 'فئة': 'أعمال خرسانية', 'إنتاجية_يومية': { 'شدة أساسات': 12, # متر مربع 'شدة أعمدة': 10, # متر مربع 'شدة أسقف': 12 # متر مربع } }, 'حداد مسلح': { 'وحدة': 'يوم', 'سعر_الوحدة': 250.0, 'وصف': 'حداد مسلح لأعمال حديد التسليح', 'فئة': 'أعمال خرسانية', 'إنتاجية_يومية': { 'تجهيز وتركيب حديد أساسات': 700, # كجم 'تجهيز وتركيب حديد أعمدة': 600, # كجم 'تجهيز وتركيب حديد أسقف': 650 # كجم } }, 'عامل خرسانة': { 'وحدة': 'يوم', 'سعر_الوحدة': 150.0, 'وصف': 'عامل لصب وتسوية الخرسانة', 'فئة': 'أعمال خرسانية', 'إنتاجية_يومية': { 'صب خرسانة': 15 # متر مكعب } }, # عمالة البناء 'بناء': { 'وحدة': 'يوم', 'سعر_الوحدة': 200.0, 'وصف': 'عامل بناء للطوب والبلوك', 'فئة': 'أعمال بناء', 'إنتاجية_يومية': { 'بناء طوب أحمر': 500, # قطعة 'بناء بلوك أسمنتي': 80 # قطعة } }, 'مساعد بناء': { 'وحدة': 'يوم', 'سعر_الوحدة': 120.0, 'وصف': 'مساعد عامل بناء', 'فئة': 'أعمال بناء', 'إنتاجية_يومية': {} }, # عمالة التشطيبات 'مبلط': { 'وحدة': 'يوم', 'سعر_الوحدة': 250.0, 'وصف': 'عامل تركيب بلاط وسيراميك', 'فئة': 'تشطيبات', 'إنتاجية_يومية': { 'تركيب سيراميك أرضيات': 15, # متر مربع 'تركيب سيراميك حوائط': 12, # متر مربع 'تركيب بورسلين': 12 # متر مربع } }, 'نقاش': { 'وحدة': 'يوم', 'سعر_الوحدة': 200.0, 'وصف': 'عامل دهانات', 'فئة': 'تشطيبات', 'إنتاجية_يومية': { 'دهانات بلاستيك': 35, # متر مربع 'دهانات زيتية': 25 # متر مربع } }, 'كهربائي': { 'وحدة': 'يوم', 'سعر_الوحدة': 270.0, 'وصف': 'فني كهرباء', 'فئة': 'تشطيبات', 'إنتاجية_يومية': { 'تأسيس نقاط كهرباء': 15, # نقطة 'تركيب لوحات توزيع': 2 # لوحة } }, 'سباك': { 'وحدة': 'يوم', 'سعر_الوحدة': 250.0, 'وصف': 'فني سباكة', 'فئة': 'تشطيبات', 'إنتاجية_يومية': { 'تأسيس نقاط صرف': 8, # نقطة 'تأسيس نقاط تغذية': 10, # نقطة 'تركيب أطقم حمامات': 2 # طقم } }, # مراقبة وإشراف 'مهندس موقع': { 'وحدة': 'يوم', 'سعر_الوحدة': 500.0, 'وصف': 'مهندس إشراف موقع', 'فئة': 'إشراف' }, 'مراقب فني': { 'وحدة': 'يوم', 'سعر_الوحدة': 300.0, 'وصف': 'مراقب فني للتنفيذ', 'فئة': 'إشراف' } } # محاولة تحميل البيانات من ملف إذا كان متاحًا try: file_path = os.path.join(config.DATA_DIR, 'labor_rates.json') if os.path.exists(file_path): with open(file_path, 'r', encoding='utf-8') as f: loaded_data = json.load(f) labor_rates.update(loaded_data) except Exception as e: print(f"خطأ في تحميل بيانات أسعار العمالة: {str(e)}") return labor_rates def _load_equipment_rates(self) -> Dict[str, Dict[str, Any]]: """تحميل أسعار المعدات""" # محاكاة تحميل البيانات من مصدر بيانات equipment_rates = { # معدات الحفر والتسوية 'حفار صغير': { 'وحدة': 'يوم', 'سعر_الوحدة': 1200.0, 'وصف': 'حفار صغير (بوبكات) بقدرة 70 حصان', 'فئة': 'معدات حفر', 'إنتاجية_يومية': { 'حفر في تربة عادية': 60 # متر مكعب } }, 'حفار متوسط': { 'وحدة': 'يوم', 'سعر_الوحدة': 2500.0, 'وصف': 'حفار متوسط الحجم بقدرة 150 حصان', 'فئة': 'معدات حفر', 'إنتاجية_يومية': { 'حفر في تربة عادية': 200 # متر مكعب } }, 'لودر': { 'وحدة': 'يوم', 'سعر_الوحدة': 2000.0, 'وصف': 'لودر أمامي لنقل التربة', 'فئة': 'معدات حفر', 'إنتاجية_يومية': { 'تحميل تربة': 300, # متر مكعب 'تسوية موقع': 1500 # متر مربع } }, 'جريدر': { 'وحدة': 'يوم', 'سعر_الوحدة': 2200.0, 'وصف': 'جريدر لتسوية الموقع', 'فئة': 'معدات حفر', 'إنتاجية_يومية': { 'تسوية طرق': 3000 # متر مربع } }, # معدات الخرسانة 'خلاطة خرسانة': { 'وحدة': 'يوم', 'سعر_الوحدة': 350.0, 'وصف': 'خلاطة خرسانة بسعة 0.5 متر مكعب', 'فئة': 'معدات خرسانة', 'إنتاجية_يومية': { 'خلط خرسانة': 15 # متر مكعب } }, 'هزاز خرسانة': { 'وحدة': 'يوم', 'سعر_الوحدة': 150.0, 'وصف': 'هزاز خرسانة كهربائي', 'فئة': 'معدات خرسانة', 'إنتاجية_يومية': { 'دمك خرسانة': 40 # متر مكعب } }, 'شاحنة خرسانة جاهزة': { 'وحدة': 'يوم', 'سعر_الوحدة': 3000.0, 'وصف': 'شاحنة خرسانة جاهزة (مكسر) سعة 8 متر مكعب', 'فئة': 'معدات خرسانة', 'إنتاجية_يومية': { 'نقل وصب خرسانة': 50 # متر مكعب } }, 'مضخة خرسانة': { 'وحدة': 'يوم', 'سعر_الوحدة': 5000.0, 'وصف': 'مضخة خرسانة بذراع 42 متر', 'فئة': 'معدات خرسانة', 'إنتاجية_يومية': { 'ضخ خرسانة': 120 # متر مكعب } }, # معدات رفع ونقل 'رافعة برجية': { 'وحدة': 'شهر', 'سعر_الوحدة': 35000.0, 'وصف': 'رافعة برجية بارتفاع 40 متر', 'فئة': 'معدات رفع', }, 'ونش شوكة': { 'وحدة': 'يوم', 'سعر_الوحدة': 1500.0, 'وصف': 'ونش شوكة لرفع مواد البناء', 'فئة': 'معدات رفع', 'إنتاجية_يومية': { 'رفع ونقل مواد': 100 # طن } }, 'شاحنة نقل': { 'وحدة': 'يوم', 'سعر_الوحدة': 1200.0, 'وصف': 'شاحنة نقل حمولة 20 طن', 'فئة': 'معدات نقل', 'إنتاجية_يومية': { 'نقل مواد': 80 # طن } } } # محاولة تحميل البيانات من ملف إذا كان متاحًا try: file_path = os.path.join(config.DATA_DIR, 'equipment_rates.json') if os.path.exists(file_path): with open(file_path, 'r', encoding='utf-8') as f: loaded_data = json.load(f) equipment_rates.update(loaded_data) except Exception as e: print(f"خطأ في تحميل بيانات أسعار المعدات: {str(e)}") return equipment_rates def calculate_item_cost(self, item_data: Dict[str, Any]) -> Dict[str, Any]: """ حساب تكلفة بند محدد بكافة مكوناته المعلمات: item_data (dict): بيانات البند، تتضمن: - وصف_البند (str): وصف البند - الكمية (float): كمية البند - الوحدة (str): وحدة القياس - المواد (list): قائمة المواد المستخدمة وكمياتها - العمالة (list): قائمة العمالة المستخدمة وعددها - المعدات (list): قائمة المعدات المستخدمة وساعات عملها - المصاريف_الإدارية (float, optional): نسبة المصاريف الإدارية (افتراضياً 5%) - هامش_الربح (float, optional): نسبة هامش الربح (افتراضياً 10%) - عوامل_التعديل (dict, optional): عوامل تعديل التكلفة العوائد: dict: تفاصيل تكلفة البند بكافة عناصرها """ # استخراج البيانات الأساسية للبند item_description = item_data.get('وصف_البند', 'بند غير محدد') quantity = item_data.get('الكمية', 0.0) unit = item_data.get('الوحدة', 'وحدة') # حساب تكلفة المواد materials_cost = self._calculate_materials_cost(item_data.get('المواد', [])) # حساب تكلفة العمالة labor_cost = self._calculate_labor_cost(item_data.get('العمالة', [])) # حساب تكلفة المعدات equipment_cost = self._calculate_equipment_cost(item_data.get('المعدات', [])) # حساب التكلفة المباشرة الإجمالية direct_cost = materials_cost['الإجمالي'] + labor_cost['الإجمالي'] + equipment_cost['الإجمالي'] # حساب المصاريف الإدارية admin_percentage = item_data.get('المصاريف_الإدارية', self.default_admin_expenses_percentage) admin_cost = direct_cost * admin_percentage # حساب هامش الربح profit_percentage = item_data.get('هامش_الربح', self.default_profit_margin_percentage) profit_margin = (direct_cost + admin_cost) * profit_percentage # حساب التكلفة الإجمالية total_cost = direct_cost + admin_cost + profit_margin # حساب سعر الوحدة unit_price = total_cost / quantity if quantity > 0 else 0.0 # تطبيق عوامل التعديل إذا وجدت adjustment_factors = item_data.get('عوامل_التعديل', self.default_adjustment_factors) adjustment_factor = self._calculate_adjustment_factor(adjustment_factors) adjusted_unit_price = unit_price * adjustment_factor adjusted_total_cost = total_cost * adjustment_factor # إعداد النتائج result = { 'وصف_البند': item_description, 'الكمية': quantity, 'الوحدة': unit, 'تكاليف_مباشرة': { 'المواد': materials_cost, 'العمالة': labor_cost, 'المعدات': equipment_cost, 'إجمالي_تكاليف_مباشرة': direct_cost }, 'مصاريف_إدارية': { 'نسبة': admin_percentage * 100, 'قيمة': admin_cost }, 'هامش_ربح': { 'نسبة': profit_percentage * 100, 'قيمة': profit_margin }, 'التكلفة_الإجمالية': total_cost, 'سعر_الوحدة': unit_price, 'عوامل_التعديل': { 'المعامل_الإجمالي': adjustment_factor, 'التفاصيل': adjustment_factors }, 'السعر_المعدل': { 'سعر_الوحدة': adjusted_unit_price, 'إجمالي': adjusted_total_cost } } return result def _calculate_materials_cost(self, materials: List[Dict[str, Any]]) -> Dict[str, Any]: """ حساب تكلفة المواد المعلمات: materials (list): قائمة المواد المستخدمة وكمياتها - الاسم (str): اسم المادة - الكمية (float): الكمية المستخدمة - الوحدة (str, optional): وحدة القياس - سعر_الوحدة (float, optional): سعر الوحدة (يستخدم السعر من البيانات المرجعية إذا لم يتم تحديده) العوائد: dict: تفاصيل تكلفة المواد """ materials_details = [] total_cost = 0.0 for material in materials: material_name = material.get('الاسم', '') quantity = material.get('الكمية', 0.0) # البحث عن سعر المادة من البيانات المرجعية إذا لم يتم تحديده if 'سعر_الوحدة' in material: unit_price = material.get('سعر_الوحدة', 0.0) unit = material.get('الوحدة', 'وحدة') elif material_name in self.material_rates: ref_material = self.material_rates[material_name] unit_price = ref_material.get('سعر_الوحدة', 0.0) unit = ref_material.get('وحدة', 'وحدة') else: unit_price = 0.0 unit = material.get('الوحدة', 'وحدة') # حساب التكلفة cost = quantity * unit_price total_cost += cost # إضافة التفاصيل materials_details.append({ 'الاسم': material_name, 'الكمية': quantity, 'الوحدة': unit, 'سعر_الوحدة': unit_price, 'التكلفة': cost }) return { 'التفاصيل': materials_details, 'الإجمالي': total_cost } def _calculate_labor_cost(self, labor: List[Dict[str, Any]]) -> Dict[str, Any]: """ حساب تكلفة العمالة المعلمات: labor (list): قائمة العمالة المستخدمة وعددها - النوع (str): نوع العامل - العدد (int): عدد العمال - المدة (float): مدة العمل بالأيام - سعر_اليوم (float, optional): أجر اليوم (يستخدم السعر من البيانات المرجعية إذا لم يتم تحديده) العوائد: dict: تفاصيل تكلفة العمالة """ labor_details = [] total_cost = 0.0 for worker in labor: worker_type = worker.get('النوع', '') count = worker.get('العدد', 0) duration = worker.get('المدة', 0.0) # البحث عن سعر العامل من البيانات المرجعية إذا لم يتم تحديده if 'سعر_اليوم' in worker: daily_rate = worker.get('سعر_اليوم', 0.0) elif worker_type in self.labor_rates: daily_rate = self.labor_rates[worker_type].get('سعر_الوحدة', 0.0) else: daily_rate = 0.0 # حساب التكلفة cost = count * duration * daily_rate total_cost += cost # إضافة التفاصيل labor_details.append({ 'النوع': worker_type, 'العدد': count, 'المدة': duration, 'سعر_اليوم': daily_rate, 'التكلفة': cost }) return { 'التفاصيل': labor_details, 'الإجمالي': total_cost } def _calculate_equipment_cost(self, equipment: List[Dict[str, Any]]) -> Dict[str, Any]: """ حساب تكلفة المعدات المعلمات: equipment (list): قائمة المعدات المستخدمة وساعات عملها - النوع (str): نوع المعدة - العدد (int): عدد المعدات - المدة (float): مدة الاستخدام بالأيام - سعر_اليوم (float, optional): أجر اليوم (يستخدم السعر من البيانات المرجعية إذا لم يتم تحديده) العوائد: dict: تفاصيل تكلفة المعدات """ equipment_details = [] total_cost = 0.0 for equip in equipment: equip_type = equip.get('النوع', '') count = equip.get('العدد', 0) duration = equip.get('المدة', 0.0) # البحث عن سعر المعدة من البيانات المرجعية إذا لم يتم تحديده if 'سعر_اليوم' in equip: daily_rate = equip.get('سعر_اليوم', 0.0) elif equip_type in self.equipment_rates: daily_rate = self.equipment_rates[equip_type].get('سعر_الوحدة', 0.0) else: daily_rate = 0.0 # حساب التكلفة cost = count * duration * daily_rate total_cost += cost # إضافة التفاصيل equipment_details.append({ 'النوع': equip_type, 'العدد': count, 'المدة': duration, 'سعر_اليوم': daily_rate, 'التكلفة': cost }) return { 'التفاصيل': equipment_details, 'الإجمالي': total_cost } def _calculate_adjustment_factor(self, factors: Dict[str, float]) -> float: """ حساب المعامل الإجمالي لتعديل التكلفة المعلمات: factors (dict): عوامل التعديل العوائد: float: المعامل الإجمالي """ # دمج العوامل المحددة مع العوامل الافتراضية effective_factors = self.default_adjustment_factors.copy() effective_factors.update(factors) # حساب المعامل الإجمالي total_factor = 1.0 for factor in effective_factors.values(): total_factor *= factor return total_factor def calculate_project_cost(self, project_data: Dict[str, Any]) -> Dict[str, Any]: """ حساب التكلفة الإجمالية لمشروع بناء كامل المعلمات: project_data (dict): بيانات المشروع، تتضمن: - اسم_المشروع (str): اسم المشروع - وصف_المشروع (str): وصف المشروع - البنود (list): قائمة بنود المشروع - المصاريف_الإدارية (float, optional): نسبة المصاريف الإدارية الإجمالية (افتراضياً 5%) - هامش_الربح (float, optional): نسبة هامش الربح الإجمالي (افتراضياً 10%) - عوامل_التعديل (dict, optional): عوامل تعديل التكلفة للمشروع العوائد: dict: تفاصيل تكلفة المشروع بكافة عناصرها """ # استخراج البيانات الأساسية للمشروع project_name = project_data.get('اسم_المشروع', 'مشروع غير محدد') project_description = project_data.get('وصف_المشروع', '') items = project_data.get('البنود', []) # استخراج النسب الإجمالية admin_percentage = project_data.get('المصاريف_الإدارية', self.default_admin_expenses_percentage) profit_percentage = project_data.get('هامش_الربح', self.default_profit_margin_percentage) # حساب تكلفة كل بند items_costs = [] total_direct_cost = 0.0 total_materials_cost = 0.0 total_labor_cost = 0.0 total_equipment_cost = 0.0 for item_data in items: # تحديث نسب المصاريف والربح للبند إذا لم تكن محددة if 'المصاريف_الإدارية' not in item_data: item_data['المصاريف_الإدارية'] = admin_percentage if 'هامش_الربح' not in item_data: item_data['هامش_الربح'] = profit_percentage # حساب تكلفة البند item_cost = self.calculate_item_cost(item_data) items_costs.append(item_cost) # تحديث الإجماليات total_materials_cost += item_cost['تكاليف_مباشرة']['المواد']['الإجمالي'] total_labor_cost += item_cost['تكاليف_مباشرة']['العمالة']['الإجمالي'] total_equipment_cost += item_cost['تكاليف_مباشرة']['المعدات']['الإجمالي'] total_direct_cost += item_cost['تكاليف_مباشرة']['إجمالي_تكاليف_مباشرة'] # حساب المصاريف الإدارية admin_cost = total_direct_cost * admin_percentage # حساب هامش الربح profit_margin = (total_direct_cost + admin_cost) * profit_percentage # حساب التكلفة الإجمالية total_cost = total_direct_cost + admin_cost + profit_margin # تطبيق عوامل التعديل إذا وجدت adjustment_factors = project_data.get('عوامل_التعديل', self.default_adjustment_factors) adjustment_factor = self._calculate_adjustment_factor(adjustment_factors) adjusted_total_cost = total_cost * adjustment_factor # إعداد النتائج result = { 'اسم_المشروع': project_name, 'وصف_المشروع': project_description, 'تكاليف_مباشرة': { 'المواد': { 'الإجمالي': total_materials_cost, 'النسبة_المئوية': (total_materials_cost / total_direct_cost * 100) if total_direct_cost > 0 else 0 }, 'العمالة': { 'الإجمالي': total_labor_cost, 'النسبة_المئوية': (total_labor_cost / total_direct_cost * 100) if total_direct_cost > 0 else 0 }, 'المعدات': { 'الإجمالي': total_equipment_cost, 'النسبة_المئوية': (total_equipment_cost / total_direct_cost * 100) if total_direct_cost > 0 else 0 }, 'إجمالي_تكاليف_مباشرة': total_direct_cost }, 'مصاريف_إدارية': { 'نسبة': admin_percentage * 100, 'قيمة': admin_cost }, 'هامش_ربح': { 'نسبة': profit_percentage * 100, 'قيمة': profit_margin }, 'التكلفة_الإجمالية': total_cost, 'عوامل_التعديل': { 'المعامل_الإجمالي': adjustment_factor, 'التفاصيل': adjustment_factors }, 'التكلفة_النهائية_المعدلة': adjusted_total_cost, 'تفاصيل_البنود': items_costs, 'عدد_البنود': len(items) } return result def get_rate_info(self, item_type: str, item_name: str) -> Dict[str, Any]: """ الحصول على معلومات تفصيلية عن معدل وسعر عنصر محدد (مادة، عمالة، معدة) المعلمات: item_type (str): نوع العنصر - 'مادة'، 'عمالة'، 'معدة' item_name (str): اسم العنصر العوائد: dict: معلومات تفصيلية عن العنصر """ # تحديد القاموس المناسب حسب نوع العنصر if item_type == 'مادة': rates_dict = self.material_rates elif item_type == 'عمالة': rates_dict = self.labor_rates elif item_type == 'معدة': rates_dict = self.equipment_rates else: return {'خطأ': 'نوع العنصر غير صحيح'} # البحث عن العنصر في القاموس if item_name in rates_dict: return rates_dict[item_name] else: return {'خطأ': 'العنصر غير موجود'} def get_all_rates(self, item_type: str = None, category: str = None) -> Dict[str, Any]: """ الحصول على قوائم معدلات الأسعار (لجميع المواد أو العمالة أو المعدات) المعلمات: item_type (str, optional): نوع العنصر - 'مادة'، 'عمالة'، 'معدة'، أو None لجميع الأنواع category (str, optional): فئة محددة للتصفية العوائد: dict: قوائم معدلات الأسعار """ result = {} # جمع المواد حسب الفئة if item_type is None or item_type == 'مادة': materials = {} for name, info in self.material_rates.items(): if category is None or info.get('فئة') == category: materials[name] = info result['المواد'] = materials # جمع العمالة حسب الفئة if item_type is None or item_type == 'عمالة': labor = {} for name, info in self.labor_rates.items(): if category is None or info.get('فئة') == category: labor[name] = info result['العمالة'] = labor # جمع المعدات حسب الفئة if item_type is None or item_type == 'معدة': equipment = {} for name, info in self.equipment_rates.items(): if category is None or info.get('فئة') == category: equipment[name] = info result['المعدات'] = equipment return result def generate_sample_project_data(self) -> Dict[str, Any]: """ توليد بيانات نموذجية لمشروع بناء صغير للاختبار العوائد: dict: بيانات المشروع النموذجية """ # إنشاء بيانات المشروع project_data = { 'اسم_المشروع': 'مبنى سكني صغير', 'وصف_المشروع': 'مبنى سكني مكون من دور أرضي بمساحة 250 متر مربع', 'المصاريف_الإدارية': 0.05, # 5% 'هامش_الربح': 0.10, # 10% 'عوامل_التعديل': { 'location_factor': 1.2, # معامل الموقع (منطقة مرتفعة التكلفة) 'time_factor': 1.0, # معامل الوقت 'risk_factor': 1.05, # معامل المخاطر 'market_factor': 1.0 # معامل السوق }, 'البنود': [ # الأساسات { 'وصف_البند': 'حفر الأساسات بعمق 2 متر', 'الكمية': 150.0, 'الوحدة': 'م3', 'المواد': [], 'العمالة': [ {'النوع': 'عامل خرسانة', 'العدد': 4, 'المدة': 3} ], 'المعدات': [ {'النوع': 'حفار متوسط', 'العدد': 1, 'المدة': 2} ] }, { 'وصف_البند': 'توريد وصب خرسانة عادية للأساسات', 'الكمية': 25.0, 'الوحدة': 'م3', 'المواد': [ {'الاسم': 'خرسانة جاهزة', 'الكمية': 25.0} ], 'العمالة': [ {'النوع': 'عامل خرسانة', 'العدد': 6, 'المدة': 1} ], 'المعدات': [ {'النوع': 'مضخة خرسانة', 'العدد': 1, 'المدة': 0.5} ] }, { 'وصف_البند': 'توريد وتركيب حديد تسليح للأساسات', 'الكمية': 3.5, 'الوحدة': 'طن', 'المواد': [ {'الاسم': 'حديد تسليح', 'الكمية': 3.5} ], 'العمالة': [ {'النوع': 'حداد مسلح', 'العدد': 4, 'المدة': 3} ], 'المعدات': [] }, { 'وصف_البند': 'نجارة وفك شدة الأساسات', 'الكمية': 120.0, 'الوحدة': 'م2', 'المواد': [], 'العمالة': [ {'النوع': 'نجار مسلح', 'العدد': 4, 'المدة': 3} ], 'المعدات': [] }, { 'وصف_البند': 'توريد وصب خرسانة مسلحة للأساسات', 'الكمية': 30.0, 'الوحدة': 'م3', 'المواد': [ {'الاسم': 'خرسانة جاهزة', 'الكمية': 30.0} ], 'العمالة': [ {'النوع': 'عامل خرسانة', 'العدد': 6, 'المدة': 1} ], 'المعدات': [ {'النوع': 'مضخة خرسانة', 'العدد': 1, 'المدة': 0.5}, {'النوع': 'هزاز خرسانة', 'العدد': 2, 'المدة': 1} ] }, # الأعمدة والأسقف { 'وصف_البند': 'توريد وتركيب حديد تسليح للأعمدة', 'الكمية': 2.8, 'الوحدة': 'طن', 'المواد': [ {'الاسم': 'حديد تسليح', 'الكمية': 2.8} ], 'العمالة': [ {'النوع': 'حداد مسلح', 'العدد': 4, 'المدة': 3} ], 'المعدات': [] }, { 'وصف_البند': 'نجارة وفك شدة الأعمدة', 'الكمية': 85.0, 'الوحدة': 'م2', 'المواد': [], 'العمالة': [ {'النوع': 'نجار مسلح', 'العدد': 3, 'المدة': 3} ], 'المعدات': [] }, { 'وصف_البند': 'توريد وصب خرسانة مسلحة للأعمدة', 'الكمية': 12.0, 'الوحدة': 'م3', 'المواد': [ {'الاسم': 'خرسانة جاهزة', 'الكمية': 12.0} ], 'العمالة': [ {'النوع': 'عامل خرسانة', 'العدد': 4, 'المدة': 1} ], 'المعدات': [ {'النوع': 'مضخة خرسانة', 'العدد': 1, 'المدة': 0.5}, {'النوع': 'هزاز خرسانة', 'العدد': 2, 'المدة': 1} ] }, # أعمال البناء { 'وصف_البند': 'توريد وبناء حوائط من الطوب الأحمر', 'الكمية': 220.0, 'الوحدة': 'م2', 'المواد': [ {'الاسم': 'طوب أحمر', 'الكمية': 16.5} # بالألف ], 'العمالة': [ {'النوع': 'بناء', 'العدد': 4, 'المدة': 8}, {'النوع': 'مساعد بناء', 'العدد': 4, 'المدة': 8} ], 'المعدات': [] }, # أعمال التشطيبات { 'وصف_البند': 'توريد وتركيب بلاط سيراميك للأرضيات', 'الكمية': 250.0, 'الوحدة': 'م2', 'المواد': [ {'الاسم': 'بلاط سيراميك', 'الكمية': 250.0} ], 'العمالة': [ {'النوع': 'مبلط', 'العدد': 4, 'المدة': 7} ], 'المعدات': [] }, { 'وصف_البند': 'توريد وتنفيذ دهانات للحوائط', 'الكمية': 450.0, 'الوحدة': 'م2', 'المواد': [ {'الاسم': 'دهانات بلاستيك', 'الكمية': 90.0} # بالتر ], 'العمالة': [ {'النوع': 'نقاش', 'العدد': 3, 'المدة': 8} ], 'المعدات': [] } ] } return project_data