// ================================================================
// 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%' });
}
}
// ================================================================
// تصدير الدوال للاستخدام في جميع الملفات
// ================================================================