# Phase 5: Invoice System

## Objective
Auto-generate a PDF invoice when a checkout is completed, send it to the customer, and provide the vendor with an option to send it to an alternate email address.

---

## Tasks

### 5.1 Install PDF Package

Add `barryvdh/laravel-dompdf` (or `spatie/laravel-pdf` if preferred):
```bash
composer require barryvdh/laravel-dompdf
```

### 5.2 Invoice Model & Migration

**File:** `app/Models/Invoice.php`

**Migration:** `database/migrations/YYYY_MM_DD_HHMMSS_create_invoices_table.php`

```php
Schema::create('invoices', function (Blueprint $table) {
    $table->id();
    $table->uuid('public_id')->unique();
    $table->foreignId('order_id')->constrained()->cascadeOnDelete();
    $table->foreignId('place_id')->constrained()->cascadeOnDelete();
    $table->foreignId('user_id')->constrained()->cascadeOnDelete();
    $table->string('invoice_number')->unique(); // e.g., INV-2026-0001
    $table->bigInteger('total_amount');
    $table->string('total_currency', 3);
    $table->json('line_items'); // Snapshot of order items at time of invoice
    $table->json('customer_snapshot'); // Name, email, address at time of invoice
    $table->json('place_snapshot'); // Place name, address, VAT number
    $table->timestamp('issued_at');
    $table->timestamps();
});
```

**Model features:**
- `AsMoney` cast for total
- Relation to `Order`, `Place`, `User`
- `generateInvoiceNumber()` method (e.g., `INV-{YEAR}-{SEQUENCE}`)
- Media collection for the generated PDF

### 5.3 Invoice Generation Service

**File:** `app/Services/Invoice/InvoiceGenerationService.php`

Responsibilities:
- Accept an `Order` model
- Snapshot order items, customer info, place info into the invoice
- Generate a sequential invoice number per place
- Render PDF from Blade template
- Store PDF on Order/Invoice media collection
- Return the `Invoice` model

### 5.4 Invoice PDF Blade Template

**File:** `resources/views/invoices/pdf.blade.php`

Contents:
- Place logo and details (name, address, VAT number)
- Invoice number and date
- Customer details (name, email)
- Line items table: product name, quantity, unit price, total
- Subtotal, VAT, Total
- Payment method used
- Footer with legal mentions

### 5.5 Auto-Generate Invoice on OrderPaid

**File:** `app/Listeners/GenerateInvoiceWhenOrderPaid.php`

- Listen to `OrderPaid` event
- Only generate for orders with `employee_id` (vendor-initiated orders)
- Call `InvoiceGenerationService`
- Dispatch invoice email notification

Register in `EventServiceProvider`.

### 5.6 Invoice Email Notification

**File:** `app/Notifications/CustomerInvoiceNotification.php`

- Send via `sendinblue_email` channel
- Attach PDF as attachment or link
- Template-based like existing notifications

### 5.7 Send Invoice to Alternate Email

**File:** `app/Http/Controllers/Api/Employee/ShopManager/SendInvoiceController.php`

- `POST /v1/places/{place}/shop/orders/{order}/invoice/send`
- Body: `{ "email": "alternate@example.com" }`
- Validates email format
- Sends the same invoice PDF to the specified email
- Records the send in a log (optional)

**Request:** `app/Http/Requests/ShopManager/SendInvoiceRequest.php`

### 5.8 Download Invoice

**File:** `app/Http/Controllers/Api/Employee/ShopManager/DownloadInvoiceController.php`

- `GET /v1/places/{place}/shop/orders/{order}/invoice`
- Returns the PDF file as download or the media URL
- Generates on-the-fly if not yet generated (edge case)

### 5.9 Invoice Resource

**File:** `app/Http/Resources/ShopManager/InvoiceResource.php`

```json
{
  "id": "public_id",
  "invoice_number": "INV-2026-0042",
  "order_id": "order_public_id",
  "customer": { "name": "...", "email": "..." },
  "total": { "amount": 40900, "currency": "USD" },
  "issued_at": "2026-03-12T14:30:00Z",
  "pdf_url": "https://..."
}
```

### 5.10 Tests

**File:** `tests/Feature/Controllers/ShopManager/InvoiceTest.php`

Test cases:
- [ ] Invoice is auto-generated when vendor order is paid
- [ ] Invoice number is sequential per place
- [ ] Invoice PDF contains correct line items
- [ ] Invoice is sent to customer email
- [ ] Invoice can be sent to alternate email
- [ ] Invoice can be downloaded
- [ ] Invoice is not generated for non-vendor orders (customer self-checkout)
- [ ] Invoice snapshot is immutable (editing order after payment doesn't change invoice)

---

## Files Created/Modified

| Action | File |
|---|---|
| Create | `app/Models/Invoice.php` |
| Create | `database/migrations/..._create_invoices_table.php` |
| Create | `app/Services/Invoice/InvoiceGenerationService.php` |
| Create | `resources/views/invoices/pdf.blade.php` |
| Create | `app/Listeners/GenerateInvoiceWhenOrderPaid.php` |
| Modify | `app/Providers/EventServiceProvider.php` |
| Create | `app/Notifications/CustomerInvoiceNotification.php` |
| Create | `app/Http/Controllers/Api/Employee/ShopManager/SendInvoiceController.php` |
| Create | `app/Http/Controllers/Api/Employee/ShopManager/DownloadInvoiceController.php` |
| Create | `app/Http/Requests/ShopManager/SendInvoiceRequest.php` |
| Create | `app/Http/Resources/ShopManager/InvoiceResource.php` |
| Modify | `routes/api.php` |
| Create | `tests/Feature/Controllers/ShopManager/InvoiceTest.php` |

---

## Acceptance Criteria

- [ ] Invoice is automatically generated on vendor checkout
- [ ] PDF is well-formatted with all required business information
- [ ] Customer receives invoice via email
- [ ] Vendor can resend invoice to any email address
- [ ] Invoice PDF can be downloaded
- [ ] Invoice numbers are sequential and unique
- [ ] Swagger annotations on all controllers
- [ ] All tests pass
- [ ] `./gitCheck.sh` passes
