SA-SAJCOAI / modules /pricing /services /standard_pricing.py
EGYADMIN's picture
Upload 75 files
fb20480 verified
raw
history blame contribute delete
10.3 kB
"""
خدمة التسعير القياسي
"""
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