# Test Scenario Guide: Contract Unit Pricing Precision

### 1. Title
# Test Scenario Guide: Fixing Contract Unit Pricing Precision

### 2. Scenario Introduction 🎯
The **Contract Unit Pricing Precision** update is designed to standardize the way unit prices and total costs are handled within the **Construction** domain (Purchase Order Contracts and Rental Contracts). 

In financial systems, floating-point arithmetic can lead to "accumulated precision loss"—where small decimal remainders (e.g., `0.00005`) result in discrepancies when summed over large quantities. This feature enforces a **consistent 2-decimal rounding policy** at the entry point (DTOs) and persistence layer (Services), ensuring that the data stored in the database perfectly matches the financial totals displayed to the user and processed in accounting.

### 3. Technical Schema Changes (Detailed) 🔍
The update involved creating missing model infrastructure and reinforcing casting/rounding across multiple layers:

*   **Model Infrastructure:**
    *   **New Model:** `PurchaseOrderContractItem` created to handle items for the `purchase_order_contract_items` table.
    *   **Casting:** Both `PurchaseOrderContractItem` and `RentalItem` now explicitly cast `unit_price`, `quantity`, and `total_price` to `float`.
*   **Validation & DTO Changes:**
    *   **DTOs:** `PurchaseOrderContractItemDTO` and `PurchaseOrderContractDTO` now implement `round($value, 2)` for all monetary fields.
    *   **Input Normalization:** Even if the API receives higher precision (e.g., `25.5555`), it is normalized to `25.56` before reaching the service.
*   **Service Persistence:**
    *   **Normalization:** `PurchaseOrderContractServices` and `RentalContractServices` now perform a final `round((float)$value, 2)` before database insertion/update.

### 4. Why the Update? (Change Log) 🔄
| Feature | Previous Behavior | New Behavior | Benefit |
| :--- | :--- | :--- | :--- |
| **Precision** | Values stored with up to 4 decimals; no consistent rounding. | Consistent **2-decimal rounding** across all layers. | Prevents "ghost pennies" in totals. |
| **Data Casting** | Reliance on implicit PHP casting or string storage. | Explicit **float casting** in Models and DTOs. | Improved **data integrity** and calculation speed. |
| **Model Coverage** | `PurchaseOrderContract` lacked a dedicated Item model. | Dedicated `PurchaseOrderContractItem` implemented. | Better **ORM support** and relationship management. |

### 5. API Endpoints Table 📊
| Process | Endpoint | Method | Description |
| :--- | :--- | :--- | :--- |
| **PO Contract Store** | `/api/v1/purchase-order-contracts` | `POST` | Creates a PO contract with normalized pricing. |
| **PO Contract Update** | `/api/v1/purchase-order-contracts/{id}` | `PUT` | Updates a PO contract with normalized pricing. |
| **Rental Contract Store** | `/api/v1/rental-contracts` | `POST` | Creates a rental contract with normalized pricing. |
| **Rental Contract Update** | `/api/v1/rental-contracts/{id}` | `PUT` | Updates a rental contract with normalized pricing. |

### 6. Test Cases 🧪

*   **[Case 1] The Happy Path (Standard Financial Input):**
    *   **Input:** `unit_price: 20.50`, `quantity: 100`.
    *   **Expected Result:** Database stores `20.50`. `total_price` matches exactly `2050.00`.
*   **[Case 2] Precision Normalization (High Decimal Input):**
    *   **Input:** `unit_price: 25.5555`.
    *   **Expected Result:** System rounds value to **25.56** before saving.
    *   **Input:** `unit_price: 29.9999`.
    *   **Expected Result:** System rounds value to **30.00** before saving.
*   **[Case 3] Backward Compatibility:**
    *   **Scenario:** Load a legacy record where `unit_price` was `25.5555`.
    *   **Expected Result:** The model casts it to float. Upon the next **Update** action, the value is normalized to `25.56`.
*   **[Case 4] Boundary Values:**
    *   **Input:** `unit_price: 0.001`.
    *   **Expected Result:** Rounded to **0.00**. (Standard financial behavior for 2-decimal systems).
    *   **Input:** `unit_price: 1000000.00`.
    *   **Expected Result:** Stored as **1000000.00** (Decimal 15,4 supports this range).

---
**Style Guidelines Applied:**
*   Professional technical English.
*   **Scannable bolding**.
*   **Emoji-coded sections**.
*   Markdown Tables for high readability.
