sepa_king 0.0.4 → 0.0.5
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/CONTRIBUTING.md +38 -0
- data/{MIT-LICENSE → LICENSE.txt} +2 -2
- data/README.md +174 -0
- data/Rakefile +1 -1
- data/lib/sepa_king.rb +1 -0
- data/lib/sepa_king/account.rb +8 -7
- data/lib/sepa_king/account/creditor_account.rb +2 -2
- data/lib/sepa_king/message.rb +14 -4
- data/lib/sepa_king/message/credit_transfer.rb +67 -60
- data/lib/sepa_king/message/direct_debit.rb +83 -73
- data/lib/sepa_king/transaction.rb +24 -11
- data/lib/sepa_king/transaction/direct_debit_transaction.rb +10 -2
- data/lib/sepa_king/validator.rb +36 -0
- data/lib/sepa_king/version.rb +1 -1
- data/sepa_king.gemspec +6 -4
- data/spec/account_spec.rb +8 -32
- data/spec/credit_transfer_spec.rb +170 -37
- data/spec/credit_transfer_transaction_spec.rb +6 -6
- data/spec/creditor_account_spec.rb +7 -15
- data/spec/debtor_account_spec.rb +3 -3
- data/spec/direct_debit_spec.rb +258 -43
- data/spec/direct_debit_transaction_spec.rb +14 -30
- data/spec/message_spec.rb +10 -3
- data/spec/spec_helper.rb +8 -3
- data/spec/support/custom_matcher.rb +46 -3
- data/spec/support/factories.rb +23 -0
- data/spec/support/validations.rb +1 -1
- data/spec/transaction_spec.rb +36 -60
- data/spec/validation_spec.rb +10 -2
- metadata +15 -11
- data/README.markdown +0 -91
@@ -4,98 +4,108 @@ module SEPA
|
|
4
4
|
class DirectDebit < Message
|
5
5
|
self.account_class = CreditorAccount
|
6
6
|
self.transaction_class = DirectDebitTransaction
|
7
|
+
self.xml_main_tag = 'CstmrDrctDbtInitn'
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
9
|
+
private
|
10
|
+
# @return {Hash<Symbol=>String>} xml schema information used in output xml
|
11
|
+
def xml_schema
|
12
|
+
{ :xmlns => 'urn:iso:std:iso:20022:tech:xsd:pain.008.002.02',
|
13
|
+
:'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
|
14
|
+
:'xsi:schemaLocation' => 'urn:iso:std:iso:20022:tech:xsd:pain.008.002.02 pain.008.002.02.xsd' }
|
15
|
+
end
|
16
|
+
|
17
|
+
# Find groups of transactions which share the same values of some attributes
|
18
|
+
def grouped_transactions
|
19
|
+
transactions.group_by do |transaction|
|
20
|
+
{ requested_date: transaction.requested_date,
|
21
|
+
local_instrument: transaction.local_instrument,
|
22
|
+
sequence_type: transaction.sequence_type,
|
23
|
+
batch_booking: transaction.batch_booking
|
24
|
+
}
|
19
25
|
end
|
20
26
|
end
|
21
27
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
builder.
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
builder.
|
31
|
-
|
28
|
+
def build_payment_informations(builder)
|
29
|
+
# Build a PmtInf block for every group of transactions
|
30
|
+
grouped_transactions.each do |group, transactions|
|
31
|
+
builder.PmtInf do
|
32
|
+
builder.PmtInfId(payment_information_identification)
|
33
|
+
builder.PmtMtd('DD')
|
34
|
+
builder.BtchBookg(group[:batch_booking])
|
35
|
+
builder.NbOfTxs(transactions.length)
|
36
|
+
builder.CtrlSum('%.2f' % amount_total(transactions))
|
37
|
+
builder.PmtTpInf do
|
38
|
+
builder.SvcLvl do
|
39
|
+
builder.Cd('SEPA')
|
40
|
+
end
|
41
|
+
builder.LclInstrm do
|
42
|
+
builder.Cd(group[:local_instrument])
|
43
|
+
end
|
44
|
+
builder.SeqTp(group[:sequence_type])
|
32
45
|
end
|
33
|
-
builder.
|
34
|
-
|
46
|
+
builder.ReqdColltnDt(group[:requested_date].iso8601)
|
47
|
+
builder.Cdtr do
|
48
|
+
builder.Nm(account.name)
|
35
49
|
end
|
36
|
-
builder.
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
builder.Nm(account.name)
|
41
|
-
end
|
42
|
-
builder.CdtrAcct do
|
43
|
-
builder.Id do
|
44
|
-
builder.IBAN(account.iban)
|
50
|
+
builder.CdtrAcct do
|
51
|
+
builder.Id do
|
52
|
+
builder.IBAN(account.iban)
|
53
|
+
end
|
45
54
|
end
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
55
|
+
builder.CdtrAgt do
|
56
|
+
builder.FinInstnId do
|
57
|
+
builder.BIC(account.bic)
|
58
|
+
end
|
50
59
|
end
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
+
builder.ChrgBr('SLEV')
|
61
|
+
builder.CdtrSchmeId do
|
62
|
+
builder.Id do
|
63
|
+
builder.PrvtId do
|
64
|
+
builder.Othr do
|
65
|
+
builder.Id(account.creditor_identifier)
|
66
|
+
builder.SchmeNm do
|
67
|
+
builder.Prtry('SEPA')
|
68
|
+
end
|
60
69
|
end
|
61
70
|
end
|
62
71
|
end
|
63
72
|
end
|
73
|
+
|
74
|
+
transactions.each do |transaction|
|
75
|
+
build_transaction(builder, transaction)
|
76
|
+
end
|
64
77
|
end
|
65
|
-
build_transactions(builder)
|
66
78
|
end
|
67
79
|
end
|
68
80
|
|
69
|
-
def
|
70
|
-
|
71
|
-
builder.
|
72
|
-
builder.
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
builder.
|
77
|
-
builder.
|
78
|
-
|
79
|
-
builder.DtOfSgntr(transaction.mandate_date_of_signature.iso8601)
|
80
|
-
end
|
81
|
-
end
|
82
|
-
builder.DbtrAgt do
|
83
|
-
builder.FinInstnId do
|
84
|
-
builder.BIC(transaction.bic)
|
85
|
-
end
|
81
|
+
def build_transaction(builder, transaction)
|
82
|
+
builder.DrctDbtTxInf do
|
83
|
+
builder.PmtId do
|
84
|
+
builder.EndToEndId(transaction.reference)
|
85
|
+
end
|
86
|
+
builder.InstdAmt('%.2f' % transaction.amount, Ccy: 'EUR')
|
87
|
+
builder.DrctDbtTx do
|
88
|
+
builder.MndtRltdInf do
|
89
|
+
builder.MndtId(transaction.mandate_id)
|
90
|
+
builder.DtOfSgntr(transaction.mandate_date_of_signature.iso8601)
|
86
91
|
end
|
87
|
-
|
88
|
-
|
92
|
+
end
|
93
|
+
builder.DbtrAgt do
|
94
|
+
builder.FinInstnId do
|
95
|
+
builder.BIC(transaction.bic)
|
89
96
|
end
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
97
|
+
end
|
98
|
+
builder.Dbtr do
|
99
|
+
builder.Nm(transaction.name)
|
100
|
+
end
|
101
|
+
builder.DbtrAcct do
|
102
|
+
builder.Id do
|
103
|
+
builder.IBAN(transaction.iban)
|
94
104
|
end
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
105
|
+
end
|
106
|
+
if transaction.remittance_information
|
107
|
+
builder.RmtInf do
|
108
|
+
builder.Ustrd(transaction.remittance_information)
|
99
109
|
end
|
100
110
|
end
|
101
111
|
end
|
@@ -1,22 +1,35 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
module SEPA
|
3
3
|
class Transaction
|
4
|
-
include ActiveModel::
|
4
|
+
include ActiveModel::Validations
|
5
5
|
extend Converter
|
6
6
|
|
7
|
-
attr_accessor :name, :iban, :bic, :amount, :reference, :remittance_information
|
8
|
-
convert :name, :reference, :remittance_information, :
|
9
|
-
convert :amount, :
|
7
|
+
attr_accessor :name, :iban, :bic, :amount, :reference, :remittance_information, :requested_date, :batch_booking
|
8
|
+
convert :name, :reference, :remittance_information, to: :text
|
9
|
+
convert :amount, to: :decimal
|
10
10
|
|
11
|
-
|
12
|
-
validates_length_of :
|
13
|
-
validates_length_of :
|
14
|
-
|
15
|
-
|
16
|
-
|
11
|
+
validates_length_of :name, within: 1..70
|
12
|
+
validates_length_of :reference, within: 1..35, allow_nil: true
|
13
|
+
validates_length_of :remittance_information, within: 1..140, allow_nil: true
|
14
|
+
validates_numericality_of :amount, greater_than: 0
|
15
|
+
validates_presence_of :requested_date
|
16
|
+
validates_inclusion_of :batch_booking, :in => [true, false]
|
17
|
+
validates_with BICValidator, IBANValidator
|
17
18
|
|
18
19
|
validate do |t|
|
19
|
-
|
20
|
+
if t.requested_date.is_a?(Date)
|
21
|
+
errors.add(:requested_date, 'is not in the future') if t.requested_date <= Date.today
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def initialize(attributes = {})
|
26
|
+
attributes.each do |name, value|
|
27
|
+
send("#{name}=", value)
|
28
|
+
end
|
29
|
+
|
30
|
+
self.requested_date ||= Date.today.next
|
31
|
+
self.reference ||= 'NOTPROVIDED'
|
32
|
+
self.batch_booking = true if self.batch_booking.nil?
|
20
33
|
end
|
21
34
|
end
|
22
35
|
end
|
@@ -1,10 +1,12 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
module SEPA
|
3
3
|
class DirectDebitTransaction < Transaction
|
4
|
-
attr_accessor :mandate_id, :mandate_date_of_signature
|
4
|
+
attr_accessor :mandate_id, :mandate_date_of_signature, :local_instrument, :sequence_type
|
5
5
|
|
6
|
-
validates_length_of :mandate_id, :
|
6
|
+
validates_length_of :mandate_id, within: 1..35
|
7
7
|
validates_presence_of :mandate_date_of_signature
|
8
|
+
validates_inclusion_of :local_instrument, :in => %w(CORE B2B)
|
9
|
+
validates_inclusion_of :sequence_type, :in => %w(FRST OOFF RCUR FNAL)
|
8
10
|
|
9
11
|
validate do |t|
|
10
12
|
if t.mandate_date_of_signature.is_a?(Date)
|
@@ -13,5 +15,11 @@ module SEPA
|
|
13
15
|
errors.add(:mandate_date_of_signature, 'is not a Date')
|
14
16
|
end
|
15
17
|
end
|
18
|
+
|
19
|
+
def initialize(attributes = {})
|
20
|
+
super
|
21
|
+
self.local_instrument ||= 'CORE'
|
22
|
+
self.sequence_type ||= 'OOFF'
|
23
|
+
end
|
16
24
|
end
|
17
25
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module SEPA
|
3
|
+
class IBANValidator < ActiveModel::Validator
|
4
|
+
def validate(record)
|
5
|
+
unless IBANTools::IBAN.valid?(record.iban.to_s)
|
6
|
+
record.errors.add(:iban, 'is invalid')
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class BICValidator < ActiveModel::Validator
|
12
|
+
def validate(record)
|
13
|
+
unless record.bic.to_s.match /[A-Z]{6,6}[A-Z2-9][A-NP-Z0-9]([A-Z0-9]{3,3}){0,1}/
|
14
|
+
record.errors.add(:bic, 'is invalid')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class CreditorIdentifierValidator < ActiveModel::Validator
|
20
|
+
def validate(record)
|
21
|
+
unless valid?(record.creditor_identifier)
|
22
|
+
record.errors.add(:creditor_identifier, 'is invalid')
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def valid?(creditor_identifier)
|
27
|
+
if ok = creditor_identifier.to_s.match(/[a-zA-Z]{2,2}[0-9]{2,2}([A-Za-z0-9]|[\+|\?|\/|\-|\:|\(|\)|\.|,|']){3,3}([A-Za-z0-9]|[\+|\?|\/|\-|:|\(|\)|\.|,|']){1,28}/)
|
28
|
+
# In Germany, the identifier has to be exactly 18 chars long
|
29
|
+
if creditor_identifier[0..1].match(/DE/i)
|
30
|
+
ok = creditor_identifier.length == 18
|
31
|
+
end
|
32
|
+
end
|
33
|
+
ok
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/sepa_king/version.rb
CHANGED
data/sepa_king.gemspec
CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |s|
|
|
9
9
|
s.authors = ['Georg Leciejewski', 'Georg Ledermann']
|
10
10
|
s.email = ['gl@salesking.eu', 'mail@georg-ledermann.de']
|
11
11
|
s.description = 'Implemention of pain.001.002.03 and pain.008.002.02 (ISO 20022)'
|
12
|
-
s.summary = '
|
12
|
+
s.summary = 'Ruby gem for creating SEPA XML files'
|
13
13
|
s.homepage = 'http://github.com/salesking/sepa_king'
|
14
14
|
s.license = 'MIT'
|
15
15
|
|
@@ -18,15 +18,17 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
19
19
|
s.require_paths = ['lib']
|
20
20
|
|
21
|
+
s.required_ruby_version = '>= 1.9.3'
|
22
|
+
|
21
23
|
s.add_runtime_dependency 'activemodel'
|
22
24
|
s.add_runtime_dependency 'i18n'
|
23
25
|
s.add_runtime_dependency 'builder'
|
24
26
|
s.add_runtime_dependency 'iban-tools'
|
25
27
|
|
26
28
|
s.add_development_dependency 'bundler', '~> 1.3'
|
27
|
-
s.add_development_dependency 'rspec'
|
28
|
-
s.add_development_dependency 'simplecov'
|
29
|
+
s.add_development_dependency 'rspec', '>=2.14'
|
29
30
|
s.add_development_dependency 'coveralls'
|
31
|
+
s.add_development_dependency 'simplecov'
|
30
32
|
s.add_development_dependency 'rake'
|
31
|
-
s.add_development_dependency '
|
33
|
+
s.add_development_dependency 'nokogiri'
|
32
34
|
end
|
data/spec/account_spec.rb
CHANGED
@@ -2,65 +2,41 @@
|
|
2
2
|
require 'spec_helper'
|
3
3
|
|
4
4
|
describe SEPA::Account do
|
5
|
-
describe
|
5
|
+
describe :new do
|
6
6
|
it 'should not accept unknown keys' do
|
7
7
|
expect {
|
8
|
-
SEPA::Account.new :
|
8
|
+
SEPA::Account.new foo: 'bar'
|
9
9
|
}.to raise_error(NoMethodError)
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
13
|
describe :name do
|
14
14
|
it 'should accept valid value' do
|
15
|
-
|
16
|
-
expect(
|
17
|
-
SEPA::Account.new :name => value_value
|
18
|
-
).to have(:no).errors_on(:name)
|
19
|
-
end
|
15
|
+
SEPA::Account.should accept('Gläubiger GmbH', 'Zahlemann & Söhne GbR', 'X' * 70, for: :name)
|
20
16
|
end
|
21
17
|
|
22
18
|
it 'should not accept invalid value' do
|
23
|
-
|
24
|
-
expect(
|
25
|
-
SEPA::Account.new :name => invalue_value
|
26
|
-
).to have_at_least(1).errors_on(:name)
|
27
|
-
end
|
19
|
+
SEPA::Account.should_not accept(nil, '', 'X' * 71, for: :name)
|
28
20
|
end
|
29
21
|
end
|
30
22
|
|
31
23
|
describe :iban do
|
32
24
|
it 'should accept valid value' do
|
33
|
-
|
34
|
-
expect(
|
35
|
-
SEPA::Account.new :iban => value_value
|
36
|
-
).to have(:no).errors_on(:iban)
|
37
|
-
end
|
25
|
+
SEPA::Account.should accept('DE21500500009876543210', 'PL61109010140000071219812874', for: :iban)
|
38
26
|
end
|
39
27
|
|
40
28
|
it 'should not accept invalid value' do
|
41
|
-
|
42
|
-
expect(
|
43
|
-
SEPA::Account.new :iban => invalue_value
|
44
|
-
).to have_at_least(1).errors_on(:iban)
|
45
|
-
end
|
29
|
+
SEPA::Account.should_not accept(nil, '', 'invalid', for: :iban)
|
46
30
|
end
|
47
31
|
end
|
48
32
|
|
49
33
|
describe :bic do
|
50
34
|
it 'should accept valid value' do
|
51
|
-
|
52
|
-
expect(
|
53
|
-
SEPA::Account.new :bic => value_value
|
54
|
-
).to have(:no).errors_on(:bic)
|
55
|
-
end
|
35
|
+
SEPA::Account.should accept('DEUTDEFF', 'DEUTDEFF500', 'SPUEDE2UXXX', for: :bic)
|
56
36
|
end
|
57
37
|
|
58
38
|
it 'should not accept invalid value' do
|
59
|
-
|
60
|
-
expect(
|
61
|
-
SEPA::Account.new :bic => invalue_value
|
62
|
-
).to have_at_least(1).errors_on(:bic)
|
63
|
-
end
|
39
|
+
SEPA::Account.should_not accept(nil, '', 'invalid', for: :bic)
|
64
40
|
end
|
65
41
|
end
|
66
42
|
end
|
@@ -3,13 +3,13 @@ require 'spec_helper'
|
|
3
3
|
|
4
4
|
describe SEPA::CreditTransfer do
|
5
5
|
let(:credit_transfer) {
|
6
|
-
SEPA::CreditTransfer.new :
|
7
|
-
:
|
8
|
-
:
|
6
|
+
SEPA::CreditTransfer.new name: 'Schuldner GmbH',
|
7
|
+
bic: 'BANKDEFFXXX',
|
8
|
+
iban: 'DE87200500001234567890'
|
9
9
|
}
|
10
10
|
|
11
11
|
describe :new do
|
12
|
-
it 'should accept
|
12
|
+
it 'should accept missing options' do
|
13
13
|
expect {
|
14
14
|
SEPA::CreditTransfer.new
|
15
15
|
}.to_not raise_error
|
@@ -18,52 +18,185 @@ describe SEPA::CreditTransfer do
|
|
18
18
|
|
19
19
|
describe :add_transaction do
|
20
20
|
it 'should add valid transactions' do
|
21
|
-
3.times
|
22
|
-
credit_transfer.add_transaction
|
23
|
-
|
24
|
-
:iban => 'DE37112589611964645802',
|
25
|
-
:amount => 102.50,
|
26
|
-
:reference => 'XYZ-1234/123',
|
27
|
-
:remittance_information => 'Rechnung vom 22.08.2013'
|
28
|
-
}
|
21
|
+
3.times do
|
22
|
+
credit_transfer.add_transaction(credit_transfer_transaction)
|
23
|
+
end
|
29
24
|
|
30
25
|
expect(credit_transfer).to have(3).transactions
|
31
26
|
end
|
32
27
|
|
33
28
|
it 'should fail for invalid transaction' do
|
34
29
|
expect {
|
35
|
-
credit_transfer.add_transaction :
|
30
|
+
credit_transfer.add_transaction name: ''
|
36
31
|
}.to raise_error(ArgumentError)
|
37
32
|
end
|
38
33
|
end
|
39
34
|
|
40
35
|
describe :to_xml do
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
36
|
+
context 'for invalid debtor' do
|
37
|
+
it 'should fail' do
|
38
|
+
expect {
|
39
|
+
SEPA::CreditTransfer.new.to_xml
|
40
|
+
}.to raise_error(RuntimeError)
|
41
|
+
end
|
45
42
|
end
|
46
43
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
44
|
+
context 'for valid debtor' do
|
45
|
+
context 'without requested_date given' do
|
46
|
+
subject do
|
47
|
+
sct = credit_transfer
|
48
|
+
|
49
|
+
sct.add_transaction name: 'Telekomiker AG',
|
50
|
+
bic: 'PBNKDEFF370',
|
51
|
+
iban: 'DE37112589611964645802',
|
52
|
+
amount: 102.50,
|
53
|
+
reference: 'XYZ-1234/123',
|
54
|
+
remittance_information: 'Rechnung vom 22.08.2013'
|
55
|
+
|
56
|
+
sct.add_transaction name: 'Amazonas GmbH',
|
57
|
+
bic: 'TUBDDEDDXXX',
|
58
|
+
iban: 'DE27793589132923472195',
|
59
|
+
amount: 59.00,
|
60
|
+
reference: 'XYZ-5678/456',
|
61
|
+
remittance_information: 'Rechnung vom 21.08.2013'
|
62
|
+
|
63
|
+
sct.to_xml
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'should create valid XML file' do
|
67
|
+
expect(subject).to validate_against('pain.001.002.03.xsd')
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'should contain <PmtMtd>' do
|
71
|
+
subject.should have_xml('//Document/CstmrCdtTrfInitn/PmtInf/PmtMtd', 'TRF')
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'should contain <BtchBookg>' do
|
75
|
+
subject.should have_xml('//Document/CstmrCdtTrfInitn/PmtInf/BtchBookg', 'true')
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'should contain <NbOfTxs>' do
|
79
|
+
subject.should have_xml('//Document/CstmrCdtTrfInitn/PmtInf/NbOfTxs', '2')
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'should contain <CtrlSum>' do
|
83
|
+
subject.should have_xml('//Document/CstmrCdtTrfInitn/PmtInf/CtrlSum', '161.50')
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'should contain <Dbtr>' do
|
87
|
+
subject.should have_xml('//Document/CstmrCdtTrfInitn/PmtInf/Dbtr/Nm', 'Schuldner GmbH')
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'should contain <DbtrAcct>' do
|
91
|
+
subject.should have_xml('//Document/CstmrCdtTrfInitn/PmtInf/DbtrAcct/Id/IBAN', 'DE87200500001234567890')
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'should contain <DbtrAgt>' do
|
95
|
+
subject.should have_xml('//Document/CstmrCdtTrfInitn/PmtInf/DbtrAgt/FinInstnId/BIC', 'BANKDEFFXXX')
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'should contain <EndToEndId>' do
|
99
|
+
subject.should have_xml('//Document/CstmrCdtTrfInitn/PmtInf/CdtTrfTxInf[1]/PmtId/EndToEndId', 'XYZ-1234/123')
|
100
|
+
subject.should have_xml('//Document/CstmrCdtTrfInitn/PmtInf/CdtTrfTxInf[2]/PmtId/EndToEndId', 'XYZ-5678/456')
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'should contain <Amt>' do
|
104
|
+
subject.should have_xml('//Document/CstmrCdtTrfInitn/PmtInf/CdtTrfTxInf[1]/Amt/InstdAmt', '102.50')
|
105
|
+
subject.should have_xml('//Document/CstmrCdtTrfInitn/PmtInf/CdtTrfTxInf[2]/Amt/InstdAmt', '59.00')
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'should contain <CdtrAgt>' do
|
109
|
+
subject.should have_xml('//Document/CstmrCdtTrfInitn/PmtInf/CdtTrfTxInf[1]/CdtrAgt/FinInstnId/BIC', 'PBNKDEFF370')
|
110
|
+
subject.should have_xml('//Document/CstmrCdtTrfInitn/PmtInf/CdtTrfTxInf[2]/CdtrAgt/FinInstnId/BIC', 'TUBDDEDDXXX')
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'should contain <Cdtr>' do
|
114
|
+
subject.should have_xml('//Document/CstmrCdtTrfInitn/PmtInf/CdtTrfTxInf[1]/Cdtr/Nm', 'Telekomiker AG')
|
115
|
+
subject.should have_xml('//Document/CstmrCdtTrfInitn/PmtInf/CdtTrfTxInf[2]/Cdtr/Nm', 'Amazonas GmbH')
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'should contain <CdtrAcct>' do
|
119
|
+
subject.should have_xml('//Document/CstmrCdtTrfInitn/PmtInf/CdtTrfTxInf[1]/CdtrAcct/Id/IBAN', 'DE37112589611964645802')
|
120
|
+
subject.should have_xml('//Document/CstmrCdtTrfInitn/PmtInf/CdtTrfTxInf[2]/CdtrAcct/Id/IBAN', 'DE27793589132923472195')
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'should contain <RmtInf>' do
|
124
|
+
subject.should have_xml('//Document/CstmrCdtTrfInitn/PmtInf/CdtTrfTxInf[1]/RmtInf/Ustrd', 'Rechnung vom 22.08.2013')
|
125
|
+
subject.should have_xml('//Document/CstmrCdtTrfInitn/PmtInf/CdtTrfTxInf[2]/RmtInf/Ustrd', 'Rechnung vom 21.08.2013')
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
context 'with different requested_date given' do
|
130
|
+
subject do
|
131
|
+
sct = credit_transfer
|
132
|
+
|
133
|
+
sct.add_transaction(credit_transfer_transaction.merge requested_date: Date.today + 1)
|
134
|
+
sct.add_transaction(credit_transfer_transaction.merge requested_date: Date.today + 2)
|
135
|
+
sct.add_transaction(credit_transfer_transaction.merge requested_date: Date.today + 2)
|
136
|
+
|
137
|
+
sct.to_xml
|
138
|
+
end
|
139
|
+
|
140
|
+
it 'should contain two payment_informations with <ReqdExctnDt>' do
|
141
|
+
subject.should have_xml('//Document/CstmrCdtTrfInitn/PmtInf[1]/ReqdExctnDt', (Date.today + 1).iso8601)
|
142
|
+
subject.should have_xml('//Document/CstmrCdtTrfInitn/PmtInf[2]/ReqdExctnDt', (Date.today + 2).iso8601)
|
143
|
+
|
144
|
+
subject.should_not have_xml('//Document/CstmrCdtTrfInitn/PmtInf[3]')
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
context 'with different batch_booking given' do
|
149
|
+
subject do
|
150
|
+
sct = credit_transfer
|
151
|
+
|
152
|
+
sct.add_transaction(credit_transfer_transaction.merge batch_booking: false)
|
153
|
+
sct.add_transaction(credit_transfer_transaction.merge batch_booking: true)
|
154
|
+
sct.add_transaction(credit_transfer_transaction.merge batch_booking: true)
|
155
|
+
|
156
|
+
sct.to_xml
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'should contain two payment_informations with <BtchBookg>' do
|
160
|
+
subject.should have_xml('//Document/CstmrCdtTrfInitn/PmtInf[1]/BtchBookg', 'false')
|
161
|
+
subject.should have_xml('//Document/CstmrCdtTrfInitn/PmtInf[2]/BtchBookg', 'true')
|
162
|
+
|
163
|
+
subject.should_not have_xml('//Document/CstmrCdtTrfInitn/PmtInf[3]')
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
context 'with transactions containing different group criteria' do
|
168
|
+
subject do
|
169
|
+
sct = credit_transfer
|
170
|
+
|
171
|
+
sct.add_transaction(credit_transfer_transaction.merge requested_date: Date.today + 1, batch_booking: false, amount: 1)
|
172
|
+
sct.add_transaction(credit_transfer_transaction.merge requested_date: Date.today + 1, batch_booking: true, amount: 2)
|
173
|
+
sct.add_transaction(credit_transfer_transaction.merge requested_date: Date.today + 2, batch_booking: false, amount: 4)
|
174
|
+
sct.add_transaction(credit_transfer_transaction.merge requested_date: Date.today + 2, batch_booking: true, amount: 8)
|
175
|
+
|
176
|
+
sct.to_xml
|
177
|
+
end
|
178
|
+
|
179
|
+
it 'should contain multiple payment_informations' do
|
180
|
+
subject.should have_xml('//Document/CstmrCdtTrfInitn/PmtInf[1]/ReqdExctnDt', (Date.today + 1).iso8601)
|
181
|
+
subject.should have_xml('//Document/CstmrCdtTrfInitn/PmtInf[1]/BtchBookg', 'false')
|
182
|
+
|
183
|
+
subject.should have_xml('//Document/CstmrCdtTrfInitn/PmtInf[2]/ReqdExctnDt', (Date.today + 1).iso8601)
|
184
|
+
subject.should have_xml('//Document/CstmrCdtTrfInitn/PmtInf[2]/BtchBookg', 'true')
|
185
|
+
|
186
|
+
subject.should have_xml('//Document/CstmrCdtTrfInitn/PmtInf[3]/ReqdExctnDt', (Date.today + 2).iso8601)
|
187
|
+
subject.should have_xml('//Document/CstmrCdtTrfInitn/PmtInf[3]/BtchBookg', 'false')
|
188
|
+
|
189
|
+
subject.should have_xml('//Document/CstmrCdtTrfInitn/PmtInf[4]/ReqdExctnDt', (Date.today + 2).iso8601)
|
190
|
+
subject.should have_xml('//Document/CstmrCdtTrfInitn/PmtInf[4]/BtchBookg', 'true')
|
191
|
+
end
|
192
|
+
|
193
|
+
it 'should have multiple control sums' do
|
194
|
+
subject.should have_xml('//Document/CstmrCdtTrfInitn/PmtInf[1]/CtrlSum', '1.00')
|
195
|
+
subject.should have_xml('//Document/CstmrCdtTrfInitn/PmtInf[2]/CtrlSum', '2.00')
|
196
|
+
subject.should have_xml('//Document/CstmrCdtTrfInitn/PmtInf[3]/CtrlSum', '4.00')
|
197
|
+
subject.should have_xml('//Document/CstmrCdtTrfInitn/PmtInf[4]/CtrlSum', '8.00')
|
198
|
+
end
|
199
|
+
end
|
67
200
|
end
|
68
201
|
end
|
69
202
|
end
|