Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
06404b7
feat(verifactu): implementar firma XAdES-EPES y habilitar envío AEAT
orbilai-dgenova Nov 20, 2025
1287c93
refactor(verifactu): usar variable VERIFACTU_PRODUCTION del .env
orbilai-dgenova Nov 20, 2025
abbf9f2
feat: configurar uso de WSDL local via variable de entorno - Añadir V…
orbilai-dgenova Nov 20, 2025
f61341d
debug: añadir logging detallado en AeatClient para diagnosticar error…
orbilai-dgenova Nov 20, 2025
0b52461
feat: Integración completa AEAT VeriFactu - Validación exitosa
orbilai-dgenova Nov 20, 2025
7f33fec
feat: añadir validación de respuesta AEAT en AeatClient
orbilai-dgenova Nov 20, 2025
0e1074f
feat: agregar campo CSV a la tabla invoices y actualizar política de …
orbilai-dgenova Nov 21, 2025
9cfe3e9
feat: Add CSV retention and clean External package code
orbilai-dgenova Nov 21, 2025
49ca5b4
refactor: Update AeatClient to use Laravel HTTP Client and improve er…
orbilai-dgenova Nov 21, 2025
615c3d6
refactor: Remove local WSDL configuration and related comments
orbilai-dgenova Nov 21, 2025
9852855
feat(verifactu): Suite completa de tests unitarios y validación AEAT
orbilai-dgenova Nov 21, 2025
aec338a
feat(verifactu): Package production-ready con autonomía total y tests…
orbilai-dgenova Nov 21, 2025
7df430a
feat(verifactu): Cobertura completa de tests según normativa AEAT
orbilai-dgenova Nov 21, 2025
39e6b5e
feat(verifactu): Cobertura completa de tests - 85-90% normativa AEAT
orbilai-dgenova Nov 21, 2025
f5af4fe
feat(verifactu): Implement VERIFACTU online mode and add installation…
orbilai-dgenova Nov 21, 2025
5a27348
refactor(verifactu): Remove legacy configuration and update invoice p…
orbilai-dgenova Nov 22, 2025
1ec1b7f
refactor(verifactu): Transition to Base64 certificate management and …
orbilai-dgenova Nov 22, 2025
3c2593a
feat(verifactu): Add AEAT status fields to invoices and enhance valid…
orbilai-dgenova Nov 22, 2025
7eac796
refactor(tests): Simplify AeatClient instantiation by removing passwo…
orbilai-dgenova Nov 23, 2025
e9165e5
ci: configure GitLab CI/CD pipeline with complete security setup
orbilai-dgenova Nov 23, 2025
0c50ed0
refactor(ci): update GitLab CI/CD configuration for package-first arc…
orbilai-dgenova Nov 23, 2025
fc55614
refactor(ci): update PHPUnit bootstrap path in GitLab CI/CD configura…
orbilai-dgenova Nov 23, 2025
1064323
feat(verifactu): soporte para certificado con contraseña separada
orbilai-dgenova Nov 27, 2025
2d70b75
refactor(verifactu): mejorar configuración de colas y manejo de certi…
orbilai-dgenova Nov 27, 2025
23351be
fix(verifactu): corregir tests y actualizar CI pipeline
orbilai-dgenova Nov 27, 2025
82c4de8
feat: Migrar certificado AEAT de Base64 (.env) a S3 (Laravel Cloud)
orbilai-dgenova Nov 28, 2025
6c2cffb
fix(verifactu): adjust HTTP client settings in AeatClient for improve…
orbilai-dgenova Nov 29, 2025
79def94
fix(verifactu): corregir errores AEAT en operaciones exentas, no suje…
orbilai-dgenova Nov 30, 2025
5f85331
fix(verifactu): corregir orden elementos XML según XSD AEAT (error 4102)
orbilai-dgenova Nov 30, 2025
2601b0b
feat(verifactu): implementar recargo equivalencia según XSD AEAT
orbilai-dgenova Nov 30, 2025
90ebda4
fix(verifactu): corregir unicidad de facturas para multi-tenant
orbilai-dgenova Nov 30, 2025
28c6cc3
perf(verifactu): añadir índices optimizados para multi-tenant
orbilai-dgenova Nov 30, 2025
b0cd375
feat(verifactu): make tax_rate and tax_amount fields nullable in brea…
orbilai-dgenova Nov 30, 2025
08a9bb4
fix(verifactu): mejorar documentación y lógica de DetalleDesglose en …
orbilai-dgenova Nov 30, 2025
79980ad
feat(verifactu): add id_type field to recipients for foreign identifi…
orbilai-dgenova Nov 30, 2025
c7489bd
fix(verifactu): ajustar validación y formato de fechas en facturas re…
orbilai-dgenova Nov 30, 2025
4e62318
feat(verifactu): add 50 automated tests for API and XSD order validation
orbilai-dgenova Nov 30, 2025
641c4eb
fix(verifactu): correct invalid enum values S3 in tests
orbilai-dgenova Nov 30, 2025
a66ef3a
docs(verifactu): actualizar CHANGELOG y tests/README para v2.0.0
orbilai-dgenova Dec 1, 2025
30f36fc
chore(verifactu): preparar paquete para contribucion open source
orbilai-dgenova Dec 1, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,13 @@
*.mdc
/vendor
composer.lock
.phpunit.result.cache
.phpunit.cache
.env
.env.testing
phpunit.xml.bak
coverage/
.idea/
.vscode/
.DS_Store
Thumbs.db
100 changes: 100 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# Changelog

Todos los cambios notables de este proyecto serán documentados en este archivo.

El formato está basado en [Keep a Changelog](https://keepachangelog.com/es-ES/1.0.0/),
y este proyecto adhiere a [Semantic Versioning](https://semver.org/lang/es/).

## [2.0.0] - 2025-12-01

### Añadido

#### Cliente AEAT
- ✅ Cliente AEAT con comunicación SOAP/XML completa
- ✅ Validación de respuestas AEAT (EstadoEnvio + EstadoRegistro + CSV)
- ✅ Manejo de errores de conexión, timeouts y SOAP Faults
- ✅ Soporte para modo producción y pruebas (sandbox)
- ✅ Extracción automática del código CSV de verificación

#### Tipos de Impuestos
- ✅ IVA península (21%, 10%, 4%, 0%)
- ✅ IGIC Canarias (7%, 3%, 0%)
- ✅ IPSI Ceuta y Melilla (10%, 4%, 1%, 0%)

#### Regímenes Especiales
- ✅ Régimen OSS (One Stop Shop) para ventas intracomunitarias B2C
- ✅ Recargo de equivalencia (5.2%, 1.4%, 0.5%)
- ✅ Criterio de caja
- ✅ Régimen especial agrícola REAGYP

#### Tipos de Operación
- ✅ Operaciones sujetas (S1, S2)
- ✅ Operaciones no sujetas (N1, N2)
- ✅ Operaciones exentas (E1-E6): educación, sanidad, exportaciones, etc.
- ✅ Inversión del sujeto pasivo: construcción, oro, chatarra, electrónica

#### Tipos de Factura
- ✅ Facturas estándar (F1)
- ✅ Facturas simplificadas (F2) sin destinatario obligatorio
- ✅ Facturas de sustitución (F3)
- ✅ Facturas rectificativas (R1-R5) por diferencia y sustitución
- ✅ Soporte para múltiples facturas rectificadas

#### Funcionalidades Avanzadas
- ✅ Encadenamiento blockchain de facturas (`previous_invoice_*`, `is_first_invoice`)
- ✅ Subsanación de facturas rechazadas (`is_subsanacion`, `rejected_invoice_number`)
- ✅ Campo `csv` para almacenar código de verificación AEAT
- ✅ Campo `operation_date` para fecha de operación distinta a expedición
- ✅ Campos de estado AEAT (`aeat_estado_registro`, `aeat_codigo_error`, `aeat_descripcion_error`)
- ✅ Soporte para destinatarios extranjeros con `IDOtro` (NIF-IVA, pasaporte, etc.)

#### Configuración
- ✅ Configuración `sistema_informatico` completa en `config/verifactu.php`
- ✅ Soporte para Representante (modelo SaaS)
- ✅ Campo `numero_instalacion` por cliente/instalación

#### Tests
- ✅ 99 tests unitarios con SQLite in-memory
- ✅ 291 assertions
- ✅ Tests de escenarios: estándar, simplificadas, IGIC, IPSI, rectificativas, encadenadas, OSS, subsanación
- ✅ Tests de operaciones: exportaciones, exentas, inversión sujeto pasivo, recargo equivalencia
- ✅ Tests de validación de respuestas AEAT
- ✅ Tests de validación XML contra XSD oficiales
- ✅ Tests de orden de elementos XML (cumplimiento XSD estricto)

#### Documentación
- ✅ Esquemas XSD oficiales AEAT incluidos en `docs/aeat-schemas/`
- ✅ Documentación completa de tests en `tests/README.md`
- ✅ README actualizado con ejemplos de todos los tipos de facturas
- ✅ Fixtures para datos de prueba

### Cambiado
- 🔄 `AeatClient` refactorizado para usar Laravel HTTP Client
- 🔄 Validación de respuestas AEAT mejorada con detección de todos los estados posibles
- 🔄 Dependencia `XadesSignatureInterface` ahora opcional (modo VERIFACTU online no requiere firma XAdES)
- 🔄 Migraciones actualizadas para soportar campos avanzados y multitenancy
- 🔄 Orden de elementos XML corregido según XSD AEAT (crítico para aceptación)

### Corregido
- 🐛 Validación correcta de respuestas AEAT (HTTP 200 no garantiza aceptación)
- 🐛 Generación de hash compatible con encadenamiento
- 🐛 Manejo de errores de conexión y timeouts
- 🐛 Orden de elementos en `DetalleDesglose` según XSD (evita error 4102)
- 🐛 Exclusión mutua de `CalificacionOperacion` y `OperacionExenta`

## [1.0.0] - 2024-01-01

### Añadido
- Versión inicial del package
- Modelos Eloquent: Invoice, Breakdown, Recipient
- Enums: InvoiceType, TaxType, RegimeType, OperationType, ForeignIdType
- Helpers: HashHelper, DateTimeHelper, StringHelper
- Form Requests y API Resources
- Factories para testing
- Tests básicos

---

[2.0.0]: https://github.com/squareetlabs/LaravelVerifactu/compare/v1.0.0...v2.0.0
[1.0.0]: https://github.com/squareetlabs/LaravelVerifactu/releases/tag/v1.0.0

210 changes: 195 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,44 @@

## Características principales

- Modelos Eloquent para invoices, breakdowns y recipients
- Enum types para campos fiscales (invoice type, tax type, regime, etc.)
- Helpers para operaciones de fecha, string y hash
- Servicio AEAT client (configurable e inyectable)
- Form Requests para validación
- API Resources para respuestas RESTful
- Factories y tests unitarios para todos los componentes core
- Listo para extensión y uso en producción
- ✅ Modelos Eloquent para invoices, breakdowns y recipients
- ✅ Enum types para campos fiscales (invoice type, tax type, regime, etc.)
- ✅ Helpers para operaciones de fecha, string y hash
- ✅ Cliente AEAT con comunicación XML y validación de respuestas
- ✅ Soporte completo para tipos de impuestos (IVA, IGIC, IPSI)
- ✅ Régimen OSS (One Stop Shop) para ventas UE
- ✅ Encadenamiento blockchain de facturas
- ✅ Facturas rectificativas con múltiples tipos
- ✅ Subsanación de facturas rechazadas
- ✅ Form Requests para validación
- ✅ API Resources para respuestas RESTful
- ✅ 54 tests unitarios con 100% cobertura de escenarios
- ✅ SQLite in-memory para tests rápidos
- ✅ Factories para testing
- ✅ Validación contra XSD oficiales AEAT
- ✅ **Modo VERIFACTU online (sin firma XAdES requerida)**
- ✅ Listo para producción

---

## ⚠️ Nota sobre Firma Electrónica XAdES-EPES

**Este paquete NO incluye firma electrónica XAdES-EPES** porque está diseñado para el **modo VERIFACTU online**.

Según la documentación oficial de AEAT (`EspecTecGenerFirmaElectRfact.txt`, página 4/15):

> "La firma electrónica de los registros de facturación sólo será exigible para los sistemas no VERI*FACTU, al no estar incluidos en las excepciones de los sistemas de remisión de facturas verificables recogidas en el artículo 3 del Real Decreto 1007/2023."

**En modo VERIFACTU:**
- ✅ La autenticación se realiza mediante certificado AEAT en HTTPS
- ✅ El envío es inmediato a AEAT (online)
- ❌ **NO se requiere firma XAdES-EPES** en el XML

**En modo NO VERIFACTU (offline):**
- ⚠️ **SÍ se requiere firma XAdES-EPES** obligatoriamente
- ⚠️ Este paquete NO soporta este modo

Para más detalles, consulta `docs/DECISION_FIRMA_XADES.md`.

---

Expand All @@ -43,20 +73,60 @@ php artisan migrate

## Configuración

Edita tu archivo `.env` o `config/verifactu.php` según tus necesidades:
Edita tu archivo `.env` con los siguientes valores:

```bash
# Configuración del emisor (tu empresa)
VERIFACTU_ISSUER_NAME="Tu Empresa S.L."
VERIFACTU_ISSUER_VAT="B12345678"

# Certificado digital AEAT
VERIFACTU_CERT_PATH="/path/to/certificate.pfx"
VERIFACTU_CERT_PASSWORD="tu-password"
VERIFACTU_PRODUCTION=false

# Sistema Informático (datos requeridos por AEAT)
VERIFACTU_SISTEMA_NOMBRE="LaravelVerifactu"
VERIFACTU_SISTEMA_ID="01"
VERIFACTU_SISTEMA_VERSION="1.0"
VERIFACTU_NUMERO_INSTALACION="001"
VERIFACTU_SOLO_VERIFACTU=true
VERIFACTU_MULTI_OT=false
VERIFACTU_INDICADOR_MULTIPLES_OT=false
```

O edita directamente `config/verifactu.php` después de publicarlo:

```php
return [
'enabled' => true,
'default_currency' => 'EUR',

'issuer' => [
'name' => env('VERIFACTU_ISSUER_NAME', ''),
'vat' => env('VERIFACTU_ISSUER_VAT', ''),
],
// ...

'aeat' => [
'cert_path' => env('VERIFACTU_CERT_PATH', storage_path('certificates/aeat.pfx')),
'cert_password' => env('VERIFACTU_CERT_PASSWORD'),
'production' => env('VERIFACTU_PRODUCTION', false),
],

'sistema_informatico' => [
'nombre' => env('VERIFACTU_SISTEMA_NOMBRE', 'LaravelVerifactu'),
'id' => env('VERIFACTU_SISTEMA_ID', '01'),
'version' => env('VERIFACTU_SISTEMA_VERSION', '1.0'),
'numero_instalacion' => env('VERIFACTU_NUMERO_INSTALACION', '001'),
'solo_verifactu' => env('VERIFACTU_SOLO_VERIFACTU', true),
'multi_ot' => env('VERIFACTU_MULTI_OT', false),
'indicador_multiples_ot' => env('VERIFACTU_INDICADOR_MULTIPLES_OT', false),
],
];
```

> **Nota:** El `numero_instalacion` debe ser único para cada cliente/instalación.

---

## Uso rápido
Expand Down Expand Up @@ -138,6 +208,8 @@ $invoice = Invoice::create([

### Factura rectificativa (R1)
```php
use Squareetlabs\VeriFactu\Enums\RectificativeType;

$invoice = Invoice::create([
'number' => 'INV-RECT-001',
'date' => '2024-07-01',
Expand All @@ -149,11 +221,102 @@ $invoice = Invoice::create([
'tax' => 25.20,
'total' => 145.20,
'type' => InvoiceType::RECTIFICATIVE_R1,
// Puedes añadir aquí la relación con facturas rectificadas y el motivo si implementas la lógica
'rectificative_type' => RectificativeType::S, // Por sustitución
'rectified_invoices' => json_encode(['INV-001', 'INV-002']), // Facturas rectificadas
'rectification_amount' => -50.00, // Importe de rectificación (negativo para abonos)
]);
```

> **Nota:** Para facturas rectificativas y sustitutivas, si implementas los campos y relaciones adicionales (como facturas rectificadas/sustituidas, tipo de rectificación, importe de rectificación), deberás añadirlos en el array de creación.
### Factura IGIC (Canarias)
```php
use Squareetlabs\VeriFactu\Enums\TaxType;
use Squareetlabs\VeriFactu\Enums\RegimeType;

$invoice = Invoice::create([
'number' => 'INV-IGIC-001',
'date' => '2024-07-01',
'customer_name' => 'Cliente Canarias',
'customer_tax_id' => 'C55667788',
'issuer_name' => 'Issuer S.A.',
'issuer_tax_id' => 'B87654321',
'amount' => 100.00,
'tax' => 7.00, // 7% IGIC
'total' => 107.00,
'type' => InvoiceType::STANDARD,
]);

// Breakdown con IGIC
$invoice->breakdowns()->create([
'tax_rate' => 7.0,
'base_amount' => 100.00,
'tax_amount' => 7.00,
'tax_type' => TaxType::IGIC->value, // '03' para IGIC
'regime_type' => RegimeType::GENERAL->value,
'operation_type' => 'S1',
]);
```

### Encadenamiento de facturas (Blockchain)
```php
// Primera factura de la cadena
$firstInvoice = Invoice::create([
'number' => 'INV-001',
'date' => '2024-07-01',
'is_first_invoice' => true, // Marca como primera
// ... otros campos
]);

// Siguientes facturas enlazadas
$secondInvoice = Invoice::create([
'number' => 'INV-002',
'date' => '2024-07-02',
'is_first_invoice' => false,
'previous_invoice_number' => 'INV-001',
'previous_invoice_date' => '2024-07-01',
'previous_invoice_hash' => $firstInvoice->hash, // Hash de la factura anterior
// ... otros campos
]);
```

### Subsanación (re-envío de facturas rechazadas)
```php
$invoice = Invoice::create([
'number' => 'INV-SUB-001',
'date' => '2024-07-01',
'is_subsanacion' => true, // Marca como subsanación
'rejected_invoice_number' => 'INV-REJECTED-001', // Factura rechazada original
'rejection_date' => '2024-06-30', // Fecha del rechazo
// ... otros campos
]);
```

### Régimen OSS (One Stop Shop - UE)
```php
use Squareetlabs\VeriFactu\Enums\RegimeType;

$invoice = Invoice::create([
'number' => 'INV-OSS-001',
'date' => '2024-07-01',
'customer_name' => 'EU Customer',
'customer_tax_id' => 'FR12345678901', // NIF UE
'issuer_name' => 'Issuer S.A.',
'issuer_tax_id' => 'B87654321',
'amount' => 100.00,
'tax' => 21.00,
'total' => 121.00,
'type' => InvoiceType::STANDARD,
]);

// Breakdown con régimen OSS
$invoice->breakdowns()->create([
'tax_rate' => 21.0,
'base_amount' => 100.00,
'tax_amount' => 21.00,
'tax_type' => TaxType::IVA->value,
'regime_type' => RegimeType::OSS->value, // '17' para OSS
'operation_type' => 'S1',
]);
```

---

Expand Down Expand Up @@ -427,14 +590,31 @@ Puedes usar paquetes como [owen-it/laravel-auditing](https://github.com/owen-it/

## Testing

Ejecuta todos los tests unitarios:
Este package incluye una suite completa de 54 tests unitarios que cubren:

- ✅ Escenarios de facturas (estándar, IGIC, rectificativas, encadenadas, OSS, subsanación)
- ✅ Validación de respuestas AEAT (EstadoEnvio, EstadoRegistro, CSV)
- ✅ Validación de XML contra esquemas XSD oficiales
- ✅ Helpers (hash, fecha, string)
- ✅ Modelos Eloquent

### Ejecutar tests

```bash
php artisan test
# o
# Todos los tests
vendor/bin/phpunit

# Tests específicos
vendor/bin/phpunit --filter Scenarios
vendor/bin/phpunit --filter AeatResponse
vendor/bin/phpunit --filter XmlValidation

# Con cobertura de código
vendor/bin/phpunit --coverage-html coverage/
```

Los tests utilizan SQLite en memoria, por lo que no necesitas configurar ninguna base de datos.

---

## Contribuir
Expand Down
Loading