From 8f8063813d5b8c441b09ec2c2fd26d99b9d4c554 Mon Sep 17 00:00:00 2001 From: Martin Guether Date: Wed, 9 May 2018 13:15:05 +0200 Subject: [PATCH] Added PstlAdr to Dbtr (#71) * added debtor feature * fix readme for SEPA::DebtorAddress * add more test coverage --- README.md | 9 ++- lib/sepa_king.rb | 1 + lib/sepa_king/account/debtor_address.rb | 23 +++++++ lib/sepa_king/message/direct_debit.rb | 7 ++ lib/sepa_king/transaction.rb | 3 +- .../transaction/direct_debit_transaction.rb | 3 +- spec/debtor_address_spec.rb | 12 ++++ spec/direct_debit_spec.rb | 64 +++++++++++++++++++ spec/transaction_spec.rb | 13 ++++ 9 files changed, 131 insertions(+), 4 deletions(-) create mode 100644 lib/sepa_king/account/debtor_address.rb create mode 100644 spec/debtor_address_spec.rb diff --git a/README.md b/README.md index db468f4..643c889 100644 --- a/README.md +++ b/README.md @@ -101,7 +101,7 @@ sdd.add_transaction( # Local instrument, in German "Lastschriftart" # One of these strings: # 'CORE' ("Basis-Lastschrift") - # 'COR1' ("Basis-Lastschrift mit verkürzter Vorlagefrist") + # 'COR1' ("Basis-Lastschrift mit verkürzter Vorlagefrist") # 'B2B' ("Firmen-Lastschrift") local_instrument: 'CORE', @@ -129,6 +129,13 @@ sdd.add_transaction( iban: 'NL08RABO0135742099', creditor_identifier: 'NL53ZZZ091734220000' ) + + # OPTIONAL: Specify the country & address of the debtor (REQUIRED for SEPA debits outside of EU) + debtor_address: SEPA::DebtorAddress.new( + country_code: 'CH', + address_line1: 'Mustergasse 123a', + address_line2: '1234 Musterstadt' + ) ) sdd.add_transaction ... diff --git a/lib/sepa_king.rb b/lib/sepa_king.rb index f5af258..64439c6 100644 --- a/lib/sepa_king.rb +++ b/lib/sepa_king.rb @@ -7,6 +7,7 @@ require 'sepa_king/validator' require 'sepa_king/account' require 'sepa_king/account/debtor_account' +require 'sepa_king/account/debtor_address' require 'sepa_king/account/creditor_account' require 'sepa_king/transaction' require 'sepa_king/transaction/direct_debit_transaction' diff --git a/lib/sepa_king/account/debtor_address.rb b/lib/sepa_king/account/debtor_address.rb new file mode 100644 index 0000000..69d1e0d --- /dev/null +++ b/lib/sepa_king/account/debtor_address.rb @@ -0,0 +1,23 @@ +# encoding: utf-8 +module SEPA + class DebtorAddress + include ActiveModel::Validations + extend Converter + + attr_accessor :country_code, :address_line1, :address_line2 + + convert :country_code, to: :text + convert :address_line1, to: :text + convert :address_line2, to: :text + + validates_length_of :country_code, is: 2 + validates_length_of :address_line1, maximum: 70 + validates_length_of :address_line2, maximum: 70 + + def initialize(attributes = {}) + attributes.each do |name, value| + public_send("#{name}=", value) + end + end + end +end diff --git a/lib/sepa_king/message/direct_debit.rb b/lib/sepa_king/message/direct_debit.rb index 62abee1..09eab8c 100644 --- a/lib/sepa_king/message/direct_debit.rb +++ b/lib/sepa_king/message/direct_debit.rb @@ -149,6 +149,13 @@ def build_transaction(builder, transaction) end builder.Dbtr do builder.Nm(transaction.name) + if transaction.debtor_address + builder.PstlAdr do + builder.Ctry transaction.debtor_address.country_code + builder.AdrLine transaction.debtor_address.address_line1 + builder.AdrLine transaction.debtor_address.address_line2 + end + end end builder.DbtrAcct do builder.Id do diff --git a/lib/sepa_king/transaction.rb b/lib/sepa_king/transaction.rb index 4fece1f..284efb5 100644 --- a/lib/sepa_king/transaction.rb +++ b/lib/sepa_king/transaction.rb @@ -6,7 +6,8 @@ class Transaction DEFAULT_REQUESTED_DATE = Date.new(1999, 1, 1).freeze - attr_accessor :name, :iban, :bic, :amount, :instruction, :reference, :remittance_information, :requested_date, :batch_booking, :currency + attr_accessor :name, :iban, :bic, :amount, :instruction, :reference, :remittance_information, :requested_date, :batch_booking, :currency, :debtor_address + convert :name, :instruction, :reference, :remittance_information, to: :text convert :amount, to: :decimal diff --git a/lib/sepa_king/transaction/direct_debit_transaction.rb b/lib/sepa_king/transaction/direct_debit_transaction.rb index 2243921..7faccb5 100644 --- a/lib/sepa_king/transaction/direct_debit_transaction.rb +++ b/lib/sepa_king/transaction/direct_debit_transaction.rb @@ -4,13 +4,12 @@ class DirectDebitTransaction < Transaction SEQUENCE_TYPES = %w(FRST OOFF RCUR FNAL) LOCAL_INSTRUMENTS = %w(CORE COR1 B2B) - attr_accessor :mandate_id, :mandate_date_of_signature, :local_instrument, :sequence_type, :creditor_account, :original_debtor_account, :same_mandate_new_debtor_agent, :original_creditor_account + attr_accessor :mandate_id, :mandate_date_of_signature, :local_instrument, :sequence_type, :creditor_account, :original_debtor_account, :same_mandate_new_debtor_agent, :original_creditor_account, :debtor_address validates_with MandateIdentifierValidator, field_name: :mandate_id, message: "%{value} is invalid" validates_presence_of :mandate_date_of_signature validates_inclusion_of :local_instrument, in: LOCAL_INSTRUMENTS validates_inclusion_of :sequence_type, in: SEQUENCE_TYPES - validate { |t| t.validate_requested_date_after(Date.today.next) } validate do |t| diff --git a/spec/debtor_address_spec.rb b/spec/debtor_address_spec.rb new file mode 100644 index 0000000..f92ada5 --- /dev/null +++ b/spec/debtor_address_spec.rb @@ -0,0 +1,12 @@ +# encoding: utf-8 +require 'spec_helper' + +describe SEPA::DebtorAddress do + it 'should initialize a new address' do + expect( + SEPA::DebtorAddress.new country_code: 'CH', + address_line1: 'Mustergasse 123', + address_line2: '12345 Musterstadt' + ).to be_valid + end +end diff --git a/spec/direct_debit_spec.rb b/spec/direct_debit_spec.rb index 58bdb94..e9ee887 100644 --- a/spec/direct_debit_spec.rb +++ b/spec/direct_debit_spec.rb @@ -74,6 +74,34 @@ end end + context 'setting debtor address' do + subject do + sdd = SEPA::DirectDebit.new name: 'Gläubiger GmbH', + iban: 'DE87200500001234567890', + creditor_identifier: 'DE98ZZZ09999999999' + + sda = SEPA::DebtorAddress.new country_code: 'CH', + address_line1: 'Mustergasse 123', + address_line2: '1234 Musterstadt' + + sdd.add_transaction name: 'Zahlemann & Söhne GbR', + bic: 'SPUEDE2UXXX', + iban: 'DE21500500009876543210', + amount: 39.99, + reference: 'XYZ/2013-08-ABO/12345', + remittance_information: 'Unsere Rechnung vom 10.08.2013', + mandate_id: 'K-02-2011-12345', + debtor_address: sda, + mandate_date_of_signature: Date.new(2011,1,25) + + sdd + end + + it 'should validate against pain.008.003.02' do + expect(subject.to_xml(SEPA::PAIN_008_003_02)).to validate_against('pain.008.003.02.xsd') + end + end + context 'for valid creditor' do context 'without BIC (IBAN-only)' do subject do @@ -137,6 +165,42 @@ end end + context 'with BIC and debtor address ' do + subject do + sdd = direct_debit + + sda = SEPA::DebtorAddress.new( + country_code: 'CH', + address_line1: 'Mustergasse 123', + address_line2: '1234 Musterstadt' + ) + + sdd.add_transaction name: 'Zahlemann & Söhne GbR', + bic: 'SPUEDE2UXXX', + iban: 'DE21500500009876543210', + amount: 39.99, + reference: 'XYZ/2013-08-ABO/12345', + remittance_information: 'Unsere Rechnung vom 10.08.2013', + mandate_id: 'K-02-2011-12345', + debtor_address: sda, + mandate_date_of_signature: Date.new(2011,1,25) + + sdd + end + + it 'should validate against pain.008.001.02' do + expect(subject.to_xml(SEPA::PAIN_008_001_02)).to validate_against('pain.008.001.02.xsd') + end + + it 'should validate against pain.008.002.02' do + expect(subject.to_xml(SEPA::PAIN_008_002_02)).to validate_against('pain.008.002.02.xsd') + end + + it 'should validate against pain.008.003.02' do + expect(subject.to_xml(SEPA::PAIN_008_003_02)).to validate_against('pain.008.003.02.xsd') + end + end + context 'without requested_date given' do subject do sdd = direct_debit diff --git a/spec/transaction_spec.rb b/spec/transaction_spec.rb index d9ac82a..c5e33fb 100644 --- a/spec/transaction_spec.rb +++ b/spec/transaction_spec.rb @@ -26,6 +26,19 @@ end end + context 'Adress' do + it 'should accept valid value' do + expect(SEPA::Transaction).to accept(SEPA::DebtorAddress.new( + country_code: "CH", + address_line1: "Musterstrasse 123", + address_line2: "1234 Musterstadt" + ), for: :debtor_address) + end + + it 'should not accept invalid value' do + expect(SEPA::Transaction).not_to accept('', {} , for: :name) + end + end context 'IBAN' do it 'should accept valid value' do expect(SEPA::Transaction).to accept('DE21500500009876543210', 'PL61109010140000071219812874', for: :iban)