# Task 19 — Invoices

## Goal
Build the Invoices module to create customer invoices from sales operations.
This module must support invoice header + lines, totals, customer linkage, and future posting to Finance.

---

## Database

### Table: `invoices`

Fields:
- id
- invoice_number (string, unique)
- invoice_date (date)
- customer_id (FK to customers.id)
- sales_order_id (nullable, FK to sales_orders.id)
- branch_id (nullable, FK to branches.id)
- currency_code (string, nullable)
- exchange_rate (decimal 18,6, nullable)
- subtotal (decimal 18,2 default 0)
- tax_amount (decimal 18,2 default 0)
- total_amount (decimal 18,2 default 0)
- status (string, default `draft`)
  - draft
  - confirmed
  - cancelled
- notes (json, nullable, translatable)
- created_by (nullable, FK to admins.id)
- updated_by (nullable, FK to admins.id)
- created_at
- updated_at

Indexes:
- unique invoice_number
- index invoice_date
- index customer_id
- index sales_order_id
- index branch_id
- index status

### Table: `invoice_lines`

Fields:
- id
- invoice_id (FK to invoices.id)
- item_id (FK to items.id)
- description (json, nullable, translatable)
- quantity (decimal 18,2)
- unit_price (decimal 18,2)
- line_total (decimal 18,2)
- created_at
- updated_at

Indexes:
- index invoice_id
- index item_id

---

## Relations

### Invoice model relations
- customer() -> belongsTo Customer
- salesOrder() -> belongsTo SalesOrder
- branch() -> belongsTo Branch
- lines() -> hasMany InvoiceLine
- creator() -> belongsTo Admin
- updater() -> belongsTo Admin

### InvoiceLine model relations
- invoice() -> belongsTo Invoice
- item() -> belongsTo Item

---

## Business Rules

1. Invoice number must be unique and generated using NumberSequenceService.
2. Customer is required.
3. At least one invoice line is required.
4. Each line must contain item, quantity, and unit price.
5. subtotal = sum(line_total).
6. total_amount = subtotal + tax_amount.
7. Status starts as `draft`.
8. Later tasks may allow invoice confirmation and financial posting.
9. Currency fields are for transaction currency tracking only.

---

## Files

### Models
- app/Models/Sales/Invoice.php
- app/Models/Sales/InvoiceLine.php

### Service
- app/Services/Sales/InvoiceService.php

### Controller
- app/Http/Controllers/Admin/Sales/InvoiceController.php

### Requests
- app/Http/Requests/Admin/Sales/StoreInvoiceRequest.php
- app/Http/Requests/Admin/Sales/UpdateInvoiceRequest.php

### Views
- resources/views/dashboard/sales/invoices/index.blade.php
- resources/views/dashboard/sales/invoices/create.blade.php
- resources/views/dashboard/sales/invoices/edit.blade.php
- resources/views/dashboard/sales/invoices/show.blade.php

### Lang files
- lang/ar/sales.php
- lang/en/sales.php

---

## Permissions

- sales.invoices.view
- sales.invoices.create
- sales.invoices.update
- sales.invoices.delete

---

## Validation Rules

### Header
- invoice_date: required, date
- customer_id: required, exists:customers,id
- sales_order_id: nullable, exists:sales_orders,id
- branch_id: nullable, exists:branches,id
- currency_code: nullable, string
- exchange_rate: nullable, numeric, min:0
- tax_amount: nullable, numeric, min:0
- status: nullable, in:draft,confirmed,cancelled
- notes.ar: nullable, string
- notes.en: nullable, string

### Lines
- lines: required, array, min:1
- lines.*.item_id: required, exists:items,id
- lines.*.description.ar: nullable, string
- lines.*.description.en: nullable, string
- lines.*.quantity: required, numeric, gt:0
- lines.*.unit_price: required, numeric, min:0

---

## UI

Views path:
`resources/views/dashboard/sales/invoices/`

### Header fields
- invoice_date
- customer
- sales_order
- branch
- currency_code
- exchange_rate
- tax_amount
- status
- notes_ar
- notes_en

### Line fields
- item
- description_ar
- description_en
- quantity
- unit_price
- line_total

### Index columns
- invoice_number
- invoice_date
- customer
- branch
- total_amount
- status
- actions

---

## Lang Keys

Suggested keys:
- invoices
- invoice
- create_invoice
- edit_invoice
- invoice_number
- invoice_date
- customer
- sales_order
- branch
- currency
- exchange_rate
- subtotal
- tax_amount
- total_amount
- status
- lines
- item
- quantity
- unit_price
- line_total
- draft
- confirmed
- cancelled

---

## Seeder

Update RolePermissionSeeder with:
- sales.invoices.view
- sales.invoices.create
- sales.invoices.update
- sales.invoices.delete

---

## Steps

### Step 1
Create migration for `invoices` table.

### Step 2
Create migration for `invoice_lines` table.

### Step 3
Create `Invoice` and `InvoiceLine` models.

### Step 4
Create `InvoiceService`.

### Step 5
Create Form Requests.

### Step 6
Create `InvoiceController`.

### Step 7
Create routes.

### Step 8
Create views.

### Step 9
Create lang files.

### Step 10
Update `RolePermissionSeeder`.

---

## Notes for AI

- Follow docs/ai/AI_MASTER_PROJECT.md
- Follow docs/ai/ARCHITECTURE_RULES.md
- Follow docs/ai/DATABASE_SCHEMA.md
- Follow docs/ai/MODULE_STRUCTURE.md
- Execute one step at a time
- Do not modify unrelated files
- Do not generate tests in this task
- Wait for confirmation after each step

