sepa_king 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
- def to_xml
9
- super
10
- builder = Builder::XmlMarkup.new :indent => 2
11
- builder.instruct!
12
- builder.Document :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' do
15
- builder.CstmrDrctDbtInitn do
16
- build_group_header(builder)
17
- build_payment_information(builder)
18
- end
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
- private
23
- def build_payment_information(builder)
24
- builder.PmtInf do
25
- builder.PmtInfId(payment_information_identification)
26
- builder.PmtMtd('DD')
27
- builder.NbOfTxs(transactions.length)
28
- builder.CtrlSum('%.2f' % amount_total)
29
- builder.PmtTpInf do
30
- builder.SvcLvl do
31
- builder.Cd('SEPA')
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.LclInstrm do
34
- builder.Cd('CORE')
46
+ builder.ReqdColltnDt(group[:requested_date].iso8601)
47
+ builder.Cdtr do
48
+ builder.Nm(account.name)
35
49
  end
36
- builder.SeqTp('OOFF')
37
- end
38
- builder.ReqdColltnDt(Date.today.next.iso8601)
39
- builder.Cdtr do
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
- end
47
- builder.CdtrAgt do
48
- builder.FinInstnId do
49
- builder.BIC(account.bic)
55
+ builder.CdtrAgt do
56
+ builder.FinInstnId do
57
+ builder.BIC(account.bic)
58
+ end
50
59
  end
51
- end
52
- builder.ChrgBr('SLEV')
53
- builder.CdtrSchmeId do
54
- builder.Id do
55
- builder.PrvtId do
56
- builder.Othr do
57
- builder.Id(account.identifier)
58
- builder.SchmeNm do
59
- builder.Prtry('SEPA')
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 build_transactions(builder)
70
- transactions.each do |transaction|
71
- builder.DrctDbtTxInf do
72
- builder.PmtId do
73
- builder.EndToEndId(transaction.reference || 'NOTPROVIDED')
74
- end
75
- builder.InstdAmt('%.2f' % transaction.amount, :Ccy => 'EUR')
76
- builder.DrctDbtTx do
77
- builder.MndtRltdInf do
78
- builder.MndtId(transaction.mandate_id)
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
- builder.Dbtr do
88
- builder.Nm(transaction.name)
92
+ end
93
+ builder.DbtrAgt do
94
+ builder.FinInstnId do
95
+ builder.BIC(transaction.bic)
89
96
  end
90
- builder.DbtrAcct do
91
- builder.Id do
92
- builder.IBAN(transaction.iban)
93
- end
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
- if transaction.remittance_information
96
- builder.RmtInf do
97
- builder.Ustrd(transaction.remittance_information)
98
- end
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::Model
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, :to => :text
9
- convert :amount, :to => :decimal
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
- validates_presence_of :name, :iban, :bic, :amount
12
- validates_length_of :name, :maximum => 70
13
- validates_length_of :bic, :within => 8..11
14
- validates_length_of :reference, :maximum => 35, :minimum => 1, :allow_nil => true
15
- validates_length_of :remittance_information, :minimum => 1, :maximum => 140, :allow_nil => true
16
- validates_numericality_of :amount, :greater_than => 0
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
- errors.add(:iban, 'is invalid') unless IBANTools::IBAN.valid?(t.iban.to_s)
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, :within => 1..35
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
@@ -1,3 +1,3 @@
1
1
  module SEPA
2
- VERSION = '0.0.4'
2
+ VERSION = '0.0.5'
3
3
  end
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 = 'Generate SEPA XML files with Ruby ... the easy way'
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 'libxml-ruby'
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 'Initialization' do
5
+ describe :new do
6
6
  it 'should not accept unknown keys' do
7
7
  expect {
8
- SEPA::Account.new :foo => 'bar'
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
- [ 'Gläubiger GmbH', 'Zahlemann & Söhne GbR', 'X' * 70 ].each do |value_value|
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
- [ nil, '', 'X' * 71 ].each do |invalue_value|
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
- [ 'DE21500500009876543210', 'PL61109010140000071219812874' ].each do |value_value|
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
- [ nil, '', 'invalid' ].each do |invalue_value|
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
- [ 'DEUTDEFF', 'DEUTDEFF500', 'SPUEDE2UXXX' ].each do |value_value|
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
- [ nil, '', 'invalid' ].each do |invalue_value|
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 :name => 'Schuldner GmbH',
7
- :bic => 'BANKDEFFXXX',
8
- :iban => 'DE87200500001234567890'
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 mission options' do
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 :name => 'Telekomiker AG',
23
- :bic => 'PBNKDEFF370',
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 :name => ''
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
- it 'should fail for invalid debtor' do
42
- expect {
43
- SEPA::CreditTransfer.new.to_xml
44
- }.to raise_error(RuntimeError)
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
- it 'should create valid XML file' do
48
- ct = credit_transfer
49
-
50
- ct.add_transaction :name => 'Telekomiker AG',
51
- :bic => 'PBNKDEFF370',
52
- :iban => 'DE37112589611964645802',
53
- :amount => 102.50,
54
- :reference => 'XYZ-1234/123',
55
- :remittance_information => 'Rechnung vom 22.08.2013'
56
-
57
- ct.add_transaction :name => 'Amazonas GmbH',
58
- :bic => 'TUBDDEDDXXX',
59
- :iban => 'DE27793589132923472195',
60
- :amount => 59.00,
61
- :reference => 'XYZ-5678/456',
62
- :remittance_information => 'Rechnung vom 21.08.2013'
63
-
64
- expect(
65
- XML::Document.string(ct.to_xml)
66
- ).to validate_against('pain.001.002.03.xsd')
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