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