# Test Scenario Guide: Maintenance Contract (US-005)

### 1. Scenario Introduction 🏢
The **Maintenance Contract** feature is a core module of the ERP designed to manage the full lifecycle of maintenance agreements. It bridges the gap between sales (Technical/Price Offers) and operations (Projects/Visits). This feature ensures that all commercial terms, technical scopes, and legal requirements (Section 2-11 of US-005) are captured, validated, and transformed into actionable operational data. Key integrations include the **Accounting** domain (for Cost Center generation) and the **Project Management** domain (for visit scheduling).

---

### 2. Technical Schema Changes (Detailed) 🔍

#### **Maintenance Contract Model & Persistence**
*   **New Fields:** Added `contract_type`, `customer_contract_number`, `subject`, `visit_frequency`, `annual_visits_count`, `sla_p1/p2/p3_hours`, `payment_method`, `exclusions`, `penalties`, and `expiry_alert_days`.
*   **Hierarchical Assets:** The `mod_contract_assets` table now utilizes `system_type` and `quantity` to support a virtual hierarchy (Systems -> Unit Types).

#### **API Endpoints & Validation**
*   **Endpoint:** `POST /api/v1/maintenance-contracts` & `PUT /api/v1/maintenance-contracts/{id}`
    *   **Validation Rules:**
        *   `contract_types`: Must be an array (preventive/corrective).
        *   `addendums.*.assets`: Supports both existing `asset_id` or full manual data.
        *   `signatures`: Integrated with Spatie Media Library for `first_party_signature` and `second_party_signature`.
*   **Endpoint:** `PUT /api/v1/maintenance-contracts/{id}/approve`
    *   **Logic:** Transitions status to `active`, triggers `createProjectsFromContract()`, and sets `expiry_alert_days` from system settings.

#### **Response Changes (Resource Layer)**
*   **Nested Structure:** `MaintenanceContractResource` now groups fields into logical sections:
    *   `first_party` / `second_party` (includes site location).
    *   `duration` / `dates`.
    *   `approval` / `audit`.
*   **Hierarchical Assets:** `ContractAddendumResource` splits assets into:
    *   `systems`: Grouped by `system_type` with aggregated `total_unit_count`.
    *   `equipment`: Flat list of assets without a system classification (Section 7).

---

### 3. Why the Update? (Change Log) 🔄

| Feature | Previous Behavior | New Behavior (US-005) | Benefit |
| :--- | :--- | :--- | :--- |
| **Asset Structure** | Flat list of assets. | Hierarchical Systems -> Unit Types. | Improved inventory accuracy and checklist mapping. |
| **Data Scope** | Missing commercial/legal fields. | Full capture of Sections 2-11. | Legal compliance and better contract documentation. |
| **Alerts** | No expiry notifications. | Configurable alerts (default 60 days). | Increased contract renewal rates. |
| **Integrations** | Manual project/cost center creation. | Automated on contract activation. | Reduced manual entry and human error. |

---

### 4. API Endpoints Table 📊

| Process | Endpoint | Method | Description |
| :--- | :--- | :--- | :--- |
| **Draft Creation** | `/api/v1/maintenance-contracts` | `POST` | Initialize a contract draft with full commercial terms. |
| **Hierarchical Update** | `/api/v1/maintenance-contracts/{id}` | `PUT` | Update contract with nested systems and unit types. |
| **Activation** | `/api/v1/maintenance-contracts/{id}/approve` | `PUT` | Activate contract, generate projects, and schedule alerts. |
| **Conversion** | `/api/v1/technical-offers/{id}/create-contract` | `POST` | Transform an approved offer into a draft contract. |
| **Detail View** | `/api/v1/maintenance-contracts/{id}` | `GET` | Retrieve full contract data with eager-loaded relations. |

---

### 5. Test Cases 🧪

#### **[Case 1] The Happy Path: Hierarchical Activation**
1.  **Create** a contract with `systems` containing "HVAC" as type and "Chillers" as sub-type (count: 2).
2.  **Verify** that the `customer` relationship is eager-loaded and returns `trade_name` and `vat_number`.
3.  **Approve** the contract.
4.  **Check** that `mod_maintenance_contracts.status` is `active`.
5.  **Check** that `mod_maintenance_contracts.expiry_alert_days` matches the value in `AdditionalSettings`.
6.  **Verify** that a `MaintenanceProject` was created for the addendum.

#### **[Case 2] Backward Compatibility: Legacy Data**
1.  Access a contract where `mod_contract_assets` has `system_type` as `null`.
2.  **Verify** that these records appear in the `equipment` array and NOT the `systems` array in the API response.
3.  Ensure the `assets` relationship on the model still returns all records regardless of hierarchy.

#### **[Case 3] Edge Cases & Constraints**
*   **Duplicate Activation:** Attempt to approve an already `active` contract; expect a `400/500` error with message "already activated".
*   **Missing End Date:** Create a contract with only `start_date` and `duration`; verify `end_date` is auto-calculated.
*   **Incomplete Parties:** Submit without `party_one_name`; expect validation error.
*   **SLA Matching:** Submit `agreed_sla_hours`; verify it propagates to `sla_p1`, `p2`, and `p3` hours correctly.

---
**Document Status:** Finalized | **Version:** 1.0 | **Owner:** Backend Engineering Team
