Class: VerifactuRails::Libro::Remesa

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

Overview

Remisión a la AEAT de los registros que una cadena tiene pendientes.

Va SEPARADO de anotar! a propósito. El encadenamiento es síncrono y bajo lock porque no se puede diferir; el envío es asíncrono y reintentable porque sí. Confundir las dos cosas es lo que llevaría a bloquear una venta porque la AEAT no responde.

Sobre el tamaño del lote: agrupar NO es el modo normal. Las FAQs exigen que la remisión sea "inmediata o sin demora apreciable" a la expedición, así que un comercio que factura cada diez minutos mandará siempre un registro por petición. El tope de 1000 es un techo para quien factura rápido, y el lote acaba siendo del tamaño que dicte el ritmo de facturación, no una decisión.

Defined Under Namespace

Classes: Resultado

Constant Summary collapse

MAXIMO =
Envio::MAXIMO_REGISTROS
ENVIABLES =

Se envían también los que quedaron 'enviando': si un envío dio timeout no se sabe si llegó, y reintentar es seguro porque un duplicado se trata como éxito. Dejarlos fuera los abandonaría para siempre.

%w[pendiente enviando].freeze

Instance Method Summary collapse

Constructor Details

#initialize(cadena, transporte:) ⇒ Remesa

Returns a new instance of Remesa.



29
30
31
32
# File 'lib/verifactu_rails/libro/remesa.rb', line 29

def initialize(cadena, transporte:)
  @cadena = cadena
  @transporte = transporte
end

Instance Method Details

#enviar!(ahora: Time.now) ⇒ Resultado

Returns con estado :enviado, :esperando, :nada_pendiente o :bloqueada_por_rechazo.

Returns:

  • (Resultado)

    con estado :enviado, :esperando, :nada_pendiente o :bloqueada_por_rechazo



36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/verifactu_rails/libro/remesa.rb', line 36

def enviar!(ahora: Time.now)
  return sin_enviar(:esperando) if esperando?(ahora)
  return sin_enviar(:bloqueada_por_rechazo) if rechazo_sin_resolver?

  lote = cadena.registros.where(estado: ENVIABLES).order(:id).limit(MAXIMO).to_a
  return sin_enviar(:nada_pendiente) if lote.empty?

  marcar_enviando(lote)
  respuesta = transmitir(lote)
  aplicar!(lote, respuesta)
  cadena.update!(no_enviar_antes_de: ahora + respuesta.tiempo_espera.to_i)

  Resultado.new(estado: :enviado, respuesta: respuesta, enviados: lote)
end