einvoicing 0.9.2 → 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 +4 -4
- data/CHANGELOG.md +10 -1
- data/lib/einvoicing/formats/cii.rb +14 -3
- data/lib/einvoicing/formats/ubl.rb +14 -3
- data/lib/einvoicing/version.rb +1 -1
- metadata +53 -11
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fc2a751c2f036e54a39379c34fa55833b7477afd9d71a339e76510fd14c90e55
|
|
4
|
+
data.tar.gz: 28856f26011c6ea745c326c47acd1569f77f6136f781cd995878e4be07161900
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: '059831c778c6060e163eee70a8e5e50e937851ee3ba285ed65e438c1bd26084e615e1de16733a07f4469c8f1a8536ad589654c89fb5a0ea1f2139c367153b1bd'
|
|
7
|
+
data.tar.gz: 2a40cf9b2a8c3ca3f6316cf687d9df8ba7888519cfa998c0565afb67705e7bdc99de782af6d8900a918e8b4e26a442d35132820e5d33bf44a8c9a9ca9f2c2df9
|
data/CHANGELOG.md
CHANGED
|
@@ -5,7 +5,16 @@ 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
|
-
## [
|
|
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
|
+
|
|
14
|
+
## [0.9.3] - 2026-08-31
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
- Declare `bigdecimal` and `rexml` as runtime dependencies. Both are required from `lib/` but neither was declared, so `require "einvoicing"` raised `LoadError: cannot load such file -- bigdecimal` in any consumer bundle that did not carry them, and Peppol validation failed on `rexml/document`. `rexml` is floored at 3.3.6, the release that fixed its parsing DoS.
|
|
9
18
|
|
|
10
19
|
## [0.9.2] - 2026-08-06
|
|
11
20
|
|
|
@@ -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",
|
|
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
|
-
|
|
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",
|
|
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
|
-
|
|
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
|
data/lib/einvoicing/version.rb
CHANGED
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.
|
|
4
|
+
version: 0.9.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Nathan Le Ray
|
|
@@ -37,6 +37,34 @@ dependencies:
|
|
|
37
37
|
- - "~>"
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
39
|
version: '1.0'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: bigdecimal
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - ">="
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '0'
|
|
47
|
+
type: :runtime
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - ">="
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '0'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: rexml
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - ">="
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: 3.3.6
|
|
61
|
+
type: :runtime
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - ">="
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: 3.3.6
|
|
40
68
|
- !ruby/object:Gem::Dependency
|
|
41
69
|
name: rspec
|
|
42
70
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -108,7 +136,7 @@ dependencies:
|
|
|
108
136
|
- !ruby/object:Gem::Version
|
|
109
137
|
version: '1.16'
|
|
110
138
|
- !ruby/object:Gem::Dependency
|
|
111
|
-
name:
|
|
139
|
+
name: prawn
|
|
112
140
|
requirement: !ruby/object:Gem::Requirement
|
|
113
141
|
requirements:
|
|
114
142
|
- - ">="
|
|
@@ -122,33 +150,47 @@ dependencies:
|
|
|
122
150
|
- !ruby/object:Gem::Version
|
|
123
151
|
version: '0'
|
|
124
152
|
- !ruby/object:Gem::Dependency
|
|
125
|
-
name:
|
|
153
|
+
name: webmock
|
|
126
154
|
requirement: !ruby/object:Gem::Requirement
|
|
127
155
|
requirements:
|
|
128
|
-
- - "
|
|
156
|
+
- - "~>"
|
|
129
157
|
- !ruby/object:Gem::Version
|
|
130
|
-
version: '0'
|
|
158
|
+
version: '3.0'
|
|
131
159
|
type: :development
|
|
132
160
|
prerelease: false
|
|
133
161
|
version_requirements: !ruby/object:Gem::Requirement
|
|
134
162
|
requirements:
|
|
135
|
-
- - "
|
|
163
|
+
- - "~>"
|
|
136
164
|
- !ruby/object:Gem::Version
|
|
137
|
-
version: '0'
|
|
165
|
+
version: '3.0'
|
|
138
166
|
- !ruby/object:Gem::Dependency
|
|
139
|
-
name:
|
|
167
|
+
name: simplecov
|
|
140
168
|
requirement: !ruby/object:Gem::Requirement
|
|
141
169
|
requirements:
|
|
142
170
|
- - "~>"
|
|
143
171
|
- !ruby/object:Gem::Version
|
|
144
|
-
version: '
|
|
172
|
+
version: '0.22'
|
|
145
173
|
type: :development
|
|
146
174
|
prerelease: false
|
|
147
175
|
version_requirements: !ruby/object:Gem::Requirement
|
|
148
176
|
requirements:
|
|
149
177
|
- - "~>"
|
|
150
178
|
- !ruby/object:Gem::Version
|
|
151
|
-
version: '
|
|
179
|
+
version: '0.22'
|
|
180
|
+
- !ruby/object:Gem::Dependency
|
|
181
|
+
name: bundler-audit
|
|
182
|
+
requirement: !ruby/object:Gem::Requirement
|
|
183
|
+
requirements:
|
|
184
|
+
- - "~>"
|
|
185
|
+
- !ruby/object:Gem::Version
|
|
186
|
+
version: '0.9'
|
|
187
|
+
type: :development
|
|
188
|
+
prerelease: false
|
|
189
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
190
|
+
requirements:
|
|
191
|
+
- - "~>"
|
|
192
|
+
- !ruby/object:Gem::Version
|
|
193
|
+
version: '0.9'
|
|
152
194
|
description: |
|
|
153
195
|
EN 16931-compliant e-invoicing for Ruby. Generates Factur-X (PDF/A-3 + CII XML),
|
|
154
196
|
UBL 2.1, and CII D16B. Validates French B2B requirements (SIREN, SIRET, TVA).
|
|
@@ -215,7 +257,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
215
257
|
- !ruby/object:Gem::Version
|
|
216
258
|
version: '0'
|
|
217
259
|
requirements: []
|
|
218
|
-
rubygems_version: 4.0.
|
|
260
|
+
rubygems_version: 4.0.23
|
|
219
261
|
specification_version: 4
|
|
220
262
|
summary: EU electronic invoicing for Ruby — EN 16931, Factur-X, UBL 2.1
|
|
221
263
|
test_files: []
|