einvoicing 0.9.3 → 0.9.4

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: 96c1b67f435b7ca99b2716f4aba9c8dcf631302d37db1a6fa3743d993de55334
4
- data.tar.gz: 0c5713cbce3d1e842b64c3361957eb2764dadd89eefd5fb361816bfbd786aa3b
3
+ metadata.gz: fc2a751c2f036e54a39379c34fa55833b7477afd9d71a339e76510fd14c90e55
4
+ data.tar.gz: 28856f26011c6ea745c326c47acd1569f77f6136f781cd995878e4be07161900
5
5
  SHA512:
6
- metadata.gz: 9c4b6d6c1907118f2743887788ac55a6b3bade8268e7ddb8ed6a78afcb735bc7581f249166501428216af1ae0ce883a6fef338c1d6eb45f473089b7f02a07924
7
- data.tar.gz: 9c4e9728880210475896ce42280595b5eecf26514dffcbc58198d97f2f0e9dee749ab3dae3b38db7780f3ec79ae8604d93c738959f6cccfd4f7961cbfb300770
6
+ metadata.gz: '059831c778c6060e163eee70a8e5e50e937851ee3ba285ed65e438c1bd26084e615e1de16733a07f4469c8f1a8536ad589654c89fb5a0ea1f2139c367153b1bd'
7
+ data.tar.gz: 2a40cf9b2a8c3ca3f6316cf687d9df8ba7888519cfa998c0565afb67705e7bdc99de782af6d8900a918e8b4e26a442d35132820e5d33bf44a8c9a9ca9f2c2df9
data/CHANGELOG.md CHANGED
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.9.4] - 2026-10-14
9
+
10
+ ### Fixed
11
+ - Unit prices kept only two decimals. The item net price (BT-146) went out through the same `%.2f` as every amount, so a line of 1 512 000 eggs at 0.0095 € said `0.01` in `ram:ChargeAmount` (CII) and `cbc:PriceAmount` (UBL) while its line total said 14 364.00 €: 756 € off, and the Peppol rule PEPPOL-EN16931-R120 rejects the UBL. EN 16931 holds amounts to two decimals but sets no such limit on prices: a price now keeps every decimal it carries and never shows fewer than two (`0.0095`, `14.00`, `14.50`). Every amount stays at two decimals
12
+ - Quantities (BT-129) went through `Float` and four decimals, so `8.915839` came out as `8.9158` while the line total used the real quantity. They are now written from the `BigDecimal` with every decimal (`5`, `2.5`, `8.915839`)
13
+
8
14
  ## [0.9.3] - 2026-08-31
9
15
 
10
16
  ### Fixed
@@ -93,7 +93,7 @@ module Einvoicing
93
93
  end
94
94
  b.tag("ram:SpecifiedLineTradeAgreement") do
95
95
  b.tag("ram:NetPriceProductTradePrice") do
96
- b.text("ram:ChargeAmount", format_amount(line.unit_price))
96
+ b.text("ram:ChargeAmount", format_price(line.unit_price))
97
97
  end
98
98
  end
99
99
  b.tag("ram:SpecifiedLineTradeDelivery") do
@@ -299,9 +299,20 @@ module Einvoicing
299
299
  end
300
300
  private_class_method :format_amount
301
301
 
302
+ # Unit prices (BT-146) are not amounts: EN 16931 holds amounts to two
303
+ # decimals but sets no such limit on prices, and a sub-cent price written
304
+ # as 0.01 contradicts its own line total. Keep every decimal the price
305
+ # carries, never write fewer than two.
306
+ def self.format_price(value)
307
+ whole, fraction = BigDecimal(value.to_s).to_s("F").split(".")
308
+ "#{whole}.#{fraction.ljust(2, "0")}"
309
+ end
310
+ private_class_method :format_price
311
+
312
+ # Every decimal of the quantity (BT-129), like the price: the line total
313
+ # is computed from both, and must stay their product once serialized.
302
314
  def self.format_quantity(value)
303
- v = value.to_f
304
- v % 1 == 0 ? v.to_i.to_s : format("%.4f", v)
315
+ BigDecimal(value.to_s).to_s("F").delete_suffix(".0")
305
316
  end
306
317
  private_class_method :format_quantity
307
318
  end
@@ -229,7 +229,7 @@ module Einvoicing
229
229
  end
230
230
  end
231
231
  b.tag("cac:Price") do
232
- b.text("cbc:PriceAmount", format_amount(line.unit_price),
232
+ b.text("cbc:PriceAmount", format_price(line.unit_price),
233
233
  "currencyID" => currency)
234
234
  end
235
235
  end
@@ -276,9 +276,20 @@ module Einvoicing
276
276
  end
277
277
  private_class_method :format_amount
278
278
 
279
+ # Unit prices (BT-146) are not amounts: EN 16931 holds amounts to two
280
+ # decimals but sets no such limit on prices, and a sub-cent price written
281
+ # as 0.01 contradicts its own line total. Keep every decimal the price
282
+ # carries, never write fewer than two.
283
+ def self.format_price(value)
284
+ whole, fraction = BigDecimal(value.to_s).to_s("F").split(".")
285
+ "#{whole}.#{fraction.ljust(2, "0")}"
286
+ end
287
+ private_class_method :format_price
288
+
289
+ # Every decimal of the quantity (BT-129), like the price: the line total
290
+ # is computed from both, and must stay their product once serialized.
279
291
  def self.format_quantity(value)
280
- v = value.to_f
281
- v % 1 == 0 ? v.to_i.to_s : format("%.4f", v)
292
+ BigDecimal(value.to_s).to_s("F").delete_suffix(".0")
282
293
  end
283
294
  private_class_method :format_quantity
284
295
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Einvoicing
4
- VERSION = "0.9.3"
4
+ VERSION = "0.9.4"
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.9.3
4
+ version: 0.9.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathan Le Ray
@@ -257,7 +257,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
257
257
  - !ruby/object:Gem::Version
258
258
  version: '0'
259
259
  requirements: []
260
- rubygems_version: 4.0.19
260
+ rubygems_version: 4.0.23
261
261
  specification_version: 4
262
262
  summary: EU electronic invoicing for Ruby — EN 16931, Factur-X, UBL 2.1
263
263
  test_files: []