sepa_king_extended 0.10.1
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 +7 -0
- data/.gitignore +9 -0
- data/.rspec +2 -0
- data/.travis.yml +30 -0
- data/CONTRIBUTING.md +38 -0
- data/Gemfile +2 -0
- data/LICENSE.txt +22 -0
- data/README.md +267 -0
- data/Rakefile +6 -0
- data/gemfiles/Gemfile-activemodel-3.0.x +5 -0
- data/gemfiles/Gemfile-activemodel-3.1.x +5 -0
- data/gemfiles/Gemfile-activemodel-3.2.x +5 -0
- data/gemfiles/Gemfile-activemodel-4.0.x +5 -0
- data/gemfiles/Gemfile-activemodel-4.1.x +5 -0
- data/gemfiles/Gemfile-activemodel-4.2.x +5 -0
- data/gemfiles/Gemfile-activemodel-5.0.x +5 -0
- data/gemfiles/Gemfile-activemodel-5.1.x +5 -0
- data/lib/schema/pain.001.001.03.xsd +921 -0
- data/lib/schema/pain.001.002.03.xsd +450 -0
- data/lib/schema/pain.001.003.03.xsd +474 -0
- data/lib/schema/pain.008.001.02.xsd +879 -0
- data/lib/schema/pain.008.002.02.xsd +597 -0
- data/lib/schema/pain.008.003.02.xsd +614 -0
- data/lib/sepa_king/account/creditor_account.rb +8 -0
- data/lib/sepa_king/account/debtor_account.rb +5 -0
- data/lib/sepa_king/account.rb +19 -0
- data/lib/sepa_king/converter.rb +51 -0
- data/lib/sepa_king/message/credit_transfer.rb +99 -0
- data/lib/sepa_king/message/direct_debit.rb +151 -0
- data/lib/sepa_king/message.rb +135 -0
- data/lib/sepa_king/transaction/credit_transfer_transaction.rb +30 -0
- data/lib/sepa_king/transaction/direct_debit_transaction.rb +45 -0
- data/lib/sepa_king/transaction.rb +44 -0
- data/lib/sepa_king/validator.rb +68 -0
- data/lib/sepa_king/version.rb +3 -0
- data/lib/sepa_king.rb +16 -0
- data/sepa_king_extended.gemspec +32 -0
- data/spec/account_spec.rb +42 -0
- data/spec/converter_spec.rb +74 -0
- data/spec/credit_transfer_spec.rb +364 -0
- data/spec/credit_transfer_transaction_spec.rb +58 -0
- data/spec/creditor_account_spec.rb +23 -0
- data/spec/debtor_account_spec.rb +12 -0
- data/spec/direct_debit_spec.rb +469 -0
- data/spec/direct_debit_transaction_spec.rb +69 -0
- data/spec/examples/pain.001.001.03.xml +89 -0
- data/spec/examples/pain.001.002.03.xml +89 -0
- data/spec/examples/pain.001.003.03.xml +89 -0
- data/spec/examples/pain.008.002.02.xml +134 -0
- data/spec/examples/pain.008.003.02.xml +134 -0
- data/spec/message_spec.rb +88 -0
- data/spec/spec_helper.rb +33 -0
- data/spec/support/active_model.rb +30 -0
- data/spec/support/custom_matcher.rb +60 -0
- data/spec/support/factories.rb +24 -0
- data/spec/support/validations.rb +27 -0
- data/spec/transaction_spec.rb +88 -0
- data/spec/validation_spec.rb +25 -0
- data/spec/validator_spec.rb +99 -0
- metadata +254 -0
@@ -0,0 +1,469 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe SEPA::DirectDebit do
|
5
|
+
let(:message_id_regex) { /SEPA-KING\/[0-9a-z_]{22}/ }
|
6
|
+
|
7
|
+
let(:direct_debit) {
|
8
|
+
SEPA::DirectDebit.new name: 'Gläubiger GmbH',
|
9
|
+
bic: 'BANKDEFFXXX',
|
10
|
+
iban: 'DE87200500001234567890',
|
11
|
+
creditor_identifier: 'DE98ZZZ09999999999'
|
12
|
+
}
|
13
|
+
|
14
|
+
describe :new do
|
15
|
+
it 'should accept missing options' do
|
16
|
+
expect {
|
17
|
+
SEPA::DirectDebit.new
|
18
|
+
}.to_not raise_error
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe :add_transaction do
|
23
|
+
it 'should add valid transactions' do
|
24
|
+
3.times do
|
25
|
+
direct_debit.add_transaction(direct_debt_transaction)
|
26
|
+
end
|
27
|
+
|
28
|
+
expect(direct_debit.transactions.size).to eq(3)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should fail for invalid transaction' do
|
32
|
+
expect {
|
33
|
+
direct_debit.add_transaction name: ''
|
34
|
+
}.to raise_error(ArgumentError)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe :batch_id do
|
39
|
+
it 'returns the id of the batch where the given transactions belongs to (1 batch)' do
|
40
|
+
direct_debit.add_transaction(direct_debt_transaction(reference: "EXAMPLE REFERENCE"))
|
41
|
+
|
42
|
+
expect(direct_debit.batch_id("EXAMPLE REFERENCE")).to match(/#{message_id_regex}\/1/)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'returns the id of the batch where the given transactions belongs to (2 batches)' do
|
46
|
+
direct_debit.add_transaction(direct_debt_transaction(reference: "EXAMPLE REFERENCE 1"))
|
47
|
+
direct_debit.add_transaction(direct_debt_transaction(reference: "EXAMPLE REFERENCE 2", requested_date: Date.today.next.next))
|
48
|
+
direct_debit.add_transaction(direct_debt_transaction(reference: "EXAMPLE REFERENCE 3"))
|
49
|
+
|
50
|
+
expect(direct_debit.batch_id("EXAMPLE REFERENCE 1")).to match(/#{message_id_regex}\/1/)
|
51
|
+
expect(direct_debit.batch_id("EXAMPLE REFERENCE 2")).to match(/#{message_id_regex}\/2/)
|
52
|
+
expect(direct_debit.batch_id("EXAMPLE REFERENCE 3")).to match(/#{message_id_regex}\/1/)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe :batches do
|
57
|
+
it 'returns an array of batch ids in the sepa message' do
|
58
|
+
direct_debit.add_transaction(direct_debt_transaction(reference: "EXAMPLE REFERENCE 1"))
|
59
|
+
direct_debit.add_transaction(direct_debt_transaction(reference: "EXAMPLE REFERENCE 2", requested_date: Date.today.next.next))
|
60
|
+
direct_debit.add_transaction(direct_debt_transaction(reference: "EXAMPLE REFERENCE 3"))
|
61
|
+
|
62
|
+
expect(direct_debit.batches.size).to eq(2)
|
63
|
+
expect(direct_debit.batches[0]).to match(/#{message_id_regex}\/[0-9]+/)
|
64
|
+
expect(direct_debit.batches[1]).to match(/#{message_id_regex}\/[0-9]+/)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe :to_xml do
|
69
|
+
context 'for invalid creditor' do
|
70
|
+
it 'should fail' do
|
71
|
+
expect {
|
72
|
+
SEPA::DirectDebit.new.to_xml
|
73
|
+
}.to raise_error(RuntimeError)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context 'for valid creditor' do
|
78
|
+
context 'without BIC (IBAN-only)' do
|
79
|
+
subject do
|
80
|
+
sdd = SEPA::DirectDebit.new name: 'Gläubiger GmbH',
|
81
|
+
iban: 'DE87200500001234567890',
|
82
|
+
creditor_identifier: 'DE98ZZZ09999999999'
|
83
|
+
|
84
|
+
sdd.add_transaction name: 'Zahlemann & Söhne GbR',
|
85
|
+
bic: 'SPUEDE2UXXX',
|
86
|
+
iban: 'DE21500500009876543210',
|
87
|
+
amount: 39.99,
|
88
|
+
reference: 'XYZ/2013-08-ABO/12345',
|
89
|
+
remittance_information: 'Unsere Rechnung vom 10.08.2013',
|
90
|
+
mandate_id: 'K-02-2011-12345',
|
91
|
+
mandate_date_of_signature: Date.new(2011,1,25)
|
92
|
+
|
93
|
+
sdd
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'should validate against pain.008.003.02' do
|
97
|
+
expect(subject.to_xml(SEPA::PAIN_008_003_02)).to validate_against('pain.008.003.02.xsd')
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'should fail for pain.008.002.02' do
|
101
|
+
expect {
|
102
|
+
subject.to_xml(SEPA::PAIN_008_002_02)
|
103
|
+
}.to raise_error(RuntimeError)
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'should validate against pain.008.001.02' do
|
107
|
+
expect(subject.to_xml(SEPA::PAIN_008_001_02)).to validate_against('pain.008.001.02.xsd')
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
context 'with BIC' do
|
112
|
+
subject do
|
113
|
+
sdd = direct_debit
|
114
|
+
|
115
|
+
sdd.add_transaction name: 'Zahlemann & Söhne GbR',
|
116
|
+
bic: 'SPUEDE2UXXX',
|
117
|
+
iban: 'DE21500500009876543210',
|
118
|
+
amount: 39.99,
|
119
|
+
reference: 'XYZ/2013-08-ABO/12345',
|
120
|
+
remittance_information: 'Unsere Rechnung vom 10.08.2013',
|
121
|
+
mandate_id: 'K-02-2011-12345',
|
122
|
+
mandate_date_of_signature: Date.new(2011,1,25)
|
123
|
+
|
124
|
+
sdd
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'should validate against pain.008.001.02' do
|
128
|
+
expect(subject.to_xml(SEPA::PAIN_008_001_02)).to validate_against('pain.008.001.02.xsd')
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'should validate against pain.008.002.02' do
|
132
|
+
expect(subject.to_xml(SEPA::PAIN_008_002_02)).to validate_against('pain.008.002.02.xsd')
|
133
|
+
end
|
134
|
+
|
135
|
+
it 'should validate against pain.008.003.02' do
|
136
|
+
expect(subject.to_xml(SEPA::PAIN_008_003_02)).to validate_against('pain.008.003.02.xsd')
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
context 'without requested_date given' do
|
141
|
+
subject do
|
142
|
+
sdd = direct_debit
|
143
|
+
|
144
|
+
sdd.add_transaction name: 'Zahlemann & Söhne GbR',
|
145
|
+
bic: 'SPUEDE2UXXX',
|
146
|
+
iban: 'DE21500500009876543210',
|
147
|
+
amount: 39.99,
|
148
|
+
reference: 'XYZ/2013-08-ABO/12345',
|
149
|
+
remittance_information: 'Unsere Rechnung vom 10.08.2013',
|
150
|
+
mandate_id: 'K-02-2011-12345',
|
151
|
+
mandate_date_of_signature: Date.new(2011,1,25)
|
152
|
+
|
153
|
+
sdd.add_transaction name: 'Meier & Schulze oHG',
|
154
|
+
iban: 'DE68210501700012345678',
|
155
|
+
amount: 750.00,
|
156
|
+
reference: 'XYZ/2013-08-ABO/6789',
|
157
|
+
remittance_information: 'Vielen Dank für Ihren Einkauf!',
|
158
|
+
mandate_id: 'K-08-2010-42123',
|
159
|
+
mandate_date_of_signature: Date.new(2010,7,25)
|
160
|
+
|
161
|
+
sdd.to_xml
|
162
|
+
end
|
163
|
+
|
164
|
+
it 'should create valid XML file' do
|
165
|
+
expect(subject).to validate_against('pain.008.003.02.xsd')
|
166
|
+
end
|
167
|
+
|
168
|
+
it 'should have message_identification' do
|
169
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/GrpHdr/MsgId', message_id_regex)
|
170
|
+
end
|
171
|
+
|
172
|
+
it 'should have creditor identifier' do
|
173
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/GrpHdr/InitgPty/Id/OrgId/Othr/Id', direct_debit.account.creditor_identifier)
|
174
|
+
end
|
175
|
+
|
176
|
+
it 'should contain <PmtInfId>' do
|
177
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf/PmtInfId', /#{message_id_regex}\/1/)
|
178
|
+
end
|
179
|
+
|
180
|
+
it 'should contain <ReqdColltnDt>' do
|
181
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf/ReqdColltnDt', Date.new(1999, 1, 1).iso8601)
|
182
|
+
end
|
183
|
+
|
184
|
+
it 'should contain <PmtMtd>' do
|
185
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf/PmtMtd', 'DD')
|
186
|
+
end
|
187
|
+
|
188
|
+
it 'should contain <BtchBookg>' do
|
189
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf/BtchBookg', 'true')
|
190
|
+
end
|
191
|
+
|
192
|
+
it 'should contain <NbOfTxs>' do
|
193
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf/NbOfTxs', '2')
|
194
|
+
end
|
195
|
+
|
196
|
+
it 'should contain <CtrlSum>' do
|
197
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf/CtrlSum', '789.99')
|
198
|
+
end
|
199
|
+
|
200
|
+
it 'should contain <Cdtr>' do
|
201
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf/Cdtr/Nm', 'Gläubiger GmbH')
|
202
|
+
end
|
203
|
+
|
204
|
+
it 'should contain <CdtrAcct>' do
|
205
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf/CdtrAcct/Id/IBAN', 'DE87200500001234567890')
|
206
|
+
end
|
207
|
+
|
208
|
+
it 'should contain <CdtrAgt>' do
|
209
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf/CdtrAgt/FinInstnId/BIC', 'BANKDEFFXXX')
|
210
|
+
end
|
211
|
+
|
212
|
+
it 'should contain <CdtrAgt>' do
|
213
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf/CdtrSchmeId/Id/PrvtId/Othr/Id', 'DE98ZZZ09999999999')
|
214
|
+
end
|
215
|
+
|
216
|
+
it 'should contain <EndToEndId>' do
|
217
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf/DrctDbtTxInf[1]/PmtId/EndToEndId', 'XYZ/2013-08-ABO/12345')
|
218
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf/DrctDbtTxInf[2]/PmtId/EndToEndId', 'XYZ/2013-08-ABO/6789')
|
219
|
+
end
|
220
|
+
|
221
|
+
it 'should contain <InstdAmt>' do
|
222
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf/DrctDbtTxInf[1]/InstdAmt', '39.99')
|
223
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf/DrctDbtTxInf[2]/InstdAmt', '750.00')
|
224
|
+
end
|
225
|
+
|
226
|
+
it 'should contain <MndtId>' do
|
227
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf/DrctDbtTxInf[1]/DrctDbtTx/MndtRltdInf/MndtId', 'K-02-2011-12345')
|
228
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf/DrctDbtTxInf[2]/DrctDbtTx/MndtRltdInf/MndtId', 'K-08-2010-42123')
|
229
|
+
end
|
230
|
+
|
231
|
+
it 'should contain <DtOfSgntr>' do
|
232
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf/DrctDbtTxInf[1]/DrctDbtTx/MndtRltdInf/DtOfSgntr', '2011-01-25')
|
233
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf/DrctDbtTxInf[2]/DrctDbtTx/MndtRltdInf/DtOfSgntr', '2010-07-25')
|
234
|
+
end
|
235
|
+
|
236
|
+
it 'should contain <DbtrAgt>' do
|
237
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf/DrctDbtTxInf[1]/DbtrAgt/FinInstnId/BIC', 'SPUEDE2UXXX')
|
238
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf/DrctDbtTxInf[2]/DbtrAgt/FinInstnId/Othr/Id', 'NOTPROVIDED')
|
239
|
+
end
|
240
|
+
|
241
|
+
it 'should contain <Dbtr>' do
|
242
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf/DrctDbtTxInf[1]/Dbtr/Nm', 'Zahlemann & Söhne GbR')
|
243
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf/DrctDbtTxInf[2]/Dbtr/Nm', 'Meier & Schulze oHG')
|
244
|
+
end
|
245
|
+
|
246
|
+
it 'should contain <DbtrAcct>' do
|
247
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf/DrctDbtTxInf[1]/DbtrAcct/Id/IBAN', 'DE21500500009876543210')
|
248
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf/DrctDbtTxInf[2]/DbtrAcct/Id/IBAN', 'DE68210501700012345678')
|
249
|
+
end
|
250
|
+
|
251
|
+
it 'should contain <RmtInf>' do
|
252
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf/DrctDbtTxInf[1]/RmtInf/Ustrd', 'Unsere Rechnung vom 10.08.2013')
|
253
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf/DrctDbtTxInf[2]/RmtInf/Ustrd', 'Vielen Dank für Ihren Einkauf')
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
context 'with different requested_date given' do
|
258
|
+
subject do
|
259
|
+
sdd = direct_debit
|
260
|
+
|
261
|
+
sdd.add_transaction(direct_debt_transaction.merge requested_date: Date.today + 1)
|
262
|
+
sdd.add_transaction(direct_debt_transaction.merge requested_date: Date.today + 2)
|
263
|
+
sdd.add_transaction(direct_debt_transaction.merge requested_date: Date.today + 2)
|
264
|
+
|
265
|
+
sdd.to_xml
|
266
|
+
end
|
267
|
+
|
268
|
+
it 'should contain two payment_informations with <ReqdColltnDt>' do
|
269
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf[1]/ReqdColltnDt', (Date.today + 1).iso8601)
|
270
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf[2]/ReqdColltnDt', (Date.today + 2).iso8601)
|
271
|
+
|
272
|
+
expect(subject).not_to have_xml('//Document/CstmrDrctDbtInitn/PmtInf[3]')
|
273
|
+
end
|
274
|
+
|
275
|
+
it 'should contain two payment_informations with different <PmtInfId>' do
|
276
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf[1]/PmtInfId', /#{message_id_regex}\/1/)
|
277
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf[2]/PmtInfId', /#{message_id_regex}\/2/)
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
context 'with different local_instrument given' do
|
282
|
+
subject do
|
283
|
+
sdd = direct_debit
|
284
|
+
|
285
|
+
sdd.add_transaction(direct_debt_transaction.merge local_instrument: 'CORE')
|
286
|
+
sdd.add_transaction(direct_debt_transaction.merge local_instrument: 'B2B')
|
287
|
+
|
288
|
+
sdd
|
289
|
+
end
|
290
|
+
|
291
|
+
it 'should have errors' do
|
292
|
+
expect(subject.errors_on(:base).size).to eq(1)
|
293
|
+
end
|
294
|
+
|
295
|
+
it 'should raise error on XML generation' do
|
296
|
+
expect {
|
297
|
+
subject.to_xml
|
298
|
+
}.to raise_error(RuntimeError)
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
context 'with different sequence_type given' do
|
303
|
+
subject do
|
304
|
+
sdd = direct_debit
|
305
|
+
|
306
|
+
sdd.add_transaction(direct_debt_transaction.merge sequence_type: 'OOFF')
|
307
|
+
sdd.add_transaction(direct_debt_transaction.merge sequence_type: 'FRST')
|
308
|
+
sdd.add_transaction(direct_debt_transaction.merge sequence_type: 'FRST')
|
309
|
+
|
310
|
+
sdd.to_xml
|
311
|
+
end
|
312
|
+
|
313
|
+
it 'should contain two payment_informations with <LclInstrm>' do
|
314
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf[1]/PmtTpInf/SeqTp', 'OOFF')
|
315
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf[2]/PmtTpInf/SeqTp', 'FRST')
|
316
|
+
|
317
|
+
expect(subject).not_to have_xml('//Document/CstmrDrctDbtInitn/PmtInf[3]')
|
318
|
+
end
|
319
|
+
end
|
320
|
+
|
321
|
+
context 'with different batch_booking given' do
|
322
|
+
subject do
|
323
|
+
sdd = direct_debit
|
324
|
+
|
325
|
+
sdd.add_transaction(direct_debt_transaction.merge batch_booking: false)
|
326
|
+
sdd.add_transaction(direct_debt_transaction.merge batch_booking: true)
|
327
|
+
sdd.add_transaction(direct_debt_transaction.merge batch_booking: true)
|
328
|
+
|
329
|
+
sdd.to_xml
|
330
|
+
end
|
331
|
+
|
332
|
+
it 'should contain two payment_informations with <BtchBookg>' do
|
333
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf[1]/BtchBookg', 'false')
|
334
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf[2]/BtchBookg', 'true')
|
335
|
+
|
336
|
+
expect(subject).not_to have_xml('//Document/CstmrDrctDbtInitn/PmtInf[3]')
|
337
|
+
end
|
338
|
+
end
|
339
|
+
|
340
|
+
context 'with transactions containing different group criteria' do
|
341
|
+
subject do
|
342
|
+
sdd = direct_debit
|
343
|
+
|
344
|
+
sdd.add_transaction(direct_debt_transaction.merge requested_date: Date.today + 1, sequence_type: 'OOFF', amount: 1)
|
345
|
+
sdd.add_transaction(direct_debt_transaction.merge requested_date: Date.today + 1, sequence_type: 'FNAL', amount: 2)
|
346
|
+
sdd.add_transaction(direct_debt_transaction.merge requested_date: Date.today + 2, sequence_type: 'OOFF', amount: 4)
|
347
|
+
sdd.add_transaction(direct_debt_transaction.merge requested_date: Date.today + 2, sequence_type: 'FNAL', amount: 8)
|
348
|
+
|
349
|
+
sdd.to_xml
|
350
|
+
end
|
351
|
+
|
352
|
+
it 'should contain multiple payment_informations' do
|
353
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf[1]/ReqdColltnDt', (Date.today + 1).iso8601)
|
354
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf[1]/PmtTpInf/SeqTp', 'OOFF')
|
355
|
+
|
356
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf[2]/ReqdColltnDt', (Date.today + 1).iso8601)
|
357
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf[2]/PmtTpInf/SeqTp', 'FNAL')
|
358
|
+
|
359
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf[3]/ReqdColltnDt', (Date.today + 2).iso8601)
|
360
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf[3]/PmtTpInf/SeqTp', 'OOFF')
|
361
|
+
|
362
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf[4]/ReqdColltnDt', (Date.today + 2).iso8601)
|
363
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf[4]/PmtTpInf/SeqTp', 'FNAL')
|
364
|
+
end
|
365
|
+
|
366
|
+
it 'should have multiple control sums' do
|
367
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf[1]/CtrlSum', '1.00')
|
368
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf[2]/CtrlSum', '2.00')
|
369
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf[3]/CtrlSum', '4.00')
|
370
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf[4]/CtrlSum', '8.00')
|
371
|
+
end
|
372
|
+
end
|
373
|
+
|
374
|
+
context 'with transactions containing different creditor_account' do
|
375
|
+
subject do
|
376
|
+
sdd = direct_debit
|
377
|
+
|
378
|
+
sdd.add_transaction(direct_debt_transaction)
|
379
|
+
sdd.add_transaction(direct_debt_transaction.merge(creditor_account: SEPA::CreditorAccount.new(
|
380
|
+
name: 'Creditor Inc.',
|
381
|
+
bic: 'RABONL2U',
|
382
|
+
iban: 'NL08RABO0135742099',
|
383
|
+
creditor_identifier: 'NL53ZZZ091734220000'))
|
384
|
+
)
|
385
|
+
|
386
|
+
sdd.to_xml
|
387
|
+
end
|
388
|
+
|
389
|
+
it 'should contain two payment_informations with <Cdtr>' do
|
390
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf[1]/Cdtr/Nm', 'Gläubiger GmbH')
|
391
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf[2]/Cdtr/Nm', 'Creditor Inc.')
|
392
|
+
end
|
393
|
+
end
|
394
|
+
|
395
|
+
context 'with mandate amendments' do
|
396
|
+
subject do
|
397
|
+
sdd = direct_debit
|
398
|
+
|
399
|
+
sdd.add_transaction(direct_debt_transaction.merge(original_debtor_account: 'NL08RABO0135742099'))
|
400
|
+
sdd.add_transaction(direct_debt_transaction.merge(same_mandate_new_debtor_agent: true))
|
401
|
+
sdd.to_xml
|
402
|
+
end
|
403
|
+
|
404
|
+
it 'should include amendment indicator' do
|
405
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf/DrctDbtTxInf[1]/DrctDbtTx/MndtRltdInf/AmdmntInd', 'true')
|
406
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf/DrctDbtTxInf[2]/DrctDbtTx/MndtRltdInf/AmdmntInd', 'true')
|
407
|
+
end
|
408
|
+
|
409
|
+
it 'should include amendment information details' do
|
410
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf/DrctDbtTxInf[1]/DrctDbtTx/MndtRltdInf/AmdmntInfDtls/OrgnlDbtrAcct/Id/IBAN', 'NL08RABO0135742099')
|
411
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf/DrctDbtTxInf[2]/DrctDbtTx/MndtRltdInf/AmdmntInfDtls/OrgnlDbtrAgt/FinInstnId/Othr/Id', 'SMNDA')
|
412
|
+
end
|
413
|
+
end
|
414
|
+
|
415
|
+
context 'with instruction given' do
|
416
|
+
subject do
|
417
|
+
sct = direct_debit
|
418
|
+
|
419
|
+
sct.add_transaction(direct_debt_transaction.merge(instruction: '1234/ABC'))
|
420
|
+
|
421
|
+
sct.to_xml
|
422
|
+
end
|
423
|
+
|
424
|
+
it 'should create valid XML file' do
|
425
|
+
expect(subject).to validate_against('pain.008.003.02.xsd')
|
426
|
+
end
|
427
|
+
|
428
|
+
it 'should contain <InstrId>' do
|
429
|
+
expect(subject).to have_xml('//Document/CstmrDrctDbtInitn/PmtInf/DrctDbtTxInf[1]/PmtId/InstrId', '1234/ABC')
|
430
|
+
end
|
431
|
+
end
|
432
|
+
|
433
|
+
context 'with a different currency given' do
|
434
|
+
subject do
|
435
|
+
sct = direct_debit
|
436
|
+
|
437
|
+
sct.add_transaction(direct_debt_transaction.merge(instruction: '1234/ABC', currency: 'SEK'))
|
438
|
+
|
439
|
+
sct
|
440
|
+
end
|
441
|
+
|
442
|
+
it 'should validate against pain.001.001.03' do
|
443
|
+
expect(subject.to_xml(SEPA::PAIN_008_001_02)).to validate_against('pain.008.001.02.xsd')
|
444
|
+
end
|
445
|
+
|
446
|
+
it 'should have a CHF Ccy' do
|
447
|
+
doc = Nokogiri::XML(subject.to_xml('pain.008.001.02'))
|
448
|
+
doc.remove_namespaces!
|
449
|
+
|
450
|
+
nodes = doc.xpath('//Document/CstmrDrctDbtInitn/PmtInf/DrctDbtTxInf[1]/InstdAmt')
|
451
|
+
expect(nodes.length).to eql(1)
|
452
|
+
expect(nodes.first.attribute('Ccy').value).to eql('SEK')
|
453
|
+
end
|
454
|
+
|
455
|
+
it 'should fail for pain.008.002.02' do
|
456
|
+
expect {
|
457
|
+
subject.to_xml(SEPA::PAIN_008_002_02)
|
458
|
+
}.to raise_error(RuntimeError)
|
459
|
+
end
|
460
|
+
|
461
|
+
it 'should fail for pain.008.003.02' do
|
462
|
+
expect {
|
463
|
+
subject.to_xml(SEPA::PAIN_008_003_02)
|
464
|
+
}.to raise_error(RuntimeError)
|
465
|
+
end
|
466
|
+
end
|
467
|
+
end
|
468
|
+
end
|
469
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe SEPA::DirectDebitTransaction do
|
5
|
+
describe :initialize do
|
6
|
+
it 'should create a valid transaction' do
|
7
|
+
expect(
|
8
|
+
SEPA::DirectDebitTransaction.new name: 'Zahlemann & Söhne Gbr',
|
9
|
+
bic: 'SPUEDE2UXXX',
|
10
|
+
iban: 'DE21500500009876543210',
|
11
|
+
amount: 39.99,
|
12
|
+
reference: 'XYZ-1234/123',
|
13
|
+
remittance_information: 'Vielen Dank für Ihren Einkauf!',
|
14
|
+
mandate_id: 'K-02-2011-12345',
|
15
|
+
mandate_date_of_signature: Date.new(2011,1,25)
|
16
|
+
).to be_valid
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe :schema_compatible? do
|
21
|
+
context 'for pain.008.003.02' do
|
22
|
+
it 'should succeed' do
|
23
|
+
expect(SEPA::DirectDebitTransaction.new({})).to be_schema_compatible('pain.008.003.02')
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'should fail for invalid attributes' do
|
27
|
+
expect(SEPA::DirectDebitTransaction.new(:currency => 'CHF')).not_to be_schema_compatible('pain.001.003.03')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'for pain.008.002.02' do
|
32
|
+
it 'should succeed for valid attributes' do
|
33
|
+
expect(SEPA::DirectDebitTransaction.new(:bic => 'SPUEDE2UXXX', :local_instrument => 'CORE')).to be_schema_compatible('pain.008.002.02')
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should fail for invalid attributes' do
|
37
|
+
expect(SEPA::DirectDebitTransaction.new(:bic => nil)).not_to be_schema_compatible('pain.008.002.02')
|
38
|
+
expect(SEPA::DirectDebitTransaction.new(:bic => 'SPUEDE2UXXX', :local_instrument => 'COR1')).not_to be_schema_compatible('pain.008.002.02')
|
39
|
+
expect(SEPA::DirectDebitTransaction.new(:bic => 'SPUEDE2UXXX', :currency => 'CHF')).not_to be_schema_compatible('pain.008.002.02')
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context 'for pain.008.001.02' do
|
44
|
+
it 'should succeed for valid attributes' do
|
45
|
+
expect(SEPA::DirectDebitTransaction.new(:bic => 'SPUEDE2UXXX', :currency => 'CHF')).to be_schema_compatible('pain.008.001.02')
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'Mandate Date of Signature' do
|
51
|
+
it 'should accept valid value' do
|
52
|
+
expect(SEPA::DirectDebitTransaction).to accept(Date.today, Date.today - 1, for: :mandate_date_of_signature)
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should not accept invalid value' do
|
56
|
+
expect(SEPA::DirectDebitTransaction).not_to accept(nil, '2010-12-01', Date.today + 1, for: :mandate_date_of_signature)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context 'Requested date' do
|
61
|
+
it 'should allow valid value' do
|
62
|
+
expect(SEPA::DirectDebitTransaction).to accept(nil, Date.new(1999, 1, 1), Date.today.next, Date.today + 2, for: :requested_date)
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'should not allow invalid value' do
|
66
|
+
expect(SEPA::DirectDebitTransaction).not_to accept(Date.new(1995,12,21), Date.today - 1, Date.today, for: :requested_date)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<!-- Mit XMLSpy v2008 rel. 2 sp2 (http://www.altova.com) von benutzerservice benutzerservice (SIZ GmbH) bearbeitet -->
|
3
|
+
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.03" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:iso:std:iso:20022:tech:xsd:pain.001.001.03 pain.001.001.03.xsd">
|
4
|
+
<CstmrCdtTrfInitn>
|
5
|
+
<GrpHdr>
|
6
|
+
<MsgId>Message-ID-4711</MsgId>
|
7
|
+
<CreDtTm>2010-11-11T09:30:47.000Z</CreDtTm>
|
8
|
+
<NbOfTxs>2</NbOfTxs>
|
9
|
+
<InitgPty>
|
10
|
+
<Nm>Initiator Name</Nm>
|
11
|
+
</InitgPty>
|
12
|
+
</GrpHdr>
|
13
|
+
<PmtInf>
|
14
|
+
<PmtInfId>Payment-Information-ID-4711</PmtInfId>
|
15
|
+
<PmtMtd>TRF</PmtMtd>
|
16
|
+
<BtchBookg>true</BtchBookg>
|
17
|
+
<NbOfTxs>2</NbOfTxs>
|
18
|
+
<CtrlSum>6655.86</CtrlSum>
|
19
|
+
<PmtTpInf>
|
20
|
+
<SvcLvl>
|
21
|
+
<Cd>SEPA</Cd>
|
22
|
+
</SvcLvl>
|
23
|
+
</PmtTpInf>
|
24
|
+
<ReqdExctnDt>2010-11-25</ReqdExctnDt>
|
25
|
+
<Dbtr>
|
26
|
+
<Nm>Debtor Name</Nm>
|
27
|
+
</Dbtr>
|
28
|
+
<DbtrAcct>
|
29
|
+
<Id>
|
30
|
+
<IBAN>DE87200500001234567890</IBAN>
|
31
|
+
</Id>
|
32
|
+
</DbtrAcct>
|
33
|
+
<DbtrAgt>
|
34
|
+
<FinInstnId>
|
35
|
+
<BIC>BANKDEFFXXX</BIC>
|
36
|
+
</FinInstnId>
|
37
|
+
</DbtrAgt>
|
38
|
+
<ChrgBr>SLEV</ChrgBr>
|
39
|
+
<CdtTrfTxInf>
|
40
|
+
<PmtId>
|
41
|
+
<EndToEndId>OriginatorID1234</EndToEndId>
|
42
|
+
</PmtId>
|
43
|
+
<Amt>
|
44
|
+
<InstdAmt Ccy="EUR">6543.14</InstdAmt>
|
45
|
+
</Amt>
|
46
|
+
<CdtrAgt>
|
47
|
+
<FinInstnId>
|
48
|
+
<BIC>SPUEDE2UXXX</BIC>
|
49
|
+
</FinInstnId>
|
50
|
+
</CdtrAgt>
|
51
|
+
<Cdtr>
|
52
|
+
<Nm>Creditor Name</Nm>
|
53
|
+
</Cdtr>
|
54
|
+
<CdtrAcct>
|
55
|
+
<Id>
|
56
|
+
<IBAN>DE21500500009876543210</IBAN>
|
57
|
+
</Id>
|
58
|
+
</CdtrAcct>
|
59
|
+
<RmtInf>
|
60
|
+
<Ustrd>Unstructured Remittance Information</Ustrd>
|
61
|
+
</RmtInf>
|
62
|
+
</CdtTrfTxInf>
|
63
|
+
<CdtTrfTxInf>
|
64
|
+
<PmtId>
|
65
|
+
<EndToEndId>OriginatorID1235</EndToEndId>
|
66
|
+
</PmtId>
|
67
|
+
<Amt>
|
68
|
+
<InstdAmt Ccy="EUR">112.72</InstdAmt>
|
69
|
+
</Amt>
|
70
|
+
<CdtrAgt>
|
71
|
+
<FinInstnId>
|
72
|
+
<BIC>SPUEDE2UXXX</BIC>
|
73
|
+
</FinInstnId>
|
74
|
+
</CdtrAgt>
|
75
|
+
<Cdtr>
|
76
|
+
<Nm>Other Creditor Name</Nm>
|
77
|
+
</Cdtr>
|
78
|
+
<CdtrAcct>
|
79
|
+
<Id>
|
80
|
+
<IBAN>DE21500500001234567897</IBAN>
|
81
|
+
</Id>
|
82
|
+
</CdtrAcct>
|
83
|
+
<RmtInf>
|
84
|
+
<Ustrd>Unstructured Remittance Information</Ustrd>
|
85
|
+
</RmtInf>
|
86
|
+
</CdtTrfTxInf>
|
87
|
+
</PmtInf>
|
88
|
+
</CstmrCdtTrfInitn>
|
89
|
+
</Document>
|