File size: 10,592 Bytes
82676b8 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 |
"""
خدمة التسعير غير المتزن
"""
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 |