einvoicing 0.7.0 → 0.7.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7581f06decdc863a7f8c7509a3ff696f73ca8d223579aa4695a3eee160f3e196
4
- data.tar.gz: 1355d8b9034f874d7f3bd7c38315428c90477c6f987ef9642e0deca071f17587
3
+ metadata.gz: a27d36b05ee79942e8828c53055b9b3088bec50a526d1277dff05aa7b447e405
4
+ data.tar.gz: bf8f072d6f8a3e15b5f74c06117f3e8def1fd1eb81173dcb2edcaf1bced32f02
5
5
  SHA512:
6
- metadata.gz: '0146294e7c5ea5515211eabf88d54dde12525052409b69a29aa4206df02762622a96b92bfd2c9e5afef820a50b4c34d939ba2e52baa4c217adf843b324bb90b6'
7
- data.tar.gz: 19dac11dd07c6dafb9856fe0878201de2ddc259678bbddef425107413a2d4649058568d6fdae988002df71223b4165b1aee38d3692bf4f7ec390a874b61a8b45
6
+ metadata.gz: 235d066a6f7d45ed40d10cbd871a560008a33e3bd5c2791e66bafd5f5649a62da0c84f31b7df854e06bf78e8c9514f948f23c88a5043f27bc8ed7f36b46ca11e
7
+ data.tar.gz: 357abed47d361906c413171f66ba6d66963b275e4149d141d94886822dca14958ca75d0e164ed3d523b293482454ad3baee49347702aec29b8e00bb97d78099f
data/CHANGELOG.md CHANGED
@@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.7.1] - 2026-07-16
11
+
12
+ ### Fixed
13
+ - CII credit notes now emit the preceding invoice number (BT-25) and optional issue date (BT-26) as a machine-readable EN 16931 BG-3 reference while retaining the legacy human-readable note when no explicit invoice note is provided
14
+
10
15
  ## [0.7.0] - 2026-07-14
11
16
 
12
17
  ### Added
@@ -91,5 +96,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
91
96
  - Zero runtime dependencies beyond hexapdf (stdlib-only XML generation via internal builder)
92
97
  - RSpec test suite
93
98
 
94
- [Unreleased]: https://github.com/sxnlabs/einvoicing/compare/v0.1.0...HEAD
99
+ [Unreleased]: https://github.com/sxnlabs/einvoicing/compare/v0.7.1...HEAD
100
+ [0.7.1]: https://github.com/sxnlabs/einvoicing/compare/v0.7.0...v0.7.1
95
101
  [0.1.0]: https://github.com/sxnlabs/einvoicing/releases/tag/v0.1.0
@@ -51,22 +51,26 @@ module Einvoicing
51
51
  b.tag("ram:IssueDateTime") do
52
52
  b.text("udt:DateTimeString", format_date(invoice.issue_date), "format" => "102")
53
53
  end
54
- if invoice.document_type == :credit_note && invoice.original_invoice_number
54
+ if (note = document_note(invoice))
55
55
  b.tag("ram:IncludedNote") do
56
- note = "Credit note for invoice #{invoice.original_invoice_number}"
57
- note += " dated #{invoice.original_invoice_date.strftime('%d/%m/%Y')}" if invoice.original_invoice_date
58
56
  b.text("ram:Content", note)
59
57
  end
60
58
  end
61
- if invoice.note
62
- b.tag("ram:IncludedNote") do
63
- b.text("ram:Content", invoice.note)
64
- end
65
- end
66
59
  end
67
60
  end
68
61
  private_class_method :exchanged_document
69
62
 
63
+ def self.document_note(invoice)
64
+ return invoice.note unless invoice.note.to_s.strip.empty?
65
+ return unless invoice.document_type == :credit_note
66
+ return if invoice.original_invoice_number.to_s.strip.empty?
67
+
68
+ note = "Credit note for invoice #{invoice.original_invoice_number}"
69
+ note += " dated #{format_display_date(invoice.original_invoice_date)}" if invoice.original_invoice_date
70
+ note
71
+ end
72
+ private_class_method :document_note
73
+
70
74
  def self.supply_chain_trade_transaction(b, invoice, profile)
71
75
  b.tag("rsm:SupplyChainTradeTransaction") do
72
76
  invoice.lines.each_with_index do |line, idx|
@@ -195,10 +199,25 @@ module Einvoicing
195
199
  b.text("ram:TotalPrepaidAmount", format_amount(invoice.prepaid_amount)) if invoice.prepaid_amount.positive?
196
200
  b.text("ram:DuePayableAmount", format_amount(invoice.due_amount))
197
201
  end
202
+
203
+ preceding_invoice_reference(b, invoice) if invoice.document_type == :credit_note &&
204
+ invoice.original_invoice_number
198
205
  end
199
206
  end
200
207
  private_class_method :header_trade_settlement
201
208
 
209
+ def self.preceding_invoice_reference(b, invoice)
210
+ b.tag("ram:InvoiceReferencedDocument") do
211
+ b.text("ram:IssuerAssignedID", invoice.original_invoice_number)
212
+ if invoice.original_invoice_date
213
+ b.tag("ram:FormattedIssueDateTime") do
214
+ b.text("qdt:DateTimeString", format_date(invoice.original_invoice_date), "format" => "102")
215
+ end
216
+ end
217
+ end
218
+ end
219
+ private_class_method :preceding_invoice_reference
220
+
202
221
  # Format a Date or string as YYYYMMDD (CII date format 102).
203
222
  def self.format_date(date)
204
223
  d = date.is_a?(Date) ? date : Date.parse(date.to_s)
@@ -206,6 +225,12 @@ module Einvoicing
206
225
  end
207
226
  private_class_method :format_date
208
227
 
228
+ def self.format_display_date(date)
229
+ d = date.is_a?(Date) ? date : Date.parse(date.to_s)
230
+ d.strftime("%d/%m/%Y")
231
+ end
232
+ private_class_method :format_display_date
233
+
209
234
  def self.format_amount(value)
210
235
  format("%.2f", value)
211
236
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Einvoicing
4
- VERSION = "0.7.0"
4
+ VERSION = "0.7.1"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: einvoicing
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.7.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathan Le Ray