# Surf Invoicing Module

Invoice generation, management, and credit notes for NGauge orders.

## Features

- **Automatic Invoice Generation**: Generate invoices for orders based on `centrearrddate`.
- **Idempotent Processing**: Duplicate prevention via unique generation keys.
- **Credit Notes**: Create and manage credit notes against invoices.
- **Cart Linkage**: Track which carts have been invoiced.
- **UI Integration**: Hide cart edit button for invoiced orders, show invoice link.
- **CLI Support**: Console command with dry-run mode.
- **Queue Support**: Async job for background processing.

## Installation

1. Copy this module to `NGauge_modules/surf-invoicing`.
2. Register in backend config:

```php
'modules' => [
    'surf-invoicing' => [
        'class' => 'NGauge_modules\surfinvoicing\Module',
    ],
],
```

## Database Setup

Run migrations:

```bash
php yii migrate --migrationPath=@app/NGauge_modules/surf-invoicing/migrations
```

This creates:
- `invoices` table (invoice snapshots)
- `credit_notes` table (credit note tracking)
- Linkage columns on `basket` table

## Usage

### Console Command

Generate invoices for today:

```bash
php yii surf-invoicing/generate
```

Generate for specific date (dry-run):

```bash
php yii surf-invoicing/generate --date=2026-03-10 --dry-run=1
```

Options:
- `--date=YYYY-MM-DD`: Process date (default: today)
- `--dry-run=1`: Simulate without saving (default: 0)

### Async Job

Queue invoice generation for background processing:

```php
Yii::$app->queue->push(new \NGauge_modules\surfinvoicing\jobs\InvoiceGenerationJob([
    'date' => '2026-03-10',
]));
```

### Credit Notes

Create and issue a credit note:

```php
use NGauge_modules\surfinvoicing\models\CreditNote;

$creditNote = new CreditNote([
    'invoice_id' => $invoice->id,
    'amount' => 100.00,
    'reason' => 'Partial refund',
]);

if ($creditNote->validate()) {
    $creditNote->issue();
}
```

### Services

#### InvoiceEligibilityService

Check eligibility:

```php
use NGauge_modules\surfinvoicing\services\InvoiceEligibilityService;

$service = new InvoiceEligibilityService();
if ($service->isEligible($cart, '2026-03-10')) {
    // Cart is eligible for invoicing
}
```

#### InvoiceFactory

Map cart to invoice data:

```php
use NGauge_modules\surfinvoicing\services\InvoiceFactory;

$factory = new InvoiceFactory();
$invoiceData = $factory->createInvoiceDataFromCart($cart);
```

#### InvoiceGenerationService

Generate invoices programmatically:

```php
use NGauge_modules\surfinvoicing\services\InvoiceGenerationService;

$service = new InvoiceGenerationService();
$results = $service->generate('2026-03-10', false);

// $results = [
//     'created' => 10,
//     'skipped' => 5,
//     'failed' => 0,
//     'errors' => [],
//     'dry_run' => false,
//     'date' => '2026-03-10',
// ]
```

## Architecture

### Models

- **Invoicesbe**: Invoice snapshot model (uses composed cart rules)
- **CreditNote**: Credit note tracking model

### Services

- **InvoiceEligibilityService**: Determines cart invoiceability
- **InvoiceFactory**: Maps cart to immutable invoice snapshot
- **InvoiceGenerationService**: Orchestrates generation with transactions

### Traits

- **InvoiceRulesTrait**: Reusable rule composition
- **CreditNoteTrait**: Credit note relation helpers

## Configuration

Cart eligibility is determined by:
- **Status**: Completed, Confirmed, Paid
- **Billing Status**: Pending, PartiallyPaid, Unpaid
- **Center Arrival Date**: Must be today or in the past

Modify `InvoiceEligibilityService` to change eligibility criteria.

## UI Integration

When a cart is invoiced:
- Edit/Update button is hidden
- Invoice link is displayed
- Invoice number and date are shown

See templates for implementation details.

## Version History

### v1.0.0 (2026-03-11)

- Initial release
- Core services and models
- Console command with dry-run
- Credit note support
- Queue job support
