sepa_king 0.11.2 → 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +19 -7
- data/LICENSE.txt +1 -1
- data/README.md +2 -2
- data/gemfiles/Gemfile-activemodel-6.0.x +5 -0
- data/lib/schema/pain.001.001.03.ch.02.xsd +1212 -0
- data/lib/sepa_king/message.rb +13 -4
- data/lib/sepa_king/message/credit_transfer.rb +4 -2
- data/lib/sepa_king/transaction/credit_transfer_transaction.rb +2 -0
- data/lib/sepa_king/version.rb +1 -1
- data/spec/credit_transfer_spec.rb +99 -0
- data/spec/credit_transfer_transaction_spec.rb +6 -0
- data/spec/direct_debit_spec.rb +81 -0
- data/spec/examples/pain.001.001.03.ch.02.xml +172 -0
- metadata +7 -4
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) }
|
@@ -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)
|
@@ -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, PAIN_001_001_03 ]
|
8
|
+
self.known_schemas = [ PAIN_001_003_03, PAIN_001_002_03, PAIN_001_001_03, PAIN_001_001_03_CH_02 ]
|
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)
|
data/lib/sepa_king/version.rb
CHANGED
@@ -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
@@ -572,5 +572,86 @@ describe SEPA::DirectDebit do
|
|
572
572
|
end
|
573
573
|
end
|
574
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)
|
653
|
+
end
|
654
|
+
end
|
655
|
+
end
|
575
656
|
end
|
576
657
|
end
|
@@ -0,0 +1,172 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<!--
|
3
|
+
(C) Copyright 2010, SKSF, www.sksf.ch
|
4
|
+
|
5
|
+
Anregungen und Fragen zu diesem Dokument können an das jeweilige Finanzinstitut gerichtet werden.
|
6
|
+
Allgemeine Anregungen können auch bei der SIX Interbank Clearing AG unter folgender Adresse angebracht werden:
|
7
|
+
pm@six-group.com
|
8
|
+
-->
|
9
|
+
<Document xmlns="http://www.six-interbank-clearing.com/de/pain.001.001.03.ch.02.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.six-interbank-clearing.com/de/pain.001.001.03.ch.02.xsd pain.001.001.03.ch.02.xsd">
|
10
|
+
<CstmrCdtTrfInitn>
|
11
|
+
<GrpHdr>
|
12
|
+
<MsgId>MSG-01</MsgId>
|
13
|
+
<CreDtTm>2010-02-15T07:30:00</CreDtTm>
|
14
|
+
<NbOfTxs>3</NbOfTxs>
|
15
|
+
<CtrlSum>15850.00</CtrlSum>
|
16
|
+
<InitgPty>
|
17
|
+
<Nm>MUSTER AG</Nm>
|
18
|
+
</InitgPty>
|
19
|
+
</GrpHdr>
|
20
|
+
<PmtInf>
|
21
|
+
<PmtInfId>PMTINF-01</PmtInfId>
|
22
|
+
<PmtMtd>TRF</PmtMtd>
|
23
|
+
<BtchBookg>true</BtchBookg>
|
24
|
+
<ReqdExctnDt>2010-02-22</ReqdExctnDt>
|
25
|
+
<Dbtr>
|
26
|
+
<Nm>MUSTER AG</Nm>
|
27
|
+
<PstlAdr>
|
28
|
+
<Ctry>CH</Ctry>
|
29
|
+
<AdrLine>SELDWYLA</AdrLine>
|
30
|
+
</PstlAdr>
|
31
|
+
</Dbtr>
|
32
|
+
<DbtrAcct>
|
33
|
+
<Id>
|
34
|
+
<IBAN>CH5481230000001998736</IBAN>
|
35
|
+
</Id>
|
36
|
+
</DbtrAcct>
|
37
|
+
<DbtrAgt>
|
38
|
+
<FinInstnId>
|
39
|
+
<BIC>RAIFCH22</BIC>
|
40
|
+
</FinInstnId>
|
41
|
+
</DbtrAgt>
|
42
|
+
<CdtTrfTxInf>
|
43
|
+
<PmtId>
|
44
|
+
<InstrId>INSTRID-01-01</InstrId>
|
45
|
+
<EndToEndId>ENDTOENDID-001</EndToEndId>
|
46
|
+
</PmtId>
|
47
|
+
<PmtTpInf>
|
48
|
+
<LclInstrm>
|
49
|
+
<Prtry>CH01</Prtry>
|
50
|
+
</LclInstrm>
|
51
|
+
</PmtTpInf>
|
52
|
+
<Amt>
|
53
|
+
<InstdAmt Ccy="CHF">3949.75</InstdAmt>
|
54
|
+
</Amt>
|
55
|
+
<CdtrAcct>
|
56
|
+
<Id>
|
57
|
+
<Othr>
|
58
|
+
<Id>01-39139-1</Id>
|
59
|
+
</Othr>
|
60
|
+
</Id>
|
61
|
+
</CdtrAcct>
|
62
|
+
<RmtInf>
|
63
|
+
<Strd>
|
64
|
+
<CdtrRefInf>
|
65
|
+
<Ref>210000000003139471430009017</Ref>
|
66
|
+
</CdtrRefInf>
|
67
|
+
</Strd>
|
68
|
+
</RmtInf>
|
69
|
+
</CdtTrfTxInf>
|
70
|
+
</PmtInf>
|
71
|
+
<PmtInf>
|
72
|
+
<PmtInfId>PMTINF-02</PmtInfId>
|
73
|
+
<PmtMtd>TRF</PmtMtd>
|
74
|
+
<BtchBookg>true</BtchBookg>
|
75
|
+
<ReqdExctnDt>2010-02-18</ReqdExctnDt>
|
76
|
+
<Dbtr>
|
77
|
+
<Nm>MUSTER AG</Nm>
|
78
|
+
<PstlAdr>
|
79
|
+
<Ctry>CH</Ctry>
|
80
|
+
<AdrLine>SELDWYLA</AdrLine>
|
81
|
+
</PstlAdr>
|
82
|
+
</Dbtr>
|
83
|
+
<DbtrAcct>
|
84
|
+
<Id>
|
85
|
+
<IBAN>CH5481230000001998736</IBAN>
|
86
|
+
</Id>
|
87
|
+
</DbtrAcct>
|
88
|
+
<DbtrAgt>
|
89
|
+
<FinInstnId>
|
90
|
+
<BIC>RAIFCH22</BIC>
|
91
|
+
</FinInstnId>
|
92
|
+
</DbtrAgt>
|
93
|
+
<CdtTrfTxInf>
|
94
|
+
<PmtId>
|
95
|
+
<InstrId>INSTRID-02-01</InstrId>
|
96
|
+
<EndToEndId>ENDTOENDID-002</EndToEndId>
|
97
|
+
</PmtId>
|
98
|
+
<PmtTpInf>
|
99
|
+
<LclInstrm>
|
100
|
+
<Prtry>CH02</Prtry>
|
101
|
+
</LclInstrm>
|
102
|
+
</PmtTpInf>
|
103
|
+
<Amt>
|
104
|
+
<InstdAmt Ccy="CHF">8479.25</InstdAmt>
|
105
|
+
</Amt>
|
106
|
+
<Cdtr>
|
107
|
+
<Nm>Robert Scheider SA</Nm>
|
108
|
+
<PstlAdr>
|
109
|
+
<StrtNm>Rue de la gare</StrtNm>
|
110
|
+
<BldgNb>24</BldgNb>
|
111
|
+
<PstCd>2501</PstCd>
|
112
|
+
<TwnNm>Biel</TwnNm>
|
113
|
+
<Ctry>CH</Ctry>
|
114
|
+
</PstlAdr>
|
115
|
+
</Cdtr>
|
116
|
+
<CdtrAcct>
|
117
|
+
<Id>
|
118
|
+
<Othr>
|
119
|
+
<Id>25-9034-2</Id>
|
120
|
+
</Othr>
|
121
|
+
</Id>
|
122
|
+
</CdtrAcct>
|
123
|
+
<RmtInf>
|
124
|
+
<Ustrd>Rechnung Nr. 408</Ustrd>
|
125
|
+
</RmtInf>
|
126
|
+
</CdtTrfTxInf>
|
127
|
+
<CdtTrfTxInf>
|
128
|
+
<PmtId>
|
129
|
+
<InstrId>INSTRID-02-02</InstrId>
|
130
|
+
<EndToEndId>ENDTOENDID-003</EndToEndId>
|
131
|
+
</PmtId>
|
132
|
+
<PmtTpInf>
|
133
|
+
<SvcLvl>
|
134
|
+
<Cd>SEPA</Cd>
|
135
|
+
</SvcLvl>
|
136
|
+
</PmtTpInf>
|
137
|
+
<Amt>
|
138
|
+
<InstdAmt Ccy="EUR">3421.00</InstdAmt>
|
139
|
+
</Amt>
|
140
|
+
<CdtrAgt>
|
141
|
+
<FinInstnId>
|
142
|
+
<BIC>DEUTDEFF</BIC>
|
143
|
+
</FinInstnId>
|
144
|
+
</CdtrAgt>
|
145
|
+
<Cdtr>
|
146
|
+
<Nm>Peter Haller</Nm>
|
147
|
+
<PstlAdr>
|
148
|
+
<AdrLine>Rosenauweg 4</AdrLine>
|
149
|
+
<AdrLine>DE-80036 München</AdrLine>
|
150
|
+
</PstlAdr>
|
151
|
+
</Cdtr>
|
152
|
+
<CdtrAcct>
|
153
|
+
<Id>
|
154
|
+
<IBAN>DE62007620110623852957</IBAN>
|
155
|
+
</Id>
|
156
|
+
</CdtrAcct>
|
157
|
+
<RmtInf>
|
158
|
+
<Strd>
|
159
|
+
<CdtrRefInf>
|
160
|
+
<Tp>
|
161
|
+
<CdOrPrtry>
|
162
|
+
<Cd>SCOR</Cd>
|
163
|
+
</CdOrPrtry>
|
164
|
+
</Tp>
|
165
|
+
<Ref>RF712348231</Ref>
|
166
|
+
</CdtrRefInf>
|
167
|
+
</Strd>
|
168
|
+
</RmtInf>
|
169
|
+
</CdtTrfTxInf>
|
170
|
+
</PmtInf>
|
171
|
+
</CstmrCdtTrfInitn>
|
172
|
+
</Document>
|