xrechnung 0.1.0

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.
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in xrechnung.gemspec
4
+ gemspec
5
+
6
+ gem "rake", "~> 13.0"
7
+ gem "rspec", "~> 3.0"
8
+ gem "rubocop-rspec", "~> 2.1"
data/Gemfile.lock ADDED
@@ -0,0 +1,70 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ xrechnung (0.1.0)
5
+ builder (~> 3.2)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ ast (2.4.2)
11
+ builder (3.2.4)
12
+ diff-lcs (1.4.4)
13
+ httparty (0.18.1)
14
+ mime-types (~> 3.0)
15
+ multi_xml (>= 0.5.2)
16
+ mime-types (3.3.1)
17
+ mime-types-data (~> 3.2015)
18
+ mime-types-data (3.2021.0225)
19
+ multi_xml (0.6.0)
20
+ parallel (1.20.1)
21
+ parser (3.0.1.0)
22
+ ast (~> 2.4.1)
23
+ rainbow (3.0.0)
24
+ rake (13.0.3)
25
+ regexp_parser (2.1.1)
26
+ rexml (3.2.5)
27
+ rspec (3.10.0)
28
+ rspec-core (~> 3.10.0)
29
+ rspec-expectations (~> 3.10.0)
30
+ rspec-mocks (~> 3.10.0)
31
+ rspec-core (3.10.1)
32
+ rspec-support (~> 3.10.0)
33
+ rspec-expectations (3.10.1)
34
+ diff-lcs (>= 1.2.0, < 2.0)
35
+ rspec-support (~> 3.10.0)
36
+ rspec-mocks (3.10.2)
37
+ diff-lcs (>= 1.2.0, < 2.0)
38
+ rspec-support (~> 3.10.0)
39
+ rspec-support (3.10.2)
40
+ rubocop (1.13.0)
41
+ parallel (~> 1.10)
42
+ parser (>= 3.0.0.0)
43
+ rainbow (>= 2.2.2, < 4.0)
44
+ regexp_parser (>= 1.8, < 3.0)
45
+ rexml
46
+ rubocop-ast (>= 1.2.0, < 2.0)
47
+ ruby-progressbar (~> 1.7)
48
+ unicode-display_width (>= 1.4.0, < 3.0)
49
+ rubocop-ast (1.4.1)
50
+ parser (>= 2.7.1.5)
51
+ rubocop-rspec (2.2.0)
52
+ rubocop (~> 1.0)
53
+ rubocop-ast (>= 1.1.0)
54
+ ruby-progressbar (1.11.0)
55
+ rubyzip (2.3.0)
56
+ unicode-display_width (2.0.0)
57
+
58
+ PLATFORMS
59
+ ruby
60
+
61
+ DEPENDENCIES
62
+ httparty
63
+ rake (~> 13.0)
64
+ rspec (~> 3.0)
65
+ rubocop-rspec (~> 2.1)
66
+ rubyzip (~> 2.0)
67
+ xrechnung!
68
+
69
+ BUNDLED WITH
70
+ 2.2.15
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2021 Digineo GmbH
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,44 @@
1
+ # Xrechnung
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/xrechnung`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'xrechnung'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle install
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install xrechnung
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/digineo/xrechnung. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/digineo/xrechnung/blob/master/CODE_OF_CONDUCT.md).
36
+
37
+
38
+ ## License
39
+
40
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
41
+
42
+ ## Code of Conduct
43
+
44
+ Everyone interacting in the Xrechnung project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/digineo/xrechnung/blob/master/CODE_OF_CONDUCT.md).
data/Rakefile ADDED
@@ -0,0 +1,55 @@
1
+ require "pathname"
2
+ require "bundler/gem_tasks"
3
+ require "rspec/core/rake_task"
4
+
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ task :default => :spec
8
+
9
+ namespace :validator do
10
+ VALIDATOR_SOURCES = {
11
+ tool: {
12
+ filename: "validator/validationtool-1.4.1-standalone.jar",
13
+ release_url: "https://github.com/itplr-kosit/validator/releases/download/v1.4.1/validationtool-1.4.1.zip",
14
+ },
15
+ scenarios: {
16
+ filename: "validator/scenarios.xml",
17
+ release_url: "https://github.com/itplr-kosit/validator-configuration-xrechnung/releases/download/release-2020-12-31/validator-configuration-xrechnung_2.0.1_2020-12-31.zip",
18
+ }
19
+ }
20
+
21
+ VALIDATOR_SOURCES.each do |_, v|
22
+ base = Pathname.new(__dir__).join("validator")
23
+ zipfile = base.join(File.basename(v[:release_url]))
24
+
25
+ file zipfile do
26
+ require "httparty"
27
+
28
+ base.mkpath unless base.exist?
29
+
30
+ res = HTTParty.get(v[:release_url], follow_redirects: true)
31
+ File.open(zipfile, "wb") { |f| f.write res.body }
32
+ end
33
+
34
+ file v[:filename] => zipfile do
35
+ require "zip"
36
+
37
+ Zip::File.foreach(zipfile) do |entry|
38
+ entry.extract base.join(entry.name)
39
+ end
40
+ end
41
+ end
42
+
43
+ desc "Download official validator and scenarios"
44
+ task download: VALIDATOR_SOURCES.map { |_, v| v[:filename] }
45
+
46
+ desc "Run validator on test fixtures"
47
+ task run: :download do
48
+ fixtures = Pathname.new(__dir__).join("spec/fixtures/*.xml")
49
+ output = Pathname.new(__dir__).join("validator/results").tap(&:mkpath)
50
+ tool = VALIDATOR_SOURCES[:tool][:filename]
51
+ scenarios = VALIDATOR_SOURCES[:scenarios][:filename]
52
+
53
+ sh "java -jar #{tool} -s #{scenarios} --output-directory #{output} --html --disable-gui #{fixtures}"
54
+ end
55
+ end
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "xrechnung"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/lib/xrechnung.rb ADDED
@@ -0,0 +1,326 @@
1
+ require "xrechnung/version"
2
+ require "date"
3
+ require "xrechnung/currency"
4
+ require "xrechnung/quantity"
5
+ require "xrechnung/id"
6
+ require "xrechnung/member_container"
7
+ require "xrechnung/contact"
8
+ require "xrechnung/party_legal_entity"
9
+ require "xrechnung/party_tax_scheme"
10
+ require "xrechnung/postal_address"
11
+ require "xrechnung/party"
12
+ require "xrechnung/payee_financial_account"
13
+ require "xrechnung/payment_means"
14
+ require "xrechnung/tax_total"
15
+ require "xrechnung/tax_category"
16
+ require "xrechnung/tax_subtotal"
17
+ require "xrechnung/legal_monetary_total"
18
+ require "xrechnung/item"
19
+ require "xrechnung/allowance_charge"
20
+ require "xrechnung/price"
21
+ require "xrechnung/invoice_line"
22
+ require "xrechnung/invoice_document_reference"
23
+ require "builder"
24
+
25
+ module Xrechnung
26
+ class Error < StandardError; end
27
+
28
+ class Document
29
+ include MemberContainer
30
+
31
+ # Invoice number BT-1
32
+ #
33
+ # Eine eindeutige Kennung der Rechnung, die diese im System des Verkäufers identifiziert.
34
+ # Anmerkung: Es ist kein „identification scheme“ zu verwenden.
35
+ #
36
+ # @!attribute id
37
+ # @return [String]
38
+ member :id, type: String
39
+
40
+ # Invoice issue date BT-2
41
+ #
42
+ # Das Datum, an dem die Rechnung ausgestellt wurde.
43
+ #
44
+ # @!attribute issue_date
45
+ # @return [Date]
46
+ member :issue_date, type: Date
47
+
48
+ # Payment due date BT-9
49
+ #
50
+ # Das Fälligkeitsdatum des Rechnungsbetrages.
51
+ #
52
+ # @!attribute due_date
53
+ # @return [Date]
54
+ member :due_date, type: Date
55
+
56
+ # Invoice type code BT-3
57
+ # Ein Code, der den Funktionstyp der Rechnung angibt.
58
+ #
59
+ # Anmerkung: Der Rechnungstyp muss gemäß UNTDID 1001 spezifiziert werden.
60
+ # Folgende Codes aus der Codeliste sollen verwendet werden:
61
+ # • 326 (Partial invoice)
62
+ # • 380 (Commercial invoice)
63
+ # • 384 (Corrected invoice)
64
+ # • 389 (Self-billed invoice)
65
+ # • 381 (Credit note)
66
+ # • 875 (Partial construction invoice)
67
+ # • 876 (Partial final construction invoice)
68
+ # • 877 (Final construction invoice)
69
+ #
70
+ # @!attribute invoice_type_code
71
+ # @return [Integer]
72
+ member :invoice_type_code, type: Integer, default: 380
73
+
74
+ # Invoice currency code BT-5
75
+ #
76
+ # Die Währung, in der alle Rechnungsbeträge angegeben werden, ausgenommen ist der Umsatzsteuer-
77
+ # Gesamtbetrag, der in der Abrechnungswährung anzugeben ist.
78
+ # Anmerkung: Nur eine Währung ist in der Rechnung zu verwenden, der „Invoice total VAT amount in accounting
79
+ # currency“ (BT-111) ist in der Abrechnungswährung auszuweisen. Die gültigen Währungen sind bei der ISO 4217
80
+ # „Codes for the representation of currencies and funds“ registriert. Nur die Alpha-3-Darstellung darf verwendet
81
+ # werden.
82
+ #
83
+ # @!attribute document_currency_code
84
+ # @return [String]
85
+ member :document_currency_code, type: String, default: "EUR"
86
+
87
+ # INVOICE NOTE BG-1
88
+ #
89
+ # Eine Gruppe von Informationselementen für rechnungsrelevante Erläuterungen
90
+ # mit Hinweisen auf den Rechnungsbetreff.
91
+ #
92
+ # @!attribute notes
93
+ # @return [Array]
94
+ member :notes, type: Array, default: []
95
+
96
+ # Purchase order reference BT-13
97
+ #
98
+ # Eine vom Erwerber ausgegebene Kennung für eine referenzierte Bestellung.
99
+ #
100
+ # @!attribute purchase_order_reference
101
+ # @return [String]
102
+ member :purchase_order_reference, type: String
103
+
104
+ # Sales order reference BT-14
105
+ #
106
+ # Eine vom Verkäufer ausgegebene Kennung für einen referenzierten Auftrag.
107
+ #
108
+ # @!attribute sales_order_reference
109
+ # @return [String]
110
+ member :sales_order_reference, type: String, optional: true
111
+
112
+ # Gruppe SELLER BG-4
113
+ #
114
+ # Eine Gruppe von Informationselementen, die Informationen über den Verkäufer liefern.
115
+ #
116
+ # @!attribute accounting_supplier_party
117
+ # @return [Xrechnung::Party]
118
+ member :accounting_supplier_party, type: Xrechnung::Party
119
+
120
+ # BUYER BG-7
121
+ #
122
+ # Eine Gruppe von Informationselementen, die Informationen über den Erwerber liefern.
123
+ #
124
+ # @!attribute accounting_customer_party
125
+ # @return [Xrechnung::Party]
126
+ member :accounting_customer_party, type: Xrechnung::Party
127
+
128
+ # Value added tax point date BT-7
129
+ #
130
+ # Das Datum, zu dem die Umsatzsteuer für den Verkäufer und für den Erwerber abrechnungsrelevant wird.
131
+ # Die Anwendung von BT-7 und 8 schließen sich gegenseitig aus.
132
+ #
133
+ # @!attribute tax_point_date
134
+ # @return [Date]
135
+ member :tax_point_date, type: Date
136
+
137
+ # VAT accounting currency code BT-6
138
+ #
139
+ # Die für die Umsatzsteuer-Abrechnungs- und -Meldezwecke verwendete Währung, die im Land des Verkäufers gültig
140
+ # ist oder verlangt wird.
141
+ # Anmerkung: Zu Verwenden in Kombination mit „Invoice total VAT amount in accounting currency“ (BT-111), wenn
142
+ # die Umsatzsteuerabrechnungswährung von der Rechnungswährung abweicht. Die gültigen Währungen sind bei
143
+ # der ISO 4217 „Codes for the representation of currencies and funds“ registriert. Nur die Alpha-3-Darstellung darf
144
+ # verwendet werden.
145
+ #
146
+ # @!attribute tax_currency_code
147
+ # @return [String]
148
+ member :tax_currency_code, type: String, default: "EUR"
149
+
150
+ # Buyer reference BT-10
151
+ #
152
+ # Ein vom Erwerber zugewiesener und für interne Lenkungszwecke benutzter Bezeichner.
153
+ # Anmerkung: Im Rahmen des Steuerungsprojekts eRechnung ist mit der so genannten Leitweg-ID eine
154
+ # Zuordnungsmöglichkeit entwickelt worden, deren verbindliche Nutzung von Bund und mehreren Ländern
155
+ # vorgegeben wird. Die Leitweg-ID ist prinzipiell für Bund, Länder und Kommunen einsetzbar. Für die Darstellung der
156
+ # Leitweg-ID wird das in XRechnung verpflichtende Feld Buyer Reference benutzt.
157
+ # Länder und Kommunen, die ihren Rechnungsstellern abweichend von der Leitweg-ID eigene Zuordnungsmuster
158
+ # mitteilen, können diese statt der Leitweg-ID im Feld Buyer Reference verwenden.
159
+ # Hinweis: Es existiert eine Handreichung zur Bildung der Leitweg-ID, die über die KoSIT zu erhalten ist (siehe Website
160
+ # XRechnung bzw. FAQ-Liste).
161
+ #
162
+ # @!attribute buyer_reference
163
+ # @return [String]
164
+ member :buyer_reference, type: String
165
+
166
+ # @!attribute billing_reference
167
+ # @return [Xrechnung::InvoiceDocumentReference]
168
+ member :billing_reference, type: Xrechnung::InvoiceDocumentReference, optional: true
169
+
170
+ # Contract reference BT-12
171
+ #
172
+ # Eine eindeutige Bezeichnung des Vertrages (z. B. Vertragsnummer).
173
+ #
174
+ # @!attribute contract_document_reference_id
175
+ # @return [String]
176
+ member :contract_document_reference_id, type: String
177
+
178
+ # Project reference BT-11
179
+ #
180
+ # Die Kennung eines Projektes, auf das sich die Rechnung bezieht.
181
+ #
182
+ # @!attribute project_reference_id
183
+ # @return [String]
184
+ member :project_reference_id, type: String
185
+
186
+ # SELLER TAX REPRESENTATIVE PARTY BG-11
187
+ #
188
+ # Eine Gruppe von Informationselementen, die Informationen über den
189
+ # Steuervertreter des Verkäufers liefern.
190
+ #
191
+ # @!attribute tax_representative_party
192
+ # @return [Xrechnung::Party]
193
+ member :tax_representative_party, type: Xrechnung::Party, optional: true
194
+
195
+ # PAYMENT INSTRUCTIONS BG-16
196
+ #
197
+ # Eine Gruppe von Informationselementen, die Informationen darüber liefern, wie die Zahlung
198
+ # erfolgen soll.
199
+ #
200
+ # @!attribute payment_means
201
+ # @return [Xrechnung::PaymentMeans]
202
+ member :payment_means, type: Xrechnung::PaymentMeans
203
+
204
+ # Payment terms BT-20
205
+ #
206
+ # Eine Textbeschreibung der Zahlungsbedingungen, die für den fälligen Zahlungsbetrag gelten (einschließlich
207
+ # Beschreibung möglicher Skonto- und Verzugsbedingungen). Dieses Informationselement kann mehrere Zeilen und
208
+ # mehrere Angaben zu Zahlungsbedingungen beinhalten und sowohl unstrukturierten als strukturierten Text enthalten.
209
+ # Der unstrukturierte Text darf dabei keine # enthalten.
210
+ #
211
+ # @!attribute payment_terms_note
212
+ # @return [String]
213
+ member :payment_terms_note, type: String
214
+
215
+ # VAT BREAKDOWN BG-23
216
+ #
217
+ # Eine Gruppe von Informationselementen, die Informationen über die
218
+ # Umsatzsteueraufschlüsselung in verschiedene Kategorien liefern.
219
+ #
220
+ # @!attribute tax_total
221
+ # @return [Xrechnung::TaxTotal]
222
+ member :tax_total, type: Xrechnung::TaxTotal
223
+
224
+ # DOCUMENT TOTALS BG-22
225
+ #
226
+ # Eine Gruppe von Informationselementen, die die monetären Gesamtbeträge der Rechnung
227
+ # liefern.
228
+ #
229
+ # @!attribute legal_monetary_total
230
+ # @return [Xrechnung::LegalMonetaryTotal]
231
+ member :legal_monetary_total, type: Xrechnung::LegalMonetaryTotal
232
+
233
+ # INVOICE LINE BG-25
234
+ #
235
+ # Eine Gruppe von Informationselementen, die Informationen über einzelne
236
+ # Rechnungspositionen liefern.
237
+ #
238
+ # @!attribute invoice_lines
239
+ # @return [Array]
240
+ member :invoice_lines, type: Array, default: []
241
+
242
+ def to_xml(indent: 2, target: "")
243
+ xml = Builder::XmlMarkup.new(indent: indent, target: target)
244
+ xml.instruct! :xml, version: "1.0", encoding: "UTF-8"
245
+
246
+ xml.ubl :Invoice, \
247
+ "xmlns:ubl" => "urn:oasis:names:specification:ubl:schema:xsd:Invoice-2",
248
+ "xmlns:cac" => "urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2",
249
+ "xmlns:cbc" => "urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2",
250
+ "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
251
+ "xsi:schemaLocation" => "urn:oasis:names:specification:ubl:schema:xsd:Invoice-2 http://docs.oasis-open.org/ubl/os-UBL-2.1/xsd/maindoc/UBL-Invoice-2.1.xsd" do
252
+ xml.cbc :CustomizationID, "urn:cen.eu:en16931:2017#compliant#urn:xoev-de:kosit:standard:xrechnung_2.0"
253
+ xml.cbc :ID, id
254
+ xml.cbc :IssueDate, issue_date
255
+ xml.cbc :DueDate, due_date
256
+ xml.cbc :InvoiceTypeCode, invoice_type_code
257
+
258
+ notes.each do |note|
259
+ xml.cbc :Note, note
260
+ end
261
+
262
+ xml.cbc :TaxPointDate, tax_point_date
263
+ xml.cbc :DocumentCurrencyCode, document_currency_code
264
+ xml.cbc :TaxCurrencyCode, tax_currency_code
265
+ xml.cbc :BuyerReference, buyer_reference
266
+
267
+ xml.cac :OrderReference do
268
+ xml.cbc :ID, purchase_order_reference
269
+ unless members[:sales_order_reference][:optional] && sales_order_reference.nil?
270
+ xml.cbc :SalesOrderID, sales_order_reference
271
+ end
272
+ end
273
+
274
+ unless members[:billing_reference][:optional] && billing_reference.nil?
275
+ xml.cac :BillingReference do
276
+ billing_reference&.to_xml(xml)
277
+ end
278
+ end
279
+
280
+ xml.cac :ContractDocumentReference do
281
+ xml.cbc :ID, contract_document_reference_id
282
+ end
283
+
284
+ xml.cac :ProjectReference do
285
+ xml.cbc :ID, project_reference_id
286
+ end
287
+
288
+ xml.cac :AccountingSupplierParty do
289
+ accounting_supplier_party&.to_xml(xml)
290
+ end
291
+
292
+ xml.cac :AccountingCustomerParty do
293
+ accounting_customer_party&.to_xml(xml)
294
+ end
295
+
296
+ unless members[:tax_representative_party][:optional] && tax_representative_party.nil?
297
+ xml.cac :TaxRepresentativeParty do
298
+ tax_representative_party&.to_xml(xml)
299
+ end
300
+ end
301
+
302
+ xml.cac :PaymentMeans do
303
+ payment_means&.to_xml(xml)
304
+ end
305
+
306
+ xml.cac :PaymentTerms do
307
+ xml.cbc :Note, payment_terms_note
308
+ end
309
+
310
+ xml.cac :TaxTotal do
311
+ tax_total&.to_xml(xml)
312
+ end
313
+
314
+ xml.cac :LegalMonetaryTotal do
315
+ legal_monetary_total&.to_xml(xml)
316
+ end
317
+
318
+ invoice_lines.each do |invoice_line|
319
+ invoice_line&.to_xml(xml)
320
+ end
321
+ end
322
+
323
+ target
324
+ end
325
+ end
326
+ end