ticketbai 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +3 -0
  3. data/.rubocop.yml +32 -0
  4. data/CHANGELOG.md +13 -0
  5. data/Gemfile +6 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +107 -0
  8. data/Rakefile +12 -0
  9. data/bin/console +15 -0
  10. data/bin/setup +8 -0
  11. data/lib/ticketbai/api/client.rb +63 -0
  12. data/lib/ticketbai/api/registry.rb +34 -0
  13. data/lib/ticketbai/api/request.rb +125 -0
  14. data/lib/ticketbai/api/response_parser.rb +36 -0
  15. data/lib/ticketbai/checksum_calculator.rb +15 -0
  16. data/lib/ticketbai/document.rb +21 -0
  17. data/lib/ticketbai/document_validator.rb +42 -0
  18. data/lib/ticketbai/documents/annulment.rb +45 -0
  19. data/lib/ticketbai/documents/api_payload.rb +47 -0
  20. data/lib/ticketbai/documents/issuance.rb +55 -0
  21. data/lib/ticketbai/documents/issuance_unsigned.rb +58 -0
  22. data/lib/ticketbai/errors.rb +27 -0
  23. data/lib/ticketbai/nodes/breakdown_type.rb +72 -0
  24. data/lib/ticketbai/nodes/invoice_chaining.rb +22 -0
  25. data/lib/ticketbai/nodes/invoice_data.rb +24 -0
  26. data/lib/ticketbai/nodes/invoice_header.rb +26 -0
  27. data/lib/ticketbai/nodes/issuer.rb +18 -0
  28. data/lib/ticketbai/nodes/lroe_header.rb +29 -0
  29. data/lib/ticketbai/nodes/lroe_issued_invoices.rb +28 -0
  30. data/lib/ticketbai/nodes/receiver.rb +36 -0
  31. data/lib/ticketbai/nodes/software.rb +17 -0
  32. data/lib/ticketbai/operation.rb +59 -0
  33. data/lib/ticketbai/operations/annulment.rb +41 -0
  34. data/lib/ticketbai/operations/issuance.rb +93 -0
  35. data/lib/ticketbai/operations/issuance_unsigned.rb +89 -0
  36. data/lib/ticketbai/signer.rb +273 -0
  37. data/lib/ticketbai/tbai_identifier.rb +33 -0
  38. data/lib/ticketbai/tbai_qr.rb +50 -0
  39. data/lib/ticketbai/version.rb +5 -0
  40. data/lib/ticketbai/xmldsig-core-schema.xsd +318 -0
  41. data/lib/ticketbai/xsd_validators/annulment.xsd +392 -0
  42. data/lib/ticketbai/xsd_validators/issuance.xsd +865 -0
  43. data/lib/ticketbai.rb +89 -0
  44. data/ticketbai.gemspec +42 -0
  45. metadata +186 -0
@@ -0,0 +1,55 @@
1
+ module Ticketbai
2
+ module Documents
3
+ class Issuance < Document
4
+ ROOT_NAME = 'T:TicketBai'.freeze
5
+ XMLNS = {
6
+ 'xmlns:T' => 'urn:ticketbai:emision'
7
+ }.freeze
8
+
9
+ ATTRIBUTES = %i[issuer receiver invoice_header invoice_data breakdown_type invoice_chaining software].freeze
10
+
11
+ attr_accessor(*ATTRIBUTES)
12
+
13
+ ###
14
+ # @param [Ticketbai::Nodes::Isuer] issuer
15
+ # @param [Ticketbai::Nodes::Receiver] receiver
16
+ # @param [Ticketbai::Nodes::InvoiceHeader] invoice_header
17
+ # @param [Ticketbai::Nodes::InvoiceData] invoice_data
18
+ # @param [Ticketbai::Nodes::BreakdownType] breakdown_type
19
+ # @param [Ticketbai::Nodes::InvoiceChaining] invoice_chaining
20
+ # @param [Ticketbai::Nodes::Software] software
21
+ ###
22
+ def initialize(**args)
23
+ super(args)
24
+ end
25
+
26
+ # @return [Nokogiri::XML::Builder]
27
+ def create
28
+ builder = Nokogiri::XML::Builder.new(encoding: Encoding::UTF_8.to_s) do |xml|
29
+ xml.TicketBai(XMLNS) do
30
+ xml.Cabecera do
31
+ xml.IDVersionTBAI TBAI_VERSION
32
+ end
33
+ xml.Sujetos do
34
+ @issuer.build_xml(xml)
35
+ @receiver&.build_xml(xml)
36
+ end
37
+ xml.Factura do
38
+ @invoice_header.build_xml(xml)
39
+ @invoice_data.build_xml(xml)
40
+ @breakdown_type.build_xml(xml)
41
+ end
42
+ xml.HuellaTBAI do
43
+ @invoice_chaining&.build_xml(xml)
44
+ @software.build_xml(xml)
45
+ end
46
+ end
47
+ end
48
+
49
+ modify_xml_root_name(builder)
50
+
51
+ builder
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,58 @@
1
+ module Ticketbai
2
+ module Documents
3
+ # This document has the pecualiarity that it does not need to be signed and it must be sent to the API without a root node, so it's not considered
4
+ # as a valid XML either. The structure of the document is as follows:
5
+ # <Destinatarios>
6
+ # ...
7
+ # ...
8
+ # </Destinatarios>
9
+ # <CabeceraFactura>
10
+ # ...
11
+ # ...
12
+ # </CabeceraFactura>
13
+ # <DatosFactura>
14
+ # ...
15
+ # ...
16
+ # </DatosFactura>
17
+ # <TipoDesglose>
18
+ # ...
19
+ # ...
20
+ # </TipoDesglose>
21
+ #
22
+ # The document is created with a temporary root node (TicketBai), and after creating it, it's returned without the root node.
23
+ class IssuanceUnsigned
24
+ ###
25
+ # @param [Ticketbai::Nodes::Receiver] receiver
26
+ # @param [Ticketbai::Nodes::InvoiceHeader] invoice_header
27
+ # @param [Ticketbai::Nodes::InvoiceData] invoice_data
28
+ # @param [Ticketbai::Nodes::BreakdownType] breakdown_type
29
+ ###
30
+ def initialize(**args)
31
+ @receiver = args[:receiver]
32
+ @invoice_header = args[:invoice_header]
33
+ @invoice_data = args[:invoice_data]
34
+ @breakdown_type = args[:breakdown_type]
35
+ end
36
+
37
+ # @return [String]
38
+ def create
39
+ builder = Nokogiri::XML::Builder.new(encoding: Encoding::UTF_8.to_s) do |xml|
40
+ xml.TicketBai do
41
+ @receiver&.build_xml(xml)
42
+ @invoice_header.build_xml(xml)
43
+ @invoice_data.build_xml(xml)
44
+ @breakdown_type.build_xml(xml)
45
+ end
46
+ end
47
+
48
+ filter_root_node(builder)
49
+ end
50
+
51
+ private
52
+
53
+ def filter_root_node(builder)
54
+ Nokogiri::XML(builder.to_xml).at('TicketBai').children.to_xml
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,27 @@
1
+ module Ticketbai
2
+ # Generic Ticketbai exception class.
3
+ class Error < StandardError; end
4
+
5
+ # For errors returned by the client library, like HTTP errors
6
+ class ClientError < Error; end
7
+
8
+ # For errors returned by the API
9
+ class APIError < Error
10
+ attr_reader :code
11
+
12
+ def initialize(message = nil, code = nil)
13
+ @code = code
14
+ super(message)
15
+ end
16
+ end
17
+
18
+ # For errors returned by the TBAIFile validation.
19
+ class TBAIFileError < Error
20
+ attr_reader :code
21
+
22
+ def initialize(message = nil, code = nil)
23
+ @code = code
24
+ super(message)
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,72 @@
1
+ module Ticketbai
2
+ module Nodes
3
+ class BreakdownType
4
+ # Exemption causes (CausaExencion):
5
+ # E1: Exenta por el articulo 20 de la Norma Foral del IVA
6
+ # E2: Exenta por el articulo 21 de la Norma Foral del IVA
7
+ # E3: Exenta por el articulo 22 de la Norma Foral del IVA
8
+ # E4: Exenta por el articulo 23 y 24 de la Norma Foral del IVA
9
+ # E5: Exenta por el articulo 25 de la Norma Foral del IVA
10
+ # E6: Exenta por otra causa
11
+
12
+ # Type of non-exempt (TipoNoExenta):
13
+ # S1: Sin inversion del sujeto pasivo
14
+ # S2: Con inversion del sujeto pasivo
15
+ def initialize(args = {})
16
+ @receiver_country = args[:receiver_country]
17
+ @invoice_amount = args[:invoice_amount]
18
+ @invoice_vat = args[:invoice_vat]
19
+ @invoice_vat_total = args[:invoice_vat_total]
20
+ @receiver_in_eu = args[:receiver_in_eu]
21
+ @simplified_invoice = args[:simplified_invoice]
22
+ end
23
+
24
+ # @return [Nokogiri::XML::Builder]
25
+ def build_xml(node)
26
+ node = Nokogiri::XML::Builder.new if node.nil?
27
+ node.TipoDesglose do |xml|
28
+ if (@receiver_country == 'ES') || (@receiver_country != 'ES' && @simplified_invoice)
29
+ xml.DesgloseFactura do
30
+ xml.Sujeta do
31
+ if (@receiver_country != 'ES') && @simplified_invoice
32
+ xml.Exenta do
33
+ xml.DetalleExenta do
34
+ xml.CausaExencion @receiver_in_eu == true ? 'E6' : 'E2'
35
+ xml.BaseImponible @invoice_amount
36
+ end
37
+ end
38
+ else
39
+ xml.NoExenta do
40
+ xml.DetalleNoExenta do
41
+ xml.TipoNoExenta 'S1'
42
+ xml.DesgloseIVA do
43
+ xml.DetalleIVA do
44
+ xml.BaseImponible @invoice_amount
45
+ xml.TipoImpositivo @invoice_vat
46
+ xml.CuotaImpuesto @invoice_vat_total
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ else
55
+ xml.DesgloseTipoOperacion do
56
+ xml.PrestacionServicios do
57
+ xml.Sujeta do
58
+ xml.Exenta do
59
+ xml.DetalleExenta do
60
+ xml.CausaExencion @receiver_in_eu == true ? 'E6' : 'E2'
61
+ xml.BaseImponible @invoice_amount
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,22 @@
1
+ module Ticketbai
2
+ module Nodes
3
+ class InvoiceChaining
4
+ def initialize(args = {})
5
+ @prev_invoice_serial = args[:prev_invoice_serial]
6
+ @prev_invoice_number = args[:prev_invoice_number]
7
+ @prev_invoice_date = args[:prev_invoice_date]
8
+ @prev_invoice_signature = args[:prev_invoice_signature]
9
+ end
10
+
11
+ def build_xml(node)
12
+ node = Nokogiri::XML::Builder.new if node.nil?
13
+ node.EncadenamientoFacturaAnterior do |xml|
14
+ xml.SerieFacturaAnterior @prev_invoice_serial if @prev_invoice_serial
15
+ xml.NumFacturaAnterior @prev_invoice_number
16
+ xml.FechaExpedicionFacturaAnterior @prev_invoice_date
17
+ xml.SignatureValueFirmaFacturaAnterior @prev_invoice_signature
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,24 @@
1
+ module Ticketbai
2
+ module Nodes
3
+ class InvoiceData
4
+ def initialize(args = {})
5
+ @invoice_description = args[:invoice_description]
6
+ @invoice_total = args[:invoice_total]
7
+ @invoice_vat_key = args[:invoice_vat_key]
8
+ end
9
+
10
+ def build_xml(node)
11
+ node = Nokogiri::XML::Builder.new if node.nil?
12
+ node.DatosFactura do |xml|
13
+ xml.DescripcionFactura @invoice_description
14
+ xml.ImporteTotalFactura @invoice_total
15
+ xml.Claves do
16
+ xml.IDClave do
17
+ xml.ClaveRegimenIvaOpTrascendencia @invoice_vat_key
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,26 @@
1
+ module Ticketbai
2
+ module Nodes
3
+ class InvoiceHeader
4
+ SIMPLIFIED_INVOICE = 'S'.freeze
5
+
6
+ def initialize(args = {})
7
+ @invoice_serial = args[:invoice_serial]
8
+ @invoice_number = args[:invoice_number]
9
+ @invoice_date = args[:invoice_date]
10
+ @invoice_time = args[:invoice_time]
11
+ @simplified_invoice = args[:simplified_invoice]
12
+ end
13
+
14
+ def build_xml(node)
15
+ node = Nokogiri::XML::Builder.new if node.nil?
16
+ node.CabeceraFactura do |xml|
17
+ xml.SerieFactura @invoice_serial
18
+ xml.NumFactura @invoice_number
19
+ xml.FechaExpedicionFactura @invoice_date
20
+ xml.HoraExpedicionFactura @invoice_time if @invoice_time
21
+ xml.FacturaSimplificada SIMPLIFIED_INVOICE if @simplified_invoice
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,18 @@
1
+ module Ticketbai
2
+ module Nodes
3
+ class Issuer
4
+ def initialize(args = {})
5
+ @issuing_company_nif = args[:issuing_company_nif]
6
+ @issuing_company_name = args[:issuing_company_name]
7
+ end
8
+
9
+ def build_xml(node)
10
+ node = Nokogiri::XML::Builder.new if node.nil?
11
+ node.Emisor do |xml|
12
+ xml.NIF @issuing_company_nif
13
+ xml.ApellidosNombreRazonSocial @issuing_company_name
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,29 @@
1
+ module Ticketbai
2
+ module Nodes
3
+ class LroeHeader
4
+ def initialize(args = {})
5
+ @year = args[:year]
6
+ @nif = args[:nif]
7
+ @company_name = args[:company_name]
8
+ @operation = args[:operation]
9
+ @subchapter = args[:subchapter]
10
+ end
11
+
12
+ def build_xml(node)
13
+ node = Nokogiri::XML::Builder.new if node.nil?
14
+ node.Cabecera do |xml|
15
+ xml.Modelo Ticketbai::Api::Request::LROE_MODEL
16
+ xml.Capitulo Ticketbai::Api::Request::LROE_CHAPTER
17
+ xml.Subcapitulo @subchapter
18
+ xml.Operacion @operation
19
+ xml.Version '1.0'
20
+ xml.Ejercicio @year
21
+ xml.ObligadoTributario do
22
+ xml.NIF @nif
23
+ xml.ApellidosNombreRazonSocial @company_name
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,28 @@
1
+ module Ticketbai
2
+ module Nodes
3
+ class LroeIssuedInvoices
4
+ def initialize(args = {})
5
+ @issued_invoices = args[:issued_invoices]
6
+ @operation = args[:operation]
7
+ end
8
+
9
+ def build_xml(node)
10
+ node = Nokogiri::XML::Builder.new if node.nil?
11
+ node.FacturasEmitidas do |xml|
12
+ @issued_invoices.each do |issued_invoice|
13
+ xml.FacturaEmitida do
14
+ case @operation
15
+ when :annulment
16
+ xml.AnulacionTicketBai Base64.strict_encode64(issued_invoice)
17
+ when :issuance
18
+ xml.TicketBai Base64.strict_encode64(issued_invoice)
19
+ when :issuance_unsigned
20
+ xml << issued_invoice
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,36 @@
1
+ module Ticketbai
2
+ module Nodes
3
+ class Receiver
4
+ # ID TYPES
5
+ # 02: NIF-IVA
6
+ # 03: Pasaporte
7
+ # 04: Documento oficial de identificacion expedido por el pais o territorio de residencia
8
+ # 05: Certificado de residencia
9
+ # 06: Otro documento probatorio
10
+
11
+ def initialize(args = {})
12
+ @receiver_country = args[:receiver_country]
13
+ @receiver_nif = args[:receiver_nif]
14
+ @receiver_name = args[:receiver_name]
15
+ end
16
+
17
+ def build_xml(node)
18
+ node = Nokogiri::XML::Builder.new if node.nil?
19
+ node.Destinatarios do |xml|
20
+ xml.IDDestinatario do
21
+ if @receiver_country == 'ES'
22
+ xml.NIF @receiver_nif
23
+ else
24
+ xml.IDOtro do
25
+ xml.CodigoPais @receiver_country
26
+ xml.IDType '04'
27
+ xml.ID @receiver_nif
28
+ end
29
+ end
30
+ xml.ApellidosNombreRazonSocial @receiver_name
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,17 @@
1
+ module Ticketbai
2
+ module Nodes
3
+ class Software
4
+ def build_xml(node)
5
+ node = Nokogiri::XML::Builder.new if node.nil?
6
+ node.Software do |xml|
7
+ xml.LicenciaTBAI Ticketbai.config.license_key
8
+ xml.EntidadDesarrolladora do
9
+ xml.NIF Ticketbai.config.developer_company_nif
10
+ end
11
+ xml.Nombre Ticketbai.config.app_name
12
+ xml.Version Ticketbai.config.app_version
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,59 @@
1
+ module Ticketbai
2
+ class Operation
3
+ attr_accessor :company_cert
4
+
5
+ def initialize(args)
6
+ self.class::ATTRIBUTES.each do |p|
7
+ instance_variable_set "@#{p}", args[p]
8
+ end
9
+
10
+ @company_cert = Ticketbai.config.certificates[args[:company_cert]]
11
+ end
12
+
13
+ ###
14
+ # Creates the Ticketbai operation by doing the following:
15
+ # 1. Build the document
16
+ # 2. Sign the document
17
+ # 3. Validate the signed document
18
+ #
19
+ # @return [Hash] xml_doc: The signed document. signature_value: The first 100 characters of the signature value
20
+ ###
21
+ def create
22
+ document = build_document
23
+
24
+ signed_document = sign_document(document)
25
+
26
+ validate_document(signed_document)
27
+
28
+ signature_value = read_signature_value(signed_document)[0..99]
29
+
30
+ { xml_doc: signed_document, signature_value: signature_value }
31
+ end
32
+
33
+ def build_document
34
+ raise NotImplementedError, 'Must implement this method'
35
+ end
36
+
37
+ private
38
+
39
+ def modify_xml_root_name(builder)
40
+ builder.doc.root.name = self.class::ROOT_NAME
41
+ end
42
+
43
+ def decoded_cert
44
+ Base64.decode64(@company_cert[:cert])
45
+ end
46
+
47
+ def sign_document(document)
48
+ Signer.new({ xml: document.to_xml, certificate: decoded_cert, key: @company_cert[:key] }).sign
49
+ end
50
+
51
+ def validate_document(document)
52
+ DocumentValidator.new(document: document, validator_type: self.class::OPERATION_NAME).validate
53
+ end
54
+
55
+ def read_signature_value(document)
56
+ Nokogiri::XML(document).children.last.children.last.children[1].children.first.text
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,41 @@
1
+ module Ticketbai
2
+ module Operations
3
+ class Annulment < Operation
4
+ OPERATION_NAME = :annulment
5
+
6
+ ATTRIBUTES = %i[issuing_company_nif issuing_company_name invoice_serial invoice_number invoice_date].freeze
7
+
8
+ attr_accessor(*ATTRIBUTES)
9
+
10
+ ###
11
+ # @param [String] issuing_company_nif NIF of the taxpayer's company
12
+ # @param [String] issuing_company_name Name of the taxpayer's company
13
+ # @param [String] invoice_serial Invoice's serial number
14
+ # @param [String] invoice_number Invoice's number
15
+ # @param [String] invoice_date Invoices emission date (Format: d-m-Y)
16
+ # @param [String] company_cert The name of the certificate to be used for issuance
17
+ ###
18
+ def initialize(**args)
19
+ super(args)
20
+ end
21
+
22
+ def build_document
23
+ @issuer = Ticketbai::Nodes::Issuer.new(issuing_company_nif: @issuing_company_nif, issuing_company_name: @issuing_company_name)
24
+
25
+ @invoice_header = Ticketbai::Nodes::InvoiceHeader.new(
26
+ invoice_serial: @invoice_serial,
27
+ invoice_number: @invoice_number,
28
+ invoice_date: @invoice_date
29
+ )
30
+
31
+ @software = Ticketbai::Nodes::Software.new
32
+
33
+ Ticketbai::Documents::Annulment.new(
34
+ issuer: @issuer,
35
+ invoice_header: @invoice_header,
36
+ software: @software
37
+ ).create
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,93 @@
1
+ module Ticketbai
2
+ module Operations
3
+ class Issuance < Operation
4
+ DEFAULT_VAT_KEY = '01'.freeze
5
+ OPERATION_NAME = :issuance
6
+
7
+ ATTRIBUTES = %i[company_cert issuing_company_nif issuing_company_name receiver_nif receiver_name receiver_country receiver_in_eu invoice_serial
8
+ invoice_number invoice_date invoice_time simplified_invoice invoice_description invoice_total invoice_vat_key
9
+ invoice_amount invoice_vat invoice_vat_total prev_invoice_number prev_invoice_signature prev_invoice_date].freeze
10
+
11
+ attr_accessor(*ATTRIBUTES)
12
+
13
+ ###
14
+ # @param [String] issuing_company_nif NIF of the taxpayer's company
15
+ # @param [String] issuing_company_name Name of the taxpayer's company
16
+ # @param [String] receiver_nif Spanish NIF or official identification document in case of being another country
17
+ # @param [String] receiver_name Name of the receiver
18
+ # @param [String] receiver_country Country code of the receiver (Ex: ES|DE)
19
+ # @param [Boolean] receiver_in_eu The receiver residence is in Europe?
20
+ # @param [String] invoice_serial Invoices serial number
21
+ # @param [String] invoice_number Invoices number
22
+ # @param [String] invoice_date Invoices emission date (Format: d-m-Y)
23
+ # @param [String] invoice_time Invoices emission time (Format: H:M:S)
24
+ # @param [Boolean] simplified_invoice is a simplified invoice?
25
+ # @param [String] invoice_description Invoices description text
26
+ # @param [String] invoice_total Total invoice amount
27
+ # @param [String] invoice_vat_key Key of the VAT regime
28
+ # @param [String] invoice_amount Taxable base of the invoice
29
+ # @param [Float] invoice_vat Invoice VAT (Ex: 21.0)
30
+ # @param [String] invoice_vat_total Invoices number
31
+ # @param [String] prev_invoice_number Number of the last invoice generated
32
+ # @param [String] prev_invoice_signature Signature of the last invoice generated
33
+ # @param [String] prev_invoice_date Emission date of the last invoice generated
34
+ # @param [Symbol] company_cert: The name of the certificate to be used for issuance
35
+ ###
36
+ def initialize(**args)
37
+ args[:receiver_nif]&.strip!
38
+ args[:receiver_country] = args[:receiver_country]&.upcase || 'ES'
39
+
40
+ super(args)
41
+ end
42
+
43
+ def build_document
44
+ @issuer = Ticketbai::Nodes::Issuer.new(issuing_company_nif: @issuing_company_nif, issuing_company_name: @issuing_company_name)
45
+
46
+ if @receiver_nif && @receiver_name
47
+ @receiver = Ticketbai::Nodes::Receiver.new(receiver_country: @receiver_country, receiver_nif: @receiver_nif, receiver_name: @receiver_name)
48
+ end
49
+
50
+ @invoice_header = Ticketbai::Nodes::InvoiceHeader.new(
51
+ invoice_serial: @invoice_serial,
52
+ invoice_number: @invoice_number,
53
+ invoice_date: @invoice_date,
54
+ invoice_time: @invoice_time,
55
+ simplified_invoice: @simplified_invoice
56
+ )
57
+ @invoice_data = Ticketbai::Nodes::InvoiceData.new(
58
+ invoice_description: @invoice_description,
59
+ invoice_total: @invoice_total,
60
+ invoice_vat_key: @invoice_vat_key
61
+ )
62
+ @breakdown_type = Ticketbai::Nodes::BreakdownType.new(
63
+ receiver_country: @receiver_country,
64
+ invoice_amount: @invoice_amount,
65
+ invoice_vat: @invoice_vat,
66
+ invoice_vat_total: @invoice_vat_total,
67
+ receiver_in_eu: @receiver_in_eu,
68
+ simplified_invoice: @simplified_invoice
69
+ )
70
+ if @prev_invoice_number && @prev_invoice_date && @prev_invoice_signature
71
+ @invoice_chaining = Ticketbai::Nodes::InvoiceChaining.new(
72
+ prev_invoice_serial: @prev_invoice_serial,
73
+ prev_invoice_number: @prev_invoice_number,
74
+ prev_invoice_date: @prev_invoice_date,
75
+ prev_invoice_signature: @prev_invoice_signature
76
+ )
77
+ end
78
+
79
+ @software = Ticketbai::Nodes::Software.new
80
+
81
+ Ticketbai::Documents::Issuance.new(
82
+ issuer: @issuer,
83
+ receiver: @receiver,
84
+ invoice_header: @invoice_header,
85
+ invoice_data: @invoice_data,
86
+ breakdown_type: @breakdown_type,
87
+ invoice_chaining: @invoice_chaining,
88
+ software: @software
89
+ ).create
90
+ end
91
+ end
92
+ end
93
+ end