# Test Scenario Guide: Preventive Maintenance Quotation Enhancements

### 1. Title
`# Test Scenario Guide: Preventive Maintenance Quotation Enhancements`

### 2. Scenario Introduction 🏢
The **Preventive Maintenance Quotation** (US-002) is a critical financial document generated after a technical assessment. This update ensures that the quotation accurately reflects the complex service scenarios introduced in **US-001 (Request)**. 

Key business drivers include:
*   **Independent Unit Pricing:** Treating Chiller and Package units as distinct contract components with their own subtotals to allow for clearer client reporting.
*   **Labor Inclusion:** Capturing **Resident Labor** costs and accommodation status directly in the financial offer.
*   **Data Consistency:** Synchronizing **Multi-site** status and **System Types** (as multi-select arrays) across the entire maintenance lifecycle.

### 3. Technical Schema Changes 🔍

#### Endpoint: `POST /api/v1/maintenance/price-offers/preventive/{technicalOffer}`
*   **Validation Changes:**
    *   Added `resident_labor_cost`: `nullable|numeric|min:0`.
*   **Response Changes (Resource):**
    *   Added `chiller_subtotal` and `package_subtotal` (decimal).
    *   Added `resident_labor` and `includes_accommodation` (boolean labels).
    *   Added `resident_labor_cost` (decimal).
    *   Added `is_multi_site` (boolean).
    *   Changed `system_type` (string) → `system_types` (array).

#### Endpoint: `PUT /api/v1/maintenance/price-offers/{offer}`
*   **Validation Changes (`UpdatePriceOfferRequest`):**
    *   Added `resident_labor_cost`: `required_if:resident_labor,true|nullable|numeric|min:0`.
*   **Behavioral Note:** The system now automatically updates `chiller_subtotal`, `package_subtotal`, and `total_visits_cost` whenever unit costs or frequencies are modified.

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

| Feature | Previous Behavior | New Behavior | Benefit |
| :--- | :--- | :--- | :--- |
| **Pricing Structure** | Combined Chiller/Package total | **Independent Subtotals** | Enhanced transparency for complex contracts. |
| **Worker Presence** | Resident labor ignored | **Full Labor Costing** | Accurate margin calculation including accommodation. |
| **Site Scope** | Text snapshot only | **Multi-site Flag** | Structural awareness of multi-location contracts. |
| **System Scope** | Single system per offer | **System Types Array** | Accurate representation of multi-system facilities. |

### 5. API Endpoints Table 📊

| Process | Endpoint | Method | Description |
| :--- | :--- | :--- | :--- |
| **Initialize Quotation** | `/api/v1/maintenance/price-offers/preventive/{technicalOffer}` | `POST` | Creates a preventive offer with auto-populated request data. |
| **Update Pricing** | `/api/v1/maintenance/price-offers/{offer}` | `PUT` | Updates visit costs, labor costs, and triggers auto-recalculation. |
| **Get Details** | `/api/v1/maintenance/price-offers/{offer}` | `GET` | Returns full financial breakdown including new subtotals. |

### 6. Test Cases 🧪

*   **[Case 1] The Happy Path (Complete Preventive Offer):**
    *   **Input:** Send a request with both `chiller_visit_cost` and `package_visit_cost`, plus `resident_labor_cost`.
    *   **Expected:** `chiller_subtotal` and `package_subtotal` are calculated correctly. `total_visits_cost` equals their sum. `total` includes the resident labor cost.
*   **[Case 2] Backward Compatibility:**
    *   **Input:** Access a legacy quotation created before the `system_types` change.
    *   **Expected:** The `system_type` column (renamed to `system_types`) is cast as an array containing the single legacy value. No 500 errors on the Resource.
*   **[Case 3] Validation Constraints (Resident Labor):**
    *   **Input:** Set `resident_labor` to `true` in the DB/Request but send a `PUT` update with a null `resident_labor_cost`.
    *   **Expected:** `422 Unprocessable Entity` with message: "The resident labor cost field is required when resident labor is true."
*   **[Case 4] Multi-site Persistence:**
    *   **Input:** Create a quotation from a technical offer linked to a multi-site request.
    *   **Expected:** `is_multi_site` is `true` in the response, and `location_names` contains the snapshot string.

---
