v3 / modules /pricing /services /standard_pricing.py
EGYADMIN's picture
Upload 115 files
82676b8 verified
"""
خدمة التسعير القياسي
"""
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