Class: VerifactuRails::Envio

Inherits:
Object
  • Object
show all
Defined in:
lib/verifactu_rails/envio.rb

Overview

Documento RegFactuSistemaFacturacion: la cabecera con el obligado tributario más un lote de registros de facturación.

El encadenamiento es estrictamente serial y esta clase NO lo gestiona: recibe los registros ya emparejados con su registro anterior. Decidir cuál es el anterior exige un lock por SIF+NIF en la base de datos, y eso pertenece a la capa de integración, no a un generador de XML.

Constant Summary collapse

MAXIMO_REGISTROS =

maxOccurs de RegistroFactura en el esquema

1000

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(nif_obligado:, nombre_obligado:, entradas:) ⇒ Envio

Returns a new instance of Envio.

Parameters:

  • entradas (Array<Array(registro, anterior)>)

    cada registro con el RegistroAnterior que le precede en la cadena (nil solo en el primero).

Raises:



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/verifactu_rails/envio.rb', line 23

def initialize(nif_obligado:, nombre_obligado:, entradas:)
  @nif_obligado = Formato.nif(nif_obligado, 'NIF del obligado')
  @nombre_obligado = Formato.limitar(nombre_obligado, 'NombreRazon del obligado', 120)
  @entradas = normalizar(entradas)

  raise ValidacionError, 'El envío necesita al menos un registro' if @entradas.empty?

  if entradas.size > MAXIMO_REGISTROS
    raise ValidacionError,
          "Un envío admite como mucho #{MAXIMO_REGISTROS} registros " \
          "(recibidos #{entradas.size}). Parte el lote."
  end

  validar_emisores!
end

Instance Attribute Details

#entradasObject (readonly)

Returns the value of attribute entradas.



19
20
21
# File 'lib/verifactu_rails/envio.rb', line 19

def entradas
  @entradas
end

#nif_obligadoObject (readonly)

Returns the value of attribute nif_obligado.



19
20
21
# File 'lib/verifactu_rails/envio.rb', line 19

def nif_obligado
  @nif_obligado
end

#nombre_obligadoObject (readonly)

Returns the value of attribute nombre_obligado.



19
20
21
# File 'lib/verifactu_rails/envio.rb', line 19

def nombre_obligado
  @nombre_obligado
end

Class Method Details

.xml_desde_fragmentos(nif_obligado:, nombre_obligado:, fragmentos:) ⇒ Object

Envío a partir de fragmentos XML ya construidos, en vez de a partir de los objetos.

Es lo que usa la capa de persistencia: cada registro guardó su XML en el momento de anotarse, con su huella dentro, y al enviar se agrupan tal cual. Así lo que viaja es LITERALMENTE lo que se calculó bajo el lock, sin volver a derivar nada. Reconstruir el XML al enviar abriría la puerta a que la huella almacenada y la enviada divergieran, que es el peor fallo posible aquí: la AEAT recalcula sobre lo que recibe.

Parameters:

  • fragmentos (Array<String>)

    elementos sum:RegistroFactura



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/verifactu_rails/envio.rb', line 50

def self.xml_desde_fragmentos(nif_obligado:, nombre_obligado:, fragmentos:)
  if fragmentos.empty?
    raise ValidacionError, 'El envío necesita al menos un registro'
  end
  if fragmentos.size > MAXIMO_REGISTROS
    raise ValidacionError,
          "Un envío admite como mucho #{MAXIMO_REGISTROS} registros " \
          "(recibidos #{fragmentos.size}). Parte el lote."
  end

  nif = Formato.nif(nif_obligado, 'NIF del obligado')
  nombre = Formato.limitar(nombre_obligado, 'NombreRazon del obligado', 120)

  constructor = Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml|
    xml['sum'].RegFactuSistemaFacturacion('xmlns:sum' => NS_LR, 'xmlns:sum1' => NS_SF) do
      xml['sum'].Cabecera do
        xml['sum1'].ObligadoEmision do
          xml['sum1'].NombreRazon nombre
          xml['sum1'].NIF nif
        end
      end
      # << inserta el markup tal cual, sin reinterpretarlo.
      fragmentos.each { |fragmento| xml << fragmento }
    end
  end
  constructor.to_xml
end

Instance Method Details

#to_xmlObject



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/verifactu_rails/envio.rb', line 78

def to_xml
  constructor = Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |xml|
    xml['sum'].RegFactuSistemaFacturacion('xmlns:sum' => NS_LR, 'xmlns:sum1' => NS_SF) do
      xml['sum'].Cabecera do
        xml['sum1'].ObligadoEmision do
          xml['sum1'].NombreRazon nombre_obligado
          xml['sum1'].NIF nif_obligado
        end
      end
      entradas.each do |registro, anterior|
        xml['sum'].RegistroFactura do
          registro.construir(xml, anterior: anterior)
        end
      end
    end
  end
  constructor.to_xml
end