sepa_king 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/sepa_king/account/creditor_account.rb +8 -0
- data/lib/sepa_king/{exception.rb → account/debtor_account.rb} +1 -1
- data/lib/sepa_king/account.rb +9 -28
- data/lib/sepa_king/converter.rb +44 -0
- data/lib/sepa_king/message/credit_transfer.rb +86 -0
- data/lib/sepa_king/message/direct_debit.rb +104 -0
- data/lib/sepa_king/message.rb +48 -0
- data/lib/sepa_king/transaction/credit_transfer_transaction.rb +5 -0
- data/lib/sepa_king/transaction/direct_debit_transaction.rb +17 -0
- data/lib/sepa_king/transaction.rb +13 -45
- data/lib/sepa_king/version.rb +1 -1
- data/lib/sepa_king.rb +9 -6
- data/sepa_king.gemspec +1 -0
- data/spec/account_spec.rb +66 -0
- data/spec/converter_spec.rb +46 -0
- data/spec/credit_transfer_spec.rb +69 -0
- data/spec/credit_transfer_transaction_spec.rb +15 -0
- data/spec/creditor_account_spec.rb +31 -0
- data/spec/debtor_account_spec.rb +12 -0
- data/spec/direct_debit_spec.rb +76 -0
- data/spec/direct_debit_transaction_spec.rb +53 -0
- data/spec/{fixtures → examples}/pain.001.002.03.xml +0 -0
- data/spec/{fixtures → examples}/pain.008.002.02.xml +0 -0
- data/spec/message_spec.rb +22 -0
- data/spec/spec_helper.rb +0 -1
- data/spec/support/validations.rb +27 -0
- data/spec/transaction_spec.rb +112 -0
- data/spec/{sepa_king/validation_spec.rb → validation_spec.rb} +2 -2
- metadata +52 -28
- data/lib/sepa_king/credit_transaction.rb +0 -5
- data/lib/sepa_king/credit_transfer.rb +0 -104
- data/lib/sepa_king/debt_transaction.rb +0 -18
- data/lib/sepa_king/direct_debit.rb +0 -122
- data/lib/sepa_king/text_converter.rb +0 -25
- data/spec/sepa_king/account_spec.rb +0 -13
- data/spec/sepa_king/credit_transaction_spec.rb +0 -15
- data/spec/sepa_king/credit_transfer_spec.rb +0 -26
- data/spec/sepa_king/debt_transaction_spec.rb +0 -53
- data/spec/sepa_king/direct_debit_spec.rb +0 -31
- data/spec/sepa_king/text_converter_spec.rb +0 -22
- data/spec/sepa_king/transaction_spec.rb +0 -112
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d39443f2a8e1403804bfc6dd0eeb03f9e5e9d845
|
4
|
+
data.tar.gz: 7fa5f5072912dee37819412cc0e05229c371b33a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a6aa54767870360c955f350ae74bd3777fc6f7928b9cf9b75806689e76f4b70db70f5f722e426c7b4df075b6dcba939e560e84af479d56417c2b8caac9b173a1
|
7
|
+
data.tar.gz: 9a06003c4a9d9c9fdbf58d1d6430651888339317c1f1a8f98d2f5c1a5f320b7b60457e3fae7e7ce8d8c74e6fdc9e3d4b2052aeae96e742079c3dbc4650a5cf1b
|
data/lib/sepa_king/account.rb
CHANGED
@@ -1,37 +1,18 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
module SEPA
|
3
3
|
class Account
|
4
|
-
include
|
4
|
+
include ActiveModel::Model
|
5
|
+
extend Converter
|
5
6
|
|
6
|
-
|
7
|
+
attr_accessor :name, :iban, :bic
|
8
|
+
convert :name, :to => :text
|
7
9
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
def name=(value)
|
15
|
-
raise ArgumentError.new('Name is missing') unless value
|
16
|
-
@name = value
|
17
|
-
end
|
18
|
-
|
19
|
-
def iban=(value)
|
20
|
-
raise ArgumentError.new('IBAN is missing') unless value
|
21
|
-
raise ArgumentError.new("IBAN has wrong length: #{value.length}, must be between 15-34") unless value.length.between?(15,34)
|
22
|
-
@iban = value
|
23
|
-
end
|
24
|
-
|
25
|
-
def bic=(value)
|
26
|
-
raise ArgumentError.new('BIC is missing') unless value
|
27
|
-
raise ArgumentError.new("BIC has wrong length: #{value.length} must be between 8-11") unless value.length.between?(8,11)
|
28
|
-
@bic = value
|
29
|
-
end
|
10
|
+
validates_presence_of :name, :iban, :bic
|
11
|
+
validates_length_of :name, :maximum => 70
|
12
|
+
validates_length_of :bic, :within => 8..11
|
30
13
|
|
31
|
-
|
32
|
-
|
33
|
-
raise ArgumentError.new("Identifier has wrong length: #{value.length} must be exactly 18") unless value.length == 18
|
34
|
-
@identifier = value
|
14
|
+
validate do |t|
|
15
|
+
errors.add(:iban, 'is invalid') unless IBANTools::IBAN.valid?(t.iban.to_s)
|
35
16
|
end
|
36
17
|
end
|
37
18
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module SEPA
|
3
|
+
module Converter
|
4
|
+
def convert(*attributes, options)
|
5
|
+
include InstanceMethods
|
6
|
+
|
7
|
+
method_name = "convert_#{options[:to]}"
|
8
|
+
raise ArgumentError.new("Converter '#{options[:to]}' does not exist!") unless InstanceMethods.method_defined?(method_name)
|
9
|
+
|
10
|
+
attributes.each do |attribute|
|
11
|
+
define_method "#{attribute}=" do |value|
|
12
|
+
instance_variable_set("@#{attribute}", send(method_name, value))
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
module InstanceMethods
|
18
|
+
def convert_text(value)
|
19
|
+
return unless value
|
20
|
+
|
21
|
+
text = value.to_s.
|
22
|
+
# Convert german umlauts
|
23
|
+
gsub('Ä', 'AE').
|
24
|
+
gsub('Ü', 'UE').
|
25
|
+
gsub('Ö', 'OE').
|
26
|
+
gsub('ä', 'ae').
|
27
|
+
gsub('ü', 'ue').
|
28
|
+
gsub('ö', 'oe').
|
29
|
+
gsub('ß', 'ss')
|
30
|
+
|
31
|
+
I18n.transliterate(text).
|
32
|
+
# Remove all invalid characters
|
33
|
+
gsub(/[^a-zA-Z0-9\ \'\:\?\,\-\(\+\.\)\/]/, '').
|
34
|
+
# Remove leading and trailing spaces
|
35
|
+
strip
|
36
|
+
end
|
37
|
+
|
38
|
+
def convert_decimal(value)
|
39
|
+
return unless value
|
40
|
+
BigDecimal(value.to_s).round(2)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module SEPA
|
4
|
+
class CreditTransfer < Message
|
5
|
+
self.account_class = DebtorAccount
|
6
|
+
self.transaction_class = CreditTransferTransaction
|
7
|
+
|
8
|
+
def to_xml
|
9
|
+
super
|
10
|
+
|
11
|
+
builder = Builder::XmlMarkup.new :indent => 2
|
12
|
+
builder.instruct!
|
13
|
+
builder.Document :xmlns => 'urn:iso:std:iso:20022:tech:xsd:pain.001.002.03',
|
14
|
+
:'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
|
15
|
+
:'xsi:schemaLocation' => 'urn:iso:std:iso:20022:tech:xsd:pain.001.002.03 pain.001.002.03.xsd' do
|
16
|
+
builder.CstmrCdtTrfInitn do
|
17
|
+
build_group_header(builder)
|
18
|
+
build_payment_information(builder)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
def build_payment_information(builder)
|
25
|
+
builder.PmtInf do
|
26
|
+
builder.PmtInfId(payment_information_identification)
|
27
|
+
builder.PmtMtd('TRF')
|
28
|
+
builder.BtchBookg(true)
|
29
|
+
builder.NbOfTxs(transactions.length)
|
30
|
+
builder.CtrlSum('%.2f' % amount_total)
|
31
|
+
builder.PmtTpInf do
|
32
|
+
builder.SvcLvl do
|
33
|
+
builder.Cd('SEPA')
|
34
|
+
end
|
35
|
+
end
|
36
|
+
builder.ReqdExctnDt(Date.today.next.iso8601)
|
37
|
+
builder.Dbtr do
|
38
|
+
builder.Nm(account.name)
|
39
|
+
end
|
40
|
+
builder.DbtrAcct do
|
41
|
+
builder.Id do
|
42
|
+
builder.IBAN(account.iban)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
builder.DbtrAgt do
|
46
|
+
builder.FinInstnId do
|
47
|
+
builder.BIC(account.bic)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
builder.ChrgBr('SLEV')
|
51
|
+
build_transactions(builder)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def build_transactions(builder)
|
56
|
+
transactions.each do |transaction|
|
57
|
+
builder.CdtTrfTxInf do
|
58
|
+
builder.PmtId do
|
59
|
+
builder.EndToEndId(transaction.reference || 'NOTPROVIDED')
|
60
|
+
end
|
61
|
+
builder.Amt do
|
62
|
+
builder.InstdAmt('%.2f' % transaction.amount, :Ccy => 'EUR')
|
63
|
+
end
|
64
|
+
builder.CdtrAgt do
|
65
|
+
builder.FinInstnId do
|
66
|
+
builder.BIC(transaction.bic)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
builder.Cdtr do
|
70
|
+
builder.Nm(transaction.name)
|
71
|
+
end
|
72
|
+
builder.CdtrAcct do
|
73
|
+
builder.Id do
|
74
|
+
builder.IBAN(transaction.iban)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
if transaction.remittance_information
|
78
|
+
builder.RmtInf do
|
79
|
+
builder.Ustrd(transaction.remittance_information)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module SEPA
|
4
|
+
class DirectDebit < Message
|
5
|
+
self.account_class = CreditorAccount
|
6
|
+
self.transaction_class = DirectDebitTransaction
|
7
|
+
|
8
|
+
def to_xml
|
9
|
+
super
|
10
|
+
builder = Builder::XmlMarkup.new :indent => 2
|
11
|
+
builder.instruct!
|
12
|
+
builder.Document :xmlns => 'urn:iso:std:iso:20022:tech:xsd:pain.008.002.02',
|
13
|
+
:'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
|
14
|
+
:'xsi:schemaLocation' => 'urn:iso:std:iso:20022:tech:xsd:pain.008.002.02 pain.008.002.02.xsd' do
|
15
|
+
builder.CstmrDrctDbtInitn do
|
16
|
+
build_group_header(builder)
|
17
|
+
build_payment_information(builder)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
def build_payment_information(builder)
|
24
|
+
builder.PmtInf do
|
25
|
+
builder.PmtInfId(payment_information_identification)
|
26
|
+
builder.PmtMtd('DD')
|
27
|
+
builder.NbOfTxs(transactions.length)
|
28
|
+
builder.CtrlSum('%.2f' % amount_total)
|
29
|
+
builder.PmtTpInf do
|
30
|
+
builder.SvcLvl do
|
31
|
+
builder.Cd('SEPA')
|
32
|
+
end
|
33
|
+
builder.LclInstrm do
|
34
|
+
builder.Cd('CORE')
|
35
|
+
end
|
36
|
+
builder.SeqTp('OOFF')
|
37
|
+
end
|
38
|
+
builder.ReqdColltnDt(Date.today.next.iso8601)
|
39
|
+
builder.Cdtr do
|
40
|
+
builder.Nm(account.name)
|
41
|
+
end
|
42
|
+
builder.CdtrAcct do
|
43
|
+
builder.Id do
|
44
|
+
builder.IBAN(account.iban)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
builder.CdtrAgt do
|
48
|
+
builder.FinInstnId do
|
49
|
+
builder.BIC(account.bic)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
builder.ChrgBr('SLEV')
|
53
|
+
builder.CdtrSchmeId do
|
54
|
+
builder.Id do
|
55
|
+
builder.PrvtId do
|
56
|
+
builder.Othr do
|
57
|
+
builder.Id(account.identifier)
|
58
|
+
builder.SchmeNm do
|
59
|
+
builder.Prtry('SEPA')
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
build_transactions(builder)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def build_transactions(builder)
|
70
|
+
transactions.each do |transaction|
|
71
|
+
builder.DrctDbtTxInf do
|
72
|
+
builder.PmtId do
|
73
|
+
builder.EndToEndId(transaction.reference || 'NOTPROVIDED')
|
74
|
+
end
|
75
|
+
builder.InstdAmt('%.2f' % transaction.amount, :Ccy => 'EUR')
|
76
|
+
builder.DrctDbtTx do
|
77
|
+
builder.MndtRltdInf do
|
78
|
+
builder.MndtId(transaction.mandate_id)
|
79
|
+
builder.DtOfSgntr(transaction.mandate_date_of_signature.iso8601)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
builder.DbtrAgt do
|
83
|
+
builder.FinInstnId do
|
84
|
+
builder.BIC(transaction.bic)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
builder.Dbtr do
|
88
|
+
builder.Nm(transaction.name)
|
89
|
+
end
|
90
|
+
builder.DbtrAcct do
|
91
|
+
builder.Id do
|
92
|
+
builder.IBAN(transaction.iban)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
if transaction.remittance_information
|
96
|
+
builder.RmtInf do
|
97
|
+
builder.Ustrd(transaction.remittance_information)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module SEPA
|
4
|
+
class Message
|
5
|
+
attr_reader :account, :transactions
|
6
|
+
class_attribute :account_class, :transaction_class
|
7
|
+
|
8
|
+
def initialize(account_options={})
|
9
|
+
@transactions = []
|
10
|
+
@account = self.account_class.new(account_options)
|
11
|
+
end
|
12
|
+
|
13
|
+
def add_transaction(options)
|
14
|
+
transaction = transaction_class.new(options)
|
15
|
+
raise ArgumentError.new(transaction.errors.full_messages.join("\n")) unless transaction.valid?
|
16
|
+
@transactions << transaction
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_xml
|
20
|
+
raise RuntimeError.new(account.errors.full_messages.join("\n")) unless account.valid?
|
21
|
+
end
|
22
|
+
|
23
|
+
def amount_total
|
24
|
+
transactions.inject(0) { |sum, t| sum + t.amount }
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
def build_group_header(builder)
|
29
|
+
builder.GrpHdr do
|
30
|
+
builder.MsgId(message_identification)
|
31
|
+
builder.CreDtTm(Time.now.iso8601)
|
32
|
+
builder.NbOfTxs(transactions.length)
|
33
|
+
builder.CtrlSum('%.2f' % amount_total)
|
34
|
+
builder.InitgPty do
|
35
|
+
builder.Nm(account.name)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def message_identification
|
41
|
+
"SEPA-KING/#{Time.now.iso8601}"
|
42
|
+
end
|
43
|
+
|
44
|
+
def payment_information_identification
|
45
|
+
message_identification
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module SEPA
|
3
|
+
class DirectDebitTransaction < Transaction
|
4
|
+
attr_accessor :mandate_id, :mandate_date_of_signature
|
5
|
+
|
6
|
+
validates_length_of :mandate_id, :within => 1..35
|
7
|
+
validates_presence_of :mandate_date_of_signature
|
8
|
+
|
9
|
+
validate do |t|
|
10
|
+
if t.mandate_date_of_signature.is_a?(Date)
|
11
|
+
errors.add(:mandate_date_of_signature, 'is in the future') if t.mandate_date_of_signature > Date.today
|
12
|
+
else
|
13
|
+
errors.add(:mandate_date_of_signature, 'is not a Date')
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -1,54 +1,22 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
module SEPA
|
3
3
|
class Transaction
|
4
|
-
include
|
5
|
-
|
4
|
+
include ActiveModel::Model
|
5
|
+
extend Converter
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
def name=(value)
|
14
|
-
raise ArgumentError.new('Name is missing') if value.nil? || value.empty?
|
15
|
-
raise ArgumentError.new("Name is too long: #{value.length}, must be 70 maximum") if value.length > 70
|
16
|
-
@name = convert_text(value)
|
17
|
-
end
|
18
|
-
|
19
|
-
def iban=(value)
|
20
|
-
raise ArgumentError.new('IBAN is missing') if value.nil? || value.empty?
|
21
|
-
raise ArgumentError.new('IBAN is invalid') unless IBANTools::IBAN.valid?(value)
|
22
|
-
@iban = value
|
23
|
-
end
|
7
|
+
attr_accessor :name, :iban, :bic, :amount, :reference, :remittance_information
|
8
|
+
convert :name, :reference, :remittance_information, :to => :text
|
9
|
+
convert :amount, :to => :decimal
|
24
10
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
def amount=(value)
|
32
|
-
raise ArgumentError.new('Amount is not a number') unless value.is_a?(Numeric)
|
33
|
-
raise ArgumentError.new('Amount cannot be zero') if value.zero?
|
34
|
-
raise ArgumentError.new('Amount cannot be negative') if value < 0
|
35
|
-
raise ArgumentError.new('Amount has more than 2 digits') if value.round(2) != value
|
36
|
-
@amount = value
|
37
|
-
end
|
38
|
-
|
39
|
-
def reference=(value)
|
40
|
-
raise ArgumentError.new('Reference is missing') if value.nil? || value.empty?
|
41
|
-
raise ArgumentError.new("Reference is too long: #{value.length}, must be 35 maximum") if value.length > 35
|
42
|
-
@reference = convert_text(value)
|
43
|
-
end
|
11
|
+
validates_presence_of :name, :iban, :bic, :amount
|
12
|
+
validates_length_of :name, :maximum => 70
|
13
|
+
validates_length_of :bic, :within => 8..11
|
14
|
+
validates_length_of :reference, :maximum => 35, :minimum => 1, :allow_nil => true
|
15
|
+
validates_length_of :remittance_information, :minimum => 1, :maximum => 140, :allow_nil => true
|
16
|
+
validates_numericality_of :amount, :greater_than => 0
|
44
17
|
|
45
|
-
|
46
|
-
|
47
|
-
raise ArgumentError.new('Remittance information has to be a string') unless value.is_a?(String)
|
48
|
-
raise ArgumentError.new('Remittance information cannot be blank') if value.empty?
|
49
|
-
raise ArgumentError.new("Remittance information is too long: #{value.length}, must be 140 maximum") if value.length > 140
|
50
|
-
end
|
51
|
-
@remittance_information = convert_text(value)
|
18
|
+
validate do |t|
|
19
|
+
errors.add(:iban, 'is invalid') unless IBANTools::IBAN.valid?(t.iban.to_s)
|
52
20
|
end
|
53
21
|
end
|
54
22
|
end
|
data/lib/sepa_king/version.rb
CHANGED
data/lib/sepa_king.rb
CHANGED
@@ -1,13 +1,16 @@
|
|
1
1
|
require 'i18n'
|
2
|
+
require 'active_model'
|
2
3
|
require 'bigdecimal'
|
3
4
|
require 'builder'
|
4
5
|
require 'iban-tools'
|
5
6
|
|
6
|
-
require 'sepa_king/
|
7
|
+
require 'sepa_king/converter'
|
7
8
|
require 'sepa_king/account'
|
9
|
+
require 'sepa_king/account/debtor_account'
|
10
|
+
require 'sepa_king/account/creditor_account'
|
8
11
|
require 'sepa_king/transaction'
|
9
|
-
require 'sepa_king/
|
10
|
-
require 'sepa_king/
|
11
|
-
require 'sepa_king/
|
12
|
-
require 'sepa_king/direct_debit'
|
13
|
-
require 'sepa_king/credit_transfer'
|
12
|
+
require 'sepa_king/transaction/direct_debit_transaction'
|
13
|
+
require 'sepa_king/transaction/credit_transfer_transaction'
|
14
|
+
require 'sepa_king/message'
|
15
|
+
require 'sepa_king/message/direct_debit'
|
16
|
+
require 'sepa_king/message/credit_transfer'
|
data/sepa_king.gemspec
CHANGED
@@ -18,6 +18,7 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
19
19
|
s.require_paths = ['lib']
|
20
20
|
|
21
|
+
s.add_runtime_dependency 'activemodel'
|
21
22
|
s.add_runtime_dependency 'i18n'
|
22
23
|
s.add_runtime_dependency 'builder'
|
23
24
|
s.add_runtime_dependency 'iban-tools'
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe SEPA::Account do
|
5
|
+
describe 'Initialization' do
|
6
|
+
it 'should not accept unknown keys' do
|
7
|
+
expect {
|
8
|
+
SEPA::Account.new :foo => 'bar'
|
9
|
+
}.to raise_error(NoMethodError)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe :name do
|
14
|
+
it 'should accept valid value' do
|
15
|
+
[ 'Gläubiger GmbH', 'Zahlemann & Söhne GbR', 'X' * 70 ].each do |value_value|
|
16
|
+
expect(
|
17
|
+
SEPA::Account.new :name => value_value
|
18
|
+
).to have(:no).errors_on(:name)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should not accept invalid value' do
|
23
|
+
[ nil, '', 'X' * 71 ].each do |invalue_value|
|
24
|
+
expect(
|
25
|
+
SEPA::Account.new :name => invalue_value
|
26
|
+
).to have_at_least(1).errors_on(:name)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe :iban do
|
32
|
+
it 'should accept valid value' do
|
33
|
+
[ 'DE21500500009876543210', 'PL61109010140000071219812874' ].each do |value_value|
|
34
|
+
expect(
|
35
|
+
SEPA::Account.new :iban => value_value
|
36
|
+
).to have(:no).errors_on(:iban)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should not accept invalid value' do
|
41
|
+
[ nil, '', 'invalid' ].each do |invalue_value|
|
42
|
+
expect(
|
43
|
+
SEPA::Account.new :iban => invalue_value
|
44
|
+
).to have_at_least(1).errors_on(:iban)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe :bic do
|
50
|
+
it 'should accept valid value' do
|
51
|
+
[ 'DEUTDEFF', 'DEUTDEFF500', 'SPUEDE2UXXX' ].each do |value_value|
|
52
|
+
expect(
|
53
|
+
SEPA::Account.new :bic => value_value
|
54
|
+
).to have(:no).errors_on(:bic)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'should not accept invalid value' do
|
59
|
+
[ nil, '', 'invalid' ].each do |invalue_value|
|
60
|
+
expect(
|
61
|
+
SEPA::Account.new :bic => invalue_value
|
62
|
+
).to have_at_least(1).errors_on(:bic)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe SEPA::Converter do
|
5
|
+
include SEPA::Converter::InstanceMethods
|
6
|
+
|
7
|
+
describe :convert_text do
|
8
|
+
it 'should remove invalid chars' do
|
9
|
+
convert_text('&@"=<>!').should == ''
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'should not touch valid chars' do
|
13
|
+
convert_text("abc-ABC-0123- ':?,-(+.)/").should == "abc-ABC-0123- ':?,-(+.)/"
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should convert umlaute' do
|
17
|
+
convert_text('üöäÜÖÄß').should == 'ueoeaeUEOEAEss'
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should convert number' do
|
21
|
+
convert_text(1234).should == '1234'
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should not touch nil' do
|
25
|
+
convert_text(nil).should == nil
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe :convert_decimal do
|
30
|
+
it "should convert Integer to BigDecimal" do
|
31
|
+
convert_decimal(42).should == BigDecimal('42.00')
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should convert Float to BigDecimal" do
|
35
|
+
convert_decimal(42.12).should == BigDecimal('42.12')
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should round' do
|
39
|
+
convert_decimal(1.345).should == BigDecimal('1.35')
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'should not touch nil' do
|
43
|
+
convert_decimal(nil).should == nil
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe SEPA::CreditTransfer do
|
5
|
+
let(:credit_transfer) {
|
6
|
+
SEPA::CreditTransfer.new :name => 'Schuldner GmbH',
|
7
|
+
:bic => 'BANKDEFFXXX',
|
8
|
+
:iban => 'DE87200500001234567890'
|
9
|
+
}
|
10
|
+
|
11
|
+
describe :new do
|
12
|
+
it 'should accept mission options' do
|
13
|
+
expect {
|
14
|
+
SEPA::CreditTransfer.new
|
15
|
+
}.to_not raise_error
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe :add_transaction do
|
20
|
+
it 'should add valid transactions' do
|
21
|
+
3.times {
|
22
|
+
credit_transfer.add_transaction :name => 'Telekomiker AG',
|
23
|
+
:bic => 'PBNKDEFF370',
|
24
|
+
:iban => 'DE37112589611964645802',
|
25
|
+
:amount => 102.50,
|
26
|
+
:reference => 'XYZ-1234/123',
|
27
|
+
:remittance_information => 'Rechnung vom 22.08.2013'
|
28
|
+
}
|
29
|
+
|
30
|
+
expect(credit_transfer).to have(3).transactions
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should fail for invalid transaction' do
|
34
|
+
expect {
|
35
|
+
credit_transfer.add_transaction :name => ''
|
36
|
+
}.to raise_error(ArgumentError)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe :to_xml do
|
41
|
+
it 'should fail for invalid debtor' do
|
42
|
+
expect {
|
43
|
+
SEPA::CreditTransfer.new.to_xml
|
44
|
+
}.to raise_error(RuntimeError)
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should create valid XML file' do
|
48
|
+
ct = credit_transfer
|
49
|
+
|
50
|
+
ct.add_transaction :name => 'Telekomiker AG',
|
51
|
+
:bic => 'PBNKDEFF370',
|
52
|
+
:iban => 'DE37112589611964645802',
|
53
|
+
:amount => 102.50,
|
54
|
+
:reference => 'XYZ-1234/123',
|
55
|
+
:remittance_information => 'Rechnung vom 22.08.2013'
|
56
|
+
|
57
|
+
ct.add_transaction :name => 'Amazonas GmbH',
|
58
|
+
:bic => 'TUBDDEDDXXX',
|
59
|
+
:iban => 'DE27793589132923472195',
|
60
|
+
:amount => 59.00,
|
61
|
+
:reference => 'XYZ-5678/456',
|
62
|
+
:remittance_information => 'Rechnung vom 21.08.2013'
|
63
|
+
|
64
|
+
expect(
|
65
|
+
XML::Document.string(ct.to_xml)
|
66
|
+
).to validate_against('pain.001.002.03.xsd')
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|