zugpferd 0.3.5 → 0.5.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: abb862a514f5dca77411e88cf1f21a3ed148192d30c3e6e661dbd9720344cae4
4
- data.tar.gz: 7effd9d5bed0d5a9e6d054acbad9602846f7c334a98ee32ec65037c62b4aee95
3
+ metadata.gz: 9a9f2f51374e01f8940bd39a69c088477348c26d77d69adca3f1737445f99c9d
4
+ data.tar.gz: 8a541edb6c9b0aa78d87d715e8a04271ef0a8ea03d9d49463b4d0f45f72ce499
5
5
  SHA512:
6
- metadata.gz: 111a8f3af318dba1cd0d4f5f208ed5a35fce92d59eda7c5660098cc83d10d61d8229ad97a400fba46160bb4bb7df80fe23820c2a35d92f81e563b3b2e1bc36a3
7
- data.tar.gz: 16c0f30986919d7365f321ef18c3f3cf820152d6d0abc3943a3889e7485733ffc77d61a392755d48859011e79bac8bd30e3b4e77e65ed0f2fca2c9f866b57065
6
+ metadata.gz: 5f3051364d36fc4b5fddb4ff6e8369f37aca520f88aaa20784443176706bbfa688da434f4f3ba28fea8953460a092914b7fa0ca4380a9d07e16df5205258b7de
7
+ data.tar.gz: 4c40141f885ee40dd9da1e67432ba2a7a80cf5d59b2847cf4b487df4682baffc224f7b61d58b5a0b5f51aeeb684b6bf8ae501b9616e124dcaa77828761e8034a
@@ -31,6 +31,13 @@ module Zugpferd
31
31
  SETTLEMENT = "#{TRANSACTION}/ram:ApplicableHeaderTradeSettlement"
32
32
  AGREEMENT = "#{TRANSACTION}/ram:ApplicableHeaderTradeAgreement"
33
33
 
34
+ # Invoicing period (BG-14)
35
+ BILLING_PERIOD = "ram:BillingSpecifiedPeriod"
36
+ BILLING_PERIOD_FIELDS = {
37
+ start_date: "ram:StartDateTime/udt:DateTimeString",
38
+ end_date: "ram:EndDateTime/udt:DateTimeString",
39
+ }.freeze
40
+
34
41
  INVOICE_SETTLEMENT = {
35
42
  currency_code: "#{SETTLEMENT}/ram:InvoiceCurrencyCode",
36
43
  buyer_reference: "#{AGREEMENT}/ram:BuyerReference",
@@ -132,6 +139,13 @@ module Zugpferd
132
139
  line_extension_amount: "ram:SpecifiedLineTradeSettlement/ram:SpecifiedTradeSettlementLineMonetarySummation/ram:LineTotalAmount",
133
140
  }.freeze
134
141
 
142
+ # Invoice line period (BG-26)
143
+ LINE_PERIOD = "ram:SpecifiedLineTradeSettlement/ram:BillingSpecifiedPeriod"
144
+ LINE_PERIOD_FIELDS = {
145
+ start_date: "ram:StartDateTime/udt:DateTimeString",
146
+ end_date: "ram:EndDateTime/udt:DateTimeString",
147
+ }.freeze
148
+
135
149
  # Item (BG-31)
136
150
  ITEM = "ram:SpecifiedTradeProduct"
137
151
  ITEM_FIELDS = {
@@ -36,6 +36,7 @@ module Zugpferd
36
36
  def build_invoice(root)
37
37
  settlement = root.at_xpath(SETTLEMENT, NS)
38
38
  delivery = root.at_xpath(DELIVERY, NS)
39
+ period = settlement&.at_xpath(BILLING_PERIOD, NS)
39
40
  type_code = text(root, INVOICE[:type_code])
40
41
  model_class = TYPE_CODE_MAP.fetch(type_code, Model::Invoice)
41
42
 
@@ -44,6 +45,8 @@ module Zugpferd
44
45
  issue_date: parse_cii_date(text(root, INVOICE[:issue_date])),
45
46
  due_date: parse_cii_date(settlement ? text(settlement, PAYMENT_TERMS_DUE_DATE) : nil),
46
47
  delivery_date: parse_cii_date(delivery ? text(delivery, DELIVERY_DATE) : nil),
48
+ invoicing_period_start_date: parse_cii_date(period ? text(period, BILLING_PERIOD_FIELDS[:start_date]) : nil),
49
+ invoicing_period_end_date: parse_cii_date(period ? text(period, BILLING_PERIOD_FIELDS[:end_date]) : nil),
47
50
  type_code: text(root, INVOICE[:type_code]),
48
51
  currency_code: text(root, INVOICE_SETTLEMENT[:currency_code]),
49
52
  buyer_reference: text(root, INVOICE_SETTLEMENT[:buyer_reference]),
@@ -167,6 +170,7 @@ module Zugpferd
167
170
  item_node = node.at_xpath(ITEM, NS)
168
171
  price_node = node.at_xpath(PRICE, NS)
169
172
  tax_node = node.at_xpath(ITEM_TAX, NS)
173
+ period_node = node.at_xpath(LINE_PERIOD, NS)
170
174
 
171
175
  Model::LineItem.new(
172
176
  id: text(node, LINE[:id]),
@@ -174,6 +178,8 @@ module Zugpferd
174
178
  unit_code: node.at_xpath(LINE[:unit_code], NS)&.text,
175
179
  line_extension_amount: text(node, LINE[:line_extension_amount]),
176
180
  note: text(node, LINE[:note]),
181
+ period_start_date: parse_cii_date(period_node ? text(period_node, LINE_PERIOD_FIELDS[:start_date]) : nil),
182
+ period_end_date: parse_cii_date(period_node ? text(period_node, LINE_PERIOD_FIELDS[:end_date]) : nil),
177
183
  item: build_item(item_node, tax_node),
178
184
  price: build_price(price_node),
179
185
  )
@@ -173,6 +173,8 @@ module Zugpferd
173
173
  end
174
174
  end
175
175
 
176
+ build_billing_period(xml, doc) if doc.invoicing_period_start_date || doc.invoicing_period_end_date
177
+
176
178
  doc.allowance_charges.each { |ac| build_allowance_charge(xml, ac) }
177
179
 
178
180
  if doc.payment_instructions&.note || doc.due_date || doc.payment_instructions&.mandate_reference
@@ -191,6 +193,21 @@ module Zugpferd
191
193
  end
192
194
  end
193
195
 
196
+ def build_billing_period(xml, doc)
197
+ xml["ram"].BillingSpecifiedPeriod do
198
+ if doc.invoicing_period_start_date
199
+ xml["ram"].StartDateTime do
200
+ xml["udt"].DateTimeString(format_cii_date(doc.invoicing_period_start_date), format: "102")
201
+ end
202
+ end
203
+ if doc.invoicing_period_end_date
204
+ xml["ram"].EndDateTime do
205
+ xml["udt"].DateTimeString(format_cii_date(doc.invoicing_period_end_date), format: "102")
206
+ end
207
+ end
208
+ end
209
+ end
210
+
194
211
  def build_payment_means(xml, payment)
195
212
  xml["ram"].SpecifiedTradeSettlementPaymentMeans do
196
213
  xml["ram"].TypeCode payment.payment_means_code
@@ -297,6 +314,8 @@ module Zugpferd
297
314
  end
298
315
  end
299
316
 
317
+ build_line_period(xml, line) if line.period_start_date || line.period_end_date
318
+
300
319
  xml["ram"].SpecifiedTradeSettlementLineMonetarySummation do
301
320
  xml["ram"].LineTotalAmount format_decimal(line.line_extension_amount)
302
321
  end
@@ -304,6 +323,21 @@ module Zugpferd
304
323
  end
305
324
  end
306
325
 
326
+ def build_line_period(xml, line)
327
+ xml["ram"].BillingSpecifiedPeriod do
328
+ if line.period_start_date
329
+ xml["ram"].StartDateTime do
330
+ xml["udt"].DateTimeString(format_cii_date(line.period_start_date), format: "102")
331
+ end
332
+ end
333
+ if line.period_end_date
334
+ xml["ram"].EndDateTime do
335
+ xml["udt"].DateTimeString(format_cii_date(line.period_end_date), format: "102")
336
+ end
337
+ end
338
+ end
339
+ end
340
+
307
341
  def build_item(xml, item)
308
342
  xml["ram"].SpecifiedTradeProduct do
309
343
  xml["ram"].SellerAssignedID item.sellers_identifier if item.sellers_identifier
@@ -19,6 +19,8 @@ module Zugpferd
19
19
  # @return [String] BT-3 Invoice type code
20
20
  # @return [String] BT-5 Document currency code (default: "EUR")
21
21
  # @return [Date, nil] BT-72 Actual delivery date
22
+ # @return [Date, nil] BT-73 Invoicing period start date
23
+ # @return [Date, nil] BT-74 Invoicing period end date
22
24
  # @return [String, nil] BT-10 Buyer reference
23
25
  # @return [String, nil] BT-24 Specification identifier
24
26
  # @return [String, nil] BT-23 Business process type
@@ -31,8 +33,9 @@ module Zugpferd
31
33
  # @return [PaymentInstructions, nil] BG-16 Payment information
32
34
  # @return [Array<AllowanceCharge>] BG-20/BG-21 Document-level allowances and charges
33
35
  attr_accessor :number, :issue_date, :due_date, :type_code,
34
- :currency_code, :delivery_date, :buyer_reference,
35
- :customization_id, :profile_id, :note, :seller, :buyer,
36
+ :currency_code, :delivery_date,
37
+ :invoicing_period_start_date, :invoicing_period_end_date,
38
+ :buyer_reference, :customization_id, :profile_id, :note, :seller, :buyer,
36
39
  :line_items, :tax_breakdown, :monetary_totals,
37
40
  :payment_instructions, :allowance_charges
38
41
 
@@ -9,10 +9,13 @@ module Zugpferd
9
9
  # @return [String] BT-130 Unit of measure code
10
10
  # @return [BigDecimal] BT-131 Line extension amount
11
11
  # @return [String, nil] BT-127 Invoice line note
12
+ # @return [Date, nil] BT-134 Invoice line period start date
13
+ # @return [Date, nil] BT-135 Invoice line period end date
12
14
  # @return [Item, nil] BG-31 Item information
13
15
  # @return [Price, nil] BG-29 Price details
14
16
  attr_accessor :id, :invoiced_quantity, :unit_code,
15
- :line_extension_amount, :note, :item, :price
17
+ :line_extension_amount, :note, :period_start_date,
18
+ :period_end_date, :item, :price
16
19
 
17
20
  # @param id [String] BT-126 Line identifier
18
21
  # @param invoiced_quantity [String, BigDecimal] BT-129 Quantity
@@ -30,6 +30,13 @@ module Zugpferd
30
30
  DELIVERY = "cac:Delivery"
31
31
  DELIVERY_DATE = "cbc:ActualDeliveryDate"
32
32
 
33
+ # Invoicing period (BG-14)
34
+ INVOICE_PERIOD = "cac:InvoicePeriod"
35
+ INVOICE_PERIOD_FIELDS = {
36
+ start_date: "cbc:StartDate",
37
+ end_date: "cbc:EndDate",
38
+ }.freeze
39
+
33
40
  # Seller (BG-4)
34
41
  SELLER = "cac:AccountingSupplierParty/cac:Party"
35
42
  # Buyer (BG-7)
@@ -125,6 +132,13 @@ module Zugpferd
125
132
  note: "cbc:Note",
126
133
  }.freeze
127
134
 
135
+ # Invoice line period (BG-26)
136
+ LINE_PERIOD = "cac:InvoicePeriod"
137
+ LINE_PERIOD_FIELDS = {
138
+ start_date: "cbc:StartDate",
139
+ end_date: "cbc:EndDate",
140
+ }.freeze
141
+
128
142
  # Item (BG-31)
129
143
  ITEM = "cac:Item"
130
144
  ITEM_FIELDS = {
@@ -34,12 +34,15 @@ module Zugpferd
34
34
  model_class = @credit_note ? Model::CreditNote : Model::Invoice
35
35
 
36
36
  delivery_node = root.at_xpath(DELIVERY, @ns)
37
+ period_node = root.at_xpath(INVOICE_PERIOD, @ns)
37
38
 
38
39
  model_class.new(
39
40
  number: text(root, INVOICE[:number]),
40
41
  issue_date: parse_date(text(root, INVOICE[:issue_date])),
41
42
  due_date: parse_date(text(root, INVOICE[:due_date])),
42
43
  delivery_date: delivery_node ? parse_date(text(delivery_node, DELIVERY_DATE)) : nil,
44
+ invoicing_period_start_date: period_node ? parse_date(text(period_node, INVOICE_PERIOD_FIELDS[:start_date])) : nil,
45
+ invoicing_period_end_date: period_node ? parse_date(text(period_node, INVOICE_PERIOD_FIELDS[:end_date])) : nil,
43
46
  type_code: text(root, type_code_element),
44
47
  currency_code: text(root, INVOICE[:currency_code]),
45
48
  buyer_reference: text(root, INVOICE[:buyer_reference]),
@@ -165,6 +168,7 @@ module Zugpferd
165
168
  def build_line_item(node)
166
169
  item_node = node.at_xpath(ITEM, @ns)
167
170
  price_node = node.at_xpath(PRICE, @ns)
171
+ period_node = node.at_xpath(LINE_PERIOD, @ns)
168
172
 
169
173
  quantity_element = @credit_note ? "cbc:CreditedQuantity" : LINE[:invoiced_quantity]
170
174
  unit_code_element = @credit_note ? "cbc:CreditedQuantity/@unitCode" : LINE[:unit_code]
@@ -175,6 +179,8 @@ module Zugpferd
175
179
  unit_code: node.at_xpath(unit_code_element, @ns)&.text,
176
180
  line_extension_amount: text(node, LINE[:line_extension_amount]),
177
181
  note: text(node, LINE[:note]),
182
+ period_start_date: period_node ? parse_date(text(period_node, LINE_PERIOD_FIELDS[:start_date])) : nil,
183
+ period_end_date: period_node ? parse_date(text(period_node, LINE_PERIOD_FIELDS[:end_date])) : nil,
178
184
  item: build_item(item_node),
179
185
  price: build_price(price_node),
180
186
  )
@@ -50,6 +50,7 @@ module Zugpferd
50
50
  xml["cbc"].Note doc.note if doc.note
51
51
  xml["cbc"].DocumentCurrencyCode doc.currency_code
52
52
  xml["cbc"].BuyerReference doc.buyer_reference if doc.buyer_reference
53
+ build_invoice_period(xml, doc) if doc.invoicing_period_start_date || doc.invoicing_period_end_date
53
54
 
54
55
  build_supplier(xml, doc.seller, doc.payment_instructions) if doc.seller
55
56
  build_customer(xml, doc.buyer) if doc.buyer
@@ -141,6 +142,13 @@ module Zugpferd
141
142
  end
142
143
  end
143
144
 
145
+ def build_invoice_period(xml, doc)
146
+ xml["cac"].InvoicePeriod do
147
+ xml["cbc"].StartDate doc.invoicing_period_start_date.to_s if doc.invoicing_period_start_date
148
+ xml["cbc"].EndDate doc.invoicing_period_end_date.to_s if doc.invoicing_period_end_date
149
+ end
150
+ end
151
+
144
152
  def build_delivery(xml, doc)
145
153
  xml["cac"].Delivery do
146
154
  xml["cbc"].ActualDeliveryDate doc.delivery_date.to_s
@@ -266,11 +274,19 @@ module Zugpferd
266
274
  unitCode: line.unit_code)
267
275
  xml["cbc"].LineExtensionAmount(format_decimal(line.line_extension_amount),
268
276
  currencyID: currency_code)
277
+ build_line_period(xml, line) if line.period_start_date || line.period_end_date
269
278
  build_item(xml, line.item) if line.item
270
279
  build_price(xml, line.price, currency_code) if line.price
271
280
  end
272
281
  end
273
282
 
283
+ def build_line_period(xml, line)
284
+ xml["cac"].InvoicePeriod do
285
+ xml["cbc"].StartDate line.period_start_date.to_s if line.period_start_date
286
+ xml["cbc"].EndDate line.period_end_date.to_s if line.period_end_date
287
+ end
288
+ end
289
+
274
290
  def build_item(xml, item)
275
291
  xml["cac"].Item do
276
292
  xml["cbc"].Description item.description if item.description
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zugpferd
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.5
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexander Zeitler
@@ -27,14 +27,14 @@ dependencies:
27
27
  name: bigdecimal
28
28
  requirement: !ruby/object:Gem::Requirement
29
29
  requirements:
30
- - - "~>"
30
+ - - ">="
31
31
  - !ruby/object:Gem::Version
32
32
  version: '3.1'
33
33
  type: :runtime
34
34
  prerelease: false
35
35
  version_requirements: !ruby/object:Gem::Requirement
36
36
  requirements:
37
- - - "~>"
37
+ - - ">="
38
38
  - !ruby/object:Gem::Version
39
39
  version: '3.1'
40
40
  - !ruby/object:Gem::Dependency