# Test Scenario Guide: Atomic Approval Rejection & Unified Auditing 🛡️

### 1. Scenario Introduction 📖
This feature significantly enhances the **Approval Lifecycle** within the ERP. It addresses the critical need for **atomic data consistency** when an approval request is rejected. Instead of merely changing a status, the system now performs a deep cleanup of "in-flight" financial and inventory data. Furthermore, it introduces a **Unified Audit Trail** and a **Notification System** to ensure transparency and timely communication across the organization.

---

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

*   **Database Level:**
    *   **New Table:** `approval_audit_logs`.
        *   Tracks `event_type` (started, step_approved, step_rejected, comment_added, completion, rejection).
        *   Stores polymorphic `itemable` references and JSON `metadata`.
    *   **Migration:** `2026_05_10_134000_create_approval_audit_logs_table.php`.
*   **Application Level:**
    *   **Enum Update:** `InvoiceStatusEnum` added `case Rejected = 'rejected'`.
    *   **Event Refactoring:** `Approval` model usage in events was unified under the `TraditionalApprove` model name.
    *   **Cleanup Logic:** The `finalizeEntityRejection` method uses `withoutGlobalScopes()` when deleting pending transactions to ensure multi-tenant or soft-delete constraints don't prevent a full cleanup.

---

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

| Feature | Previous Behavior | New Behavior | Benefit |
| :--- | :--- | :--- | :--- |
| **Rejection Cleanup** | Status changed to 'rejected', but pending transactions remained. | Atomically deletes pending `Accounting` and `Inventory` transactions. | **Data Integrity:** Prevents ledger clutter and balance discrepancies. |
| **Audit Visibility** | Scattered logs or no centralized history of approval steps. | Centralized `ApprovalAuditLog` capturing every transition and comment. | **Compliance:** Full transparency for financial audits. |
| **Communication** | Creators had to manually monitor status changes. | Automated ERP notifications sent to creators on final outcome. | **Efficiency:** Faster response times for rejected requests. |

---

### 4. API Endpoints Table 📊

| Process | Endpoint | Method | Description |
| :--- | :--- | :--- | :--- |
| **Step Approval** | `/api/v1/approvals/{id}/approve` | `POST` | Records approval for current level and moves to next level. |
| **Step Rejection** | `/api/v1/approvals/{id}/reject` | `POST` | Triggers atomic cleanup and sends rejection notification. |
| **Audit Timeline** | `/api/v1/approvals/{id}/timeline` | `GET` | (Service Layer) Retrieves the unified audit trail for the entity. |
| **Comment Submission** | `/api/v1/approvals/{id}/comments` | `POST` | Adds a comment and automatically injects it into the audit log. |

---

### 5. Test Cases 🧪

#### **[Case 1] The Happy Path: Full Approval & Notification**
*   **Setup:** Create a `SalesInvoice` that requires 2 levels of approval.
*   **Action:** Level 1 approves, then Level 2 approves.
*   **Expected Result:**
    *   `TraditionalApprove` status becomes `approved`.
    *   Audit Log contains 1 `approval_started` entry and 2 `step_approved` entries.
    *   Creator receives a database notification: *"SalesInvoice request #123 has been approved."*

#### **[Case 2] Atomic Rejection Cleanup**
*   **Setup:** Create a `Purchase` request with pending `AccountingTransactions` (Status: Pending).
*   **Action:** An approver rejects the request at Level 1 with reason "Invalid pricing".
*   **Expected Result:**
    *   `traditional_approves` table marks the record as `rejected`.
    *   Remaining approval steps are marked as `skipped`.
    *   **CRITICAL:** All pending `AccountingTransaction` and `InventoryTransaction` records for this model are **permanently deleted**.
    *   `InvoiceManagement` status is updated to `rejected`.

#### **[Case 3] Edge Cases & Constraints**
*   **Self-Action Notification Suppression:**
    *   *Scenario:* The creator of the invoice is also the one who performs the final approval (e.g., an Admin).
    *   *Expected Result:* The system should **skip** sending the notification to the user (since they performed the action).
*   **Missing Status Column:**
    *   *Scenario:* Rejecting a model that does not have a `status` column but has `approval_status`.
    *   *Expected Result:* `ApprovalActionHandler` should dynamically detect and update the `approval_status` column instead.
*   **Unauthorized Audit Access:**
    *   *Scenario:* Attempting to view a timeline for an approval outside the user's `company_id`.
    *   *Expected Result:* Global `company_id` scope in `ApprovalAuditLog` must prevent data leakage.

---
