Spaces:
Sleeping
Sleeping
""" | |
خدمة التسعير غير المتزن | |
""" | |
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 |