sepa_king_extended 0.10.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +30 -0
  5. data/CONTRIBUTING.md +38 -0
  6. data/Gemfile +2 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +267 -0
  9. data/Rakefile +6 -0
  10. data/gemfiles/Gemfile-activemodel-3.0.x +5 -0
  11. data/gemfiles/Gemfile-activemodel-3.1.x +5 -0
  12. data/gemfiles/Gemfile-activemodel-3.2.x +5 -0
  13. data/gemfiles/Gemfile-activemodel-4.0.x +5 -0
  14. data/gemfiles/Gemfile-activemodel-4.1.x +5 -0
  15. data/gemfiles/Gemfile-activemodel-4.2.x +5 -0
  16. data/gemfiles/Gemfile-activemodel-5.0.x +5 -0
  17. data/gemfiles/Gemfile-activemodel-5.1.x +5 -0
  18. data/lib/schema/pain.001.001.03.xsd +921 -0
  19. data/lib/schema/pain.001.002.03.xsd +450 -0
  20. data/lib/schema/pain.001.003.03.xsd +474 -0
  21. data/lib/schema/pain.008.001.02.xsd +879 -0
  22. data/lib/schema/pain.008.002.02.xsd +597 -0
  23. data/lib/schema/pain.008.003.02.xsd +614 -0
  24. data/lib/sepa_king/account/creditor_account.rb +8 -0
  25. data/lib/sepa_king/account/debtor_account.rb +5 -0
  26. data/lib/sepa_king/account.rb +19 -0
  27. data/lib/sepa_king/converter.rb +51 -0
  28. data/lib/sepa_king/message/credit_transfer.rb +99 -0
  29. data/lib/sepa_king/message/direct_debit.rb +151 -0
  30. data/lib/sepa_king/message.rb +135 -0
  31. data/lib/sepa_king/transaction/credit_transfer_transaction.rb +30 -0
  32. data/lib/sepa_king/transaction/direct_debit_transaction.rb +45 -0
  33. data/lib/sepa_king/transaction.rb +44 -0
  34. data/lib/sepa_king/validator.rb +68 -0
  35. data/lib/sepa_king/version.rb +3 -0
  36. data/lib/sepa_king.rb +16 -0
  37. data/sepa_king_extended.gemspec +32 -0
  38. data/spec/account_spec.rb +42 -0
  39. data/spec/converter_spec.rb +74 -0
  40. data/spec/credit_transfer_spec.rb +364 -0
  41. data/spec/credit_transfer_transaction_spec.rb +58 -0
  42. data/spec/creditor_account_spec.rb +23 -0
  43. data/spec/debtor_account_spec.rb +12 -0
  44. data/spec/direct_debit_spec.rb +469 -0
  45. data/spec/direct_debit_transaction_spec.rb +69 -0
  46. data/spec/examples/pain.001.001.03.xml +89 -0
  47. data/spec/examples/pain.001.002.03.xml +89 -0
  48. data/spec/examples/pain.001.003.03.xml +89 -0
  49. data/spec/examples/pain.008.002.02.xml +134 -0
  50. data/spec/examples/pain.008.003.02.xml +134 -0
  51. data/spec/message_spec.rb +88 -0
  52. data/spec/spec_helper.rb +33 -0
  53. data/spec/support/active_model.rb +30 -0
  54. data/spec/support/custom_matcher.rb +60 -0
  55. data/spec/support/factories.rb +24 -0
  56. data/spec/support/validations.rb +27 -0
  57. data/spec/transaction_spec.rb +88 -0
  58. data/spec/validation_spec.rb +25 -0
  59. data/spec/validator_spec.rb +99 -0
  60. 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>