sepafm 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +156 -6
- data/lib/danske_get_bank_certificate_test.rb +2 -2
- data/lib/sepa/custom_exceptions.rb +2 -0
- data/lib/sepa/payload.rb +109 -0
- data/lib/sepa/payment.rb +97 -0
- data/lib/sepa/transaction.rb +178 -0
- data/lib/sepa/version.rb +1 -1
- data/lib/sepa/xml_schemas/pain.001.001.02.xsd +784 -0
- data/lib/sepa_client_testing_mika.rb +1 -1
- data/lib/sepa_client_testing_tiere.rb +183 -6
- data/lib/{sepa.rb → sepafm.rb} +4 -0
- data/test/sepa/payload_test.rb +297 -0
- data/test/sepa/payment_test.rb +198 -0
- data/test/sepa/sepa_test.rb +1 -1
- data/test/sepa/transaction_test.rb +362 -0
- data/test/test_helper.rb +3 -4
- metadata +14 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1bcf3a08974b359e66ea01c5c484f143d7416b94
|
4
|
+
data.tar.gz: 452856d46a88d78db3f2187d5d7618479a92f1ad
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cd9566b7a6bd7237b7620a6d1245d6e42fa55b4c962857f03f8dae76c6a8c4aecc8b0341e87cb88b06527259fcf6debd5e4ff5e82e409047526a5473569aec11
|
7
|
+
data.tar.gz: 89f83a46436f0e6ecae783e4c0f964a0d0ce817bc6952e81d65acc1076f84903bc31cd7b9f36c89ecfeb92d71850098a6040ee46678b59c1b43d4544efb0a46d
|
data/README.md
CHANGED
@@ -14,7 +14,7 @@ This project aims to create an open source implementation of SEPA Financial Mess
|
|
14
14
|
|
15
15
|
Add this line to your application's Gemfile:
|
16
16
|
|
17
|
-
gem '
|
17
|
+
gem 'sepafm'
|
18
18
|
|
19
19
|
And then execute:
|
20
20
|
|
@@ -22,15 +22,165 @@ And then execute:
|
|
22
22
|
|
23
23
|
Or install it yourself as:
|
24
24
|
|
25
|
-
$ gem install
|
25
|
+
$ gem install sepafm
|
26
26
|
|
27
27
|
## Usage
|
28
28
|
|
29
|
+
### Building the payload
|
30
|
+
|
31
|
+
* You can optionally have an invoice bundle included in a given transaction. If that is the case, you first have to define the invoices i.e. as follows:
|
32
|
+
|
33
|
+
invoice_bundle = []
|
34
|
+
|
35
|
+
invoice_1 = {
|
36
|
+
|
37
|
+
# Has to be either CINV for normal invoice or CREN for credit note.
|
38
|
+
type: 'CINV',
|
39
|
+
|
40
|
+
# Positive for invoices and negative for credits.
|
41
|
+
amount: '700',
|
42
|
+
|
43
|
+
currency: 'EUR',
|
44
|
+
|
45
|
+
# You either have to specify an invoice number or a reference.
|
46
|
+
invoice_number: '123456'
|
47
|
+
}
|
48
|
+
|
49
|
+
invoice_2 = {
|
50
|
+
type: 'CINV',
|
51
|
+
amount: '300',
|
52
|
+
currency: 'EUR',
|
53
|
+
reference: '123456789',
|
54
|
+
}
|
55
|
+
|
56
|
+
invoice_3 = {
|
57
|
+
type: 'CREN',
|
58
|
+
amount: '-100',
|
59
|
+
currency: 'EUR',
|
60
|
+
invoice_number: '654321'
|
61
|
+
}
|
62
|
+
|
63
|
+
invoice_4 = {
|
64
|
+
type: 'CREN',
|
65
|
+
amount: '-500',
|
66
|
+
currency: 'EUR',
|
67
|
+
reference: '987654321'
|
68
|
+
}
|
69
|
+
|
70
|
+
# All the invoices are pushed to an array which is later included in the
|
71
|
+
# transaction's params.
|
72
|
+
invoice_bundle.push(invoice_1)
|
73
|
+
invoice_bundle.push(invoice_2)
|
74
|
+
invoice_bundle.push(invoice_3)
|
75
|
+
invoice_bundle.push(invoice_4)
|
76
|
+
|
77
|
+
1. Define parameters for the transactions. You need at least one and one payment can have multiple. It is also worth noting that one payload can also have multiple payments. Here's how the parameters are defined:
|
78
|
+
|
79
|
+
transactions_params = {
|
80
|
+
|
81
|
+
# Optional id for the transaction. This is returned to the payer only.
|
82
|
+
# Max length is 35 characters.
|
83
|
+
instruction_id: '70CEF29BEBA8396A1F806005EDA51DEE4CE',
|
84
|
+
|
85
|
+
# Mandatory id for the transaction. This id is also passed on the the
|
86
|
+
# beneficiary. Max length is 35 characters.
|
87
|
+
end_to_end_id: '629CADFDAD5246AD915BA24A3C8E9FC3313',
|
88
|
+
|
89
|
+
# Amount to be transferred. Decimals separated by a period.
|
90
|
+
amount: '30.75',
|
91
|
+
|
92
|
+
# Currency. For Euros EUR etc.
|
93
|
+
currency: 'EUR',
|
94
|
+
|
95
|
+
# Bank's unique BIC.
|
96
|
+
bic: 'NDEAFIHH',
|
97
|
+
|
98
|
+
# Name of the creditor company or person
|
99
|
+
name: 'Testi Saaja Oy',
|
100
|
+
|
101
|
+
# Street and street number of the creditor.
|
102
|
+
address: 'Kokeilukatu 66',
|
103
|
+
|
104
|
+
# Creditor's county code.
|
105
|
+
country: 'FI',
|
106
|
+
|
107
|
+
# Creditor's postcode.
|
108
|
+
postcode: '00200',
|
109
|
+
|
110
|
+
# Creditor's town
|
111
|
+
town: 'Helsinki',
|
112
|
+
|
113
|
+
# Creditor's IBAN.
|
114
|
+
iban: 'FI7429501800000014',
|
115
|
+
|
116
|
+
# Reference number for the transaction. Mandatory if message not given.
|
117
|
+
reference: '00000000000000001245',
|
118
|
+
|
119
|
+
# Message for the transaction. Mandatory if reference not given.
|
120
|
+
message: 'Maksu',
|
121
|
+
|
122
|
+
# Optional set of invoices to be bundled in this transaction. If a bundle
|
123
|
+
# is provided amount, currency and reference will be automatically taken
|
124
|
+
# from that bundle.
|
125
|
+
invoice_bundle: invoice_bundle
|
126
|
+
}
|
127
|
+
|
128
|
+
2. Create an array of Sepa::Transaction objects in which you put all the transactions of a given payment. You need to create an array for each payment separately.
|
129
|
+
|
130
|
+
payment_transactions = []
|
131
|
+
|
132
|
+
payment_transactions.push(Sepa::Transaction.new(transaction_params))
|
133
|
+
|
134
|
+
3. Define the parameters for the payment/payments:
|
135
|
+
|
136
|
+
payment_params = {
|
137
|
+
|
138
|
+
# Unique id the payment. Max length is 35 characters.
|
139
|
+
payment_info_id: 'F56D46DDA136A981F58C05999479E768C92',
|
140
|
+
|
141
|
+
# Requested executin date for the payment in form YYY-MM-DD.
|
142
|
+
execution_date: '2013-08-10',
|
143
|
+
|
144
|
+
# The array of transactions for this payment
|
145
|
+
transactions: payment_transactions
|
146
|
+
|
147
|
+
# If this is a payment consisting of salary of pension transactions, you
|
148
|
+
# need to provide the following flag.
|
149
|
+
salary_or_pension: true
|
150
|
+
}
|
151
|
+
|
152
|
+
4. Define parameters for the debtor as follows:
|
153
|
+
|
154
|
+
debtor_params = {
|
155
|
+
name: 'Testi Maksaja Oy',
|
156
|
+
address: 'Testing Street 12',
|
157
|
+
country: 'FI',
|
158
|
+
postcode: '00100',
|
159
|
+
town: 'Helsinki',
|
160
|
+
customer_id: '111111111',
|
161
|
+
iban: 'FI4819503000000010',
|
162
|
+
bic: 'NDEAFIHH'
|
163
|
+
}
|
164
|
+
|
165
|
+
5. Create an array of Sepa::Payment objects in which you put all the payments that are going to be in the payload.
|
166
|
+
|
167
|
+
payments = []
|
168
|
+
|
169
|
+
payments.push(Sepa::Payment.new(debtor_params, payment_params))
|
170
|
+
|
171
|
+
6. Create the actual payload object:
|
172
|
+
|
173
|
+
payload = Sepa::Payload.new(debtor_params, payments)
|
174
|
+
|
175
|
+
# Will return the payload as an xml document which can be included in the
|
176
|
+
# construction of the SOAP message.
|
177
|
+
payload.to_xml
|
178
|
+
|
29
179
|
### Communicating with the bank
|
30
180
|
|
31
181
|
1. Require the gem:
|
32
182
|
|
33
|
-
require '
|
183
|
+
require 'sepafm'
|
34
184
|
|
35
185
|
2. Define the hash that will be passed to the gem when initializing it:
|
36
186
|
|
@@ -45,7 +195,7 @@ Or install it yourself as:
|
|
45
195
|
target_id: '11111111A1',
|
46
196
|
language: 'FI',
|
47
197
|
file_type: 'TITO',
|
48
|
-
content: payload,
|
198
|
+
content: payload, # You can use the payload you may have constructed earlier. I.e. payload.to_xml
|
49
199
|
file_reference: "11111111A12006030329501800000014"
|
50
200
|
}
|
51
201
|
|
@@ -112,7 +262,7 @@ Or install it yourself as:
|
|
112
262
|
|
113
263
|
1. Require the gem:
|
114
264
|
|
115
|
-
require '
|
265
|
+
require 'sepafm'
|
116
266
|
|
117
267
|
2. Define the hash that will be passed to the gem when initializing it:
|
118
268
|
|
@@ -136,7 +286,7 @@ Or install it yourself as:
|
|
136
286
|
|
137
287
|
1. Require the gem:
|
138
288
|
|
139
|
-
require '
|
289
|
+
require 'sepafm'
|
140
290
|
|
141
291
|
2. Define the hash that will be passed to the gem when initializing it:
|
142
292
|
|
data/lib/sepa/payload.rb
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
module Sepa
|
2
|
+
class Payload
|
3
|
+
def initialize(debtor, payments)
|
4
|
+
@debtor_name = debtor.fetch(:name)
|
5
|
+
@debtor_address = debtor.fetch(:address)
|
6
|
+
@debtor_country = debtor.fetch(:country)
|
7
|
+
@debtor_postcode = debtor.fetch(:postcode)
|
8
|
+
@debtor_town = debtor.fetch(:town)
|
9
|
+
@debtor_customer_id = debtor.fetch(:customer_id)
|
10
|
+
|
11
|
+
unless @payments = payments
|
12
|
+
fail KeyError, 'No payments provided for the payload.'
|
13
|
+
end
|
14
|
+
|
15
|
+
@doc = build
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_xml
|
19
|
+
@doc.to_xml
|
20
|
+
end
|
21
|
+
|
22
|
+
# Checks whether the payload validates against the schema.
|
23
|
+
def valid?
|
24
|
+
@xsd ||= load_schema
|
25
|
+
@xsd.valid?(@doc)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Errors that a schema validation of the document produces.
|
29
|
+
def errors
|
30
|
+
@xsd ||= load_schema
|
31
|
+
@xsd.validate(@doc).collect { |e| e.message }
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def build
|
37
|
+
doc = build_root
|
38
|
+
doc = build_group_header(doc)
|
39
|
+
add_payments(doc)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Gets the number of transactions in this payload.
|
43
|
+
def number_of_transactions
|
44
|
+
count = 0
|
45
|
+
@payments.each { |payment| count += payment.number_of_transactions }
|
46
|
+
count
|
47
|
+
end
|
48
|
+
|
49
|
+
# Builds the root and pain elements with namespace and schema definitions.
|
50
|
+
def build_root
|
51
|
+
builder = Nokogiri::XML::Builder.new do |xml|
|
52
|
+
xml.Document(
|
53
|
+
xmlns: 'urn:iso:std:iso:20022:tech:xsd:pain.001.001.02',
|
54
|
+
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
|
55
|
+
'xsi:schemaLocation' => 'urn:iso:std:iso:20022:tech:xsd:pain.001.' \
|
56
|
+
'001.02 pain.001.001.02.xsd'
|
57
|
+
) {
|
58
|
+
xml.send 'pain.001.001.02'
|
59
|
+
}
|
60
|
+
end
|
61
|
+
|
62
|
+
builder.doc
|
63
|
+
end
|
64
|
+
|
65
|
+
# Builds the group header.
|
66
|
+
def build_group_header(root_e)
|
67
|
+
builder = Nokogiri::XML::Builder.with(root_e.at('Document > *')) do |xml|
|
68
|
+
xml.GrpHdr {
|
69
|
+
xml.MsgId SecureRandom.hex(17)
|
70
|
+
xml.CreDtTm Time.new.iso8601
|
71
|
+
xml.BtchBookg 'true'
|
72
|
+
xml.NbOfTxs number_of_transactions
|
73
|
+
xml.Grpg 'MIXD'
|
74
|
+
xml.InitgPty {
|
75
|
+
xml.Nm @debtor_name
|
76
|
+
xml.PstlAdr {
|
77
|
+
xml.AdrLine @debtor_address
|
78
|
+
xml.AdrLine "#{@debtor_country}-#{@debtor_postcode}"
|
79
|
+
xml.StrtNm @debtor_address
|
80
|
+
xml.PstCd "#{@debtor_country}-#{@debtor_postcode}"
|
81
|
+
xml.TwnNm @debtor_town
|
82
|
+
xml.Ctry @debtor_country
|
83
|
+
}
|
84
|
+
}
|
85
|
+
}
|
86
|
+
end
|
87
|
+
|
88
|
+
builder.doc
|
89
|
+
end
|
90
|
+
|
91
|
+
# Adds all the payments specified in the parameters to the payload.
|
92
|
+
def add_payments(root_e)
|
93
|
+
@payments.each do |payment|
|
94
|
+
root_e.at(
|
95
|
+
'/xmlns:Document/xmlns:pain.001.001.02',
|
96
|
+
'xmlns' => 'urn:iso:std:iso:20022:tech:xsd:pain.001.001.02'
|
97
|
+
).add_child(payment.to_node)
|
98
|
+
end
|
99
|
+
|
100
|
+
root_e
|
101
|
+
end
|
102
|
+
|
103
|
+
def load_schema
|
104
|
+
schemas_path = File.expand_path('../../../lib/sepa/xml_schemas', __FILE__)
|
105
|
+
xsd = Nokogiri::XML::Schema(File.read("#{schemas_path}/pain.001.001.02.xsd"))
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
end
|
data/lib/sepa/payment.rb
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
module Sepa
|
2
|
+
class Payment
|
3
|
+
def initialize(debtor, params)
|
4
|
+
@payment_info_id = params.fetch(:payment_info_id)
|
5
|
+
@execution_date = params.fetch(:execution_date)
|
6
|
+
@salary_or_pension = params[:salary_or_pension]
|
7
|
+
|
8
|
+
@debtor_name = debtor.fetch(:name)
|
9
|
+
@debtor_address = debtor.fetch(:address)
|
10
|
+
@debtor_country = debtor.fetch(:country)
|
11
|
+
@debtor_postcode = debtor.fetch(:postcode)
|
12
|
+
@debtor_town = debtor.fetch(:town)
|
13
|
+
@debtor_customer_id = debtor.fetch(:customer_id)
|
14
|
+
@debtor_iban = debtor.fetch(:iban)
|
15
|
+
@debtor_bic = debtor.fetch(:bic)
|
16
|
+
|
17
|
+
@transactions = params.fetch(:transactions)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Returns a Nokogiri::XML::Node of the payment.
|
21
|
+
def to_node
|
22
|
+
node = build.doc.root
|
23
|
+
add_transactions(node)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Returns the number of transactions in this payment.
|
27
|
+
def number_of_transactions
|
28
|
+
@transactions.count
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
# Builds the payment.
|
34
|
+
def build
|
35
|
+
Nokogiri::XML::Builder.new do |xml|
|
36
|
+
xml.PmtInf {
|
37
|
+
xml.PmtInfId @payment_info_id
|
38
|
+
xml.PmtMtd 'TRF'
|
39
|
+
|
40
|
+
xml.PmtTpInf {
|
41
|
+
xml.SvcLvl {
|
42
|
+
xml.Cd 'SEPA'
|
43
|
+
}
|
44
|
+
|
45
|
+
# Needs to be specified in case the payment contains salaris or
|
46
|
+
# pensions.
|
47
|
+
if @salary_or_pension
|
48
|
+
xml.CtgyPurp 'SALA'
|
49
|
+
end
|
50
|
+
}
|
51
|
+
|
52
|
+
xml.ReqdExctnDt @execution_date
|
53
|
+
xml.Dbtr {
|
54
|
+
xml.Nm @debtor_name
|
55
|
+
xml.PstlAdr {
|
56
|
+
xml.AdrLine @debtor_address
|
57
|
+
xml.AdrLine "#{@debtor_country}-#{@debtor_postcode} " \
|
58
|
+
"#{@debtor_town}"
|
59
|
+
xml.Ctry @debtor_country
|
60
|
+
}
|
61
|
+
|
62
|
+
xml.Id {
|
63
|
+
xml.OrgId {
|
64
|
+
if @debtor_customer_id
|
65
|
+
xml.BkPtyId @debtor_customer_id
|
66
|
+
end
|
67
|
+
}
|
68
|
+
}
|
69
|
+
}
|
70
|
+
|
71
|
+
xml.DbtrAcct {
|
72
|
+
xml.Id {
|
73
|
+
xml.IBAN @debtor_iban
|
74
|
+
}
|
75
|
+
}
|
76
|
+
|
77
|
+
xml.DbtrAgt {
|
78
|
+
xml.FinInstnId {
|
79
|
+
xml.BIC @debtor_bic
|
80
|
+
}
|
81
|
+
}
|
82
|
+
|
83
|
+
xml.ChrgBr 'SLEV'
|
84
|
+
}
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# Adds the transactions specified in the params hash to the payment.
|
89
|
+
def add_transactions(node)
|
90
|
+
@transactions.each do |transaction|
|
91
|
+
node.add_child(transaction.to_node)
|
92
|
+
end
|
93
|
+
|
94
|
+
node
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,178 @@
|
|
1
|
+
module Sepa
|
2
|
+
class Transaction
|
3
|
+
def initialize(params)
|
4
|
+
@instruction_id = params[:instruction_id]
|
5
|
+
@end_to_end_id = params.fetch(:end_to_end_id)
|
6
|
+
|
7
|
+
# If the parameters contains an invoice bundle, the amount is taken from
|
8
|
+
# them.
|
9
|
+
if params[:invoice_bundle]
|
10
|
+
@amount = 0
|
11
|
+
params[:invoice_bundle].each do |invoice|
|
12
|
+
@amount += invoice.fetch(:amount).to_f
|
13
|
+
end
|
14
|
+
else
|
15
|
+
@amount = params.fetch(:amount)
|
16
|
+
end
|
17
|
+
|
18
|
+
@currency = params.fetch(:currency)
|
19
|
+
@bic = params.fetch(:bic)
|
20
|
+
@name = params.fetch(:name)
|
21
|
+
@address = params.fetch(:address)
|
22
|
+
@country = params.fetch(:country)
|
23
|
+
@postcode = params.fetch(:postcode)
|
24
|
+
@town = params.fetch(:town)
|
25
|
+
@iban = params.fetch(:iban)
|
26
|
+
@reference = params[:reference]
|
27
|
+
@message = params[:message]
|
28
|
+
@salary = params[:salary]
|
29
|
+
@pension = params[:pension]
|
30
|
+
@social_security_number = params[:social_security_number]
|
31
|
+
@invoice_bundle = params[:invoice_bundle]
|
32
|
+
end
|
33
|
+
|
34
|
+
# Returns a Nokogiri::XML::Node of the transaction.
|
35
|
+
def to_node
|
36
|
+
build.doc.root
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
# Builds the transaction
|
42
|
+
def build
|
43
|
+
Nokogiri::XML::Builder.new do |xml|
|
44
|
+
xml.CdtTrfTxInf {
|
45
|
+
xml.PmtId {
|
46
|
+
if @instruction_id
|
47
|
+
xml.InstrId @instruction_id
|
48
|
+
end
|
49
|
+
|
50
|
+
xml.EndToEndId @end_to_end_id
|
51
|
+
}
|
52
|
+
|
53
|
+
xml.Amt {
|
54
|
+
xml.InstdAmt(@amount, :Ccy => @currency)
|
55
|
+
}
|
56
|
+
|
57
|
+
xml.CdtrAgt {
|
58
|
+
xml.FinInstnId {
|
59
|
+
xml.BIC @bic
|
60
|
+
}
|
61
|
+
}
|
62
|
+
|
63
|
+
xml.Cdtr {
|
64
|
+
xml.Nm @name
|
65
|
+
xml.PstlAdr {
|
66
|
+
xml.AdrLine @address
|
67
|
+
xml.AdrLine("#{@country}-#{@postcode} " \
|
68
|
+
"#{@town}")
|
69
|
+
xml.StrtNm @address
|
70
|
+
xml.PstCd "#{@country}-#{@postcode}"
|
71
|
+
xml.TwnNm @town
|
72
|
+
xml.Ctry @country
|
73
|
+
}
|
74
|
+
|
75
|
+
# Social security number needs to be added in case the transaction
|
76
|
+
# contains a salary.
|
77
|
+
if @salary
|
78
|
+
xml.Id {
|
79
|
+
xml.PrvtId {
|
80
|
+
xml.SclSctyNb @social_security_number
|
81
|
+
}
|
82
|
+
}
|
83
|
+
end
|
84
|
+
}
|
85
|
+
|
86
|
+
xml.CdtrAcct {
|
87
|
+
xml.Id {
|
88
|
+
xml.IBAN @iban
|
89
|
+
}
|
90
|
+
}
|
91
|
+
|
92
|
+
# If the transaction contains a pension, this element needs to be
|
93
|
+
# specified.
|
94
|
+
if @pension
|
95
|
+
xml.Purp {
|
96
|
+
xml.Cd 'PENS'
|
97
|
+
}
|
98
|
+
end
|
99
|
+
|
100
|
+
xml.RmtInf {
|
101
|
+
|
102
|
+
# In case this transaction contains an invoice bundle, a Strd
|
103
|
+
# element is added for each invoice either with an invoice number
|
104
|
+
# or a reference.
|
105
|
+
if @invoice_bundle
|
106
|
+
message = ''
|
107
|
+
@invoice_bundle.each do |invoice|
|
108
|
+
|
109
|
+
if invoice[:amount].to_f < 0
|
110
|
+
amount = "#{invoice[:amount].to_f.abs}-"
|
111
|
+
else
|
112
|
+
amount = invoice[:amount]
|
113
|
+
end
|
114
|
+
|
115
|
+
if invoice[:reference]
|
116
|
+
message += "RFS/#{invoice[:reference]}/" \
|
117
|
+
"#{invoice[:currency]}#{amount}/"
|
118
|
+
elsif invoice[:invoice_number]
|
119
|
+
message += "#{invoice[:type]}/#{invoice[:invoice_number]}/" \
|
120
|
+
"#{invoice[:currency]}#{amount}/"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
xml.Ustrd message
|
125
|
+
|
126
|
+
@invoice_bundle.each do |invoice|
|
127
|
+
xml.Strd {
|
128
|
+
xml.RfrdDocInf {
|
129
|
+
xml.RfrdDocTp {
|
130
|
+
xml.Cd invoice.fetch(:type)
|
131
|
+
}
|
132
|
+
|
133
|
+
if invoice[:invoice_number]
|
134
|
+
xml.RfrdDocNb invoice[:invoice_number]
|
135
|
+
end
|
136
|
+
}
|
137
|
+
xml.RfrdDocAmt {
|
138
|
+
if invoice.fetch(:amount).to_f > 0
|
139
|
+
xml.RmtdAmt(invoice[:amount],
|
140
|
+
:Ccy => invoice[:currency])
|
141
|
+
else
|
142
|
+
xml.CdtNoteAmt(invoice[:amount].to_f.abs,
|
143
|
+
:Ccy => invoice[:currency])
|
144
|
+
end
|
145
|
+
}
|
146
|
+
|
147
|
+
if invoice[:reference]
|
148
|
+
xml.CdtrRefInf {
|
149
|
+
xml.CdtrRefTp {
|
150
|
+
xml.Cd 'SCOR'
|
151
|
+
}
|
152
|
+
|
153
|
+
xml.CdtrRef invoice[:reference]
|
154
|
+
}
|
155
|
+
end
|
156
|
+
}
|
157
|
+
end
|
158
|
+
|
159
|
+
elsif @reference
|
160
|
+
xml.Strd {
|
161
|
+
xml.CdtrRefInf {
|
162
|
+
xml.CdtrRefTp {
|
163
|
+
xml.Cd 'SCOR'
|
164
|
+
}
|
165
|
+
|
166
|
+
xml.CdtrRef @reference
|
167
|
+
}
|
168
|
+
}
|
169
|
+
|
170
|
+
else
|
171
|
+
xml.Ustrd @message
|
172
|
+
end
|
173
|
+
}
|
174
|
+
}
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
data/lib/sepa/version.rb
CHANGED