einvoicing 0.6.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: 24047fa12d3baaca75ebea76468a98ee023e5716bdee7dfa90f7f532e13ab5d1
4
- data.tar.gz: 934ca40e5c588c9593d39b839e13eabd413b34b3f36f56d5481e99dddb5a1b69
3
+ metadata.gz: a27d36b05ee79942e8828c53055b9b3088bec50a526d1277dff05aa7b447e405
4
+ data.tar.gz: bf8f072d6f8a3e15b5f74c06117f3e8def1fd1eb81173dcb2edcaf1bced32f02
5
5
  SHA512:
6
- metadata.gz: 54accf1d18eb7e32a35aba28d1c5c9f362eb1de5f19025b89c784724285ce59535394c603b9272a678a8bda7b1b13ae6f6a4dfca949528a303cf41a070681c43
7
- data.tar.gz: 2eebc04105e663f581c83c6e81523aceba000188f0fc4b00c15138094d7659008bf59ce98b7afa5f867d875e307b806dbbea5281824d7d8c3eb11659976f7e86
6
+ metadata.gz: 235d066a6f7d45ed40d10cbd871a560008a33e3bd5c2791e66bafd5f5649a62da0c84f31b7df854e06bf78e8c9514f948f23c88a5043f27bc8ed7f36b46ca11e
7
+ data.tar.gz: 357abed47d361906c413171f66ba6d66963b275e4149d141d94886822dca14958ca75d0e164ed3d523b293482454ad3baee49347702aec29b8e00bb97d78099f
data/CHANGELOG.md CHANGED
@@ -5,6 +5,29 @@ 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
+ ## [Unreleased]
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
+
15
+ ## [0.7.0] - 2026-07-14
16
+
17
+ ### Added
18
+ - `prepaid_amount` on `Invoice` (BT-113 `TotalPrepaidAmount` in CII / `PrepaidAmount` in UBL) so a retained/prepaid amount (e.g. retenue de garantie) reduces the amount due (BR-CO-16: `DuePayableAmount = GrandTotal − TotalPrepaidAmount`) without affecting the taxable base or VAT totals
19
+ - CII profile support: `:chorus_pro` and `:en16931` selectable per invoice
20
+
21
+ ### Fixed
22
+ - CII `schemeID` SIRET correctly emitted for Chorus Pro
23
+ - `PaymentMeans` is now required when generating CII/UBL
24
+
25
+ ## [0.6.0] - 2026-03-14
26
+
27
+ ### Changed
28
+ - Codebase aligned on `rubocop-rails-omakase` standards
29
+ - Locale strings extracted into `config/locales/*.yml` (English + French)
30
+
8
31
  ## [0.5.0] - 2026-03-14
9
32
 
10
33
  ### Fixed
@@ -73,5 +96,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
73
96
  - Zero runtime dependencies beyond hexapdf (stdlib-only XML generation via internal builder)
74
97
  - RSpec test suite
75
98
 
76
- [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
77
101
  [0.1.0]: https://github.com/sxnlabs/einvoicing/releases/tag/v0.1.0
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 SXN Labs
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 all
13
+ 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 THE
21
+ SOFTWARE.
data/README.md CHANGED
@@ -55,7 +55,7 @@ seller = Einvoicing::Party.new(
55
55
 
56
56
  buyer = Einvoicing::Party.new(
57
57
  name: "Gecobat",
58
- street: "12 rue du Bâtiment",
58
+ street: "12 Construction Street",
59
59
  city: "Paris",
60
60
  postal_code: "75001",
61
61
  country_code: "FR",
@@ -65,13 +65,13 @@ buyer = Einvoicing::Party.new(
65
65
 
66
66
  lines = [
67
67
  Einvoicing::LineItem.new(
68
- description: "Développement backend — API REST (forfait)",
68
+ description: "Backend developmentREST API (fixed fee)",
69
69
  quantity: 1,
70
70
  unit_price: BigDecimal("2500.00"),
71
71
  vat_rate: 0.20
72
72
  ),
73
73
  Einvoicing::LineItem.new(
74
- description: "Intégration Factur-X",
74
+ description: "Factur-X integration",
75
75
  quantity: 5,
76
76
  unit_price: BigDecimal("350.00"),
77
77
  vat_rate: 0.20
@@ -86,7 +86,7 @@ invoice = Einvoicing::Invoice.new(
86
86
  buyer: buyer,
87
87
  lines: lines,
88
88
  payment_reference: "FAC-2024-0042",
89
- note: "30 jours net",
89
+ note: "Net 30",
90
90
  payment_means_code: 30,
91
91
  iban: "FR7630006000011234567890189",
92
92
  bic: "BNPAFRPP"
@@ -175,6 +175,20 @@ ubl = Einvoicing::Formats::UBL.generate(invoice)
175
175
 
176
176
  Produces a UBL 2.1 `Invoice` document with Peppol BIS Billing 3.0 customization ID.
177
177
 
178
+ ## Chorus Pro / PPF (France)
179
+
180
+ When submitting to Chorus Pro (French B2G portal), generate CII XML with the `:chorus_pro` profile:
181
+
182
+ ```ruby
183
+ xml = Einvoicing.xml(invoice, format: :cii, profile: :chorus_pro)
184
+ ```
185
+
186
+ Chorus Pro-specific requirements:
187
+ - `schemeID` for SIRET identifiers must be `"SIRET"` (not the ISO 6523 code `"0002"`)
188
+ - `SpecifiedTradeSettlementPaymentMeans` is mandatory — set `payment_means_code:` on the invoice (30 = credit transfer)
189
+ - Invoice ID (`invoice_number`) must not exceed 20 characters
190
+ - Use `einvoicing-connect` for the actual API submission
191
+
178
192
  ## Rails Integration
179
193
 
180
194
  Include `Einvoicing::Invoiceable` in your ActiveRecord model and implement three methods:
@@ -10,6 +10,8 @@ en:
10
10
  original_invoice_number_missing: "Original invoice number is required for credit notes"
11
11
  iban_invalid: "IBAN format or checksum is invalid"
12
12
  bic_invalid: "BIC format is invalid (8 or 11 characters)"
13
+ prepaid_amount_negative: "Prepaid amount cannot be negative"
14
+ prepaid_amount_exceeds_total: "Prepaid amount cannot exceed the invoice total"
13
15
  seller:
14
16
  name_missing: "Seller name is required"
15
17
  siren_invalid: "Seller SIREN must be 9 digits (Luhn check failed)"
@@ -10,6 +10,8 @@ fr:
10
10
  original_invoice_number_missing: "Le numéro de facture d'origine est requis pour les avoirs"
11
11
  iban_invalid: "Le format ou la somme de contrôle de l'IBAN est invalide"
12
12
  bic_invalid: "Le format du BIC est invalide (8 ou 11 caractères)"
13
+ prepaid_amount_negative: "Le montant déjà payé ne peut pas être négatif"
14
+ prepaid_amount_exceeds_total: "Le montant déjà payé ne peut pas dépasser le total de la facture"
13
15
  seller:
14
16
  name_missing: "Le nom du vendeur est requis"
15
17
  siren_invalid: "Le SIREN du vendeur doit comporter 9 chiffres (vérification Luhn échouée)"
@@ -16,7 +16,7 @@ module Einvoicing
16
16
  UDT_NS = "urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100"
17
17
  QDT_NS = "urn:un:unece:uncefact:data:standard:QualifiedDataType:100"
18
18
 
19
- def self.generate(invoice)
19
+ def self.generate(invoice, profile: :en16931)
20
20
  b = XMLBuilder.new
21
21
  b.tag(
22
22
  "rsm:CrossIndustryInvoice",
@@ -28,7 +28,7 @@ module Einvoicing
28
28
  ) do
29
29
  exchanged_document_context(b)
30
30
  exchanged_document(b, invoice)
31
- supply_chain_trade_transaction(b, invoice)
31
+ supply_chain_trade_transaction(b, invoice, profile)
32
32
  end
33
33
  b.to_xml
34
34
  end
@@ -51,28 +51,32 @@ 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 = "Avoir sur facture #{invoice.original_invoice_number}"
57
- note += " du #{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
 
70
- def self.supply_chain_trade_transaction(b, invoice)
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
+
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|
73
77
  trade_line_item(b, line, idx + 1, invoice.currency)
74
78
  end
75
- header_trade_agreement(b, invoice)
79
+ header_trade_agreement(b, invoice, profile)
76
80
  b.tag("ram:ApplicableHeaderTradeDelivery")
77
81
  header_trade_settlement(b, invoice)
78
82
  end
@@ -109,21 +113,23 @@ module Einvoicing
109
113
  end
110
114
  private_class_method :trade_line_item
111
115
 
112
- def self.header_trade_agreement(b, invoice)
116
+ def self.header_trade_agreement(b, invoice, profile)
113
117
  b.tag("ram:ApplicableHeaderTradeAgreement") do
114
118
  # BuyerReference must be first in the sequence (EN 16931 BR-10 / XSD order).
115
119
  b.text("ram:BuyerReference", invoice.payment_reference || "")
116
- b.tag("ram:SellerTradeParty") { party_xml(b, invoice.seller) }
117
- b.tag("ram:BuyerTradeParty") { party_xml(b, invoice.buyer) }
120
+ b.tag("ram:SellerTradeParty") { party_xml(b, invoice.seller, profile) }
121
+ b.tag("ram:BuyerTradeParty") { party_xml(b, invoice.buyer, profile) }
118
122
  end
119
123
  end
120
124
  private_class_method :header_trade_agreement
121
125
 
122
- def self.party_xml(b, party)
126
+ def self.party_xml(b, party, profile)
123
127
  b.text("ram:Name", party.name)
124
- if party.siren_number
128
+ legal_id = party.siret || party.siren
129
+ if legal_id
125
130
  b.tag("ram:SpecifiedLegalOrganization") do
126
- b.text("ram:ID", party.siren_number, "schemeID" => "0002")
131
+ scheme = (profile == :chorus_pro && party.siret) ? "SIRET" : "0002"
132
+ b.text("ram:ID", legal_id, "schemeID" => scheme)
127
133
  end
128
134
  end
129
135
  b.tag("ram:PostalTradeAddress") do
@@ -190,12 +196,28 @@ module Einvoicing
190
196
  b.text("ram:TaxTotalAmount", format_amount(invoice.tax_total),
191
197
  "currencyID" => invoice.currency)
192
198
  b.text("ram:GrandTotalAmount", format_amount(invoice.gross_total))
199
+ b.text("ram:TotalPrepaidAmount", format_amount(invoice.prepaid_amount)) if invoice.prepaid_amount.positive?
193
200
  b.text("ram:DuePayableAmount", format_amount(invoice.due_amount))
194
201
  end
202
+
203
+ preceding_invoice_reference(b, invoice) if invoice.document_type == :credit_note &&
204
+ invoice.original_invoice_number
195
205
  end
196
206
  end
197
207
  private_class_method :header_trade_settlement
198
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
+
199
221
  # Format a Date or string as YYYYMMDD (CII date format 102).
200
222
  def self.format_date(date)
201
223
  d = date.is_a?(Date) ? date : Date.parse(date.to_s)
@@ -203,6 +225,12 @@ module Einvoicing
203
225
  end
204
226
  private_class_method :format_date
205
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
+
206
234
  def self.format_amount(value)
207
235
  format("%.2f", value)
208
236
  end
@@ -159,6 +159,10 @@ module Einvoicing
159
159
  "currencyID" => invoice.currency)
160
160
  b.text("cbc:TaxInclusiveAmount", format_amount(invoice.gross_total),
161
161
  "currencyID" => invoice.currency)
162
+ if invoice.prepaid_amount.positive?
163
+ b.text("cbc:PrepaidAmount", format_amount(invoice.prepaid_amount),
164
+ "currencyID" => invoice.currency)
165
+ end
162
166
  b.text("cbc:PayableAmount", format_amount(invoice.due_amount),
163
167
  "currencyID" => invoice.currency)
164
168
  end
@@ -35,13 +35,15 @@ module Einvoicing
35
35
  :bic,
36
36
  :document_type,
37
37
  :original_invoice_number,
38
- :original_invoice_date
38
+ :original_invoice_date,
39
+ :prepaid_amount
39
40
  ) do
40
41
  def initialize(invoice_number:, issue_date:, seller:, buyer:, lines:,
41
42
  due_date: nil, currency: "EUR", tax_currency: nil, tax_breakdown: nil,
42
43
  payment_reference: nil, note: nil,
43
44
  payment_means_code: nil, iban: nil, bic: nil,
44
- document_type: :invoice, original_invoice_number: nil, original_invoice_date: nil)
45
+ document_type: :invoice, original_invoice_number: nil, original_invoice_date: nil,
46
+ prepaid_amount: BigDecimal(0))
45
47
  computed_breakdown = tax_breakdown || compute_tax_breakdown(lines)
46
48
  super(
47
49
  invoice_number: invoice_number,
@@ -60,7 +62,8 @@ module Einvoicing
60
62
  bic: bic,
61
63
  document_type: document_type,
62
64
  original_invoice_number: original_invoice_number,
63
- original_invoice_date: original_invoice_date
65
+ original_invoice_date: original_invoice_date,
66
+ prepaid_amount: prepaid_amount.nil? ? BigDecimal(0) : BigDecimal(prepaid_amount.to_s)
64
67
  )
65
68
  end
66
69
 
@@ -80,9 +83,11 @@ module Einvoicing
80
83
  lines.sum(BigDecimal("0"), &:gross_amount).round(2, :half_up)
81
84
  end
82
85
 
83
- # Amount due (same as gross_total; override for prepayments).
86
+ # Amount due after deducting any retained/prepaid amount (BT-113).
87
+ # VAT remains due on the full gross_total — only the payable balance is reduced
88
+ # (EN 16931 BR-CO-16: DuePayableAmount = GrandTotal − TotalPrepaidAmount).
84
89
  def due_amount
85
- gross_total
90
+ gross_total - prepaid_amount
86
91
  end
87
92
 
88
93
  private
@@ -46,9 +46,9 @@ module Einvoicing
46
46
  end
47
47
 
48
48
  # POST /v1/soumettre/factures — submit an invoice.
49
- # facture_hash: Hash matching the Chorus Pro invoice schema.
50
- def submit_invoice(facture_hash)
51
- post("/v1/soumettre/factures", facture_hash)
49
+ # invoice_hash: Hash matching the Chorus Pro invoice schema.
50
+ def submit_invoice(invoice_hash)
51
+ post("/v1/soumettre/factures", invoice_hash)
52
52
  end
53
53
 
54
54
  private
@@ -8,12 +8,12 @@ module Einvoicing
8
8
  # @param invoice [Einvoicing::Invoice]
9
9
  # @param id_structure_cpp [Integer] from find_structure()
10
10
  # @param code_service [String, nil] from list_services() — optional
11
- # @param numero_engagement [String, nil] buyer PO/engagement number — optional for B2B
12
- def self.to_chorus_payload(invoice, id_structure_cpp:, code_service: nil, numero_engagement: nil)
11
+ # @param engagement_number [String, nil] buyer PO/engagement number — optional for B2B
12
+ def self.to_chorus_payload(invoice, id_structure_cpp:, code_service: nil, engagement_number: nil)
13
13
  {
14
14
  idStructureCPP: id_structure_cpp,
15
15
  codeService: code_service,
16
- numeroEngagement: numero_engagement,
16
+ numeroEngagement: engagement_number,
17
17
  cadreFacturation: {
18
18
  codeCadreFacturation: "FACTURE_FOURNISSEUR",
19
19
  codeServiceValideur: nil
@@ -12,17 +12,17 @@ module Einvoicing
12
12
  #
13
13
  # @param invoice [Einvoicing::Invoice]
14
14
  # @param code_service [String, nil] optional service code from list_services
15
- # @param numero_engagement [String, nil] optional engagement number
16
- def submit(invoice, code_service: nil, numero_engagement: nil)
15
+ # @param engagement_number [String, nil] optional engagement number
16
+ def submit(invoice, code_service: nil, engagement_number: nil)
17
17
  structure = @client.find_structure(siret: invoice.buyer.siret)
18
18
  id_structure = structure["idStructureCPP"] || structure.dig("parametres", "idStructureCPP")
19
19
  raise ValidationError, "Buyer SIRET #{invoice.buyer.siret} not found in Chorus Pro" unless id_structure
20
20
 
21
21
  payload = InvoiceAdapter.to_chorus_payload(
22
22
  invoice,
23
- id_structure_cpp: id_structure,
24
- code_service: code_service,
25
- numero_engagement: numero_engagement
23
+ id_structure_cpp: id_structure,
24
+ code_service: code_service,
25
+ engagement_number: engagement_number
26
26
  )
27
27
 
28
28
  @client.submit_invoice(payload)
@@ -124,6 +124,13 @@ module Einvoicing
124
124
  errors << { field: :bic, error: :bic_invalid,
125
125
  message: Einvoicing::I18n.t("errors.invoice.bic_invalid") }
126
126
  end
127
+ if invoice.prepaid_amount.negative?
128
+ errors << { field: :prepaid_amount, error: :prepaid_amount_negative,
129
+ message: Einvoicing::I18n.t("errors.invoice.prepaid_amount_negative") }
130
+ elsif invoice.prepaid_amount > invoice.gross_total
131
+ errors << { field: :prepaid_amount, error: :prepaid_amount_exceeds_total,
132
+ message: Einvoicing::I18n.t("errors.invoice.prepaid_amount_exceeds_total") }
133
+ end
127
134
  errors
128
135
  end
129
136
  private_class_method :validate_invoice_fields
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Einvoicing
4
- VERSION = "0.6.0"
4
+ VERSION = "0.7.1"
5
5
  end
data/lib/einvoicing.rb CHANGED
@@ -56,10 +56,11 @@ module Einvoicing
56
56
  # Generate XML from an invoice.
57
57
  # @param invoice [Einvoicing::Invoice]
58
58
  # @param format [Symbol] :cii (default, Factur-X) or :ubl (Peppol BIS 3.0)
59
+ # @param profile [Symbol] :en16931 (default) or :chorus_pro (French B2G portal)
59
60
  # @return [String] XML document
60
- def self.xml(invoice, format: :cii)
61
+ def self.xml(invoice, format: :cii, profile: :en16931)
61
62
  case format
62
- when :cii then Formats::CII.generate(invoice)
63
+ when :cii then Formats::CII.generate(invoice, profile: profile)
63
64
  when :ubl then Formats::UBL.generate(invoice)
64
65
  else raise ArgumentError, Einvoicing::I18n.t("formats.unknown_format", fmt: format.inspect)
65
66
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: einvoicing
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.7.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathan Le Ray
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2026-03-14 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: hexapdf
@@ -161,6 +160,7 @@ extensions: []
161
160
  extra_rdoc_files: []
162
161
  files:
163
162
  - CHANGELOG.md
163
+ - LICENSE
164
164
  - README.md
165
165
  - config/locales/einvoicing.en.yml
166
166
  - config/locales/einvoicing.fr.yml
@@ -200,7 +200,6 @@ metadata:
200
200
  source_code_uri: https://github.com/sxnlabs/einvoicing
201
201
  changelog_uri: https://github.com/sxnlabs/einvoicing/blob/master/CHANGELOG.md
202
202
  documentation_uri: https://www.sxnlabs.com/en/gems/einvoicing/
203
- post_install_message:
204
203
  rdoc_options: []
205
204
  require_paths:
206
205
  - lib
@@ -215,8 +214,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
215
214
  - !ruby/object:Gem::Version
216
215
  version: '0'
217
216
  requirements: []
218
- rubygems_version: 3.5.22
219
- signing_key:
217
+ rubygems_version: 4.0.16
220
218
  specification_version: 4
221
219
  summary: EU electronic invoicing for Ruby — EN 16931, Factur-X, UBL 2.1
222
220
  test_files: []