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.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/lib/sepa_king/account/creditor_account.rb +8 -0
  3. data/lib/sepa_king/{exception.rb → account/debtor_account.rb} +1 -1
  4. data/lib/sepa_king/account.rb +9 -28
  5. data/lib/sepa_king/converter.rb +44 -0
  6. data/lib/sepa_king/message/credit_transfer.rb +86 -0
  7. data/lib/sepa_king/message/direct_debit.rb +104 -0
  8. data/lib/sepa_king/message.rb +48 -0
  9. data/lib/sepa_king/transaction/credit_transfer_transaction.rb +5 -0
  10. data/lib/sepa_king/transaction/direct_debit_transaction.rb +17 -0
  11. data/lib/sepa_king/transaction.rb +13 -45
  12. data/lib/sepa_king/version.rb +1 -1
  13. data/lib/sepa_king.rb +9 -6
  14. data/sepa_king.gemspec +1 -0
  15. data/spec/account_spec.rb +66 -0
  16. data/spec/converter_spec.rb +46 -0
  17. data/spec/credit_transfer_spec.rb +69 -0
  18. data/spec/credit_transfer_transaction_spec.rb +15 -0
  19. data/spec/creditor_account_spec.rb +31 -0
  20. data/spec/debtor_account_spec.rb +12 -0
  21. data/spec/direct_debit_spec.rb +76 -0
  22. data/spec/direct_debit_transaction_spec.rb +53 -0
  23. data/spec/{fixtures → examples}/pain.001.002.03.xml +0 -0
  24. data/spec/{fixtures → examples}/pain.008.002.02.xml +0 -0
  25. data/spec/message_spec.rb +22 -0
  26. data/spec/spec_helper.rb +0 -1
  27. data/spec/support/validations.rb +27 -0
  28. data/spec/transaction_spec.rb +112 -0
  29. data/spec/{sepa_king/validation_spec.rb → validation_spec.rb} +2 -2
  30. metadata +52 -28
  31. data/lib/sepa_king/credit_transaction.rb +0 -5
  32. data/lib/sepa_king/credit_transfer.rb +0 -104
  33. data/lib/sepa_king/debt_transaction.rb +0 -18
  34. data/lib/sepa_king/direct_debit.rb +0 -122
  35. data/lib/sepa_king/text_converter.rb +0 -25
  36. data/spec/sepa_king/account_spec.rb +0 -13
  37. data/spec/sepa_king/credit_transaction_spec.rb +0 -15
  38. data/spec/sepa_king/credit_transfer_spec.rb +0 -26
  39. data/spec/sepa_king/debt_transaction_spec.rb +0 -53
  40. data/spec/sepa_king/direct_debit_spec.rb +0 -31
  41. data/spec/sepa_king/text_converter_spec.rb +0 -22
  42. data/spec/sepa_king/transaction_spec.rb +0 -112
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 975c5018834a59ef2185c0b36f0f9ae64a49f600
4
- data.tar.gz: 0af3c482071e0b707162776b948d4cc55fa2bacf
3
+ metadata.gz: d39443f2a8e1403804bfc6dd0eeb03f9e5e9d845
4
+ data.tar.gz: 7fa5f5072912dee37819412cc0e05229c371b33a
5
5
  SHA512:
6
- metadata.gz: 75b1b3c8cd76dfe4142b549c5b7c3512a9e3077ff278f9d7c0a879ecf278824b0da5d629043b72dce7762ba5bb61c5005bfd0a307b1c84899446bf9177345720
7
- data.tar.gz: 7c6b844e79e783258601b637596c30c7bc07a3f557e475a9ea667ffd67cacafe3780bf4992ba2448965547575d5ca4261b5e4a9dbda89af56a01b91cc5c5b2b7
6
+ metadata.gz: a6aa54767870360c955f350ae74bd3777fc6f7928b9cf9b75806689e76f4b70db70f5f722e426c7b4df075b6dcba939e560e84af479d56417c2b8caac9b173a1
7
+ data.tar.gz: 9a06003c4a9d9c9fdbf58d1d6430651888339317c1f1a8f98d2f5c1a5f320b7b60457e3fae7e7ce8d8c74e6fdc9e3d4b2052aeae96e742079c3dbc4650a5cf1b
@@ -0,0 +1,8 @@
1
+ # encoding: utf-8
2
+ module SEPA
3
+ class CreditorAccount < Account
4
+ attr_accessor :identifier
5
+
6
+ validates_length_of :identifier, :is => 18
7
+ end
8
+ end
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
  module SEPA
3
- class Exception < ::Exception
3
+ class DebtorAccount < Account
4
4
  end
5
5
  end
@@ -1,37 +1,18 @@
1
1
  # encoding: utf-8
2
2
  module SEPA
3
3
  class Account
4
- include TextConverter
4
+ include ActiveModel::Model
5
+ extend Converter
5
6
 
6
- attr_reader :name, :iban, :bic, :identifier
7
+ attr_accessor :name, :iban, :bic
8
+ convert :name, :to => :text
7
9
 
8
- def initialize(options)
9
- options.each_pair do |k,v|
10
- send("#{k}=", convert_text(v))
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
- def identifier=(value)
32
- raise ArgumentError.new('Identifier is missing') unless value
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,5 @@
1
+ # encoding: utf-8
2
+ module SEPA
3
+ class CreditTransferTransaction < Transaction
4
+ end
5
+ 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 TextConverter
5
- attr_reader :name, :iban, :bic, :amount, :reference, :remittance_information
4
+ include ActiveModel::Model
5
+ extend Converter
6
6
 
7
- def initialize(options)
8
- options.each_pair do |k,v|
9
- send("#{k}=", v)
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
- def bic=(value)
26
- raise ArgumentError.new('BIC is missing') if value.nil? || value.empty?
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
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
- def remittance_information=(value)
46
- if value
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
@@ -1,3 +1,3 @@
1
1
  module SEPA
2
- VERSION = '0.0.3'
2
+ VERSION = '0.0.4'
3
3
  end
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/text_converter'
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/debt_transaction'
10
- require 'sepa_king/credit_transaction'
11
- require 'sepa_king/exception'
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