sepa_king 0.0.3 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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