Spaces:
Runtime error
Runtime error
| """ | |
| دوال مساعدة عامة للنظام | |
| """ | |
| import re | |
| import os | |
| import json | |
| import pandas as pd | |
| import numpy as np | |
| from datetime import datetime, timedelta | |
| import uuid | |
| import config | |
| def generate_unique_id(prefix=""): | |
| """ | |
| توليد معرف فريد | |
| المعلمات: | |
| prefix: بادئة للمعرف (اختياري) | |
| الإرجاع: | |
| معرف فريد | |
| """ | |
| unique_id = str(uuid.uuid4()).replace("-", "")[:12] | |
| return f"{prefix}{unique_id}" if prefix else unique_id | |
| def format_number(number, decimal_places=2): | |
| """ | |
| تنسيق الأرقام مع إضافة فواصل الآلاف | |
| المعلمات: | |
| number: الرقم المراد تنسيقه | |
| decimal_places: عدد المنازل العشرية (افتراضي: 2) | |
| الإرجاع: | |
| الرقم المنسق كنص | |
| """ | |
| if number is None: | |
| return "" | |
| try: | |
| return "{:,.{precision}f}".format(number, precision=decimal_places) | |
| except (ValueError, TypeError): | |
| return str(number) | |
| def format_currency(amount, currency="SAR", decimal_places=2): | |
| """ | |
| تنسيق المبالغ المالية مع إضافة رمز العملة | |
| المعلمات: | |
| amount: المبلغ المراد تنسيقه | |
| currency: رمز العملة (افتراضي: SAR) | |
| decimal_places: عدد المنازل العشرية (افتراضي: 2) | |
| الإرجاع: | |
| المبلغ المنسق كنص | |
| """ | |
| if amount is None: | |
| return "" | |
| try: | |
| formatted_amount = "{:,.{precision}f}".format(amount, precision=decimal_places) | |
| # تخصيص العرض حسب نوع العملة | |
| if currency.upper() in ["SAR", "ريال"]: | |
| return f"{formatted_amount} ريال" | |
| elif currency.upper() == "USD": | |
| return f"${formatted_amount}" | |
| elif currency.upper() == "EUR": | |
| return f"€{formatted_amount}" | |
| else: | |
| return f"{formatted_amount} {currency}" | |
| except (ValueError, TypeError): | |
| return str(amount) | |
| def format_date(date_obj, format_str="%Y-%m-%d"): | |
| """ | |
| تنسيق التاريخ | |
| المعلمات: | |
| date_obj: كائن التاريخ | |
| format_str: صيغة التاريخ (افتراضي: %Y-%m-%d) | |
| الإرجاع: | |
| التاريخ المنسق كنص | |
| """ | |
| if date_obj is None: | |
| return "" | |
| try: | |
| if isinstance(date_obj, str): | |
| # محاولة تحويل النص إلى تاريخ | |
| date_obj = datetime.strptime(date_obj, "%Y-%m-%d") | |
| return date_obj.strftime(format_str) | |
| except Exception: | |
| return str(date_obj) | |
| def extract_numbers_from_text(text): | |
| """ | |
| استخراج الأرقام من النص | |
| المعلمات: | |
| text: النص المراد استخراج الأرقام منه | |
| الإرجاع: | |
| قائمة بالأرقام المستخرجة | |
| """ | |
| if not text: | |
| return [] | |
| # نمط للبحث عن الأرقام (يدعم الأرقام العشرية والأرقام مع فواصل) | |
| number_pattern = r'\d+(?:,\d+)*(?:\.\d+)?' | |
| numbers = re.findall(number_pattern, str(text)) | |
| # تحويل الأرقام إلى قيم عددية | |
| return [float(num.replace(',', '')) for num in numbers] | |
| def extract_units_from_text(text): | |
| """ | |
| استخراج وحدات القياس من النص | |
| المعلمات: | |
| text: النص المراد استخراج وحدات القياس منه | |
| الإرجاع: | |
| قائمة بوحدات القياس المستخرجة | |
| """ | |
| if not text: | |
| return [] | |
| # قائمة بوحدات القياس الشائعة | |
| common_units = [ | |
| 'م2', 'م3', 'م.ط', 'متر مربع', 'متر مكعب', 'متر طولي', | |
| 'كجم', 'طن', 'جم', 'كيلوجرام', 'لتر', 'مل', | |
| 'قطعة', 'عدد', 'وحدة', 'مجموعة', 'زوج', | |
| 'يوم', 'ساعة', 'شهر', 'سنة', | |
| 'نقطة', 'مخرج' | |
| ] | |
| # إنشاء نمط بحث للوحدات | |
| pattern = r'\b(' + '|'.join(common_units) + r')\b' | |
| units = re.findall(pattern, str(text)) | |
| return units | |
| def safe_convert_to_float(value, default=0.0): | |
| """ | |
| تحويل آمن للقيمة إلى عدد عشري | |
| المعلمات: | |
| value: القيمة المراد تحويلها | |
| default: القيمة الافتراضية في حالة فشل التحويل (افتراضي: 0.0) | |
| الإرجاع: | |
| القيمة بعد التحويل | |
| """ | |
| try: | |
| if isinstance(value, str): | |
| # إزالة أي فواصل آلاف | |
| value = value.replace(',', '') | |
| return float(value) | |
| except (ValueError, TypeError): | |
| return default | |
| def safe_convert_to_int(value, default=0): | |
| """ | |
| تحويل آمن للقيمة إلى عدد صحيح | |
| المعلمات: | |
| value: القيمة المراد تحويلها | |
| default: القيمة الافتراضية في حالة فشل التحويل (افتراضي: 0) | |
| الإرجاع: | |
| القيمة بعد التحويل | |
| """ | |
| try: | |
| if isinstance(value, str): | |
| # إزالة أي فواصل آلاف | |
| value = value.replace(',', '') | |
| return int(float(value)) | |
| except (ValueError, TypeError): | |
| return default | |
| def save_to_json(data, file_path): | |
| """ | |
| حفظ البيانات في ملف JSON | |
| المعلمات: | |
| data: البيانات المراد حفظها | |
| file_path: مسار الملف | |
| الإرجاع: | |
| True في حالة النجاح، False في حالة الفشل | |
| """ | |
| try: | |
| # التأكد من وجود المجلد | |
| os.makedirs(os.path.dirname(file_path), exist_ok=True) | |
| with open(file_path, 'w', encoding='utf-8') as f: | |
| json.dump(data, f, ensure_ascii=False, indent=4) | |
| return True | |
| except Exception as e: | |
| print(f"خطأ في حفظ البيانات إلى JSON: {str(e)}") | |
| return False | |
| def load_from_json(file_path, default=None): | |
| """ | |
| تحميل البيانات من ملف JSON | |
| المعلمات: | |
| file_path: مسار الملف | |
| default: القيمة الافتراضية في حالة فشل التحميل (افتراضي: None) | |
| الإرجاع: | |
| البيانات المحملة | |
| """ | |
| if not os.path.exists(file_path): | |
| return default | |
| try: | |
| with open(file_path, 'r', encoding='utf-8') as f: | |
| return json.load(f) | |
| except Exception as e: | |
| print(f"خطأ في تحميل البيانات من JSON: {str(e)}") | |
| return default | |
| def export_to_excel(df, file_path, sheet_name="Sheet1"): | |
| """ | |
| تصدير DataFrame إلى ملف Excel | |
| المعلمات: | |
| df: DataFrame المراد تصديره | |
| file_path: مسار ملف Excel | |
| sheet_name: اسم الصفحة (افتراضي: Sheet1) | |
| الإرجاع: | |
| True في حالة النجاح، False في حالة الفشل | |
| """ | |
| try: | |
| # التأكد من وجود المجلد | |
| os.makedirs(os.path.dirname(file_path), exist_ok=True) | |
| # تصدير DataFrame إلى Excel | |
| df.to_excel(file_path, sheet_name=sheet_name, index=False) | |
| return True | |
| except Exception as e: | |
| print(f"خطأ في تصدير البيانات إلى Excel: {str(e)}") | |
| return False | |
| def create_directory_if_not_exists(directory_path): | |
| """ | |
| إنشاء المجلد إذا لم يكن موجوداً | |
| المعلمات: | |
| directory_path: مسار المجلد | |
| الإرجاع: | |
| True في حالة النجاح، False في حالة الفشل | |
| """ | |
| try: | |
| if not os.path.exists(directory_path): | |
| os.makedirs(directory_path) | |
| return True | |
| except Exception as e: | |
| print(f"خطأ في إنشاء المجلد: {str(e)}") | |
| return False | |
| def get_file_extension(file_name): | |
| """ | |
| الحصول على امتداد الملف | |
| المعلمات: | |
| file_name: اسم الملف | |
| الإرجاع: | |
| امتداد الملف | |
| """ | |
| return os.path.splitext(file_name)[1].lower() | |
| def is_file_type_supported(file_name): | |
| """ | |
| التحقق مما إذا كان نوع الملف مدعوماً | |
| المعلمات: | |
| file_name: اسم الملف | |
| الإرجاع: | |
| True إذا كان نوع الملف مدعوماً، False خلاف ذلك | |
| """ | |
| ext = get_file_extension(file_name) | |
| return ext[1:] in config.SUPPORTED_DOCUMENT_TYPES # إزالة النقطة من الامتداد | |
| def calculate_percentage_difference(value1, value2): | |
| """ | |
| حساب نسبة الفرق بين قيمتين | |
| المعلمات: | |
| value1: القيمة الأولى | |
| value2: القيمة الثانية | |
| الإرجاع: | |
| نسبة الفرق | |
| """ | |
| if value1 == 0 and value2 == 0: | |
| return 0 | |
| if value2 == 0: | |
| return float('inf') if value1 > 0 else float('-inf') | |
| return ((value1 - value2) / abs(value2)) * 100 | |
| from openai import OpenAI | |
| def get_openai_response(prompt, api_key, model_name="gpt-4"): | |
| """ | |
| إرسال استعلام إلى OpenAI واسترجاع الرد من النموذج المحدد. | |
| """ | |
| try: | |
| client = OpenAI(api_key=api_key) | |
| response = client.chat.completions.create( | |
| model=model_name, | |
| messages=[ | |
| {"role": "user", "content": prompt} | |
| ] | |
| ) | |
| return response.choices[0].message.content.strip() | |
| except Exception as e: | |
| return f"❌ حدث خطأ أثناء الاتصال بـ OpenAI: {str(e)}" | |