# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

This is a **Laravel package** (`daniv04/hacienda-package`) that integrates with Costa Rica's Ministerio de Hacienda electronic invoicing system. It supports multiple providers (Cyberfuel, Hacienda) and handles these document types:

- **FE** - Factura Electrónica (Electronic Invoice)
- **FEE** - Factura Electrónica de Exportación (Electronic Export Invoice)
- **FEC** - Factura Electrónica de Compra (Electronic Purchase Invoice)
- **TE** - Tiquete Electrónico (Electronic Ticket)
- **NC** - Nota de Crédito (Credit Note)
- **ND** - Nota de Débito (Debit Note)
- **REP** - Recibo Electrónico de Pago (Electronic Payment Receipt)

Reception messages: **CA** (Acceptance), **CAP** (Partial Acceptance), **CR** (Rejection)

## Commands

```bash
# Install dependencies
composer install

# Run tests (uses Orchestra Testbench)
./vendor/bin/phpunit

# Run a single test file
./vendor/bin/phpunit tests/Path/To/TestFile.php

# Run a specific test method
./vendor/bin/phpunit --filter testMethodName
```

## Architecture

### Data Flow

1. **HTTP Request** → Controller validates via Form Request class
2. **InvoicingService::createAndSend()** → delegates to type-specific ValidatorService
3. **DbService::saveReceipt()** → persists `Receipt` + `ReceiptPayload` in a transaction
4. **Queue Dispatch** → `SendReceiptToProviderJob` dispatched asynchronously
5. **Provider** → `ProviderFactoryService` resolves Cyberfuel or Hacienda provider, calls `sendDocument()`
6. **Webhook** → `HaciendaWebhookController` processes Hacienda status callbacks → updates `HaciendaResponse`

Reception messages follow the same flow but use `SendSentReceiptToProviderJob` and `SentReceipt` model.

### Key Services

| Service | Responsibility |
|---|---|
| `InvoicingService` | Central orchestrator — validates, saves, dispatches all document types |
| `DbService` | All Eloquent database operations (CRUD for receipts, consecutive numbers) |
| `ProviderFactoryService` | Factory that resolves the configured provider (`cyberfuel` or `hacienda`) |
| `CertificateLoaderService` | Reads `.p12` digital certificate once per request (singleton) |
| `XmlSignerService` | Signs XML using the loaded certificate |
| `HaciendaIdpService` | Authenticates with Hacienda Identity Provider for access tokens |
| `WebhookService` / `WebhookVerifierService` | Handles and verifies incoming Hacienda webhook callbacks |
| `PdfGeneratorService` | Generates PDF documents from receipts |

All services are registered as singletons in `HaciendaPackageServiceProvider`. Access via:
- `app('facturacion')` → `InvoicingService`
- `app('facturacion.db')` → `DbService`
- `app('facturacion.provider')` → `ProviderFactoryService`
- `app('facturacion.signer')` → `XmlSignerService`
- `app('facturacion.idp')` → `HaciendaIdpService`
- Helper functions: `invoicing()`, `invoicing_create(string $type, array $data)`, etc.

### Validators

Every document type has a dedicated validator in `src/Services/Validators/`, all extending `BaseReceiptValidatorService`. Shared validators:
- `DetailLinesValidator` — line items
- `TaxesValidator` — tax calculations
- `InvoiceSummaryValidator` — totals
- `AssortmentDetailsValidator` — assortment fields
- `ReceptionDocumentValidatorService` — CA/CAP/CR messages

### Providers

Providers implement `ProviderInterface` (`sendDocument()`, `getDocumentStatus()`). Each provider has its own `Transformer` class that converts the internal payload format to the provider's API format. Configured via `config/invoicing.php` → `electronic_invoicing_provider`.

### Database Tables

All package tables are prefixed with `mythicbyte_`:
- `mythicbyte_receipts` — main document store (FE, FEE, FEC, TE, ND, NC, REP)
- `mythicbyte_receipts_payloads` — full JSON payload for each document
- `mythicbyte_sent_receipts` — reception messages (CA, CAP, CR)
- `hacienda_responses` — Hacienda API responses per document
- `receipt_consecutives` — consecutive number tracking per document type

### Traits

- `ConsecutiveNumberTrait` — increments and locks consecutive numbers (used in `DbService`)
- `UniqueKeyTrait` — generates the Hacienda `Clave` (unique document key)
- `GenerateSecurityCode` — generates security codes from consecutive number + date
- `ResponseTrait` — standardizes API response format
- `DateParserTrait` — parses dates to array format required by Hacienda
- `XmlBase64DecoderTrait` — decodes Base64-encoded XML in webhook payloads

### Configuration

Published configs:
- `config/invoicing.php` — provider selection (`cyberfuel`|`hacienda`) and callback URL
- `config/catalogues.php` — Hacienda code catalogues (units of measure, currencies, tax types)
- `src/Providers/Cyberfuel/Config/cyberfuel.php` — Cyberfuel API credentials/URLs
- `src/Providers/Hacienda/Config/hacienda.php` — certificate path/password, Hacienda IDP credentials

### Routes

All routes are under `api/v1/e-invoicing/` and loaded automatically by the service provider. Document creation is `POST`, retrieval is `GET`. Test endpoints (`/test/*`) exist for signing XML and sending directly to Hacienda.

## Adding a New Document Type

1. Create a `Request` class extending `BaseReceiptRequest` in `src/Http/Requests/`
2. Create a `ValidatorService` extending `BaseReceiptValidatorService` in `src/Services/Validators/`
3. Register the type constant and validator mapping in `InvoicingService`
4. Add a `Controller` extending `BaseController` in `src/Http/Controllers/`
5. Register routes in `routes/api.php`
6. Add transformer logic in each provider's `Transformer` class

## Adding a New Provider

1. Implement `ProviderInterface` in `src/Providers/YourProvider/`
2. Create a `Transformer` class for payload conversion
3. Add a config file in `src/Providers/YourProvider/Config/`
4. Register the provider in `ProviderFactoryService`
5. Merge the config in `HaciendaPackageServiceProvider`
