sepa_king 0.11.1 → 0.13.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/main.yml +50 -0
- data/.gitignore +1 -1
- data/LICENSE.txt +1 -1
- data/README.md +10 -11
- data/gemfiles/{Gemfile-activemodel-4.0.x → Gemfile-activemodel-6.0.x} +1 -1
- data/gemfiles/{Gemfile-activemodel-4.1.x → Gemfile-activemodel-6.1.x} +1 -1
- data/gemfiles/{Gemfile-activemodel-3.1.x → Gemfile-activemodel-7.0.x} +1 -1
- data/lib/schema/pain.001.001.03.ch.02.xsd +1212 -0
- data/lib/sepa_king/message/credit_transfer.rb +4 -2
- data/lib/sepa_king/message/direct_debit.rb +1 -1
- data/lib/sepa_king/message.rb +15 -6
- data/lib/sepa_king/transaction/credit_transfer_transaction.rb +2 -0
- data/lib/sepa_king/validator.rb +11 -6
- data/lib/sepa_king/version.rb +1 -1
- data/sepa_king.gemspec +6 -8
- data/spec/credit_transfer_spec.rb +111 -12
- data/spec/credit_transfer_transaction_spec.rb +6 -0
- data/spec/direct_debit_spec.rb +90 -9
- data/spec/examples/pain.001.001.03.ch.02.xml +172 -0
- data/spec/validator_spec.rb +23 -5
- metadata +21 -46
- data/.travis.yml +0 -25
- data/bin/rake +0 -29
- data/gemfiles/Gemfile-activemodel-3.2.x +0 -5
@@ -5,7 +5,7 @@ module SEPA
|
|
5
5
|
self.account_class = DebtorAccount
|
6
6
|
self.transaction_class = CreditTransferTransaction
|
7
7
|
self.xml_main_tag = 'CstmrCdtTrfInitn'
|
8
|
-
self.known_schemas = [ PAIN_001_003_03, PAIN_001_002_03
|
8
|
+
self.known_schemas = [ PAIN_001_001_03, PAIN_001_001_03_CH_02, PAIN_001_003_03, PAIN_001_002_03 ]
|
9
9
|
|
10
10
|
private
|
11
11
|
# Find groups of transactions which share the same values of some attributes
|
@@ -59,7 +59,9 @@ module SEPA
|
|
59
59
|
end
|
60
60
|
end
|
61
61
|
end
|
62
|
-
|
62
|
+
if group[:service_level]
|
63
|
+
builder.ChrgBr('SLEV')
|
64
|
+
end
|
63
65
|
|
64
66
|
transactions.each do |transaction|
|
65
67
|
build_transaction(builder, transaction)
|
@@ -5,7 +5,7 @@ module SEPA
|
|
5
5
|
self.account_class = CreditorAccount
|
6
6
|
self.transaction_class = DirectDebitTransaction
|
7
7
|
self.xml_main_tag = 'CstmrDrctDbtInitn'
|
8
|
-
self.known_schemas = [ PAIN_008_003_02, PAIN_008_002_02
|
8
|
+
self.known_schemas = [ PAIN_008_001_02, PAIN_008_003_02, PAIN_008_002_02 ]
|
9
9
|
|
10
10
|
validate do |record|
|
11
11
|
if record.transactions.map(&:local_instrument).uniq.size > 1
|
data/lib/sepa_king/message.rb
CHANGED
@@ -7,6 +7,7 @@ module SEPA
|
|
7
7
|
PAIN_001_001_03 = 'pain.001.001.03'
|
8
8
|
PAIN_001_002_03 = 'pain.001.002.03'
|
9
9
|
PAIN_001_003_03 = 'pain.001.003.03'
|
10
|
+
PAIN_001_001_03_CH_02 = 'pain.001.001.03.ch.02'
|
10
11
|
|
11
12
|
class Message
|
12
13
|
include ActiveModel::Validations
|
@@ -41,7 +42,7 @@ module SEPA
|
|
41
42
|
raise SEPA::Error.new(errors.full_messages.join("\n")) unless valid?
|
42
43
|
raise SEPA::Error.new("Incompatible with schema #{schema_name}!") unless schema_compatible?(schema_name)
|
43
44
|
|
44
|
-
builder = Nokogiri::XML::Builder.new do |builder|
|
45
|
+
builder = Nokogiri::XML::Builder.new(encoding: 'UTF-8') do |builder|
|
45
46
|
builder.Document(xml_schema(schema_name)) do
|
46
47
|
builder.__send__(xml_main_tag) do
|
47
48
|
build_group_header(builder)
|
@@ -62,7 +63,7 @@ module SEPA
|
|
62
63
|
raise ArgumentError.new("Schema #{schema_name} is unknown!") unless self.known_schemas.include?(schema_name)
|
63
64
|
|
64
65
|
case schema_name
|
65
|
-
when PAIN_001_002_03, PAIN_008_002_02, PAIN_001_001_03
|
66
|
+
when PAIN_001_002_03, PAIN_008_002_02, PAIN_001_001_03, PAIN_001_001_03_CH_02
|
66
67
|
account.bic.present? && transactions.all? { |t| t.schema_compatible?(schema_name) }
|
67
68
|
when PAIN_001_003_03, PAIN_008_003_02, PAIN_008_001_02
|
68
69
|
transactions.all? { |t| t.schema_compatible?(schema_name) }
|
@@ -74,7 +75,7 @@ module SEPA
|
|
74
75
|
raise ArgumentError.new('message_identification must be a string!') unless value.is_a?(String)
|
75
76
|
|
76
77
|
regex = /\A([A-Za-z0-9]|[\+|\?|\/|\-|\:|\(|\)|\.|\,|\'|\ ]){1,35}\z/
|
77
|
-
raise ArgumentError.new("message_identification does not match #{regex}!") unless value.match(regex)
|
78
|
+
raise ArgumentError.new("message_identification does not match #{regex}!") unless value.match?(regex)
|
78
79
|
|
79
80
|
@message_identification = value
|
80
81
|
end
|
@@ -90,7 +91,7 @@ module SEPA
|
|
90
91
|
raise ArgumentError.new('creation_date_time must be a string!') unless value.is_a?(String)
|
91
92
|
|
92
93
|
regex = /[0-9]{4}[-][0-9]{2,2}[-][0-9]{2,2}(?:\s|T)[0-9]{2,2}[:][0-9]{2,2}[:][0-9]{2,2}/
|
93
|
-
raise ArgumentError.new("creation_date_time does not match #{regex}!") unless value.match(regex)
|
94
|
+
raise ArgumentError.new("creation_date_time does not match #{regex}!") unless value.match?(regex)
|
94
95
|
|
95
96
|
@creation_date_time = value
|
96
97
|
end
|
@@ -117,9 +118,17 @@ module SEPA
|
|
117
118
|
private
|
118
119
|
# @return {Hash<Symbol=>String>} xml schema information used in output xml
|
119
120
|
def xml_schema(schema_name)
|
120
|
-
|
121
|
+
return {
|
122
|
+
:xmlns => "urn:iso:std:iso:20022:tech:xsd:#{schema_name}",
|
121
123
|
:'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
|
122
|
-
:'xsi:schemaLocation' => "urn:iso:std:iso:20022:tech:xsd:#{schema_name} #{schema_name}.xsd"
|
124
|
+
:'xsi:schemaLocation' => "urn:iso:std:iso:20022:tech:xsd:#{schema_name} #{schema_name}.xsd"
|
125
|
+
} unless schema_name == PAIN_001_001_03_CH_02
|
126
|
+
|
127
|
+
{
|
128
|
+
xmlns: 'http://www.six-interbank-clearing.com/de/pain.001.001.03.ch.02.xsd',
|
129
|
+
'xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance',
|
130
|
+
'xsi:schemaLocation': 'http://www.six-interbank-clearing.com/de/pain.001.001.03.ch.02.xsd pain.001.001.03.ch.02.xsd'
|
131
|
+
}
|
123
132
|
end
|
124
133
|
|
125
134
|
def build_group_header(builder)
|
data/lib/sepa_king/validator.rb
CHANGED
@@ -8,7 +8,7 @@ module SEPA
|
|
8
8
|
field_name = options[:field_name] || :iban
|
9
9
|
value = record.send(field_name).to_s
|
10
10
|
|
11
|
-
unless IBANTools::IBAN.valid?(value) && value.match(REGEX)
|
11
|
+
unless IBANTools::IBAN.valid?(value) && value.match?(REGEX)
|
12
12
|
record.errors.add(field_name, :invalid, message: options[:message])
|
13
13
|
end
|
14
14
|
end
|
@@ -31,7 +31,12 @@ module SEPA
|
|
31
31
|
end
|
32
32
|
|
33
33
|
class CreditorIdentifierValidator < ActiveModel::Validator
|
34
|
-
REGEX =
|
34
|
+
REGEX = %r{\A
|
35
|
+
[a-zA-Z]{2} # ISO country code
|
36
|
+
[0-9]{2} # Check digits
|
37
|
+
[A-Za-z0-9]{3} # Creditor business code
|
38
|
+
[A-Za-z0-9+?/:().,'-]{1,28} # National identifier
|
39
|
+
\z}x
|
35
40
|
|
36
41
|
def validate(record)
|
37
42
|
field_name = options[:field_name] || :creditor_identifier
|
@@ -43,9 +48,9 @@ module SEPA
|
|
43
48
|
end
|
44
49
|
|
45
50
|
def valid?(creditor_identifier)
|
46
|
-
if ok = creditor_identifier.to_s.match(REGEX)
|
51
|
+
if ok = creditor_identifier.to_s.match?(REGEX)
|
47
52
|
# In Germany, the identifier has to be exactly 18 chars long
|
48
|
-
if creditor_identifier[0..1].match(/DE/i)
|
53
|
+
if creditor_identifier[0..1].match?(/DE/i)
|
49
54
|
ok = creditor_identifier.length == 18
|
50
55
|
end
|
51
56
|
end
|
@@ -54,13 +59,13 @@ module SEPA
|
|
54
59
|
end
|
55
60
|
|
56
61
|
class MandateIdentifierValidator < ActiveModel::Validator
|
57
|
-
REGEX =
|
62
|
+
REGEX = %r{\A[A-Za-z0-9 +?/:().,'-]{1,35}\z}
|
58
63
|
|
59
64
|
def validate(record)
|
60
65
|
field_name = options[:field_name] || :mandate_id
|
61
66
|
value = record.send(field_name)
|
62
67
|
|
63
|
-
unless value.to_s.match(REGEX)
|
68
|
+
unless value.to_s.match?(REGEX)
|
64
69
|
record.errors.add(field_name, :invalid, message: options[:message])
|
65
70
|
end
|
66
71
|
end
|
data/lib/sepa_king/version.rb
CHANGED
data/sepa_king.gemspec
CHANGED
@@ -7,26 +7,24 @@ Gem::Specification.new do |s|
|
|
7
7
|
s.name = 'sepa_king'
|
8
8
|
s.version = SEPA::VERSION
|
9
9
|
s.authors = ['Georg Leciejewski', 'Georg Ledermann']
|
10
|
-
s.email = ['gl@salesking.eu', '
|
11
|
-
s.description = 'Implemention of
|
10
|
+
s.email = ['gl@salesking.eu', 'georg@ledermann.dev']
|
11
|
+
s.description = 'Implemention of Payments Initiation (ISO 20022)'
|
12
12
|
s.summary = 'Ruby gem for creating SEPA XML files'
|
13
|
-
s.homepage = '
|
13
|
+
s.homepage = 'https://github.com/salesking/sepa_king'
|
14
14
|
s.license = 'MIT'
|
15
15
|
|
16
16
|
s.files = `git ls-files`.split($/)
|
17
|
-
s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
-
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
19
17
|
s.require_paths = ['lib']
|
20
18
|
|
21
|
-
s.required_ruby_version = '>= 2.
|
19
|
+
s.required_ruby_version = '>= 2.7'
|
22
20
|
|
23
|
-
s.add_runtime_dependency 'activemodel', '>=
|
21
|
+
s.add_runtime_dependency 'activemodel', '>= 4.2'
|
24
22
|
s.add_runtime_dependency 'nokogiri'
|
25
23
|
s.add_runtime_dependency 'iban-tools'
|
26
24
|
|
27
25
|
s.add_development_dependency 'bundler'
|
28
26
|
s.add_development_dependency 'rspec'
|
29
|
-
s.add_development_dependency '
|
27
|
+
s.add_development_dependency 'coveralls_reborn'
|
30
28
|
s.add_development_dependency 'simplecov'
|
31
29
|
s.add_development_dependency 'rake'
|
32
30
|
end
|
@@ -38,7 +38,7 @@ describe SEPA::CreditTransfer do
|
|
38
38
|
it 'should fail' do
|
39
39
|
expect {
|
40
40
|
SEPA::CreditTransfer.new.to_xml
|
41
|
-
}.to raise_error(SEPA::Error)
|
41
|
+
}.to raise_error(SEPA::Error, /Name is too short/)
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
@@ -62,7 +62,7 @@ describe SEPA::CreditTransfer do
|
|
62
62
|
sct
|
63
63
|
end
|
64
64
|
|
65
|
-
it 'should validate against pain.001.003.
|
65
|
+
it 'should validate against pain.001.003.03' do
|
66
66
|
expect(subject.to_xml(SEPA::PAIN_001_003_03)).to validate_against('pain.001.003.03.xsd')
|
67
67
|
end
|
68
68
|
end
|
@@ -90,7 +90,7 @@ describe SEPA::CreditTransfer do
|
|
90
90
|
sct
|
91
91
|
end
|
92
92
|
|
93
|
-
it 'should validate against pain.001.001.
|
93
|
+
it 'should validate against pain.001.001.03' do
|
94
94
|
expect(subject.to_xml(SEPA::PAIN_001_001_03)).to validate_against('pain.001.001.03.xsd')
|
95
95
|
end
|
96
96
|
end
|
@@ -112,19 +112,19 @@ describe SEPA::CreditTransfer do
|
|
112
112
|
end
|
113
113
|
|
114
114
|
it 'should create valid XML file' do
|
115
|
-
expect(subject.to_xml).to validate_against('pain.001.003.03.xsd')
|
115
|
+
expect(subject.to_xml(SEPA::PAIN_001_003_03)).to validate_against('pain.001.003.03.xsd')
|
116
116
|
end
|
117
117
|
|
118
118
|
it 'should fail for pain.001.001.03' do
|
119
119
|
expect {
|
120
120
|
subject.to_xml(SEPA::PAIN_001_001_03)
|
121
|
-
}.to raise_error(SEPA::Error)
|
121
|
+
}.to raise_error(SEPA::Error, /Incompatible with schema/)
|
122
122
|
end
|
123
123
|
|
124
124
|
it 'should fail for pain.001.002.03' do
|
125
125
|
expect {
|
126
126
|
subject.to_xml(SEPA::PAIN_001_002_03)
|
127
|
-
}.to raise_error(SEPA::Error)
|
127
|
+
}.to raise_error(SEPA::Error, /Incompatible with schema/)
|
128
128
|
end
|
129
129
|
end
|
130
130
|
|
@@ -143,7 +143,7 @@ describe SEPA::CreditTransfer do
|
|
143
143
|
end
|
144
144
|
|
145
145
|
it 'should validate against pain.001.001.03' do
|
146
|
-
expect(subject.to_xml
|
146
|
+
expect(subject.to_xml).to validate_against('pain.001.001.03.xsd')
|
147
147
|
end
|
148
148
|
|
149
149
|
it 'should validate against pain.001.002.03' do
|
@@ -176,7 +176,7 @@ describe SEPA::CreditTransfer do
|
|
176
176
|
end
|
177
177
|
|
178
178
|
it 'should create valid XML file' do
|
179
|
-
expect(subject).to validate_against('pain.001.
|
179
|
+
expect(subject).to validate_against('pain.001.001.03.xsd')
|
180
180
|
end
|
181
181
|
|
182
182
|
it 'should have message_identification' do
|
@@ -344,7 +344,7 @@ describe SEPA::CreditTransfer do
|
|
344
344
|
end
|
345
345
|
|
346
346
|
it 'should create valid XML file' do
|
347
|
-
expect(subject).to validate_against('pain.001.
|
347
|
+
expect(subject).to validate_against('pain.001.001.03.xsd')
|
348
348
|
end
|
349
349
|
|
350
350
|
it 'should contain <InstrId>' do
|
@@ -381,13 +381,13 @@ describe SEPA::CreditTransfer do
|
|
381
381
|
it 'should fail for pain.001.002.03' do
|
382
382
|
expect {
|
383
383
|
subject.to_xml(SEPA::PAIN_001_002_03)
|
384
|
-
}.to raise_error(SEPA::Error)
|
384
|
+
}.to raise_error(SEPA::Error, /Incompatible with schema/)
|
385
385
|
end
|
386
386
|
|
387
387
|
it 'should fail for pain.001.003.03' do
|
388
388
|
expect {
|
389
389
|
subject.to_xml(SEPA::PAIN_001_003_03)
|
390
|
-
}.to raise_error(SEPA::Error)
|
390
|
+
}.to raise_error(SEPA::Error, /Incompatible with schema/)
|
391
391
|
end
|
392
392
|
end
|
393
393
|
|
@@ -409,7 +409,7 @@ describe SEPA::CreditTransfer do
|
|
409
409
|
it 'should fail for pain.001.002.03' do
|
410
410
|
expect {
|
411
411
|
subject.to_xml(SEPA::PAIN_001_002_03)
|
412
|
-
}.to raise_error(SEPA::Error)
|
412
|
+
}.to raise_error(SEPA::Error, /Incompatible with schema/)
|
413
413
|
end
|
414
414
|
|
415
415
|
it 'should validate against pain.001.003.03' do
|
@@ -417,5 +417,104 @@ describe SEPA::CreditTransfer do
|
|
417
417
|
end
|
418
418
|
end
|
419
419
|
end
|
420
|
+
|
421
|
+
context 'xml_schema_header' do
|
422
|
+
subject { credit_transfer.to_xml(format) }
|
423
|
+
|
424
|
+
let(:xml_header) do
|
425
|
+
'<?xml version="1.0" encoding="UTF-8"?>' +
|
426
|
+
"\n<Document xmlns=\"urn:iso:std:iso:20022:tech:xsd:#{format}\"" +
|
427
|
+
' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' +
|
428
|
+
" xsi:schemaLocation=\"urn:iso:std:iso:20022:tech:xsd:#{format} #{format}.xsd\">\n"
|
429
|
+
end
|
430
|
+
|
431
|
+
let(:transaction) do
|
432
|
+
{
|
433
|
+
name: 'Telekomiker AG',
|
434
|
+
iban: 'DE37112589611964645802',
|
435
|
+
bic: 'PBNKDEFF370',
|
436
|
+
amount: 102.50,
|
437
|
+
currency: 'CHF'
|
438
|
+
}
|
439
|
+
end
|
440
|
+
|
441
|
+
before do
|
442
|
+
credit_transfer.add_transaction transaction
|
443
|
+
end
|
444
|
+
|
445
|
+
context "when format is #{SEPA::PAIN_001_001_03}" do
|
446
|
+
let(:format) { SEPA::PAIN_001_001_03 }
|
447
|
+
|
448
|
+
it 'should return correct header' do
|
449
|
+
is_expected.to start_with(xml_header)
|
450
|
+
end
|
451
|
+
end
|
452
|
+
|
453
|
+
context "when format is #{SEPA::PAIN_001_002_03}" do
|
454
|
+
let(:format) { SEPA::PAIN_001_002_03 }
|
455
|
+
let(:transaction) do
|
456
|
+
{
|
457
|
+
name: 'Telekomiker AG',
|
458
|
+
bic: 'PBNKDEFF370',
|
459
|
+
iban: 'DE37112589611964645802',
|
460
|
+
amount: 102.50,
|
461
|
+
reference: 'XYZ-1234/123',
|
462
|
+
remittance_information: 'Rechnung vom 22.08.2013'
|
463
|
+
}
|
464
|
+
end
|
465
|
+
|
466
|
+
it 'should return correct header' do
|
467
|
+
is_expected.to start_with(xml_header)
|
468
|
+
end
|
469
|
+
end
|
470
|
+
|
471
|
+
context "when format is #{SEPA::PAIN_001_003_03}" do
|
472
|
+
let(:format) { SEPA::PAIN_001_003_03 }
|
473
|
+
let(:transaction) do
|
474
|
+
{
|
475
|
+
name: 'Telekomiker AG',
|
476
|
+
bic: 'PBNKDEFF370',
|
477
|
+
iban: 'DE37112589611964645802',
|
478
|
+
amount: 102.50,
|
479
|
+
reference: 'XYZ-1234/123',
|
480
|
+
remittance_information: 'Rechnung vom 22.08.2013'
|
481
|
+
}
|
482
|
+
end
|
483
|
+
|
484
|
+
it 'should return correct header' do
|
485
|
+
is_expected.to start_with(xml_header)
|
486
|
+
end
|
487
|
+
end
|
488
|
+
|
489
|
+
context "when format is #{SEPA::PAIN_001_001_03_CH_02}" do
|
490
|
+
let(:format) { SEPA::PAIN_001_001_03_CH_02 }
|
491
|
+
let(:credit_transfer) do
|
492
|
+
SEPA::CreditTransfer.new name: 'Schuldner GmbH',
|
493
|
+
iban: 'CH5481230000001998736',
|
494
|
+
bic: 'RAIFCH22'
|
495
|
+
end
|
496
|
+
let(:transaction) do
|
497
|
+
{
|
498
|
+
name: 'Telekomiker AG',
|
499
|
+
iban: 'DE62007620110623852957',
|
500
|
+
amount: 102.50,
|
501
|
+
currency: 'CHF',
|
502
|
+
reference: 'XYZ-1234/123',
|
503
|
+
remittance_information: 'Rechnung vom 22.08.2013'
|
504
|
+
}
|
505
|
+
end
|
506
|
+
|
507
|
+
let(:xml_header) do
|
508
|
+
'<?xml version="1.0" encoding="UTF-8"?>' +
|
509
|
+
"\n<Document xmlns=\"http://www.six-interbank-clearing.com/de/#{format}.xsd\"" +
|
510
|
+
' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' +
|
511
|
+
" xsi:schemaLocation=\"http://www.six-interbank-clearing.com/de/#{format}.xsd #{format}.xsd\">\n"
|
512
|
+
end
|
513
|
+
|
514
|
+
it 'should return correct header' do
|
515
|
+
is_expected.to start_with(xml_header)
|
516
|
+
end
|
517
|
+
end
|
518
|
+
end
|
420
519
|
end
|
421
520
|
end
|
@@ -44,6 +44,12 @@ describe SEPA::CreditTransferTransaction do
|
|
44
44
|
expect(SEPA::CreditTransferTransaction.new(:bic => nil)).to be_schema_compatible('pain.001.003.03')
|
45
45
|
end
|
46
46
|
end
|
47
|
+
|
48
|
+
context 'for pain.001.001.03.ch.02' do
|
49
|
+
it 'should succeed for valid attributes' do
|
50
|
+
expect(SEPA::CreditTransferTransaction.new(:bic => 'SPUEDE2UXXX', :currency => 'CHF')).to be_schema_compatible('pain.001.001.03.ch.02')
|
51
|
+
end
|
52
|
+
end
|
47
53
|
end
|
48
54
|
|
49
55
|
context 'Requested date' do
|
data/spec/direct_debit_spec.rb
CHANGED
@@ -70,7 +70,7 @@ describe SEPA::DirectDebit do
|
|
70
70
|
it 'should fail' do
|
71
71
|
expect {
|
72
72
|
SEPA::DirectDebit.new.to_xml
|
73
|
-
}.to raise_error(SEPA::Error)
|
73
|
+
}.to raise_error(SEPA::Error, /Name is too short/)
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
@@ -158,7 +158,7 @@ describe SEPA::DirectDebit do
|
|
158
158
|
it 'should fail for pain.008.002.02' do
|
159
159
|
expect {
|
160
160
|
subject.to_xml(SEPA::PAIN_008_002_02)
|
161
|
-
}.to raise_error(SEPA::Error)
|
161
|
+
}.to raise_error(SEPA::Error, /Incompatible with schema/)
|
162
162
|
end
|
163
163
|
|
164
164
|
it 'should validate against pain.008.001.02' do
|
@@ -256,7 +256,7 @@ describe SEPA::DirectDebit do
|
|
256
256
|
end
|
257
257
|
|
258
258
|
it 'should create valid XML file' do
|
259
|
-
expect(subject).to validate_against('pain.008.
|
259
|
+
expect(subject).to validate_against('pain.008.001.02.xsd')
|
260
260
|
end
|
261
261
|
|
262
262
|
it 'should have creditor identifier' do
|
@@ -385,7 +385,7 @@ describe SEPA::DirectDebit do
|
|
385
385
|
it 'should raise error on XML generation' do
|
386
386
|
expect {
|
387
387
|
subject.to_xml
|
388
|
-
}.to raise_error(SEPA::Error)
|
388
|
+
}.to raise_error(SEPA::Error, /CORE, COR1 AND B2B must not be mixed in one message/)
|
389
389
|
end
|
390
390
|
end
|
391
391
|
|
@@ -516,7 +516,7 @@ describe SEPA::DirectDebit do
|
|
516
516
|
end
|
517
517
|
|
518
518
|
it 'should create valid XML file' do
|
519
|
-
expect(subject).to validate_against('pain.008.
|
519
|
+
expect(subject).to validate_against('pain.008.001.02.xsd')
|
520
520
|
end
|
521
521
|
|
522
522
|
it 'should contain <InstrId>' do
|
@@ -533,7 +533,7 @@ describe SEPA::DirectDebit do
|
|
533
533
|
end
|
534
534
|
|
535
535
|
it 'should fail as the payment identification becomes too large' do
|
536
|
-
expect { subject.to_xml }.to raise_error(SEPA::Error)
|
536
|
+
expect { subject.to_xml }.to raise_error(SEPA::Error, /The value has a length of '37'; this exceeds the allowed maximum length of '35'/)
|
537
537
|
end
|
538
538
|
end
|
539
539
|
|
@@ -546,7 +546,7 @@ describe SEPA::DirectDebit do
|
|
546
546
|
sct
|
547
547
|
end
|
548
548
|
|
549
|
-
it 'should validate against pain.
|
549
|
+
it 'should validate against pain.008.001.02' do
|
550
550
|
expect(subject.to_xml(SEPA::PAIN_008_001_02)).to validate_against('pain.008.001.02.xsd')
|
551
551
|
end
|
552
552
|
|
@@ -562,13 +562,94 @@ describe SEPA::DirectDebit do
|
|
562
562
|
it 'should fail for pain.008.002.02' do
|
563
563
|
expect {
|
564
564
|
subject.to_xml(SEPA::PAIN_008_002_02)
|
565
|
-
}.to raise_error(SEPA::Error)
|
565
|
+
}.to raise_error(SEPA::Error, /Incompatible with schema/)
|
566
566
|
end
|
567
567
|
|
568
568
|
it 'should fail for pain.008.003.02' do
|
569
569
|
expect {
|
570
570
|
subject.to_xml(SEPA::PAIN_008_003_02)
|
571
|
-
}.to raise_error(SEPA::Error)
|
571
|
+
}.to raise_error(SEPA::Error, /Incompatible with schema/)
|
572
|
+
end
|
573
|
+
end
|
574
|
+
end
|
575
|
+
|
576
|
+
context 'xml_schema_header' do
|
577
|
+
subject { sepa_direct_debit.to_xml(format) }
|
578
|
+
|
579
|
+
let(:sepa_direct_debit) do
|
580
|
+
SEPA::DirectDebit.new name: 'Gläubiger GmbH',
|
581
|
+
iban: 'DE87200500001234567890',
|
582
|
+
creditor_identifier: 'DE98ZZZ09999999999'
|
583
|
+
end
|
584
|
+
|
585
|
+
let(:xml_header) do
|
586
|
+
'<?xml version="1.0" encoding="UTF-8"?>' +
|
587
|
+
"\n<Document xmlns=\"urn:iso:std:iso:20022:tech:xsd:#{format}\"" +
|
588
|
+
' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' +
|
589
|
+
" xsi:schemaLocation=\"urn:iso:std:iso:20022:tech:xsd:#{format} #{format}.xsd\">\n"
|
590
|
+
end
|
591
|
+
|
592
|
+
let(:transaction) do
|
593
|
+
{
|
594
|
+
name: 'Zahlemann & Söhne GbR',
|
595
|
+
bic: 'SPUEDE2UXXX',
|
596
|
+
iban: 'DE21500500009876543210',
|
597
|
+
amount: 39.99,
|
598
|
+
reference: 'XYZ/2013-08-ABO/12345',
|
599
|
+
remittance_information: 'Unsere Rechnung vom 10.08.2013',
|
600
|
+
mandate_id: 'K-02-2011-12345',
|
601
|
+
mandate_date_of_signature: Date.new(2011, 1, 25)
|
602
|
+
}
|
603
|
+
end
|
604
|
+
|
605
|
+
before do
|
606
|
+
sepa_direct_debit.add_transaction transaction
|
607
|
+
end
|
608
|
+
|
609
|
+
context "when format is #{SEPA::PAIN_008_001_02}" do
|
610
|
+
let(:format) { SEPA::PAIN_008_001_02 }
|
611
|
+
|
612
|
+
it 'should return correct header' do
|
613
|
+
is_expected.to start_with(xml_header)
|
614
|
+
end
|
615
|
+
end
|
616
|
+
|
617
|
+
context "when format is #{SEPA::PAIN_008_002_02}" do
|
618
|
+
let(:format) { SEPA::PAIN_008_002_02 }
|
619
|
+
let(:sepa_direct_debit) do
|
620
|
+
SEPA::DirectDebit.new name: 'Gläubiger GmbH',
|
621
|
+
bic: 'SPUEDE2UXXX',
|
622
|
+
iban: 'DE87200500001234567890',
|
623
|
+
creditor_identifier: 'DE98ZZZ09999999999'
|
624
|
+
end
|
625
|
+
let(:transaction) do
|
626
|
+
{
|
627
|
+
name: 'Zahlemann & Söhne GbR',
|
628
|
+
bic: 'SPUEDE2UXXX',
|
629
|
+
iban: 'DE21500500009876543210',
|
630
|
+
amount: 39.99,
|
631
|
+
reference: 'XYZ/2013-08-ABO/12345',
|
632
|
+
remittance_information: 'Unsere Rechnung vom 10.08.2013',
|
633
|
+
mandate_id: 'K-02-2011-12345',
|
634
|
+
debtor_address: SEPA::DebtorAddress.new(
|
635
|
+
country_code: 'CH',
|
636
|
+
address_line1: 'Mustergasse 123',
|
637
|
+
address_line2: '1234 Musterstadt'
|
638
|
+
),
|
639
|
+
mandate_date_of_signature: Date.new(2011, 1, 25)
|
640
|
+
}
|
641
|
+
end
|
642
|
+
|
643
|
+
it 'should return correct header' do
|
644
|
+
is_expected.to start_with(xml_header)
|
645
|
+
end
|
646
|
+
end
|
647
|
+
|
648
|
+
context "when format is #{SEPA::PAIN_008_003_02}" do
|
649
|
+
let(:format) { SEPA::PAIN_008_003_02 }
|
650
|
+
|
651
|
+
it 'should return correct header' do
|
652
|
+
is_expected.to start_with(xml_header)
|
572
653
|
end
|
573
654
|
end
|
574
655
|
end
|