# Serial Numbers - Implementation Summary

## Quick Reference

### Files Added

| File | Purpose |
|------|---------|
| `database/migrations/2026_05_08_create_serial_numbers_table.php` | Database schema |
| `app/Models/SerialNumber.php` | Eloquent model with validation |
| `app/Services/SerialNumberService.php` | Business logic service |
| `app/Observers/OrderObserver.php` | Auto-generation trigger |
| `app/Console/Commands/GenerateSerialNumbers.php` | CLI tool |
| `app/Http/Controllers/SerialNumberController.php` | API endpoints |
| `routes/serial-numbers.php` | Route definitions |

### Example Order Serial Output

**Order ID**: 45821
**Order Date**: 2026-05-08

#### Wireless Mouse (SKU: WM-101, Qty: 2)
| Serial Number | Warranty Expiry | Status |
|---|---|---|
| WM-101-20260508-001 | 2027-05-08 | Active |
| WM-101-20260508-002 | 2027-05-08 | Active |

#### Keyboard (SKU: KB-205, Qty: 1)
| Serial Number | Warranty Expiry | Status |
|---|---|---|
| KB-205-20260508-001 | 2027-05-08 | Active |

### Database Query Examples

```php
// Find serial by number
$serial = SerialNumber::where('serial_number', 'WM-101-20260508-001')->first();

// Get all serials for an order
$serials = SerialNumber::where('order_id', 45821)->get();

// Get active warranties
$active = SerialNumber::where('warranty_status', 'active')
    ->where('warranty_expiry', '>', now())
    ->get();

// Get expiring warranties (next 30 days)
$expiring = SerialNumber::whereBetween('warranty_expiry', [
    now(),
    now()->addDays(30)
])->get();

// Get claimed warranties
$claimed = SerialNumber::where('warranty_status', 'claimed')->get();
```

### Artisan Commands

```bash
# Generate serials for a specific order
php artisan serials:generate --order-id=45821

# Generate for all orders without serials
php artisan serials:generate

# Regenerate (delete and recreate)
php artisan serials:generate --order-id=45821 --regenerate
```

### Model Methods

```php
$serial = SerialNumber::find(1);

// Validate warranty
$result = $serial->validateWarranty(); // returns array with status

// Activate warranty
$serial->activateWarranty();

// Claim warranty
$serial->claimWarranty('Screen malfunction');

// Void serial
$serial->void('Damaged during shipping');
```

### Service Methods

```php
$service = app(\App\Services\SerialNumberService::class);

// Generate for order
$serials = $service->generateForOrder($order);

// Validate serial
$result = $service->validateSerial('WM-101-20260508-001');

// Get order serials
$serials = $service->getOrderSerials(45821);

// Export as JSON
$json = $service->exportAsJson($order);

// Export as CSV
$csv = $service->exportAsCsv($order);
```

### API Endpoints Summary

| Method | Endpoint | Auth | Description |
|--------|----------|------|-------------|
| POST | `/api/serials/validate` | No | Validate serial number |
| GET | `/api/serials/warranty/{serial}` | No | Check warranty info |
| GET | `/api/orders/{id}/serials` | Yes | List order serials |
| GET | `/api/orders/{id}/serials/export/json` | Yes | Export as JSON |
| GET | `/api/orders/{id}/serials/export/csv` | Yes | Export as CSV |
| POST | `/api/serials/{serial}/claim` | Yes | Claim warranty |

## Integration Checklist

- [ ] Run migration: `php artisan migrate`
- [ ] Register OrderObserver in AppServiceProvider
- [ ] Include routes in api.php or web.php
- [ ] Test serial generation: `php artisan serials:generate --order-id=1`
- [ ] Test API: `curl -X POST http://localhost/api/serials/validate`
- [ ] Update documentation
- [ ] Add to deployment scripts

## Example Responses

### Validate Serial (Success)
```json
{
  "valid": true,
  "serial_number": "WM-101-20260508-001",
  "product_name": "Wireless Mouse",
  "product_sku": "WM-101",
  "order_id": 45821,
  "warranty_status": "active",
  "warranty_expiry": "2027-05-08",
  "is_expired": false,
  "is_active": true,
  "activation_date": "2026-05-08",
  "generated_at": "2026-05-08"
}
```

### Validate Serial (Not Found)
```json
{
  "valid": false,
  "message": "Serial number not found"
}
```

### Get Warranty Info
```json
{
  "serial_number": "WM-101-20260508-001",
  "product_name": "Wireless Mouse",
  "product_sku": "WM-101",
  "order_id": 45821,
  "warranty_status": "active",
  "warranty_expiry": "2027-05-08 00:00:00",
  "is_expired": false,
  "activation_date": "2026-05-08",
  "status": "active"
}
```

### Export Order Serials (JSON)
```json
{
  "order_id": 45821,
  "order_number": 45821,
  "generated_at": "2026-05-08T12:34:56Z",
  "total_serials": 3,
  "serials": [
    {
      "serial_number": "WM-101-20260508-001",
      "product_sku": "WM-101",
      "product_name": "Wireless Mouse",
      "item_quantity_index": 1,
      "item_quantity_total": 2,
      "warranty_expiry": "2027-05-08",
      "status": "active"
    },
    {
      "serial_number": "WM-101-20260508-002",
      "product_sku": "WM-101",
      "product_name": "Wireless Mouse",
      "item_quantity_index": 2,
      "item_quantity_total": 2,
      "warranty_expiry": "2027-05-08",
      "status": "active"
    },
    {
      "serial_number": "KB-205-20260508-001",
      "product_sku": "KB-205",
      "product_name": "Keyboard",
      "item_quantity_index": 1,
      "item_quantity_total": 1,
      "warranty_expiry": "2027-05-08",
      "status": "active"
    }
  ]
}
```

## Notes
- Serial numbers are unique at database level via unique constraint
- Warranty expiry is set to 1 year from generation (configurable)
- All timestamps in UTC
- CSV exports include headers
- Rate limiting recommended for public API endpoints
