# Phase 9: Filament Admin Updates — Completion Log

## Date Completed
2026-03-12

## Files Created
| File | Purpose |
|---|---|
| `app/Filament/Resources/InvoiceResource.php` | Read-only Invoice resource with table, filters, view form, PDF/resend/send actions |
| `app/Filament/Resources/InvoiceResource/Pages/ListInvoices.php` | Invoice list page |
| `app/Filament/Resources/InvoiceResource/Pages/ViewInvoice.php` | Invoice view page with PDF download, resend, and send-to-email actions |
| `app/Filament/Resources/OrderResource/RelationManagers/InvoiceRelationManager.php` | Shows invoice linked to an order |
| `app/Filament/Resources/CustomerResource/RelationManagers/InvoicesRelationManager.php` | Shows all invoices for a customer |
| `database/migrations/2026_07_01_000005_seed_shop_manager_permissions.php` | Seeds shop_manager and invoices permissions |
| `tests/Feature/Filament/InvoiceResourceTest.php` | Tests for InvoiceResource pages and canCreate |
| `app/Filament/Resources/PlaceResource/Widgets/ShopSalesWidget.php` | Shop revenue, active managers, and order count stats widget for PlaceResource |

## Files Modified
| File | Change |
|---|---|
| `app/Filament/Resources/EmployeeResource.php` | Added SHOP_MANAGER to hospitality assignable roles |
| `app/Filament/Resources/ProductResource.php` | Added `is_active` toggle, `sku` field to form; `is_active` column to table |
| `app/Filament/Resources/ProductResource/RelationManagers/VariationsRelationManager.php` | Added barcode, SKU, low_stock_threshold to form; barcode, SKU, current_stock, reorder_status columns to table |
| `app/Filament/Resources/OrderResource.php` | Added Payment Details section (payment_provider, payment_details JSON, refund info), Receipt/Cash Photos section with SpatieMediaLibrary, InvoiceRelationManager |
| `app/Filament/Resources/CustomerResource.php` | Registered InvoicesRelationManager |
| `app/Models/User.php` | Added `invoices()` HasMany relationship |
| `app/Filament/Resources/ProductResource/RelationManagers/StocksRelationManager.php` | Added "Quick Refill" header action for one-click stock addition |
| `app/Filament/Resources/PlaceResource.php` | Registered ShopSalesWidget in `getWidgets()` |
| `app/Filament/Resources/PlaceResource/Pages/EditPlace.php` | Added `getFooterWidgets()` returning ShopSalesWidget |

## Migrations
| Migration | Tables/Columns |
|---|---|
| `2026_07_01_000005_seed_shop_manager_permissions.php` | Seeds 10 permissions: shop_manager.* (7) + invoices.* (3) |

## Permissions Seeded
```
shop_manager.view_dashboard
shop_manager.manage_carts
shop_manager.manage_products
shop_manager.manage_orders
shop_manager.manage_invoices
shop_manager.manage_customers
shop_manager.manage_inventory
invoices.view_any
invoices.view
invoices.resend
```

## Tests Written
| Test File | Test Count | All Pass? |
|---|---|---|
| `tests/Feature/Filament/InvoiceResourceTest.php` | 4 | Pending run |

## Swagger Docs
- N/A — Filament resources don't use Swagger annotations

## Quality Checks
- [ ] `./gitCheck.sh` passes — not yet run
- [x] `declare(strict_types=1)` in every PHP file
- [x] No dd(), dump(), var_dump() in code
- [x] public_id used in API (never id)
- [ ] `composer test` — not yet run

## Commits
Not yet committed.

## Implementation Details

### 9.1 EmployeeResource — SHOP_MANAGER Role
- Added `AdminRole::SHOP_MANAGER` to the hospitality-assignable roles array
- Super admins already see all roles via `AdminRole::options()`

### 9.2 Permissions
- Created migration to seed permissions using `Spatie\Permission\Models\Permission::firstOrCreate`
- Permissions follow the existing `module.action` convention
- RolePermissionsManager page auto-discovers new permissions (groups by prefix)

### 9.3 ProductResource — New Fields
- **Form:** Added `is_active` toggle and `sku` text input in the Settings section
- **Table:** Added `is_active` as boolean icon column
- **VariationsRelationManager Form:** Added barcode, SKU, low_stock_threshold in a new "Identifiers" fieldset
- **VariationsRelationManager Table:** Added barcode (searchable), SKU (searchable), current_stock (computed via `currentStock()`), reorder_status (badge with success/warning/danger colors)

### 9.5 OrderResource — POS/CASH Display
- Added "Payment Details" section to form with: payment_provider label, payment_details KeyValue (disabled), refund info placeholder
- Added "Receipt / Cash Photos" section with SpatieMediaLibraryFileUpload for `payment_receipt` (POS) and `cash_photo` (CASH) collections — both disabled/read-only
- Both sections are conditionally visible based on payment provider

### 9.6 InvoiceResource (NEW)
- **Read-only** — `canCreate()` returns false
- **Table:** invoice_number (searchable), order link, customer (searchable), place (searchable), total (formatted money), issued_at (sortable)
- **Filters:** Place select, date range (issued_at)
- **Actions:** View, Download PDF (opens in new tab), Resend (confirmation modal), Send to email (with email input form)
- **View form:** Invoice details (invoice #, issued_at, total, order, customer, place), line items display, customer snapshot, place snapshot — all read-only
- **View page actions:** Download PDF, Resend to Customer, Send to Email

### 9.6b InvoiceRelationManager (OrderResource)
- Shows invoice linked to order with invoice_number, total, issued_at, and PDF download action

### 9.7 InvoicesRelationManager (CustomerResource)
- Shows all customer invoices with invoice_number, place, total, issued_at
- Actions: View (links to InvoiceResource view page), Download PDF

### 9.4 StocksRelationManager — Quick Refill Action
- Added "Quick Refill" header action alongside existing CreateAction
- Form: Variation select (searchable, required) + Quantity input (numeric, min 1, default 1)
- Creates stock entry with `start_at = now()`, no `end_at` (permanent addition)
- Uses `$livewire->getOwnerRecord()->stocks()->create(...)` pattern

### 9.8 PlaceResource — Shop Manager Stats Widget
- Created `ShopSalesWidget` extending `StatsOverviewWidget`
- Shows 3 cards: Shop Revenue (30d), Active Shop Managers, Shop Orders (30d)
- Queries vendor orders via `whereNotNull('employee_id')` + `OrderStatus::PAID`
- Revenue calculated by joining `order_items` and summing `money_price_amount`
- Visibility restricted to `super_admin` and `hospitality` roles
- Registered in `PlaceResource::getWidgets()` and rendered as footer widget in `EditPlace::getFooterWidgets()`

## Blockers / Open Questions
- `./gitCheck.sh` and `composer test` need to be run
