diff --git a/lib/secretariat/constants.rb b/lib/secretariat/constants.rb
index 30f2ae7..291c1fa 100644
--- a/lib/secretariat/constants.rb
+++ b/lib/secretariat/constants.rb
@@ -53,6 +53,10 @@ module Secretariat
:DEBITADVICE => "31",
:CREDITCARD => "48",
:DEBIT => "49",
+ :CREDITTRANSFER => "54",
+ :DIRECTDEBIT => "55",
+ :SEPACREDITTRANSFER => "58",
+ :SEPADIRECTDEBIT => "59",
:COMPENSATION => "97"
}
diff --git a/lib/secretariat/invoice.rb b/lib/secretariat/invoice.rb
index 4e88664..05af4e6 100644
--- a/lib/secretariat/invoice.rb
+++ b/lib/secretariat/invoice.rb
@@ -48,6 +48,9 @@ module Secretariat
:tax_calculation_method,
:notes,
:attachments,
+ :direct_debit_mandate_reference_id, # BT-89
+ :direct_debit_creditor_id, # BT-90
+ :direct_debit_iban, # BT-91
keyword_init: true
) do
@@ -260,6 +263,9 @@ def to_xml(version: 1, validate: true)
end
trade_settlement = by_version(version, 'ApplicableSupplyChainTradeSettlement', 'ApplicableHeaderTradeSettlement')
xml['ram'].send(trade_settlement) do
+ if direct_debit_creditor_id
+ xml['ram'].CreditorReferenceID direct_debit_creditor_id # BT-90
+ end
if payment_reference.present?
xml['ram'].PaymentReference payment_reference
end
@@ -278,6 +284,11 @@ def to_xml(version: 1, validate: true)
xml['ram'].BICID payment_bic
end
end
+ if direct_debit_iban
+ xml['ram'].PayerPartyDebtorFinancialAccount do
+ xml['ram'].IBANID direct_debit_iban
+ end
+ end
end
taxes.each do |tax|
xml['ram'].ApplicableTradeTax do
@@ -311,6 +322,9 @@ def to_xml(version: 1, validate: true)
Helpers.date_element(xml, payment_due_date)
end
end
+ if direct_debit_mandate_reference_id
+ xml['ram'].DirectDebitMandateID direct_debit_mandate_reference_id
+ end
end
monetary_summation = by_version(version, 'SpecifiedTradeSettlementMonetarySummation', 'SpecifiedTradeSettlementHeaderMonetarySummation')
diff --git a/test/invoice_test.rb b/test/invoice_test.rb
index cf7fbb7..9115b4d 100644
--- a/test/invoice_test.rb
+++ b/test/invoice_test.rb
@@ -57,6 +57,64 @@ def make_eu_invoice(tax_category: :REVERSECHARGE)
)
end
+ def make_eu_invoice_with_sepa_direct_debit(tax_category: :REVERSECHARGE)
+ seller = TradeParty.new(
+ name: 'Depfu inc',
+ street1: 'Quickbornstr. 46',
+ city: 'Hamburg',
+ postal_code: '20253',
+ country_id: 'DE',
+ vat_id: 'DE304755032'
+ )
+ buyer = TradeParty.new(
+ name: 'Depfu inc',
+ street1: 'Quickbornstr. 46',
+ city: 'Hamburg',
+ postal_code: '20253',
+ country_id: 'SE',
+ vat_id: 'SE304755032'
+ )
+ line_item = LineItem.new(
+ name: 'Depfu Premium Plan',
+ quantity: 1,
+ gross_amount: BigDecimal('29'),
+ net_amount: BigDecimal('29'),
+ unit: :YEAR,
+ charge_amount: BigDecimal('29'),
+ tax_category: tax_category,
+ tax_percent: 0,
+ tax_amount: 0,
+ origin_country_code: 'DE',
+ currency_code: 'EUR',
+ service_period_start: Date.today,
+ service_period_end: Date.today + 364,
+ )
+ Invoice.new(
+ id: '12345',
+ issue_date: Date.today,
+ # service_period on line_item. removed here to simplify testing of BillingSpecifiedPeriod presence
+ # service_period_start: Date.today,
+ # service_period_end: Date.today + 30,
+ seller: seller,
+ buyer: buyer,
+ line_items: [line_item],
+ currency_code: 'USD',
+ payment_type: :CREDITCARD,
+ payment_text: 'Kreditkarte',
+ tax_category: tax_category,
+ tax_amount: 0,
+ basis_amount: BigDecimal('29'),
+ grand_total_amount: BigDecimal('29'),
+ due_amount: 0,
+ paid_amount: 29,
+ payment_due_date: Date.today + 14,
+ notes: "This is a test invoice",
+ direct_debit_mandate_reference_id: "MANDATE REFERENCE", # BT-89
+ direct_debit_creditor_id: "DE98ZZZ09999999999", # BT-90
+ direct_debit_iban: "DE02120300000000202051", # BT-91
+ )
+ end
+
def make_foreign_invoice(tax_category: :TAXEXEMPT)
seller = TradeParty.new(
name: 'Depfu inc',
@@ -381,6 +439,30 @@ def test_simple_eu_invoice_v2
puts e.errors
end
+ def test_simple_eu_invoice_v2_with_sepa_direct_debit
+ begin
+ xml = make_eu_invoice_with_sepa_direct_debit.to_xml(version: 2)
+ rescue ValidationError => e
+ pp e.errors
+ end
+
+ assert_match(%r{DE98ZZZ09999999999}, xml)
+ assert_match(%r{\s*DE02120300000000202051\s*}, xml)
+ assert_match(%r{MANDATE REFERENCE}, xml)
+
+ v = Validator.new(xml, version: 2)
+ errors = v.validate_against_schema
+ if !errors.empty?
+ puts xml
+ errors.each do |error|
+ puts error
+ end
+ end
+ assert_equal [], errors
+ rescue ValidationError => e
+ puts e.errors
+ end
+
def test_simple_foreign_invoice_v2_taxexpempt
begin
xml = make_foreign_invoice(tax_category: :TAXEXEMPT).to_xml(version: 2)