invoiceninja/app/Services/EDocument/Standards/Verifactu/Models/RegistroAnulacion.php

454 lines
16 KiB
PHP

<?php
namespace App\Services\EDocument\Standards\Verifactu\Models;
/**
* RegistroAnulacion - Invoice Cancellation Record
*
* This class represents the cancellation record information required for Verifactu e-invoicing
* modification operations. It contains the details of the invoice to be cancelled.
*/
class RegistroAnulacion extends BaseXmlModel
{
protected string $idVersion;
protected string $idEmisorFactura;
protected string $numSerieFactura;
protected string $fechaExpedicionFactura;
protected string $motivoAnulacion;
protected string $nombreRazonEmisor;
// Additional properties required by XSD schema
protected ?string $refExterna = null;
protected ?string $sinRegistroPrevio = null;
protected ?string $rechazoPrevio = null;
protected ?string $generadoPor = null;
protected ?PersonaFisicaJuridica $generador = null;
protected Encadenamiento $encadenamiento;
protected SistemaInformatico $sistemaInformatico;
protected string $fechaHoraHusoGenRegistro;
protected string $tipoHuella;
protected string $huella;
protected ?string $signature = null;
public function __construct()
{
$this->idVersion = '1.0';
$this->motivoAnulacion = '1'; // Default: Sustitución por otra factura
$this->encadenamiento = new Encadenamiento();
$this->sistemaInformatico = new SistemaInformatico();
$this->fechaHoraHusoGenRegistro = now()->format('Y-m-d\TH:i:sP');
$this->tipoHuella = '01';
$this->huella = '';
}
public function getIdVersion(): string
{
return $this->idVersion;
}
public function setIdVersion(string $idVersion): self
{
$this->idVersion = $idVersion;
return $this;
}
public function getIdEmisorFactura(): string
{
return $this->idEmisorFactura;
}
public function setIdEmisorFactura(string $idEmisorFactura): self
{
$this->idEmisorFactura = $idEmisorFactura;
return $this;
}
public function getNumSerieFactura(): string
{
return $this->numSerieFactura;
}
public function setNumSerieFactura(string $numSerieFactura): self
{
$this->numSerieFactura = $numSerieFactura;
return $this;
}
public function getFechaExpedicionFactura(): string
{
return $this->fechaExpedicionFactura;
}
public function setFechaExpedicionFactura(string $fechaExpedicionFactura): self
{
$this->fechaExpedicionFactura = $fechaExpedicionFactura;
return $this;
}
public function getMotivoAnulacion(): string
{
return $this->motivoAnulacion;
}
public function setMotivoAnulacion(string $motivoAnulacion): self
{
$this->motivoAnulacion = $motivoAnulacion;
return $this;
}
public function getRefExterna(): ?string
{
return $this->refExterna;
}
public function setRefExterna(?string $refExterna): self
{
$this->refExterna = $refExterna;
return $this;
}
public function getSinRegistroPrevio(): ?string
{
return $this->sinRegistroPrevio;
}
public function setSinRegistroPrevio(?string $sinRegistroPrevio): self
{
$this->sinRegistroPrevio = $sinRegistroPrevio;
return $this;
}
public function getRechazoPrevio(): ?string
{
return $this->rechazoPrevio;
}
public function setRechazoPrevio(?string $rechazoPrevio): self
{
$this->rechazoPrevio = $rechazoPrevio;
return $this;
}
public function getGeneradoPor(): ?string
{
return $this->generadoPor;
}
public function setGeneradoPor(?string $generadoPor): self
{
$this->generadoPor = $generadoPor;
return $this;
}
public function getGenerador(): ?PersonaFisicaJuridica
{
return $this->generador;
}
public function setGenerador(?PersonaFisicaJuridica $generador): self
{
$this->generador = $generador;
return $this;
}
public function getEncadenamiento(): Encadenamiento
{
return $this->encadenamiento;
}
public function setEncadenamiento(Encadenamiento $encadenamiento): self
{
$this->encadenamiento = $encadenamiento;
return $this;
}
public function getSistemaInformatico(): SistemaInformatico
{
return $this->sistemaInformatico;
}
public function setSistemaInformatico(SistemaInformatico $sistemaInformatico): self
{
$this->sistemaInformatico = $sistemaInformatico;
return $this;
}
public function getFechaHoraHusoGenRegistro(): string
{
return $this->fechaHoraHusoGenRegistro;
}
public function setFechaHoraHusoGenRegistro(string $fechaHoraHusoGenRegistro): self
{
$this->fechaHoraHusoGenRegistro = $fechaHoraHusoGenRegistro;
return $this;
}
public function getTipoHuella(): string
{
return $this->tipoHuella;
}
public function setTipoHuella(string $tipoHuella): self
{
$this->tipoHuella = $tipoHuella;
return $this;
}
public function getHuella(): string
{
return $this->huella;
}
public function setHuella(string $huella): self
{
$this->huella = $huella;
return $this;
}
public function getSignature(): ?string
{
return $this->signature;
}
public function setSignature(?string $signature): self
{
$this->signature = $signature;
return $this;
}
public function getNombreRazonEmisor(): string
{
return $this->nombreRazonEmisor;
}
public function setNombreRazonEmisor(string $nombreRazonEmisor): self
{
$this->nombreRazonEmisor = $nombreRazonEmisor;
return $this;
}
public function toXml(\DOMDocument $doc): \DOMElement
{
$root = $doc->createElementNS(self::XML_NAMESPACE, self::XML_NAMESPACE_PREFIX . ':RegistroAnulacion');
// Add IDVersion
$root->appendChild($this->createElement($doc, 'IDVersion', $this->idVersion));
// Create IDFactura structure
$idFactura = $this->createElement($doc, 'IDFactura');
$idFactura->appendChild($this->createElement($doc, 'IDEmisorFacturaAnulada', $this->idEmisorFactura));
$idFactura->appendChild($this->createElement($doc, 'NumSerieFacturaAnulada', $this->numSerieFactura));
$idFactura->appendChild($this->createElement($doc, 'FechaExpedicionFacturaAnulada', $this->fechaExpedicionFactura));
$root->appendChild($idFactura);
// Add optional RefExterna
if ($this->refExterna !== null) {
$root->appendChild($this->createElement($doc, 'RefExterna', $this->refExterna));
}
// Add optional SinRegistroPrevio
if ($this->sinRegistroPrevio !== null) {
$root->appendChild($this->createElement($doc, 'SinRegistroPrevio', $this->sinRegistroPrevio));
}
// Add optional RechazoPrevio
if ($this->rechazoPrevio !== null) {
$root->appendChild($this->createElement($doc, 'RechazoPrevio', $this->rechazoPrevio));
}
// Add optional GeneradoPor
if ($this->generadoPor !== null) {
$root->appendChild($this->createElement($doc, 'GeneradoPor', $this->generadoPor));
}
// Add optional Generador
if ($this->generador !== null) {
$root->appendChild($this->generador->toXml($doc));
}
// Add Encadenamiento using actual property
$encadenamientoElement = $this->encadenamiento->toXml($doc);
$root->appendChild($encadenamientoElement);
// Add SistemaInformatico using actual property
$sistemaInformaticoElement = $this->sistemaInformatico->toXml($doc);
$root->appendChild($sistemaInformaticoElement);
// Add FechaHoraHusoGenRegistro using actual property
$root->appendChild($this->createElement($doc, 'FechaHoraHusoGenRegistro', $this->fechaHoraHusoGenRegistro));
// Add TipoHuella using actual property
$root->appendChild($this->createElement($doc, 'TipoHuella', $this->tipoHuella));
// Add Huella using actual property
$root->appendChild($this->createElement($doc, 'Huella', $this->huella));
// Add optional Signature
if ($this->signature !== null) {
$root->appendChild($this->createDsElement($doc, 'Signature', $this->signature));
}
return $root;
}
public static function fromDOMElement(\DOMElement $element): self
{
$registroAnulacion = new self();
// Handle IDVersion
$idVersion = $element->getElementsByTagNameNS(self::XML_NAMESPACE, 'IDVersion')->item(0);
if ($idVersion) {
$registroAnulacion->setIdVersion($idVersion->nodeValue);
}
// Handle IDFactura
$idFactura = $element->getElementsByTagNameNS(self::XML_NAMESPACE, 'IDFactura')->item(0);
if ($idFactura) {
$idEmisorFactura = $idFactura->getElementsByTagNameNS(self::XML_NAMESPACE, 'IDEmisorFacturaAnulada')->item(0);
if ($idEmisorFactura) {
$registroAnulacion->setIdEmisorFactura($idEmisorFactura->nodeValue);
}
$numSerieFactura = $idFactura->getElementsByTagNameNS(self::XML_NAMESPACE, 'NumSerieFacturaAnulada')->item(0);
if ($numSerieFactura) {
$registroAnulacion->setNumSerieFactura($numSerieFactura->nodeValue);
}
$fechaExpedicionFactura = $idFactura->getElementsByTagNameNS(self::XML_NAMESPACE, 'FechaExpedicionFacturaAnulada')->item(0);
if ($fechaExpedicionFactura) {
$registroAnulacion->setFechaExpedicionFactura($fechaExpedicionFactura->nodeValue);
}
}
// Handle optional elements
$refExterna = $element->getElementsByTagNameNS(self::XML_NAMESPACE, 'RefExterna')->item(0);
if ($refExterna) {
$registroAnulacion->setRefExterna($refExterna->nodeValue);
}
$sinRegistroPrevio = $element->getElementsByTagNameNS(self::XML_NAMESPACE, 'SinRegistroPrevio')->item(0);
if ($sinRegistroPrevio) {
$registroAnulacion->setSinRegistroPrevio($sinRegistroPrevio->nodeValue);
}
$rechazoPrevio = $element->getElementsByTagNameNS(self::XML_NAMESPACE, 'RechazoPrevio')->item(0);
if ($rechazoPrevio) {
$registroAnulacion->setRechazoPrevio($rechazoPrevio->nodeValue);
}
$generadoPor = $element->getElementsByTagNameNS(self::XML_NAMESPACE, 'GeneradoPor')->item(0);
if ($generadoPor) {
$registroAnulacion->setGeneradoPor($generadoPor->nodeValue);
}
// Handle Generador
$generador = $element->getElementsByTagNameNS(self::XML_NAMESPACE, 'Generador')->item(0);
if ($generador) {
$registroAnulacion->setGenerador(PersonaFisicaJuridica::fromDOMElement($generador));
}
// Handle Encadenamiento
$encadenamiento = $element->getElementsByTagNameNS(self::XML_NAMESPACE, 'Encadenamiento')->item(0);
if ($encadenamiento) {
$registroAnulacion->setEncadenamiento(Encadenamiento::fromDOMElement($encadenamiento));
}
// Handle SistemaInformatico
$sistemaInformatico = $element->getElementsByTagNameNS(self::XML_NAMESPACE, 'SistemaInformatico')->item(0);
if ($sistemaInformatico) {
$registroAnulacion->setSistemaInformatico(SistemaInformatico::fromDOMElement($sistemaInformatico));
}
// Handle FechaHoraHusoGenRegistro
$fechaHoraHusoGenRegistro = $element->getElementsByTagNameNS(self::XML_NAMESPACE, 'FechaHoraHusoGenRegistro')->item(0);
if ($fechaHoraHusoGenRegistro) {
$registroAnulacion->setFechaHoraHusoGenRegistro($fechaHoraHusoGenRegistro->nodeValue);
}
// Handle TipoHuella
$tipoHuella = $element->getElementsByTagNameNS(self::XML_NAMESPACE, 'TipoHuella')->item(0);
if ($tipoHuella) {
$registroAnulacion->setTipoHuella($tipoHuella->nodeValue);
}
// Handle Huella
$huella = $element->getElementsByTagNameNS(self::XML_NAMESPACE, 'Huella')->item(0);
if ($huella) {
$registroAnulacion->setHuella($huella->nodeValue);
}
// Handle MotivoAnulacion
$motivoAnulacion = $element->getElementsByTagNameNS(self::XML_NAMESPACE, 'MotivoAnulacion')->item(0);
if ($motivoAnulacion) {
$registroAnulacion->setMotivoAnulacion($motivoAnulacion->nodeValue);
}
return $registroAnulacion;
}
public function toXmlString(): string
{
$doc = new \DOMDocument('1.0', 'UTF-8');
$doc->preserveWhiteSpace = false;
$doc->formatOutput = true;
$root = $this->toXml($doc);
$doc->appendChild($root);
return $doc->saveXML();
}
public function toSoapEnvelope(): string
{
// Create the SOAP document
$soapDoc = new \DOMDocument('1.0', 'UTF-8');
$soapDoc->preserveWhiteSpace = false;
$soapDoc->formatOutput = true;
// Create SOAP envelope with namespaces
$envelope = $soapDoc->createElementNS('http://schemas.xmlsoap.org/soap/envelope/', 'soapenv:Envelope');
$envelope->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:soapenv', 'http://schemas.xmlsoap.org/soap/envelope/');
$envelope->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:sum', 'https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/tike/cont/ws/SuministroLR.xsd');
$envelope->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:sum1', 'https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/tike/cont/ws/SuministroInformacion.xsd');
$soapDoc->appendChild($envelope);
// Create Header
$header = $soapDoc->createElementNS('http://schemas.xmlsoap.org/soap/envelope/', 'soapenv:Header');
$envelope->appendChild($header);
// Create Body
$body = $soapDoc->createElementNS('http://schemas.xmlsoap.org/soap/envelope/', 'soapenv:Body');
$envelope->appendChild($body);
// Create RegFactuSistemaFacturacion
$regFactu = $soapDoc->createElementNS('https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/tike/cont/ws/SuministroLR.xsd', 'sum:RegFactuSistemaFacturacion');
$body->appendChild($regFactu);
// Create Cabecera
$cabecera = $soapDoc->createElementNS('https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/tike/cont/ws/SuministroLR.xsd', 'sum:Cabecera');
$regFactu->appendChild($cabecera);
// Create ObligadoEmision
$obligadoEmision = $soapDoc->createElementNS('https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/tike/cont/ws/SuministroInformacion.xsd', 'sum1:ObligadoEmision');
$cabecera->appendChild($obligadoEmision);
// Add ObligadoEmision content (using default values for now)
$obligadoEmision->appendChild($soapDoc->createElementNS('https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/tike/cont/ws/SuministroInformacion.xsd', 'sum1:NombreRazon', $this->getNombreRazonEmisor()));
$obligadoEmision->appendChild($soapDoc->createElementNS('https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/tike/cont/ws/SuministroInformacion.xsd', 'sum1:NIF', $this->getIdEmisorFactura()));
// Create RegistroFactura
$registroFactura = $soapDoc->createElementNS('https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/tike/cont/ws/SuministroLR.xsd', 'sum:RegistroFactura');
$regFactu->appendChild($registroFactura);
// Import your existing XML into the RegistroFactura
$yourXmlDoc = new \DOMDocument();
$yourXmlDoc->loadXML($this->toXmlString());
// Import the root element from your XML
$importedNode = $soapDoc->importNode($yourXmlDoc->documentElement, true);
$registroFactura->appendChild($importedNode);
return $soapDoc->saveXML();
}
}