v3 / modules /pricing /services /local_content_calculator.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 LocalContentCalculator:
"""خدمة حساب وتحسين المحتوى المحلي"""
def __init__(self):
"""تهيئة خدمة حساب المحتوى المحلي"""
# تحميل بيانات المواد المحلية ونسب المحتوى المحلي
self.local_products = self._load_local_products()
self.local_services = self._load_local_services()
self.local_labor = self._load_local_labor()
# تحديد الأوزان النسبية لمكونات المحتوى المحلي
self.component_weights = {
'القوى العاملة': 0.3, # 30% من وزن المحتوى المحلي
'المنتجات': 0.5, # 50% من وزن المحتوى المحلي
'الخدمات': 0.2 # 20% من وزن المحتوى المحلي
}
# تحديد المستهدفات (متطلبات المحتوى المحلي)
self.targets = {
'القوى العاملة': 0.8, # 80% محتوى محلي للقوى العاملة
'المنتجات': 0.7, # 70% محتوى محلي للمنتجات
'الخدمات': 0.6 # 60% محتوى محلي للخدمات
}
def _load_local_products(self):
"""تحميل بيانات المنتجات المحلية ونسب المحتوى المحلي"""
# محاكاة تحميل البيانات من مصدر بيانات
local_products = {
'خرسانة': {
'نسبة_المحتوى_المحلي': 0.95, # 95% محتوى محلي
'بديل_محلي': True,
'مصدر': 'محلي',
'ملاحظات': 'منتج محلي بالكامل'
},
'حديد تسليح': {
'نسبة_المحتوى_المحلي': 0.70, # 70% محتوى محلي
'بديل_محلي': True,
'مصدر': 'محلي/مستورد',
'ملاحظات': 'متوفر من مصانع محلية ومستورد'
},
'عزل مائي': {
'نسبة_المحتوى_المحلي': 0.60, # 60% محتوى محلي
'بديل_محلي': True,
'مصدر': 'محلي/مستورد',
'ملاحظات': 'منتج محلي متوفر بجودة معقولة'
},
'بلوك خرساني': {
'نسبة_المحتوى_المحلي': 0.98, # 98% محتوى محلي
'بديل_محلي': True,
'مصدر': 'محلي',
'ملاحظات': 'منتج محلي بالكامل'
},
'رخام': {
'نسبة_المحتوى_المحلي': 0.80, # 80% محتوى محلي
'بديل_محلي': True,
'مصدر': 'محلي',
'ملاحظات': 'متوفر من محاجر محلية'
},
'أثاث مكتبي': {
'نسبة_المحتوى_المحلي': 0.75, # 75% محتوى محلي
'بديل_محلي': True,
'مصدر': 'محلي',
'ملاحظات': 'يُصنع محليًا ويستخدم بعض المكونات المستوردة'
},
'أجهزة تكييف': {
'نسبة_المحتوى_المحلي': 0.40, # 40% محتوى محلي
'بديل_محلي': True,
'مصدر': 'محلي/مستورد',
'ملاحظات': 'تجميع محلي مع مكونات مستوردة'
},
'أنظمة إضاءة': {
'نسبة_المحتوى_المحلي': 0.55, # 55% محتوى محلي
'بديل_محلي': True,
'مصدر': 'محلي/مستورد',
'ملاحظات': 'متوفر محليًا وبجودة متفاوتة'
},
'زجاج': {
'نسبة_المحتوى_المحلي': 0.65, # 65% محتوى محلي
'بديل_محلي': True,
'مصدر': 'محلي/مستورد',
'ملاحظات': 'إنتاج محلي بمواصفات جيدة'
},
'أسلاك كهربائية': {
'نسبة_المحتوى_المحلي': 0.85, # 85% محتوى محلي
'بديل_محلي': True,
'مصدر': 'محلي',
'ملاحظات': 'تصنيع محلي بجودة عالية'
}
}
# محاولة تحميل البيانات من ملف إذا كان متاحًا
try:
file_path = os.path.join(config.DATA_DIR, 'local_products.csv')
if os.path.exists(file_path):
df = pd.read_csv(file_path, encoding='utf-8')
local_products = {}
for _, row in df.iterrows():
local_products[row['اسم_المنتج']] = {
'نسبة_المحتوى_المحلي': row['نسبة_المحتوى_المحلي'],
'بديل_محلي': row['بديل_محلي'],
'مصدر': row['مصدر'],
'ملاحظات': row['ملاحظات']
}
except Exception as e:
print(f"خطأ في تحميل بيانات المنتجات المحلية: {str(e)}")
return local_products
def _load_local_services(self):
"""تحميل بيانات الخدمات المحلية ونسب المحتوى المحلي"""
# محاكاة تحميل البيانات من مصدر بيانات
local_services = {
'تصميم معماري': {
'نسبة_المحتوى_المحلي': 0.90, # 90% محتوى محلي
'بديل_محلي': True,
'مصدر': 'محلي',
'ملاحظات': 'متوفرة من مكاتب استشارية محلية'
},
'إشراف هندسي': {
'نسبة_المحتوى_المحلي': 0.85, # 85% محتوى محلي
'بديل_محلي': True,
'مصدر': 'محلي',
'ملاحظات': 'متوفر من شركات محلية'
},
'خدمات تنسيق المواقع': {
'نسبة_المحتوى_المحلي': 0.80, # 80% محتوى محلي
'بديل_محلي': True,
'مصدر': 'محلي',
'ملاحظات': 'شركات محلية متخصصة'
},
'خدمات أمن وسلامة': {
'نسبة_المحتوى_المحلي': 0.95, # 95% محتوى محلي
'بديل_محلي': True,
'مصدر': 'محلي',
'ملاحظات': 'شركات محلية متخصصة'
},
'استشارات بيئية': {
'نسبة_المحتوى_المحلي': 0.65, # 65% محتوى محلي
'بديل_محلي': True,
'مصدر': 'محلي/دولي',
'ملاحظات': 'متوفرة محليًا مع بعض الخبرات الأجنبية'
},
'دراسات جدوى': {
'نسبة_المحتوى_المحلي': 0.70, # 70% محتوى محلي
'بديل_محلي': True,
'مصدر': 'محلي/دولي',
'ملاحظات': 'متوفرة من مكاتب استشارية محلية'
},
'خدمات نقل': {
'نسبة_المحتوى_المحلي': 0.90, # 90% محتوى محلي
'بديل_محلي': True,
'مصدر': 'محلي',
'ملاحظات': 'شركات نقل محلية متعددة'
},
'صيانة ونظافة': {
'نسبة_المحتوى_المحلي': 0.95, # 95% محتوى محلي
'بديل_محلي': True,
'مصدر': 'محلي',
'ملاحظات': 'شركات محلية متخصصة'
}
}
# محاولة تحميل البيانات من ملف إذا كان متاحًا
try:
file_path = os.path.join(config.DATA_DIR, 'local_services.csv')
if os.path.exists(file_path):
df = pd.read_csv(file_path, encoding='utf-8')
local_services = {}
for _, row in df.iterrows():
local_services[row['اسم_الخدمة']] = {
'نسبة_المحتوى_المحلي': row['نسبة_المحتوى_المحلي'],
'بديل_محلي': row['بديل_محلي'],
'مصدر': row['مصدر'],
'ملاحظات': row['ملاحظات']
}
except Exception as e:
print(f"خطأ في تحميل بيانات الخدمات المحلية: {str(e)}")
return local_services
def _load_local_labor(self):
"""تحميل بيانات القوى العاملة المحلية ونسب المحتوى المحلي"""
# محاكاة تحميل البيانات من مصدر بيانات
local_labor = {
'عمال بناء': {
'نسبة_المحتوى_المحلي': 0.60, # 60% محتوى محلي
'بديل_محلي': True,
'مصدر': 'محلي/أجنبي',
'ملاحظات': 'متوفر محليًا مع نسبة من العمالة الأجنبية'
},
'مهندسون': {
'نسبة_المحتوى_المحلي': 0.75, # 75% محتوى محلي
'بديل_محلي': True,
'مصدر': 'محلي/أجنبي',
'ملاحظات': 'كفاءات محلية متوفرة'
},
'فنيون': {
'نسبة_المحتوى_المحلي': 0.65, # 65% محتوى محلي
'بديل_محلي': True,
'مصدر': 'محلي/أجنبي',
'ملاحظات': 'متوفر محليًا بنسب متفاوتة'
},
'إداريون': {
'نسبة_المحتوى_المحلي': 0.90, # 90% محتوى محلي
'بديل_محلي': True,
'مصدر': 'محلي',
'ملاحظات': 'معظمهم من الكوادر المحلية'
},
'مشرفون': {
'نسبة_المحتوى_المحلي': 0.80, # 80% محتوى محلي
'بديل_محلي': True,
'مصدر': 'محلي',
'ملاحظات': 'معظمهم من الكوادر المحلية'
},
'مصممون': {
'نسبة_المحتوى_المحلي': 0.70, # 70% محتوى محلي
'بديل_محلي': True,
'مصدر': 'محلي/أجنبي',
'ملاحظات': 'كفاءات محلية مع بعض الخبرات الأجنبية'
},
'عمال مهرة': {
'نسبة_المحتوى_المحلي': 0.55, # 55% محتوى محلي
'بديل_محلي': True,
'مصدر': 'محلي/أجنبي',
'ملاحظات': 'نسبة من العمالة الأجنبية ذات الخبرة'
}
}
# محاولة تحميل البيانات من ملف إذا كان متاحًا
try:
file_path = os.path.join(config.DATA_DIR, 'local_labor.csv')
if os.path.exists(file_path):
df = pd.read_csv(file_path, encoding='utf-8')
local_labor = {}
for _, row in df.iterrows():
local_labor[row['فئة_العمالة']] = {
'نسبة_المحتوى_المحلي': row['نسبة_المحتوى_المحلي'],
'بديل_محلي': row['بديل_محلي'],
'مصدر': row['مصدر'],
'ملاحظات': row['ملاحظات']
}
except Exception as e:
print(f"خطأ في تحميل بيانات القوى العاملة المحلية: {str(e)}")
return local_labor
def calculate_project_local_content(self, project_data):
"""
حساب نسبة المحتوى المحلي للمشروع
المعلمات:
project_data: بيانات المشروع، تتضمن مكونات المنتجات والخدمات والقوى العاملة
إرجاع:
نسبة المحتوى المحلي الإجمالية، وتفاصيل حسب كل مكون
"""
# تهيئة نتائج الحساب
results = {
'نسبة_المحتوى_المحلي_الإجمالية': 0,
'تفاصيل_المكونات': {
'المنتجات': {'نسبة': 0, 'تفاصيل': {}},
'الخدمات': {'نسبة': 0, 'تفاصيل': {}},
'القوى العاملة': {'نسبة': 0, 'تفاصيل': {}}
},
'ملخص_المحتوى_المحلي': {},
'توصيات_التحسين': []
}
# حساب نسبة المحتوى المحلي للمنتجات
if 'المنتجات' in project_data:
products_local_content = self._calculate_products_local_content(project_data['المنتجات'])
results['تفاصيل_المكونات']['المنتجات'] = products_local_content
# حساب نسبة المحتوى المحلي للخدمات
if 'الخدمات' in project_data:
services_local_content = self._calculate_services_local_content(project_data['الخدمات'])
results['تفاصيل_المكونات']['الخدمات'] = services_local_content
# حساب نسبة المحتوى المحلي للقوى العاملة
if 'القوى العاملة' in project_data:
labor_local_content = self._calculate_labor_local_content(project_data['القوى العاملة'])
results['تفاصيل_المكونات']['القوى العاملة'] = labor_local_content
# حساب النسبة الإجمالية للمحتوى المحلي بناءً على الأوزان النسبية
total_local_content = 0
for component, weight in self.component_weights.items():
if component in results['تفاصيل_المكونات']:
component_percentage = results['تفاصيل_المكونات'][component]['نسبة']
total_local_content += component_percentage * weight
results['نسبة_المحتوى_المحلي_الإجمالية'] = total_local_content
# تحديد ملخص المحتوى المحلي ومقارنته بالمستهدف
for component, target in self.targets.items():
if component in results['تفاصيل_المكونات']:
actual = results['تفاصيل_المكونات'][component]['نسبة']
status = 'مطابق' if actual >= target else 'غير مطابق'
gap = round((target - actual) * 100, 2) if actual < target else 0
results['ملخص_المحتوى_المحلي'][component] = {
'المستهدف': target * 100,
'الفعلي': round(actual * 100, 2),
'الحالة': status,
'الفجوة (%)': gap
}
# توليد توصيات لتحسين نسبة المحتوى المحلي
results['توصيات_التحسين'] = self._generate_improvement_recommendations(results)
return results
def _calculate_products_local_content(self, products_data):
"""
حساب نسبة المحتوى المحلي للمنتجات
المعلمات:
products_data: بيانات المنتجات المستخدمة في المشروع
إرجاع:
تفاصيل نسبة المحتوى المحلي للمنتجات
"""
total_cost = 0
local_content_value = 0
details = {}
for product_name, product_info in products_data.items():
quantity = product_info.get('الكمية', 0)
unit_price = product_info.get('سعر_الوحدة', 0)
total_product_cost = quantity * unit_price
# البحث عن نسبة المحتوى المحلي للمنتج
local_content_percentage = 0
if product_name in self.local_products:
local_content_percentage = self.local_products[product_name]['نسبة_المحتوى_المحلي']
# حساب قيمة المحتوى المحلي للمنتج
product_local_content_value = total_product_cost * local_content_percentage
# تحديث الإجماليات
total_cost += total_product_cost
local_content_value += product_local_content_value
# تسجيل التفاصيل
details[product_name] = {
'الكمية': quantity,
'سعر_الوحدة': unit_price,
'التكلفة_الإجمالية': total_product_cost,
'نسبة_المحتوى_المحلي': local_content_percentage,
'قيمة_المحتوى_المحلي': product_local_content_value,
'مصدر': self.local_products.get(product_name, {}).get('مصدر', 'غير معروف'),
'ملاحظات': self.local_products.get(product_name, {}).get('ملاحظات', '')
}
# حساب النسبة الإجمالية للمحتوى المحلي للمنتجات
local_content_percentage = local_content_value / total_cost if total_cost > 0 else 0
return {
'نسبة': local_content_percentage,
'إجمالي_التكلفة': total_cost,
'قيمة_المحتوى_المحلي': local_content_value,
'تفاصيل': details
}
def _calculate_services_local_content(self, services_data):
"""
حساب نسبة المحتوى المحلي للخدمات
المعلمات:
services_data: بيانات الخدمات المستخدمة في المشروع
إرجاع:
تفاصيل نسبة المحتوى المحلي للخدمات
"""
total_cost = 0
local_content_value = 0
details = {}
for service_name, service_info in services_data.items():
cost = service_info.get('التكلفة', 0)
# البحث عن نسبة المحتوى المحلي للخدمة
local_content_percentage = 0
if service_name in self.local_services:
local_content_percentage = self.local_services[service_name]['نسبة_المحتوى_المحلي']
# حساب قيمة المحتوى المحلي للخدمة
service_local_content_value = cost * local_content_percentage
# تحديث الإجماليات
total_cost += cost
local_content_value += service_local_content_value
# تسجيل التفاصيل
details[service_name] = {
'التكلفة': cost,
'نسبة_المحتوى_المحلي': local_content_percentage,
'قيمة_المحتوى_المحلي': service_local_content_value,
'مصدر': self.local_services.get(service_name, {}).get('مصدر', 'غير معروف'),
'ملاحظات': self.local_services.get(service_name, {}).get('ملاحظات', '')
}
# حساب النسبة الإجمالية للمحتوى المحلي للخدمات
local_content_percentage = local_content_value / total_cost if total_cost > 0 else 0
return {
'نسبة': local_content_percentage,
'إجمالي_التكلفة': total_cost,
'قيمة_المحتوى_المحلي': local_content_value,
'تفاصيل': details
}
def _calculate_labor_local_content(self, labor_data):
"""
حساب نسبة المحتوى المحلي للقوى العاملة
المعلمات:
labor_data: بيانات القوى العاملة المستخدمة في المشروع
إرجاع:
تفاصيل نسبة المحتوى المحلي للقوى العاملة
"""
total_cost = 0
local_content_value = 0
details = {}
for labor_type, labor_info in labor_data.items():
count = labor_info.get('العدد', 0)
monthly_salary = labor_info.get('الراتب_الشهري', 0)
duration_months = labor_info.get('المدة_بالأشهر', 0)
total_labor_cost = count * monthly_salary * duration_months
# البحث عن نسبة المحتوى المحلي للقوى العاملة
local_content_percentage = 0
if labor_type in self.local_labor:
local_content_percentage = self.local_labor[labor_type]['نسبة_المحتوى_المحلي']
# حساب قيمة المحتوى المحلي للقوى العاملة
labor_local_content_value = total_labor_cost * local_content_percentage
# تحديث الإجماليات
total_cost += total_labor_cost
local_content_value += labor_local_content_value
# تسجيل التفاصيل
details[labor_type] = {
'العدد': count,
'الراتب_الشهري': monthly_salary,
'المدة_بالأشهر': duration_months,
'التكلفة_الإجمالية': total_labor_cost,
'نسبة_المحتوى_المحلي': local_content_percentage,
'قيمة_المحتوى_المحلي': labor_local_content_value,
'مصدر': self.local_labor.get(labor_type, {}).get('مصدر', 'غير معروف'),
'ملاحظات': self.local_labor.get(labor_type, {}).get('ملاحظات', '')
}
# حساب النسبة الإجمالية للمحتوى المحلي للقوى العاملة
local_content_percentage = local_content_value / total_cost if total_cost > 0 else 0
return {
'نسبة': local_content_percentage,
'إجمالي_التكلفة': total_cost,
'قيمة_المحتوى_المحلي': local_content_value,
'تفاصيل': details
}
def _generate_improvement_recommendations(self, results):
"""
توليد توصيات لتحسين نسبة المحتوى المحلي
المعلمات:
results: نتائج حساب المحتوى المحلي
إرجاع:
قائمة بالتوصيات لتحسين نسبة المحتوى المحلي
"""
recommendations = []
# تحليل المكونات التي تحتاج إلى تحسين
for component, summary in results['ملخص_المحتوى_المحلي'].items():
if summary['الحالة'] == 'غير مطابق':
if component == 'المنتجات':
# تحديد المنتجات ذات المحتوى المحلي المنخفض
low_content_products = []
for product, details in results['تفاصيل_المكونات']['المنتجات']['تفاصيل'].items():
if details['نسبة_المحتوى_المحلي'] < 0.5: # أقل من 50%
low_content_products.append({
'اسم': product,
'نسبة_المحتوى_المحلي': details['نسبة_المحتوى_المحلي'],
'التكلفة_الإجمالية': details['التكلفة_الإجمالية']
})
elif component == 'الخدمات':
# تحديد البنود ذات المحتوى المحلي المنخفض
low_content_services = []
for service, details in results['تفاصيل_المكونات']['الخدمات']['تفاصيل'].items():
if details['نسبة_المحتوى_المحلي'] < 0.5: # أقل من 50%
low_content_services.append({
'اسم': service,
'نسبة_المحتوى_المحلي': details['نسبة_المحتوى_المحلي'],
'التكلفة': details['التكلفة']
})
elif component == 'القوى العاملة':
# تحديد فئات العمالة ذات المحتوى المحلي المنخفض
low_content_labor = []
for labor_type, details in results['تفاصيل_المكونات']['القوى العاملة']['تفاصيل'].items():
if details['نسبة_المحتوى_المحلي'] < 0.5: # أقل من 50%
low_content_labor.append({
'اسم': labor_type,
'نسبة_المحتوى_المحلي': details['نسبة_المحتوى_المحلي'],
'التكلفة_الإجمالية': details['التكلفة_الإجمالية']
})
# إنشاء توصيات لتحسين المحتوى المحلي
# توصيات للمنتجات
if 'المنتجات' in results['ملخص_المحتوى_المحلي'] and results['ملخص_المحتوى_المحلي']['المنتجات']['الحالة'] == 'غير مطابق':
low_content_products = []
for product, details in results['تفاصيل_المكونات']['المنتجات']['تفاصيل'].items():
if details['نسبة_المحتوى_المحلي'] < 0.5:
low_content_products.append({
'اسم': product,
'نسبة_المحتوى_المحلي': details['نسبة_المحتوى_المحلي']
})
if low_content_products:
recommendations.append(f"استبدال المنتجات ذات المحتوى المحلي المنخفض: {', '.join([p['اسم'] for p in low_content_products[:3]])}")
recommendations.append("البحث عن موردين محليين للمنتجات ذات الأولوية العالية")
# توصيات للخدمات
if 'الخدمات' in results['ملخص_المحتوى_المحلي'] and results['ملخص_المحتوى_المحلي']['الخدمات']['الحالة'] == 'غير مطابق':
low_content_services = []
for service, details in results['تفاصيل_المكونات']['الخدمات']['تفاصيل'].items():
if details['نسبة_المحتوى_المحلي'] < 0.5:
low_content_services.append({
'اسم': service,
'نسبة_المحتوى_المحلي': details['نسبة_المحتوى_المحلي']
})
if low_content_services:
recommendations.append(f"تحسين نسبة المحتوى المحلي للخدمات: {', '.join([s['اسم'] for s in low_content_services[:3]])}")
recommendations.append("التعاقد مع شركات خدمية محلية")
# توصيات للقوى العاملة
if 'القوى العاملة' in results['ملخص_المحتوى_المحلي'] and results['ملخص_المحتوى_المحلي']['القوى العاملة']['الحالة'] == 'غير مطابق':
low_content_labor = []
for labor_type, details in results['تفاصيل_المكونات']['القوى العاملة']['تفاصيل'].items():
if details['نسبة_المحتوى_المحلي'] < 0.5:
low_content_labor.append({
'اسم': labor_type,
'نسبة_المحتوى_المحلي': details['نسبة_المحتوى_المحلي']
})
if low_content_labor:
recommendations.append(f"زيادة توظيف العمالة المحلية في الفئات: {', '.join([l['اسم'] for l in low_content_labor[:3]])}")
recommendations.append("الاستثمار في برامج تدريب وتأهيل الكوادر المحلية")
# توصيات عامة
if 'المنتجات' in results['ملخص_المحتوى_المحلي'] and results['ملخص_المحتوى_المحلي']['المنتجات'].get('الفجوة (%)', 0) > 10:
recommendations.append(f"خطة تطوير المحتوى المحلي للمنتجات لتقليل الفجوة البالغة {results['ملخص_المحتوى_المحلي']['المنتجات']['الفجوة (%)']}%")
if 'الخدمات' in results['ملخص_المحتوى_المحلي'] and results['ملخص_المحتوى_المحلي']['الخدمات'].get('الفجوة (%)', 0) > 10:
recommendations.append(f"خطة تطوير المحتوى المحلي للخدمات لتقليل الفجوة البالغة {results['ملخص_المحتوى_المحلي']['الخدمات']['الفجوة (%)']}%")
if 'القوى العاملة' in results['ملخص_المحتوى_المحلي'] and results['ملخص_المحتوى_المحلي']['القوى العاملة'].get('الفجوة (%)', 0) > 10:
recommendations.append(f"خطة تطوير المحتوى المحلي للقوى العاملة لتقليل الفجوة البالغة {results['ملخص_المحتوى_المحلي']['القوى العاملة']['الفجوة (%)']}%")
return recommendations