|
"""
|
|
خدمة التسعير القياسي
|
|
"""
|
|
|
|
import pandas as pd
|
|
import numpy as np
|
|
from datetime import datetime
|
|
import os
|
|
import config
|
|
|
|
|
|
class StandardPricing:
|
|
"""خدمة التسعير القياسي للبنود"""
|
|
|
|
def __init__(self):
|
|
"""تهيئة خدمة التسعير القياسي"""
|
|
|
|
self.material_prices = self._load_material_prices()
|
|
self.labor_rates = self._load_labor_rates()
|
|
self.equipment_rates = self._load_equipment_rates()
|
|
|
|
def _load_material_prices(self):
|
|
"""تحميل أسعار المواد"""
|
|
|
|
material_prices = {
|
|
'خرسانة': {
|
|
'م3': 750.0,
|
|
'وحدة_قياسية': 'م3',
|
|
'آخر_تحديث': datetime(2025, 3, 1)
|
|
},
|
|
'حديد تسليح': {
|
|
'طن': 5500.0,
|
|
'وحدة_قياسية': 'طن',
|
|
'آخر_تحديث': datetime(2025, 3, 1)
|
|
},
|
|
'عزل مائي': {
|
|
'م2': 80.0,
|
|
'وحدة_قياسية': 'م2',
|
|
'آخر_تحديث': datetime(2025, 3, 1)
|
|
},
|
|
'بلوك خرساني': {
|
|
'20سم': 11.0,
|
|
'وحدة_قياسية': 'عدد',
|
|
'آخر_تحديث': datetime(2025, 3, 1)
|
|
},
|
|
'رمل': {
|
|
'م3': 140.0,
|
|
'وحدة_قياسية': 'م3',
|
|
'آخر_تحديث': datetime(2025, 3, 1)
|
|
},
|
|
'اسمنت': {
|
|
'كيس': 25.0,
|
|
'وحدة_قياسية': 'كيس',
|
|
'آخر_تحديث': datetime(2025, 3, 1)
|
|
}
|
|
}
|
|
return material_prices
|
|
|
|
def _load_labor_rates(self):
|
|
"""تحميل معدلات أجور العمالة"""
|
|
|
|
labor_rates = {
|
|
'عامل': {
|
|
'يومي': 150.0,
|
|
'وحدة_قياسية': 'يوم',
|
|
'آخر_تحديث': datetime(2025, 3, 1)
|
|
},
|
|
'نجار': {
|
|
'يومي': 250.0,
|
|
'وحدة_قياسية': 'يوم',
|
|
'آخر_تحديث': datetime(2025, 3, 1)
|
|
},
|
|
'حداد': {
|
|
'يومي': 250.0,
|
|
'وحدة_قياسية': 'يوم',
|
|
'آخر_تحديث': datetime(2025, 3, 1)
|
|
},
|
|
'سباك': {
|
|
'يومي': 300.0,
|
|
'وحدة_قياسية': 'يوم',
|
|
'آخر_تحديث': datetime(2025, 3, 1)
|
|
},
|
|
'كهربائي': {
|
|
'يومي': 300.0,
|
|
'وحدة_قياسية': 'يوم',
|
|
'آخر_تحديث': datetime(2025, 3, 1)
|
|
},
|
|
'مراقب': {
|
|
'يومي': 400.0,
|
|
'وحدة_قياسية': 'يوم',
|
|
'آخر_تحديث': datetime(2025, 3, 1)
|
|
}
|
|
}
|
|
return labor_rates
|
|
|
|
def _load_equipment_rates(self):
|
|
"""تحميل معدلات تأجير المعدات"""
|
|
|
|
equipment_rates = {
|
|
'خلاطة خرسانة': {
|
|
'يومي': 800.0,
|
|
'وحدة_قياسية': 'يوم',
|
|
'آخر_تحديث': datetime(2025, 3, 1)
|
|
},
|
|
'هزاز خرسانة': {
|
|
'يومي': 150.0,
|
|
'وحدة_قياسية': 'يوم',
|
|
'آخر_تحديث': datetime(2025, 3, 1)
|
|
},
|
|
'حفارة': {
|
|
'يومي': 1500.0,
|
|
'وحدة_قياسية': 'يوم',
|
|
'آخر_تحديث': datetime(2025, 3, 1)
|
|
},
|
|
'لودر': {
|
|
'يومي': 1200.0,
|
|
'وحدة_قياسية': 'يوم',
|
|
'آخر_تحديث': datetime(2025, 3, 1)
|
|
},
|
|
'رافعة': {
|
|
'يومي': 2000.0,
|
|
'وحدة_قياسية': 'يوم',
|
|
'آخر_تحديث': datetime(2025, 3, 1)
|
|
},
|
|
'شاحنة نقل': {
|
|
'يومي': 900.0,
|
|
'وحدة_قياسية': 'يوم',
|
|
'آخر_تحديث': datetime(2025, 3, 1)
|
|
}
|
|
}
|
|
return equipment_rates
|
|
|
|
def calculate_prices(self, items_df):
|
|
"""حساب الأسعار للبنود باستخدام التسعير القياسي"""
|
|
|
|
df = items_df.copy()
|
|
|
|
|
|
if 'سعر الوحدة' not in df.columns:
|
|
df['سعر الوحدة'] = 0.0
|
|
|
|
if 'الإجمالي' not in df.columns:
|
|
df['الإجمالي'] = 0.0
|
|
|
|
|
|
for idx, row in df.iterrows():
|
|
|
|
unit_price = self._estimate_unit_price(row['وصف البند'], row['الوحدة'])
|
|
df.at[idx, 'سعر الوحدة'] = unit_price
|
|
|
|
|
|
df['الإجمالي'] = df['الكمية'] * df['سعر الوحدة']
|
|
|
|
return df
|
|
|
|
def _estimate_unit_price(self, description, unit):
|
|
"""تقدير سعر الوحدة بناءً على وصف البند ووحدة القياس"""
|
|
description = description.lower()
|
|
|
|
|
|
if 'خرسان' in description:
|
|
if 'أساسات' in description:
|
|
return 1200.0 if unit == 'م3' else 0.0
|
|
elif 'أعمدة' in description:
|
|
return 1800.0 if unit == 'م3' else 0.0
|
|
elif 'سقف' in description:
|
|
return 1500.0 if unit == 'م3' else 0.0
|
|
else:
|
|
return 1400.0 if unit == 'م3' else 0.0
|
|
|
|
elif 'حديد' in description and 'تسليح' in description:
|
|
if 'أساسات' in description:
|
|
return 6000.0 if unit == 'طن' else 0.0
|
|
elif 'أعمدة' in description or 'سقف' in description:
|
|
return 6500.0 if unit == 'طن' else 0.0
|
|
else:
|
|
return 6200.0 if unit == 'طن' else 0.0
|
|
|
|
elif 'عزل' in description:
|
|
if 'مائي' in description:
|
|
return 120.0 if unit == 'م2' else 0.0
|
|
elif 'حراري' in description:
|
|
return 90.0 if unit == 'م2' else 0.0
|
|
else:
|
|
return 100.0 if unit == 'م2' else 0.0
|
|
|
|
elif 'ردم' in description or 'حفر' in description:
|
|
return 75.0 if unit == 'م3' else 0.0
|
|
|
|
elif 'بلوك' in description or 'طوب' in description:
|
|
return 250.0 if unit == 'م2' else 0.0
|
|
|
|
elif 'لياسة' in description or 'بياض' in description:
|
|
return 80.0 if unit == 'م2' else 0.0
|
|
|
|
elif 'دهان' in description or 'طلاء' in description:
|
|
return 65.0 if unit == 'م2' else 0.0
|
|
|
|
elif 'سيراميك' in description or 'بلاط' in description:
|
|
return 180.0 if unit == 'م2' else 0.0
|
|
|
|
elif 'كهرباء' in description:
|
|
return 150.0 if unit == 'نقطة' else 500.0
|
|
|
|
|
|
return 100.0
|
|
|
|
def adjust_prices_for_factors(self, items_df, factors=None):
|
|
"""تعديل الأسعار بناءً على عوامل مؤثرة"""
|
|
|
|
df = items_df.copy()
|
|
|
|
|
|
if factors is None:
|
|
factors = {
|
|
'location_factor': 1.0,
|
|
'time_factor': 1.0,
|
|
'risk_factor': 1.1,
|
|
'market_factor': 1.05
|
|
}
|
|
|
|
|
|
total_factor = (factors['location_factor'] * factors['time_factor'] *
|
|
factors['risk_factor'] * factors['market_factor'])
|
|
|
|
|
|
df['سعر الوحدة'] = df['سعر الوحدة'] * total_factor
|
|
|
|
|
|
df['الإجمالي'] = df['الكمية'] * df['سعر الوحدة']
|
|
|
|
return df |