v3 / modules /pricing /services /unbalanced_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 UnbalancedPricing:
"""خدمة التسعير غير المتزن للبنود"""
def __init__(self):
"""تهيئة خدمة التسعير غير المتزن"""
self.strategies = {
'front_loading': self.apply_front_loading,
'back_loading': self.apply_back_loading,
'confirmed_items': self.apply_confirmed_items_loading,
'variable_items': self.apply_variable_items_discount
}
def apply_strategy(self, items_df, strategy, params=None):
"""تطبيق استراتيجية تسعير غير متزن على البنود"""
# نسخة من البيانات المدخلة للعمل عليها
df = items_df.copy()
# إضافة عمود إستراتيجية التسعير إذا لم يكن موجوداً
if 'إستراتيجية التسعير' not in df.columns:
df['إستراتيجية التسعير'] = 'متوازن'
# تطبيق الإستراتيجية المطلوبة
if strategy in self.strategies:
df = self.strategies[strategy](df, params)
else:
# إذا كانت الإستراتيجية غير معروفة، أعد البيانات بدون تغيير
pass
# حساب الإجمالي بعد التعديل
df['الإجمالي'] = df['الكمية'] * df['سعر الوحدة']
return df
def apply_front_loading(self, items_df, params=None):
"""تطبيق استراتيجية التحميل الأمامي (Front Loading)"""
df = items_df.copy()
# استخراج المعلمات الافتراضية إذا لم يتم تحديدها
if params is None:
params = {
'early_increase': 1.3, # زيادة 30% للبنود المبكرة
'late_decrease': 0.7, # تخفيض 30% للبنود المتأخرة
'early_percentage': 0.33, # نسبة البنود المبكرة 33%
'late_percentage': 0.33 # نسبة البنود المتأخرة 33%
}
# تحديد البنود المبكرة والمتأخرة والمتوسطة
items_count = len(df)
early_count = int(items_count * params['early_percentage'])
late_count = int(items_count * params['late_percentage'])
early_items = df.iloc[:early_count].index
middle_items = df.iloc[early_count:items_count-late_count].index
late_items = df.iloc[items_count-late_count:].index
# تطبيق الزيادة والنقصان
for idx in early_items:
df.at[idx, 'سعر الوحدة'] = df.at[idx, 'سعر الوحدة'] * params['early_increase']
df.at[idx, 'إستراتيجية التسعير'] = 'زيادة'
for idx in middle_items:
df.at[idx, 'إستراتيجية التسعير'] = 'متوازن'
for idx in late_items:
df.at[idx, 'سعر الوحدة'] = df.at[idx, 'سعر الوحدة'] * params['late_decrease']
df.at[idx, 'إستراتيجية التسعير'] = 'نقص'
return df
def apply_back_loading(self, items_df, params=None):
"""تطبيق استراتيجية التحميل الخلفي (Back Loading)"""
df = items_df.copy()
# استخراج المعلمات الافتراضية إذا لم يتم تحديدها
if params is None:
params = {
'early_decrease': 0.7, # تخفيض 30% للبنود المبكرة
'late_increase': 1.3, # زيادة 30% للبنود المتأخرة
'early_percentage': 0.33, # نسبة البنود المبكرة 33%
'late_percentage': 0.33 # نسبة البنود المتأخرة 33%
}
# تحديد البنود المبكرة والمتأخرة والمتوسطة
items_count = len(df)
early_count = int(items_count * params['early_percentage'])
late_count = int(items_count * params['late_percentage'])
early_items = df.iloc[:early_count].index
middle_items = df.iloc[early_count:items_count-late_count].index
late_items = df.iloc[items_count-late_count:].index
# تطبيق الزيادة والنقصان
for idx in early_items:
df.at[idx, 'سعر الوحدة'] = df.at[idx, 'سعر الوحدة'] * params['early_decrease']
df.at[idx, 'إستراتيجية التسعير'] = 'نقص'
for idx in middle_items:
df.at[idx, 'إستراتيجية التسعير'] = 'متوازن'
for idx in late_items:
df.at[idx, 'سعر الوحدة'] = df.at[idx, 'سعر الوحدة'] * params['late_increase']
df.at[idx, 'إستراتيجية التسعير'] = 'زيادة'
return df
def apply_confirmed_items_loading(self, items_df, params=None):
"""تطبيق استراتيجية تحميل البنود المؤكدة"""
df = items_df.copy()
# استخراج المعلمات الافتراضية إذا لم يتم تحديدها
if params is None:
params = {
'confirmed_increase': 1.25, # زيادة 25% للبنود المؤكدة
'others_decrease': 0.85, # تخفيض 15% للبنود الأخرى
'confirmed_items_indices': [] # قائمة مؤشرات البنود المؤكدة
}
# إذا لم يتم تحديد البنود المؤكدة، استخدم قواعد اختيار افتراضية
if not params['confirmed_items_indices']:
# البنود التي تحتوي على كلمات مثل "أساسات" أو "هيكل" عادة ما تكون مؤكدة
confirmed_items = []
for idx, row in df.iterrows():
description = row['وصف البند'].lower()
if any(term in description for term in ['أساس', 'خرسان', 'هيكل', 'إنشائي']):
confirmed_items.append(idx)
else:
confirmed_items = params['confirmed_items_indices']
# تحديد البنود غير المؤكدة
all_indices = set(range(len(df)))
confirmed_indices = set(confirmed_items)
variable_indices = list(all_indices - confirmed_indices)
# تطبيق الزيادة والنقصان
for idx in confirmed_items:
df.at[idx, 'سعر الوحدة'] = df.at[idx, 'سعر الوحدة'] * params['confirmed_increase']
df.at[idx, 'إستراتيجية التسعير'] = 'زيادة'
for idx in variable_indices:
df.at[idx, 'سعر الوحدة'] = df.at[idx, 'سعر الوحدة'] * params['others_decrease']
df.at[idx, 'إستراتيجية التسعير'] = 'نقص'
return df
def apply_variable_items_discount(self, items_df, params=None):
"""تطبيق استراتيجية تخفيض البنود المحتمل زيادتها"""
df = items_df.copy()
# استخراج المعلمات الافتراضية إذا لم يتم تحديدها
if params is None:
params = {
'variable_decrease': 0.7, # تخفيض 30% للبنود المحتمل زيادتها
'others_increase': 1.15, # زيادة 15% للبنود الأخرى
'variable_items_indices': [] # قائمة مؤشرات البنود المحتمل زيادتها
}
# إذا لم يتم تحديد البنود المحتمل زيادتها، استخدم قواعد اختيار افتراضية
if not params['variable_items_indices']:
# البنود التي تحتوي على كلمات مثل "حفر" أو "ردم" عادة ما تكون محتمل زيادتها
variable_items = []
for idx, row in df.iterrows():
description = row['وصف البند'].lower()
if any(term in description for term in ['حفر', 'ردم', 'تمديد', 'صرف', 'مياه']):
variable_items.append(idx)
else:
variable_items = params['variable_items_indices']
# تحديد البنود الأخرى
all_indices = set(range(len(df)))
variable_indices = set(variable_items)
other_indices = list(all_indices - variable_indices)
# تطبيق الزيادة والنقصان
for idx in variable_items:
df.at[idx, 'سعر الوحدة'] = df.at[idx, 'سعر الوحدة'] * params['variable_decrease']
df.at[idx, 'إستراتيجية التسعير'] = 'نقص'
for idx in other_indices:
df.at[idx, 'سعر الوحدة'] = df.at[idx, 'سعر الوحدة'] * params['others_increase']
df.at[idx, 'إستراتيجية التسعير'] = 'زيادة'
return df
def calibrate_prices(self, original_df, unbalanced_df):
"""معايرة الأسعار للحفاظ على إجمالي التسعير الأصلي"""
# حساب الإجماليات
original_total = original_df['الإجمالي'].sum()
unbalanced_total = unbalanced_df['الإجمالي'].sum()
# نسخة من البيانات المدخلة للعمل عليها
df = unbalanced_df.copy()
# حساب معامل التعديل
adjustment_factor = original_total / unbalanced_total if unbalanced_total > 0 else 1.0
# تعديل الأسعار
df['سعر الوحدة'] = df['سعر الوحدة'] * adjustment_factor
# حساب الإجمالي بعد التعديل
df['الإجمالي'] = df['الكمية'] * df['سعر الوحدة']
return df