# Serial Number System - Implementation Guide

## Overview
This system generates unique serial numbers for each product quantity in an order, enabling warranty tracking and product authentication.

## Features
- ✅ Globally unique serial numbers (SKU-DATE-INDEX format)
- ✅ Warranty expiration tracking
- ✅ Warranty claim management
- ✅ Serial validation API
- ✅ Export to JSON/CSV
- ✅ Database persistence with Eloquent ORM
- ✅ Auto-generation on order completion
- ✅ Manual generation via Artisan command

## Files Created

### Database
- `database/migrations/2026_05_08_create_serial_numbers_table.php` - Serial numbers table

### Models
- `app/Models/SerialNumber.php` - SerialNumber model with validation methods

### Services
- `app/Services/SerialNumberService.php` - Core service for serial generation and management

### Observers
- `app/Observers/OrderObserver.php` - Auto-generate serials on order completion

### Commands
- `app/Console/Commands/GenerateSerialNumbers.php` - CLI command for batch generation

### Controllers/API
- `app/Http/Controllers/SerialNumberController.php` - REST API endpoints

## Setup Instructions

### 1. Run Migration
```bash
php artisan migrate
```

### 2. Register Observer (in AppServiceProvider)
```php
use App\Models\Order;
use App\Observers\OrderObserver;

public function boot(): void
{
    Order::observe(OrderObserver::class);
}
```

### 3. Register Routes (in routes/api.php or routes/web.php)
```php
use App\Http\Controllers\SerialNumberController;

Route::post('/serials/validate', [SerialNumberController::class, 'validate']);
Route::get('/serials/warranty/{serialNumber}', [SerialNumberController::class, 'getWarrantyInfo']);
Route::post('/serials/{serialNumber}/claim', [SerialNumberController::class, 'claimWarranty'])->middleware('auth');
Route::get('/orders/{orderId}/serials', [SerialNumberController::class, 'getOrderSerials'])->middleware('auth');
Route::get('/orders/{orderId}/serials/export/json', [SerialNumberController::class, 'exportJson']);
Route::get('/orders/{orderId}/serials/export/csv', [SerialNumberController::class, 'exportCsv']);
```

## Usage Examples

### Generate Serials for an Order (Automatic)
When an order status changes to "completed", serials are auto-generated:
```php
$order->update(['status' => 'completed']); // Triggers OrderObserver
```

### Generate Serials Manually
```php
// Via Command
php artisan serials:generate --order-id=45821
php artisan serials:generate --regenerate  // For all orders

// Via Service
$service = app(SerialNumberService::class);
$serials = $service->generateForOrder($order);
```

### Validate a Serial
```bash
curl -X POST http://localhost/api/serials/validate \
  -H "Content-Type: application/json" \
  -d '{"serial_number":"WM-101-20260508-001"}'
```

Response:
```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,
  "generated_at": "2026-05-08"
}
```

### Get Warranty Info
```bash
curl http://localhost/api/serials/warranty/WM-101-20260508-001
```

### Claim Warranty
```bash
curl -X POST http://localhost/api/serials/WM-101-20260508-001/claim \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer TOKEN" \
  -d '{"notes":"Product malfunctioned after 6 months of use"}'
```

### Export Serials
```bash
# JSON
curl http://localhost/api/orders/45821/serials/export/json

# CSV
curl http://localhost/api/orders/45821/serials/export/csv > serials.csv
```

### Get All Serials for an Order
```bash
curl http://localhost/api/orders/45821/serials \
  -H "Authorization: Bearer TOKEN"
```

## Database Schema

| Column | Type | Notes |
|--------|------|-------|
| id | bigint | Primary key |
| serial_number | varchar | Unique, indexed |
| order_id | bigint | Foreign key to orders |
| product_id | bigint | Foreign key to products |
| product_sku | varchar | Product SKU or identifier |
| product_name | varchar | Product name for quick lookup |
| item_quantity_index | smallint | Position in quantity (1-N) |
| item_quantity_total | smallint | Total quantity ordered |
| status | varchar | active, replaced, voided |
| warranty_status | varchar | active, expired, claimed |
| warranty_expiry | timestamp | When warranty expires |
| warranty_notes | text | Claim details or notes |
| user_id | bigint | Customer/owner |
| activation_date | timestamp | When warranty was activated |
| created_at | timestamp | Record creation time |
| updated_at | timestamp | Last update time |

## Serial Number Format

Pattern: `{SKU}-{DATE}-{INDEX}[-{RANDOM}]`

Example: `WM-101-20260508-001`

- **WM-101**: Product SKU
- **20260508**: Date (YYYYMMDD)
- **001**: Quantity index
- **RANDOM** (optional): Added if collision detected

## Warranty Logic

1. **Default**: 1 year from generation
2. **Status Tracking**: active → claimed or expired
3. **Expiration Check**: `warranty_expiry->isPast()`
4. **Claim Management**: Prevent claims on expired serials

## Database Relationships

```
SerialNumber
├── belongsTo Order
├── belongsTo Product
└── belongsTo User

Order
└── hasMany SerialNumbers

Product
└── hasMany SerialNumbers

User
└── hasMany SerialNumbers (owned)
```

## API Response Codes

| Code | Meaning |
|------|---------|
| 200 | Success |
| 404 | Serial number not found |
| 400 | Invalid request or expired warranty |
| 401 | Unauthorized |
| 422 | Validation error |

## Security Considerations

1. **Serial Uniqueness**: Database constraint + application-level check
2. **Warranty Claims**: Require authentication
3. **Order Access**: Implement proper authorization checks
4. **Export**: Consider rate limiting for CSV/JSON exports
5. **Validation API**: Rate limit to prevent brute force lookups

## Future Enhancements

- [ ] QR codes linked to serials
- [ ] SMS/Email warranty notifications
- [ ] Integration with RMA (Return Merchandise Authorization)
- [ ] Warranty transfer between users
- [ ] Bulk import/export functionality
- [ ] Audit logging for warranty claims
- [ ] Dashboard for warranty analytics
