From 794007f15c81145913878a710b8624e7ce953a7c Mon Sep 17 00:00:00 2001 From: David Neugebauer Date: Tue, 15 Sep 2026 15:16:10 +0200 Subject: [PATCH 1/2] Allow setting a business_process_id and a specification_id --- lib/secretariat/invoice.rb | 9 ++++++++- test/invoice_test.rb | 23 +++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/lib/secretariat/invoice.rb b/lib/secretariat/invoice.rb index 140627b..08bc0a7 100644 --- a/lib/secretariat/invoice.rb +++ b/lib/secretariat/invoice.rb @@ -20,6 +20,8 @@ module Secretariat using ObjectExtensions Invoice = Struct.new("Invoice", + :specification_id, + :business_process_id, :id, :issue_date, :service_period_start, @@ -199,9 +201,14 @@ def to_xml(version: 1, validate: true) context = by_version(version, 'SpecifiedExchangedDocumentContext', 'ExchangedDocumentContext') xml['rsm'].send(context) do + if business_process_id.present? + xml['ram'].BusinessProcessSpecifiedDocumentContextParameter do + xml['ram'].ID business_process_id + end + end xml['ram'].GuidelineSpecifiedDocumentContextParameter do version_id = by_version(version, 'urn:ferd:CrossIndustryDocument:invoice:1p0:comfort', 'urn:cen.eu:en16931:2017') - xml['ram'].ID version_id + xml['ram'].ID specification_id || version_id end end diff --git a/test/invoice_test.rb b/test/invoice_test.rb index 8af2c76..d639560 100644 --- a/test/invoice_test.rb +++ b/test/invoice_test.rb @@ -884,5 +884,28 @@ def test_invoice_with_quantity_causing_sub_cent_amounts end assert_equal [], errors end + + def test_default_specification_id + xml = make_de_invoice.to_xml(version: 2) + + assert_match(/\s*urn:cen.eu:en16931:2017<\/ram:ID>/, xml) + end + + def test_custom_specification_id + invoice = make_de_invoice + invoice.specification_id = 'urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0' + xml = invoice.to_xml(version: 2) + + assert_match(/urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0<\/ram:ID>/, xml) + end + + def test_business_process_id + invoice = make_de_invoice + invoice.business_process_id = 'urn:fdc:peppol.eu:2017:poacc:billing:01:1.0' + xml = invoice.to_xml(version: 2) + + assert_match(/\s*urn:fdc:peppol.eu:2017:poacc:billing:01:1.0<\/ram:ID>/, xml) + assert_equal [], Validator.new(xml, version: 2).validate_against_schema + end end end From 26955018dea328e1c0a84975be1e99b517fd651a Mon Sep 17 00:00:00 2001 From: David Neugebauer Date: Tue, 15 Sep 2026 18:16:43 +0200 Subject: [PATCH 2/2] Add constants for XRechnung specification and Peppol billing process IDs --- lib/secretariat/constants.rb | 8 ++++++++ test/invoice_test.rb | 8 ++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/lib/secretariat/constants.rb b/lib/secretariat/constants.rb index 1445064..1777244 100644 --- a/lib/secretariat/constants.rb +++ b/lib/secretariat/constants.rb @@ -96,4 +96,12 @@ module Secretariat :TON => "TNE", :WEEK => "WEE" } + + SPECIFICATION_IDS = { + :XRECHNUNG_3_0 => "urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0" + } + + BUSINESS_PROCESS_IDS = { + :PEPPOL_BILLING => "urn:fdc:peppol.eu:2017:poacc:billing:01:1.0" + } end diff --git a/test/invoice_test.rb b/test/invoice_test.rb index d639560..1b07543 100644 --- a/test/invoice_test.rb +++ b/test/invoice_test.rb @@ -893,18 +893,18 @@ def test_default_specification_id def test_custom_specification_id invoice = make_de_invoice - invoice.specification_id = 'urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0' + invoice.specification_id = SPECIFICATION_IDS[:XRECHNUNG_3_0] xml = invoice.to_xml(version: 2) - assert_match(/urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0<\/ram:ID>/, xml) + assert_match(/#{Regexp.escape(SPECIFICATION_IDS[:XRECHNUNG_3_0])}<\/ram:ID>/, xml) end def test_business_process_id invoice = make_de_invoice - invoice.business_process_id = 'urn:fdc:peppol.eu:2017:poacc:billing:01:1.0' + invoice.business_process_id = BUSINESS_PROCESS_IDS[:PEPPOL_BILLING] xml = invoice.to_xml(version: 2) - assert_match(/\s*urn:fdc:peppol.eu:2017:poacc:billing:01:1.0<\/ram:ID>/, xml) + assert_match(/\s*#{Regexp.escape(BUSINESS_PROCESS_IDS[:PEPPOL_BILLING])}<\/ram:ID>/, xml) assert_equal [], Validator.new(xml, version: 2).validate_against_schema end end