// ================================================================ // database.js – طبقة البيانات الأساسية لـ BuildSmart // جميع الملفات الـ 16 تستورد هذا الملف // ================================================================ const DB_NAME = 'BuildSmartDB'; const DB_VERSION = 2; let db = null; // ----- فتح قاعدة البيانات ----- function openDB() { return new Promise((resolve, reject) => { const request = indexedDB.open(DB_NAME, DB_VERSION); request.onupgradeneeded = function(e) { const db = e.target.result; // إنشاء جميع الجداول (Object Stores) if (!db.objectStoreNames.contains('users')) { const store = db.createObjectStore('users', { keyPath: 'id' }); store.createIndex('email', 'email', { unique: true }); store.createIndex('role', 'role', { unique: false }); } if (!db.objectStoreNames.contains('projects')) { const store = db.createObjectStore('projects', { keyPath: 'id' }); store.createIndex('status', 'status', { unique: false }); } if (!db.objectStoreNames.contains('suppliers')) { const store = db.createObjectStore('suppliers', { keyPath: 'id' }); store.createIndex('name', 'name', { unique: false }); } if (!db.objectStoreNames.contains('orders')) { const store = db.createObjectStore('orders', { keyPath: 'id' }); store.createIndex('status', 'status', { unique: false }); store.createIndex('supplierId', 'supplierId', { unique: false }); store.createIndex('projectId', 'projectId', { unique: false }); } if (!db.objectStoreNames.contains('payments')) { const store = db.createObjectStore('payments', { keyPath: 'id' }); store.createIndex('orderId', 'orderId', { unique: false }); store.createIndex('status', 'status', { unique: false }); } if (!db.objectStoreNames.contains('contracts')) { const store = db.createObjectStore('contracts', { keyPath: 'id' }); store.createIndex('orderId', 'orderId', { unique: false }); store.createIndex('status', 'status', { unique: false }); } if (!db.objectStoreNames.contains('shipments')) { const store = db.createObjectStore('shipments', { keyPath: 'id' }); store.createIndex('orderId', 'orderId', { unique: false }); store.createIndex('status', 'status', { unique: false }); } if (!db.objectStoreNames.contains('certificates')) { const store = db.createObjectStore('certificates', { keyPath: 'id' }); store.createIndex('orderId', 'orderId', { unique: false }); store.createIndex('status', 'status', { unique: false }); } if (!db.objectStoreNames.contains('progressSteps')) { const store = db.createObjectStore('progressSteps', { keyPath: 'id' }); store.createIndex('projectId', 'projectId', { unique: false }); } if (!db.objectStoreNames.contains('transportRequests')) { const store = db.createObjectStore('transportRequests', { keyPath: 'id' }); store.createIndex('userId', 'userId', { unique: false }); store.createIndex('status', 'status', { unique: false }); } if (!db.objectStoreNames.contains('iotDevices')) { const store = db.createObjectStore('iotDevices', { keyPath: 'id' }); store.createIndex('projectId', 'projectId', { unique: false }); } if (!db.objectStoreNames.contains('greenMaterials')) { const store = db.createObjectStore('greenMaterials', { keyPath: 'id' }); } if (!db.objectStoreNames.contains('internetPartners')) { const store = db.createObjectStore('internetPartners', { keyPath: 'id' }); } if (!db.objectStoreNames.contains('employees')) { const store = db.createObjectStore('employees', { keyPath: 'id' }); store.createIndex('userId', 'userId', { unique: true }); store.createIndex('department', 'department', { unique: false }); } if (!db.objectStoreNames.contains('supportTickets')) { const store = db.createObjectStore('supportTickets', { keyPath: 'id' }); store.createIndex('status', 'status', { unique: false }); store.createIndex('userId', 'userId', { unique: false }); } if (!db.objectStoreNames.contains('settings')) { db.createObjectStore('settings', { keyPath: 'key' }); } }; request.onsuccess = function(e) { db = e.target.result; resolve(db); }; request.onerror = function(e) { reject(e.target.error); }; }); } // ----- دوال CRUD عامة ----- function getStore(storeName, mode = 'readonly') { return db.transaction(storeName, mode).objectStore(storeName); } async function addData(storeName, data) { return new Promise((resolve, reject) => { const store = getStore(storeName, 'readwrite'); const request = store.add(data); request.onsuccess = () => resolve(request.result); request.onerror = () => reject(request.error); }); } async function putData(storeName, data) { return new Promise((resolve, reject) => { const store = getStore(storeName, 'readwrite'); const request = store.put(data); request.onsuccess = () => resolve(request.result); request.onerror = () => reject(request.error); }); } async function deleteData(storeName, id) { return new Promise((resolve, reject) => { const store = getStore(storeName, 'readwrite'); const request = store.delete(id); request.onsuccess = () => resolve(); request.onerror = () => reject(request.error); }); } async function getAllData(storeName) { return new Promise((resolve, reject) => { const store = getStore(storeName); const request = store.getAll(); request.onsuccess = () => resolve(request.result); request.onerror = () => reject(request.error); }); } async function getDataById(storeName, id) { return new Promise((resolve, reject) => { const store = getStore(storeName); const request = store.get(id); request.onsuccess = () => resolve(request.result); request.onerror = () => reject(request.error); }); } async function getDataByIndex(storeName, indexName, value) { return new Promise((resolve, reject) => { const store = getStore(storeName); const index = store.index(indexName); const request = index.getAll(value); request.onsuccess = () => resolve(request.result); request.onerror = () => reject(request.error); }); } // ----- دالة تهيئة البيانات الأولية (Seed) ----- async function initDB() { await openDB(); const users = await getAllData('users'); if (users.length === 0) { const defaultUsers = [ { id: 1, name: 'مدير النظام', email: 'admin@buildsmart.com', password: 'admin123', role: 'admin' }, { id: 2, name: 'أحمد المالي', email: 'finance@buildsmart.com', password: '123456', role: 'finance' }, { id: 3, name: 'سارة العمليات', email: 'ops@buildsmart.com', password: '123456', role: 'operations' }, { id: 4, name: 'خالد المشتريات', email: 'procurement@buildsmart.com', password: '123456', role: 'procurement' }, { id: 5, name: 'محمود مدير مشروع', email: 'pm@buildsmart.com', password: '123456', role: 'project_manager' }, { id: 6, name: 'وديع المقاول', email: 'contractor@test.com', password: '123456', role: 'contractor' }, { id: 7, name: 'مجموعة المناصير', email: 'supplier@test.com', password: '123456', role: 'supplier' }, { id: 8, name: 'علي اللوجستي', email: 'logistics@buildsmart.com', password: '123456', role: 'logistics' }, { id: 9, name: 'نور الجودة', email: 'quality@buildsmart.com', password: '123456', role: 'quality' }, { id: 10, name: 'دعم فني', email: 'support@buildsmart.com', password: '123456', role: 'support' }, { id: 11, name: 'سامي التسويق', email: 'marketing@buildsmart.com', password: '123456', role: 'marketing' }, { id: 12, name: 'ليلى الموارد', email: 'hr@buildsmart.com', password: '123456', role: 'hr' }, { id: 13, name: 'مهند التقني', email: 'tech@buildsmart.com', password: '123456', role: 'tech' }, ]; for (const u of defaultUsers) { await addData('users', u); } // إضافة موردين افتراضيين await addData('suppliers', { id: 1, name: 'مجموعة المناصير', products: [{ name: 'حديد تسليح 14 مم', price: 540, unit: 'طن' }] }); await addData('suppliers', { id: 2, name: 'شركة جوتن للدهانات', products: [{ name: 'دهان داخلي', price: 25, unit: 'لتر' }] }); // إضافة مشاريع await addData('projects', { id: 1, name: 'حدائق عمان', location: 'عمان', budget: 250000, status: 'قيد التنفيذ', progress: 35 }); // إضافة شركات إنترنت await addData('internetPartners', { id: 1, name: 'زين الأردن', coverage: '5G', offer: 'باقة مخصصة' }); await addData('internetPartners', { id: 2, name: 'أورانج', coverage: '4.5G', offer: 'خصم 25%' }); } } // ================================================================ // تصدير الدوال للاستخدام في جميع الملفات // ================================================================