File size: 10,266 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
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
"""

خدمة التسعير القياسي

"""

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