ticketbai 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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