diff --git a/README.md b/README.md index b98a4b9..574dd6e 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,45 @@ if ($aeatResponse->status === ResponseStatus::Correct) { } ``` +## Remisión Voluntaria (Voluntary Discontinuation) + +La librería también soporta la funcionalidad de **Remisión Voluntaria** que permite notificar a la AEAT cuando una empresa decide dejar de usar VERI*FACTU. + +### Ejemplo de uso de Remisión Voluntaria + +```php +setCertificate(__DIR__ . '/certificado.pfx', 'contraseña'); +$client->setProduction(false); + +// Crea una remisión voluntaria +$client->setVoluntaryDiscontinuation( + new VoluntaryDiscontinuation( + new DateTimeImmutable('2025-12-31') // Debe ser a finales del año contable + ) +); + +// Envía la remisión (no se requieren registros de facturación) +$res = $client->send([])->wait(); +echo $res->asXML() . "\n"; +``` + +### Parámetros de Remisión Voluntaria + +- **`endDate`**: Fecha en la que la empresa dejará de usar VERI*FACTU. **Debe ser a finales del año contable actual** según indica la AEAT. +- **`incident`**: Indica si la razón de la remisión es una incidencia (`true`) o es voluntaria (`false`). + +### Notas importantes + +- La remisión voluntaria debe enviarse **antes** de la fecha de fin especificada +- Una vez llega la fecha de remisión, el SIF no debería de volver a enviar facturas a VERI*FACTU a no ser que el cliente vuelva a activarlo de forma voluntaria. +- La fecha de fin debe ser a finales del año contable actual (31 de diciembre) + ## Exención de responsabilidad Esta librería se proporciona sin una declaración responsable al no ser un Sistema Informático de Facturación (SIF). Verifactu-PHP es una herramienta para crear SIFs, es tu responsabilidad auditar su código y usarlo de acuerdo a la normativa vigente. diff --git a/src/Models/Records/VoluntaryDiscontinuation.php b/src/Models/Records/VoluntaryDiscontinuation.php new file mode 100644 index 0000000..6067517 --- /dev/null +++ b/src/Models/Records/VoluntaryDiscontinuation.php @@ -0,0 +1,47 @@ +endDate = $endDate; + } + if ($incident !== null) { + $this->incident = $incident; + } + } + + /** + * Fecha fin de VERI*FACTU. Debe ser a finales del año contable actual. + * + * @field Caberecera/RemisionVoluntaria/FechaFinVeriFactu + */ + public ?DateTimeImmutable $endDate = null; + + /** + * Incidencia + * + * @field Caberecera/RemisionVoluntaria/Incidencia + */ + #[Assert\Type('boolean')] + public bool $incident = false; +} diff --git a/src/Services/AeatClient.php b/src/Services/AeatClient.php index b669e64..c8ad9f3 100644 --- a/src/Services/AeatClient.php +++ b/src/Services/AeatClient.php @@ -10,6 +10,7 @@ use josemmo\Verifactu\Models\Records\FiscalIdentifier; use josemmo\Verifactu\Models\Records\Record; use josemmo\Verifactu\Models\Records\RegistrationRecord; +use josemmo\Verifactu\Models\Records\VoluntaryDiscontinuation; use josemmo\Verifactu\Models\Responses\AeatResponse; use Psr\Http\Client\ClientExceptionInterface; use Psr\Http\Message\ResponseInterface; @@ -31,6 +32,7 @@ class AeatClient { private ?string $certificatePath = null; private ?string $certificatePassword = null; private ?FiscalIdentifier $representative = null; + private ?VoluntaryDiscontinuation $voluntaryDiscontinuation = null; private bool $isProduction = true; private bool $isEntitySeal = false; @@ -44,7 +46,7 @@ class AeatClient { public function __construct( ComputerSystem $system, FiscalIdentifier $taxpayer, - ?Client $httpClient = null, + ?Client $httpClient = null ) { $this->system = $system; $this->taxpayer = $taxpayer; @@ -96,6 +98,18 @@ public function setProduction(bool $production): static { return $this; } + /** + * Set voluntary discontinuation + * + * @param VoluntaryDiscontinuation|null $voluntaryDiscontinuation Sends the date of which the company will stop using VERI*FACTU. + * + * @return $this This instance + */ + public function setVoluntaryDiscontinuation(?VoluntaryDiscontinuation $voluntaryDiscontinuation): static { + $this->voluntaryDiscontinuation = $voluntaryDiscontinuation; + return $this; + } + /** * Set entity seal * @@ -138,6 +152,11 @@ public function send(array $records): PromiseInterface { /** @phpstan-ignore gen $representanteElement->add('sum1:NombreRazon', $this->representative->name); $representanteElement->add('sum1:NIF', $this->representative->nif); } + if ($this->voluntaryDiscontinuation !== null && $this->voluntaryDiscontinuation->endDate !== null) { + $remisionVoluntariaElement = $cabeceraElement->add('sum1:RemisionVoluntaria'); + $remisionVoluntariaElement->add('sum1:FechaFinVeriFactu', $this->voluntaryDiscontinuation->endDate->format('d-m-Y')); + $remisionVoluntariaElement->add('sum1:Incidencia', $this->voluntaryDiscontinuation->incident ? 'S' : 'N'); + } // Add registration records foreach ($records as $record) {