Spaces:
Runtime error
Runtime error
| import json | |
| import os | |
| from datetime import datetime | |
| class DataStorage: | |
| """فئة لإدارة تخزين واسترجاع البيانات""" | |
| def __init__(self, data_dir="./data"): | |
| """تهيئة مدير التخزين""" | |
| self.data_dir = data_dir | |
| # إنشاء مجلد البيانات إذا لم يكن موجوداً | |
| if not os.path.exists(data_dir): | |
| os.makedirs(data_dir) | |
| # مسارات الملفات | |
| self.projects_file = os.path.join(data_dir, "projects.json") | |
| self.boq_items_file = os.path.join(data_dir, "boq_items.json") | |
| self.pricing_history_file = os.path.join(data_dir, "pricing_history.json") | |
| self.risks_file = os.path.join(data_dir, "risks.json") | |
| # تهيئة الملفات إذا لم تكن موجودة | |
| self._initialize_files() | |
| def _initialize_files(self): | |
| """تهيئة ملفات البيانات إذا لم تكن موجودة""" | |
| files = [ | |
| self.projects_file, | |
| self.boq_items_file, | |
| self.pricing_history_file, | |
| self.risks_file | |
| ] | |
| for file in files: | |
| if not os.path.exists(file): | |
| with open(file, 'w', encoding='utf-8') as f: | |
| json.dump([], f, ensure_ascii=False, indent=4) | |
| # وظائف إدارة المشاريع | |
| def load_projects(self): | |
| """تحميل بيانات المشاريع""" | |
| with open(self.projects_file, 'r', encoding='utf-8') as f: | |
| return json.load(f) | |
| def save_projects(self, projects): | |
| """حفظ بيانات المشاريع""" | |
| with open(self.projects_file, 'w', encoding='utf-8') as f: | |
| json.dump(projects, f, ensure_ascii=False, indent=4) | |
| def add_project(self, project): | |
| """إضافة مشروع جديد""" | |
| projects = self.load_projects() | |
| # إضافة طابع زمني للإنشاء والتحديث | |
| project['created_at'] = datetime.now().strftime("%Y-%m-%d %H:%M:%S") | |
| project['updated_at'] = project['created_at'] | |
| projects.append(project) | |
| self.save_projects(projects) | |
| return project | |
| def update_project(self, project_id, updated_data): | |
| """تحديث بيانات مشروع""" | |
| projects = self.load_projects() | |
| for i, project in enumerate(projects): | |
| if project['id'] == project_id: | |
| # تحديث البيانات مع الحفاظ على البيانات الأصلية | |
| projects[i].update(updated_data) | |
| # تحديث طابع زمني التحديث | |
| projects[i]['updated_at'] = datetime.now().strftime("%Y-%m-%d %H:%M:%S") | |
| self.save_projects(projects) | |
| return projects[i] | |
| return None # المشروع غير موجود | |
| def delete_project(self, project_id): | |
| """حذف مشروع""" | |
| projects = self.load_projects() | |
| items = self.load_boq_items() | |
| risks = self.load_risks() | |
| # حذف المشروع | |
| projects = [p for p in projects if p['id'] != project_id] | |
| self.save_projects(projects) | |
| # حذف بنود المشروع | |
| items = [item for item in items if item['project_id'] != project_id] | |
| self.save_boq_items(items) | |
| # حذف مخاطر المشروع | |
| risks = [risk for risk in risks if risk['project_id'] != project_id] | |
| self.save_risks(risks) | |
| return True | |
| # وظائف إدارة بنود جداول الكميات | |
| def load_boq_items(self): | |
| """تحميل بنود جداول الكميات""" | |
| with open(self.boq_items_file, 'r', encoding='utf-8') as f: | |
| return json.load(f) | |
| def save_boq_items(self, items): | |
| """حفظ بنود جداول الكميات""" | |
| with open(self.boq_items_file, 'w', encoding='utf-8') as f: | |
| json.dump(items, f, ensure_ascii=False, indent=4) | |
| def add_boq_item(self, item): | |
| """إضافة بند جديد""" | |
| items = self.load_boq_items() | |
| # إضافة طابع زمني للإنشاء والتحديث | |
| item['created_at'] = datetime.now().strftime("%Y-%m-%d %H:%M:%S") | |
| item['updated_at'] = item['created_at'] | |
| items.append(item) | |
| self.save_boq_items(items) | |
| return item | |
| def update_boq_item(self, item_id, updated_data): | |
| """تحديث بيانات بند""" | |
| items = self.load_boq_items() | |
| for i, item in enumerate(items): | |
| if item['id'] == item_id: | |
| # تحديث البيانات مع الحفاظ على البيانات الأصلية | |
| items[i].update(updated_data) | |
| # تحديث طابع زمني التحديث | |
| items[i]['updated_at'] = datetime.now().strftime("%Y-%m-%d %H:%M:%S") | |
| self.save_boq_items(items) | |
| return items[i] | |
| return None # البند غير موجود | |
| def delete_boq_item(self, item_id): | |
| """حذف بند""" | |
| items = self.load_boq_items() | |
| # حذف البند | |
| items = [item for item in items if item['id'] != item_id] | |
| self.save_boq_items(items) | |
| return True | |
| def get_project_items(self, project_id): | |
| """الحصول على بنود مشروع معين""" | |
| items = self.load_boq_items() | |
| return [item for item in items if item['project_id'] == project_id] | |
| # وظائف إدارة سجل التسعير | |
| def load_pricing_history(self): | |
| """تحميل سجل التسعير""" | |
| with open(self.pricing_history_file, 'r', encoding='utf-8') as f: | |
| return json.load(f) | |
| def save_pricing_history(self, history): | |
| """حفظ سجل التسعير""" | |
| with open(self.pricing_history_file, 'w', encoding='utf-8') as f: | |
| json.dump(history, f, ensure_ascii=False, indent=4) | |
| def save_pricing(self, pricing_data): | |
| """حفظ تسعير جديد""" | |
| history = self.load_pricing_history() | |
| # إضافة طابع زمني | |
| pricing_data['saved_at'] = datetime.now().strftime("%Y-%m-%d %H:%M:%S") | |
| history.append(pricing_data) | |
| self.save_pricing_history(history) | |
| return pricing_data | |
| def get_project_pricing_history(self, project_id): | |
| """الحصول على سجل تسعير مشروع معين""" | |
| history = self.load_pricing_history() | |
| return [entry for entry in history if entry['project_id'] == project_id] | |
| # وظائف إدارة المخاطر | |
| def load_risks(self): | |
| """تحميل بيانات المخاطر""" | |
| with open(self.risks_file, 'r', encoding='utf-8') as f: | |
| return json.load(f) | |
| def save_risks(self, risks): | |
| """حفظ بيانات المخاطر""" | |
| with open(self.risks_file, 'w', encoding='utf-8') as f: | |
| json.dump(risks, f, ensure_ascii=False, indent=4) | |
| def add_risk(self, risk): | |
| """إضافة مخاطرة جديدة""" | |
| risks = self.load_risks() | |
| # إضافة طابع زمني للإنشاء والتحديث | |
| risk['created_at'] = datetime.now().strftime("%Y-%m-%d %H:%M:%S") | |
| risk['updated_at'] = risk['created_at'] | |
| risks.append(risk) | |
| self.save_risks(risks) | |
| return risk | |
| def update_risk(self, risk_id, updated_data): | |
| """تحديث بيانات مخاطرة""" | |
| risks = self.load_risks() | |
| for i, risk in enumerate(risks): | |
| if risk['id'] == risk_id: | |
| # تحديث البيانات مع الحفاظ على البيانات الأصلية | |
| risks[i].update(updated_data) | |
| # تحديث طابع زمني التحديث | |
| risks[i]['updated_at'] = datetime.now().strftime("%Y-%m-%d %H:%M:%S") | |
| self.save_risks(risks) | |
| return risks[i] | |
| return None # المخاطرة غير موجودة | |
| def delete_risk(self, risk_id): | |
| """حذف مخاطرة""" | |
| risks = self.load_risks() | |
| # حذف المخاطرة | |
| risks = [r for r in risks if r['id'] != risk_id] | |
| self.save_risks(risks) | |
| return True | |
| def get_project_risks(self, project_id): | |
| """الحصول على مخاطر مشروع معين""" | |
| risks = self.load_risks() | |
| return [risk for risk in risks if risk['project_id'] == project_id] | |
| # وظائف النسخ الاحتياطي | |
| def backup_data(self, backup_dir="./backup"): | |
| """إنشاء نسخة احتياطية من البيانات""" | |
| if not os.path.exists(backup_dir): | |
| os.makedirs(backup_dir) | |
| timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") | |
| # نسخ ملفات البيانات | |
| files = { | |
| "projects.json": self.projects_file, | |
| "boq_items.json": self.boq_items_file, | |
| "pricing_history.json": self.pricing_history_file, | |
| "risks.json": self.risks_file | |
| } | |
| for filename, src_file in files.items(): | |
| if os.path.exists(src_file): | |
| backup_file = os.path.join(backup_dir, f"{filename.split('.')[0]}_{timestamp}.json") | |
| with open(src_file, 'r', encoding='utf-8') as src: | |
| with open(backup_file, 'w', encoding='utf-8') as dst: | |
| dst.write(src.read()) | |
| return timestamp | |