# تحليل شامل: شركات الصيانة وعلاقتها بطلبات الصيانة والفواتير وتجميد الأموال

## 📋 نظرة عامة

شركات الصيانة هي **مقدمي خدمات الصيانة** للعقارات. النظام يربط طلبات الصيانة بالعقارات التي تعود للمكتب العقاري، ويستخدم نظام تجميد الأموال كضمان مالي لضمان جودة الخدمة.

**الهدف:** إدارة طلبات الصيانة للعقارات المرتبطة بالمكتب، مع ضمان مالي عبر تجميد الأموال في المحفظة.

---

## 🏢 جدول شركات الصيانة (`maintenance_companies`)

### الهيكل الكامل:

```sql
CREATE TABLE `maintenance_companies` (
  `id` int(11) NOT NULL,
  `companies_id` int(11) DEFAULT NULL COMMENT 'يربط الشركة بالمستخدم (users.usercode)',
  `company_name` varchar(255) NOT NULL,
  `contact_phone` varchar(20) DEFAULT NULL,
  `contact_email` varchar(255) DEFAULT NULL,
  `specialization` set('سباكة','كهرباء','تكييف','نجارة','دهان','عام') DEFAULT 'عام',
  `service_area` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT 'المناطق التي تخدمها' CHECK (json_valid(`service_area`)),
  `avg_rating` decimal(3,2) DEFAULT 0.00 COMMENT 'متوسط التقييم من 5',
  `total_requests_completed` int(11) DEFAULT 0,
  `avg_response_time_hours` int(11) DEFAULT 0,
  `reliability_score` decimal(3,2) DEFAULT 0.00 COMMENT 'نقاط الموثوقية من 5',
  `is_active` tinyint(1) DEFAULT 1,
  `created_at` timestamp NOT NULL DEFAULT current_timestamp(),
  `updated_at` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
  `usercode` int(11) NOT NULL
)
```

### العلاقة الأساسية:
```
users (usercode)
  → maintenance_companies (companies_id أو usercode)
    → maintenance_bids (company_id)
      → maintenance_requests (maintenance_request_id)
        → properties (property_id)
          → office (office_id)
```

---

## 🔗 علاقة شركات الصيانة بطلبات الصيانة

### السلسلة الكاملة:

```
office (id)
  ↓
properties (office_id)
  ↓
maintenance_requests (property_id, office_id)
  ↓
maintenance_bids (maintenance_request_id, company_id)
  ↓
maintenance_companies (id)
```

### جدول `maintenance_requests` - طلبات الصيانة:

```sql
CREATE TABLE `maintenance_requests` (
  `id` int(11) NOT NULL COMMENT 'الرقم التسلسلي للطلب',
  `user_id` int(11) DEFAULT NULL,
  `request_title` varchar(50) NOT NULL,
  `request_number` varchar(50) DEFAULT NULL,
  `property_id` int(11) NOT NULL COMMENT 'رقم العقار المرتبط بالطلب',
  `description` text NOT NULL COMMENT 'تفاصيل الطلب أو المشكلة',
  `status` enum('قيد الانتظار','جارٍ التنفيذ','تم الإنجاز','ملغي') DEFAULT 'قيد الانتظار',
  `estimated_cost` decimal(10,2) DEFAULT 0.00 COMMENT 'التكلفة التقديرية',
  `actual_cost` decimal(10,2) DEFAULT 0.00 COMMENT 'التكلفة الفعلية',
  `office_id` int(11) DEFAULT NULL COMMENT 'رقم المكتب أو الجهة المسؤولة عن العقار',
  `service_id` int(11) DEFAULT NULL COMMENT 'نوع الخدمة المرتبطة بالطلب',
  `request_type` enum('شغل_يد','أغراض_مع_شغل_اليد') DEFAULT 'شغل_يد',
  `request_date` date NOT NULL COMMENT 'تاريخ تقديم طلب الصيانة',
  `completion_date` date DEFAULT NULL COMMENT 'تاريخ إتمام التنفيذ',
  `created_at` timestamp NOT NULL DEFAULT current_timestamp(),
  `updated_at` datetime DEFAULT NULL
)
```

**العلاقة مع المكتب:**
- `office_id` - يربط طلب الصيانة بالمكتب العقاري
- `property_id` - يربط الطلب بالعقار (والعقار مرتبط بالمكتب عبر `properties.office_id`)

### جدول `maintenance_bids` - عروض الصيانة:

```sql
CREATE TABLE `maintenance_bids` (
  `id` int(11) NOT NULL,
  `maintenance_request_id` int(11) NOT NULL COMMENT 'رقم طلب الصيانة',
  `company_id` int(11) NOT NULL COMMENT 'رقم الشركة',
  `offer_amount` decimal(10,2) NOT NULL COMMENT 'مبلغ العرض',
  `labor_cost` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT 'تكلفة العمالة',
  `items_total` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT 'إجمالي الأغراض',
  `total_amount` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT 'المبلغ الإجمالي',
  `status` enum('معلق','مقبول','مرفوض','مكتمل') NOT NULL DEFAULT 'معلق',
  `created_at` timestamp NOT NULL DEFAULT current_timestamp(),
  `updated_at` datetime DEFAULT NULL ON UPDATE current_timestamp()
)
```

**العلاقة:**
- `maintenance_request_id` → `maintenance_requests.id`
- `company_id` → `maintenance_companies.id`

---

## 💰 علاقة الفواتير (Invoices)

### جدول `invoices` - الفواتير:

```sql
CREATE TABLE `invoices` (
  `id` int(11) NOT NULL,
  `service_type` varchar(50) DEFAULT NULL COMMENT 'نوع الخدمة',
  `maintenance_tenders` int(11) DEFAULT NULL COMMENT 'رقم طلب الصيانة',
  `maintenance_bid_id` int(11) DEFAULT NULL COMMENT 'رقم عرض الصيانة',
  `user_id` int(11) DEFAULT NULL COMMENT 'المستخدم مقدم الطلب',
  `company_id` int(11) DEFAULT NULL COMMENT 'شركة الصيانة (maintenance_companies.id)',
  `invoice_amount` decimal(10,2) DEFAULT NULL COMMENT 'القيمة الأساسية',
  `total_with_tax` decimal(10,2) DEFAULT NULL COMMENT 'المجموع الكلي شامل الضريبة',
  `commission_amount` decimal(10,2) DEFAULT 0.00 COMMENT 'قيمة العمولة',
  `status` enum('معلقة','ملغاة','مدفوعة جزئياً','مدفوعة','اعتراض','متنازع عليها','مكتملة') DEFAULT 'معلقة',
  `fund_action` enum('تم حجز المبلغ','تم اطلاق سراح المبلغ','تم استرجاع المبلغ') DEFAULT NULL,
  `created_at` datetime DEFAULT current_timestamp(),
  `paid_at` datetime DEFAULT NULL
)
```

**العلاقات:**
- `maintenance_tenders` → `maintenance_requests.id` (CASCADE)
- `maintenance_bid_id` → `maintenance_bids.id`
- `company_id` → `maintenance_companies.id` (CASCADE)

**دورة الفاتورة:**
```
1. قبول عرض صيانة (maintenance_bids.status = 'مقبول')
   ↓
2. إنشاء فاتورة (invoices)
   ↓
3. ربط الفاتورة بطلب الصيانة (maintenance_tenders)
   ↓
4. ربط الفاتورة بعرض الصيانة (maintenance_bid_id)
   ↓
5. ربط الفاتورة بشركة الصيانة (company_id)
   ↓
6. تجميد المبلغ في المحفظة (wallet_holds)
```

---

## 🔒 نظام تجميد الأموال (Wallet Holds) - الضمان المالي

### نظرة عامة:

نظام تجميد الأموال يضمن **جودة الخدمة** من خلال:
1. تجميد مبلغ الصيانة في محفظة العميل
2. الاحتفاظ بالمبلغ حتى إتمام الخدمة
3. إطلاق المبلغ للشركة بعد إتمام الخدمة بنجاح
4. إمكانية استرجاع المبلغ في حالة المشاكل

---

## 💳 جدول المحافظ (`wallets`)

### الهيكل:

```sql
CREATE TABLE `wallets` (
  `id` int(11) NOT NULL,
  `user_id` int(11) NOT NULL COMMENT 'يرتبط بحقل usercode في جدول users',
  `balance` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT 'الرصيد المتاح',
  `hold_balance` decimal(12,2) NOT NULL DEFAULT 0.00 COMMENT 'الرصيد المجمد (الضمان)',
  `wallet_status` enum('active','suspended','blocked') NOT NULL DEFAULT 'active',
  `currency` varchar(3) NOT NULL DEFAULT 'SAR',
  `is_locked` tinyint(1) NOT NULL DEFAULT 0,
  `last_transaction_at` datetime DEFAULT NULL,
  `created_at` timestamp NOT NULL DEFAULT current_timestamp(),
  `updated_at` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
  `wallet_number` varchar(50) DEFAULT NULL COMMENT 'رقم المحفظة'
)
```

### الحقول المهمة:
- **`balance`** - الرصيد المتاح (يمكن استخدامه)
- **`hold_balance`** - الرصيد المجمد (ضمان مالي)
- **`wallet_status`** - حالة المحفظة (نشط، موقوف، محظور)

---

## 🔐 جدول تجميد الأموال (`wallet_holds`)

### الهيكل الكامل:

```sql
CREATE TABLE `wallet_holds` (
  `id` int(11) NOT NULL COMMENT 'المعرّف الفريد لكل عملية حجز مبلغ',
  `maintenance_request_id` int(11) DEFAULT NULL COMMENT 'مناقصة الصيانة',
  `hold_tx_id` int(11) NOT NULL COMMENT 'رقم المعاملة في محفظة المستخدم',
  `tender_id` int(11) DEFAULT NULL COMMENT 'رقم المناقصة',
  `maintenance_bid_id` int(11) DEFAULT NULL COMMENT 'رقم عرض الصيانة',
  `from_user_id` int(11) NOT NULL COMMENT 'المستخدم الذي تم حجز المبلغ من محفظته (طالب الخدمة)',
  `to_user_id` int(11) NOT NULL COMMENT 'المستخدم المستفيد (الشركة)',
  `amount` decimal(12,2) NOT NULL COMMENT 'قيمة المبلغ المحجوز',
  `status` enum('active','released','cancelled') NOT NULL DEFAULT 'active',
  `created_at` timestamp NOT NULL DEFAULT current_timestamp(),
  `released_at` datetime DEFAULT NULL COMMENT 'تاريخ إطلاق سراح المبلغ',
  `invoice_id` int(10) UNSIGNED DEFAULT NULL COMMENT 'يرتبط بالفاتورة',
  `company_id` int(10) UNSIGNED DEFAULT NULL COMMENT 'الشركة التي سيتم تحويل المبلغ لها',
  `payout_status` enum('pending','transferred','failed') DEFAULT 'pending',
  `payout_at` datetime DEFAULT NULL COMMENT 'تاريخ تحويل المبلغ للمستفيد',
  `platform_fee` decimal(12,2) DEFAULT 0.00 COMMENT 'عمولة المنصة'
)
```

### العلاقات:
- `maintenance_request_id` → `maintenance_requests.id`
- `maintenance_bid_id` → `maintenance_bids.id`
- `hold_tx_id` → `wallet_transactions.id` (CASCADE)
- `invoice_id` → `invoices.id`
- `company_id` → `companies.id` أو `maintenance_companies.id`
- `from_user_id` → `users.usercode` (طالب الخدمة)
- `to_user_id` → `users.usercode` (الشركة)

---

## 💸 جدول معاملات المحفظة (`wallet_transactions`)

### الهيكل:

```sql
CREATE TABLE `wallet_transactions` (
  `id` int(11) NOT NULL,
  `invoice_id` int(11) DEFAULT NULL COMMENT 'مرجع الفاتورة',
  `wallet_id` int(11) NOT NULL,
  `user_id` int(11) NOT NULL,
  `type` enum('deposit','withdrawal','payment','transfer','hold','release','commit') NOT NULL,
  `amount` decimal(12,2) NOT NULL,
  `currency_source` varchar(3) DEFAULT NULL,
  `description` text DEFAULT NULL,
  `reference` varchar(255) DEFAULT NULL,
  `transaction_date` timestamp NOT NULL DEFAULT current_timestamp(),
  `status` enum('completed','pending','failed','cancelled') NOT NULL DEFAULT 'completed',
  `admin_response` text NOT NULL,
  `created_at` timestamp NOT NULL DEFAULT current_timestamp(),
  `related_invoice_id` int(11) DEFAULT NULL,
  `updated_at` datetime NOT NULL,
  `admin_id` int(11) DEFAULT NULL,
  `manual_id` int(11) DEFAULT NULL,
  `id_withdrawal` int(11) DEFAULT NULL
)
```

### أنواع المعاملات (`type`):
- **`deposit`** - إيداع
- **`withdrawal`** - سحب
- **`payment`** - دفع
- **`transfer`** - تحويل
- **`hold`** - تجميد (حجز مبلغ كضمان)
- **`release`** - إطلاق (إطلاق المبلغ المجمد)
- **`commit`** - تأكيد (تحويل المبلغ للشركة)

---

## 🔄 دورة العمل الكاملة: من الطلب إلى الدفع

### المرحلة 1: إنشاء طلب صيانة
```
1. المكتب/المالك/المستأجر يطلب صيانة
   ↓
2. إنشاء طلب صيانة (maintenance_requests)
   - property_id → properties.id (العقار)
   - office_id → office.id (المكتب)
   - status = 'قيد الانتظار'
   ↓
3. عرض الطلب على شركات الصيانة
```

**التحقق:**
```sql
-- جلب طلبات الصيانة للعقارات المرتبطة بالمكتب
SELECT mr.*, p.main_title, p.office_id
FROM maintenance_requests mr
JOIN properties p ON mr.property_id = p.id
WHERE p.office_id = :office_id
  AND mr.status = 'قيد الانتظار';
```

---

### المرحلة 2: تقديم العروض
```
1. شركة الصيانة ترى الطلب
   ↓
2. شركة الصيانة تقدم عرض (maintenance_bids)
   - maintenance_request_id → maintenance_requests.id
   - company_id → maintenance_companies.id
   - offer_amount, labor_cost, items_total
   - total_amount = offer_amount + labor_cost + items_total
   - status = 'معلق'
   ↓
3. المالك/المكتب يراجع العروض
```

**التحقق:**
```sql
-- جلب عروض الصيانة لطلبات المكتب
SELECT mb.*, mc.company_name, mr.request_title, p.main_title
FROM maintenance_bids mb
JOIN maintenance_requests mr ON mb.maintenance_request_id = mr.id
JOIN properties p ON mr.property_id = p.id
JOIN maintenance_companies mc ON mb.company_id = mc.id
WHERE p.office_id = :office_id
  AND mb.status = 'معلق';
```

---

### المرحلة 3: قبول العرض وإنشاء الفاتورة
```
1. المالك/المكتب يختار أفضل عرض
   ↓
2. تحديث حالة العرض (maintenance_bids.status = 'مقبول')
   ↓
3. إنشاء فاتورة (invoices)
   - service_type = 'صيانة'
   - maintenance_tenders = maintenance_requests.id
   - maintenance_bid_id = maintenance_bids.id
   - company_id = maintenance_companies.id
   - invoice_amount = maintenance_bids.total_amount
   - status = 'معلقة'
   ↓
4. تجميد المبلغ في المحفظة (wallet_holds)
```

---

### المرحلة 4: تجميد المبلغ (الضمان المالي)

#### أ. إنشاء معاملة تجميد (`wallet_transactions`):
```sql
INSERT INTO wallet_transactions (
  wallet_id, user_id, type, amount, description,
  invoice_id, status, created_at
) VALUES (
  (SELECT id FROM wallets WHERE user_id = :user_id),
  :user_id,
  'hold',                    -- نوع المعاملة: تجميد
  :amount,                   -- المبلغ المراد تجميده
  'حجز مبلغ لصيانة عقار',
  :invoice_id,
  'completed',
  NOW()
);
```

#### ب. إنشاء سجل الحجز (`wallet_holds`):
```sql
INSERT INTO wallet_holds (
  hold_tx_id,                -- رقم معاملة التجميد
  maintenance_request_id,     -- رقم طلب الصيانة
  maintenance_bid_id,         -- رقم عرض الصيانة
  from_user_id,              -- طالب الخدمة (المالك/المكتب)
  to_user_id,                -- الشركة (من maintenance_companies.usercode)
  amount,                     -- المبلغ المجمد
  status,                     -- 'active' = محجوز
  invoice_id,                -- رقم الفاتورة
  company_id,                -- رقم شركة الصيانة
  created_at
) VALUES (
  :transaction_id,
  :maintenance_request_id,
  :maintenance_bid_id,
  :from_user_id,
  :to_user_id,
  :amount,
  'active',
  :invoice_id,
  :company_id,
  NOW()
);
```

#### ج. تحديث رصيد المحفظة:
```sql
UPDATE wallets 
SET balance = balance - :amount,        -- خصم من الرصيد المتاح
    hold_balance = hold_balance + :amount,  -- إضافة للرصيد المجمد
    last_transaction_at = NOW()
WHERE user_id = :user_id;
```

**النتيجة:**
- الرصيد المتاح (`balance`) ينقص
- الرصيد المجمد (`hold_balance`) يزيد
- المبلغ محجوز كضمان مالي

---

### المرحلة 5: تنفيذ الصيانة
```
1. شركة الصيانة تبدأ العمل
   ↓
2. تحديث حالة الطلب (maintenance_requests.status = 'جارٍ التنفيذ')
   ↓
3. شركة الصيانة تنفذ الصيانة
   ↓
4. تحديث التكلفة الفعلية (maintenance_requests.actual_cost)
   ↓
5. إتمام الصيانة
```

---

### المرحلة 6: إتمام الخدمة وإطلاق المبلغ

#### أ. تحديث حالة الطلب:
```sql
UPDATE maintenance_requests 
SET status = 'تم الإنجاز',
    actual_cost = :actual_cost,
    completion_date = NOW()
WHERE id = :request_id;
```

#### ب. إطلاق المبلغ المجمد (`wallet_holds`):
```sql
UPDATE wallet_holds 
SET status = 'released',           -- إطلاق المبلغ
    released_at = NOW(),
    payout_status = 'pending'      -- جاهز للتحويل
WHERE maintenance_bid_id = :bid_id
  AND status = 'active';
```

#### ج. إنشاء معاملة إطلاق (`wallet_transactions`):
```sql
INSERT INTO wallet_transactions (
  wallet_id, user_id, type, amount, description,
  invoice_id, status, created_at
) VALUES (
  (SELECT id FROM wallets WHERE user_id = :from_user_id),
  :from_user_id,
  'release',                      -- نوع المعاملة: إطلاق
  :amount,
  'إطلاق مبلغ صيانة عقار',
  :invoice_id,
  'completed',
  NOW()
);
```

#### د. تحديث رصيد المحفظة (طالب الخدمة):
```sql
UPDATE wallets 
SET hold_balance = hold_balance - :amount,  -- خصم من الرصيد المجمد
    last_transaction_at = NOW()
WHERE user_id = :from_user_id;
```

#### هـ. تحويل المبلغ للشركة (`wallet_transactions`):
```sql
INSERT INTO wallet_transactions (
  wallet_id, user_id, type, amount, description,
  invoice_id, status, created_at
) VALUES (
  (SELECT id FROM wallets WHERE user_id = :to_user_id),
  :to_user_id,
  'commit',                       -- نوع المعاملة: تحويل للشركة
  :amount - :platform_fee,        -- المبلغ ناقص عمولة المنصة
  'استلام مبلغ صيانة عقار',
  :invoice_id,
  'completed',
  NOW()
);
```

#### و. تحديث رصيد محفظة الشركة:
```sql
UPDATE wallets 
SET balance = balance + (:amount - :platform_fee),
    last_transaction_at = NOW()
WHERE user_id = :to_user_id;
```

#### ز. تحديث حالة الحجز:
```sql
UPDATE wallet_holds 
SET payout_status = 'transferred',
    payout_at = NOW()
WHERE id = :hold_id;
```

#### ح. تحديث حالة الفاتورة:
```sql
UPDATE invoices 
SET status = 'مدفوعة',
    paid_at = NOW(),
    fund_action = 'تم اطلاق سراح المبلغ'
WHERE id = :invoice_id;
```

---

## 🔄 حالات تجميد الأموال (Wallet Holds Status)

### 1. **`active`** - محجوز (نشط):
- **الوصف:** المبلغ محجوز كضمان مالي
- **الاستخدام:** بعد قبول العرض وقبل إتمام الخدمة
- **الرصيد:** المبلغ في `hold_balance` (مجمد)

### 2. **`released`** - تم الإطلاق:
- **الوصف:** تم إطلاق المبلغ من الحجز
- **الاستخدام:** بعد إتمام الخدمة بنجاح
- **الرصيد:** المبلغ تم تحويله للشركة

### 3. **`cancelled`** - ملغي:
- **الوصف:** تم إلغاء الحجز
- **الاستخدام:** في حالة إلغاء الطلب أو رفض العرض
- **الرصيد:** المبلغ يعود للرصيد المتاح

---

## 💼 حالات الدفع (Payout Status)

### 1. **`pending`** - قيد الانتظار:
- **الوصف:** المبلغ جاهز للتحويل ولكن لم يتم تحويله بعد
- **الاستخدام:** بعد إطلاق المبلغ وقبل التحويل

### 2. **`transferred`** - تم التحويل:
- **الوصف:** تم تحويل المبلغ للشركة بنجاح
- **الاستخدام:** بعد إتمام عملية التحويل

### 3. **`failed`** - فشل التحويل:
- **الوصف:** فشلت عملية التحويل
- **الاستخدام:** في حالة خطأ في التحويل

---

## 📊 العلاقات الكاملة في النظام

### السلسلة الكاملة:

```
office (id)
  ↓
properties (office_id)
  ↓
maintenance_requests (property_id, office_id)
  ↓
maintenance_bids (maintenance_request_id, company_id)
  ↓
maintenance_companies (id)
  ↓
invoices (maintenance_tenders, maintenance_bid_id, company_id)
  ↓
wallet_holds (maintenance_request_id, maintenance_bid_id, invoice_id, company_id)
  ↓
wallet_transactions (invoice_id, type='hold' أو 'release' أو 'commit')
  ↓
wallets (user_id)
```

---

## 🔍 أمثلة على الاستعلامات

### 1. جلب طلبات الصيانة للعقارات المرتبطة بالمكتب:

```sql
SELECT 
    mr.id,
    mr.request_number,
    mr.request_title,
    mr.description,
    mr.status,
    mr.estimated_cost,
    mr.actual_cost,
    mr.request_date,
    p.main_title AS property_title,
    p.office_id,
    o.officeName
FROM maintenance_requests mr
JOIN properties p ON mr.property_id = p.id
LEFT JOIN office o ON p.office_id = o.id
WHERE p.office_id = :office_id
ORDER BY mr.created_at DESC;
```

### 2. جلب عروض الصيانة لطلبات المكتب:

```sql
SELECT 
    mb.id AS bid_id,
    mb.offer_amount,
    mb.total_amount,
    mb.status AS bid_status,
    mc.company_name,
    mc.avg_rating,
    mr.id AS request_id,
    mr.request_title,
    p.main_title AS property_title
FROM maintenance_bids mb
JOIN maintenance_requests mr ON mb.maintenance_request_id = mr.id
JOIN properties p ON mr.property_id = p.id
JOIN maintenance_companies mc ON mb.company_id = mc.id
WHERE p.office_id = :office_id
  AND mb.status = 'معلق'
ORDER BY mb.created_at DESC;
```

### 3. جلب الفواتير المرتبطة بطلبات الصيانة:

```sql
SELECT 
    i.id AS invoice_id,
    i.invoice_number,
    i.invoice_amount,
    i.total_with_tax,
    i.status AS invoice_status,
    i.fund_action,
    mr.request_title,
    mc.company_name,
    p.main_title AS property_title
FROM invoices i
JOIN maintenance_requests mr ON i.maintenance_tenders = mr.id
JOIN properties p ON mr.property_id = p.id
LEFT JOIN maintenance_companies mc ON i.company_id = mc.id
WHERE p.office_id = :office_id
  AND i.service_type = 'صيانة'
ORDER BY i.created_at DESC;
```

### 4. جلب الأموال المجمدة لطلبات الصيانة:

```sql
SELECT 
    wh.id AS hold_id,
    wh.amount AS hold_amount,
    wh.status AS hold_status,
    wh.payout_status,
    wh.created_at AS hold_created_at,
    wh.released_at,
    mr.request_title,
    mc.company_name,
    u_from.name AS from_user_name,
    u_to.name AS to_user_name,
    i.invoice_number
FROM wallet_holds wh
JOIN maintenance_requests mr ON wh.maintenance_request_id = mr.id
JOIN properties p ON mr.property_id = p.id
LEFT JOIN maintenance_companies mc ON wh.company_id = mc.id
LEFT JOIN users u_from ON wh.from_user_id = u_from.usercode
LEFT JOIN users u_to ON wh.to_user_id = u_to.usercode
LEFT JOIN invoices i ON wh.invoice_id = i.id
WHERE p.office_id = :office_id
  AND wh.status = 'active'
ORDER BY wh.created_at DESC;
```

### 5. حساب إجمالي الأموال المجمدة للمكتب:

```sql
SELECT 
    SUM(wh.amount) AS total_hold_amount,
    COUNT(wh.id) AS total_holds,
    COUNT(CASE WHEN wh.status = 'active' THEN 1 END) AS active_holds,
    COUNT(CASE WHEN wh.status = 'released' THEN 1 END) AS released_holds
FROM wallet_holds wh
JOIN maintenance_requests mr ON wh.maintenance_request_id = mr.id
JOIN properties p ON mr.property_id = p.id
WHERE p.office_id = :office_id;
```

---

## 🔐 قواعد الأمان والصلاحيات

### 1. التحقق من ملكية المكتب للعقار:

```php
// التحقق من أن العقار مرتبط بالمكتب
SELECT id FROM properties 
WHERE id = :property_id 
  AND office_id = :office_id;
```

### 2. التحقق من ملكية المكتب لطلب الصيانة:

```php
// التحقق من أن طلب الصيانة مرتبط بعقار يخص المكتب
SELECT mr.id 
FROM maintenance_requests mr
JOIN properties p ON mr.property_id = p.id
WHERE mr.id = :request_id 
  AND p.office_id = :office_id;
```

### 3. التحقق من ملكية المكتب للعرض:

```php
// التحقق من أن عرض الصيانة مرتبط بطلب يخص المكتب
SELECT mb.id 
FROM maintenance_bids mb
JOIN maintenance_requests mr ON mb.maintenance_request_id = mr.id
JOIN properties p ON mr.property_id = p.id
WHERE mb.id = :bid_id 
  AND p.office_id = :office_id;
```

### 4. التحقق من ملكية المكتب للفاتورة:

```php
// التحقق من أن الفاتورة مرتبطة بطلب صيانة يخص المكتب
SELECT i.id 
FROM invoices i
JOIN maintenance_requests mr ON i.maintenance_tenders = mr.id
JOIN properties p ON mr.property_id = p.id
WHERE i.id = :invoice_id 
  AND p.office_id = :office_id;
```

---

## 📈 الإحصائيات المتوقعة

### لمكتب واحد (متوسط):
- **طلبات الصيانة:** 200 طلب/شهر
- **عروض الصيانة:** 600 عرض/شهر (3 عروض لكل طلب)
- **العروض المقبولة:** 150 عرض/شهر (25%)
- **الفواتير:** 150 فاتورة/شهر
- **الأموال المجمدة:** 500,000 ريال (متوسط)
- **قيمة الصيانة الشهرية:** 300,000 ريال

### لـ 100 مكتب:
- **طلبات الصيانة:** 20,000 طلب/شهر
- **عروض الصيانة:** 60,000 عرض/شهر
- **العروض المقبولة:** 15,000 عرض/شهر
- **الفواتير:** 15,000 فاتورة/شهر
- **الأموال المجمدة:** 50,000,000 ريال
- **قيمة الصيانة الشهرية:** 30,000,000 ريال

---

## 🎯 الخلاصة

### المبادئ الأساسية:
1. ✅ **كل طلب صيانة مرتبط بعقار** (`maintenance_requests.property_id`)
2. ✅ **كل عقار مرتبط بمكتب** (`properties.office_id`)
3. ✅ **كل عرض مرتبط بشركة صيانة** (`maintenance_bids.company_id`)
4. ✅ **كل فاتورة مرتبطة بطلب صيانة** (`invoices.maintenance_tenders`)
5. ✅ **نظام تجميد الأموال** يضمن جودة الخدمة
6. ✅ **الأموال المجمدة** في `wallet_holds` حتى إتمام الخدمة

### العلاقات الرئيسية:
```
office → properties (office_id) → maintenance_requests (property_id)
  → maintenance_bids (maintenance_request_id, company_id)
    → maintenance_companies (id)
      → invoices (maintenance_tenders, company_id)
        → wallet_holds (maintenance_request_id, invoice_id, company_id)
          → wallet_transactions (invoice_id, type='hold'/'release'/'commit')
            → wallets (user_id)
```

### دورة الأموال:
1. **تجميد** (`hold`) - حجز المبلغ كضمان
2. **إطلاق** (`release`) - إطلاق المبلغ بعد إتمام الخدمة
3. **تحويل** (`commit`) - تحويل المبلغ للشركة

---

**تاريخ الإنشاء:** 2025-01-25
**آخر تحديث:** 2025-01-25
