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.
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>