payment_dta 0.0.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e203d13d27d3c009b4a4272e5f29081448834171
4
+ data.tar.gz: a9f68912e4ac9a66c48d332a9c18fd731f102235
5
+ SHA512:
6
+ metadata.gz: fdbeb4b0f138f16542a0f3a07597944890208c3c21a393561d21d459e0b1cc39a0da505a173b2656a58d3c885b9bd45e1e3ebfa485d1b84f56093392869d6b0c
7
+ data.tar.gz: 8ab81bac6b497554505da76df997f7aca3016d0797808e9846cd159db73c4040a6e621b2f973fd2911f28e9101cc486a96579cd392f611537ef941cab3a1958a
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
@@ -0,0 +1,9 @@
1
+ .DS_Store
2
+ .rvmrc
3
+ coverage
4
+ rdoc
5
+ pkg
6
+ *.tmproj
7
+ tmp/*.dta
8
+ .bundle
9
+ Gemfile.lock
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.0
4
+ - 1.9.2
5
+ - 1.9.3
6
+ - jruby-19mode
@@ -0,0 +1,20 @@
1
+ # Changelog
2
+
3
+ ## 1.0.0
4
+
5
+ * Discontinue support for Ruby 1.8
6
+ * Support for Ruby 1.9.x and Ruby 2.0
7
+ * Move to bundler
8
+ * Run tests on travis.ci
9
+ * fix issue #2 (calculate entry_sequence_number) (gewo)
10
+ * use swift convention for amount formatting (gewo)
11
+ * use BigDecimal for calculating the TotalRecord sum to prevent rounding
12
+ errors (gewo)
13
+ * truncate long input for beneficiary_address_line[1-4] (gewo)
14
+ * convert characters in the @data-hash getter, before building the final
15
+ record to get the correct record-lengths (gewo)
16
+
17
+ ### Contributors
18
+
19
+ * [gewo](https://github.com/gewo)
20
+ * [senny](https://github.com/senny)
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in payment_dta.gemspec
4
+ gemspec
@@ -0,0 +1,23 @@
1
+ require 'rubygems'
2
+ require 'bundler/gem_tasks'
3
+ require 'rake'
4
+ require 'rdoc/task'
5
+ require 'rspec/core/rake_task'
6
+ RSpec::Core::RakeTask.new(:spec) do |spec|
7
+ end
8
+
9
+ task :default => :spec
10
+
11
+
12
+ RDoc::Task.new do |rdoc|
13
+ if File.exist?('VERSION')
14
+ version = File.read('VERSION')
15
+ else
16
+ version = ""
17
+ end
18
+
19
+ rdoc.rdoc_dir = 'rdoc'
20
+ rdoc.title = "payment_dta #{version}"
21
+ rdoc.rdoc_files.include('README*')
22
+ rdoc.rdoc_files.include('lib/**/*.rb')
23
+ end
@@ -1,4 +1,5 @@
1
+ require 'payment_dta/version'
1
2
  require 'payment_dta/dta_file'
2
3
  %w(esr_payment domestic_chf_payment financial_institution_payment bank_cheque_payment iban_payment special_financial_institution_payment total_record).each do |payment_type|
3
4
  require "payment_dta/payments/#{payment_type}"
4
- end
5
+ end
@@ -1,4 +1,3 @@
1
- require 'iconv'
2
1
  module DTA
3
2
  module CharacterConversion
4
3
  CONVERSION_MAP_UTF8 = {
@@ -230,7 +229,7 @@ module DTA
230
229
  def map_characters(string)
231
230
  new_string = ""
232
231
  string.each_char do |character|
233
- code = character.size == 1 ? character[0] : "#{character[0]}#{character[1]}".to_i
232
+ code = character.bytes.to_a.join('').to_i
234
233
  if CONVERSION_MAP_UTF8.has_key?(code)
235
234
  new_string << CONVERSION_MAP_UTF8[code][:convert_to]
236
235
  else
@@ -241,11 +240,11 @@ module DTA
241
240
  end
242
241
 
243
242
  def encode_characters(string)
244
- Iconv.conv("ISO-8859-1", "UTF8",string)
243
+ string.encode('iso-8859-1')
245
244
  end
246
245
 
247
246
  def dta_string(string)
248
247
  encode_characters(map_characters(string))
249
248
  end
250
249
  end
251
- end
250
+ end
@@ -0,0 +1,15 @@
1
+ require 'payment_dta/character_conversion'
2
+
3
+ module DTA
4
+ class CharacterConversionHash < Hash
5
+ include CharacterConversion
6
+
7
+ # Character conversion must be done _before_ building the final record to
8
+ # prevent changing the length.
9
+ #
10
+ # @return [String] The original value with character conversion applied.
11
+ def [](key)
12
+ (value = super(key)).respond_to?(:each_char) ? dta_string(value) : value
13
+ end
14
+ end
15
+ end
@@ -1,31 +1,37 @@
1
1
  require 'set'
2
+ require 'bigdecimal'
3
+ require 'payment_dta/character_conversion_hash'
2
4
  require 'payment_dta/payments/total_record'
3
5
  class DTAFile
4
6
  attr_reader :records
5
-
7
+
6
8
  def initialize(path, transaction_number = rand(100000000000).to_s)
7
9
  @transaction_number = transaction_number.to_s
8
10
  @path = path
9
11
  @records = SortedSet.new
10
12
  end
11
-
13
+
12
14
  def write_file
13
15
  File.open(@path,"w") do |file|
14
16
  @records.each{|record| file.puts record.to_dta}
15
17
  file.puts build_total_record.to_dta
16
18
  end
17
19
  end
18
-
20
+
19
21
  def total
20
22
  @records.inject(0) do |sum, record|
21
- sum + record.amount.to_f
23
+ sum + BigDecimal.new(record.amount.to_s, 16)
22
24
  end
23
25
  end
24
-
26
+
25
27
  def <<(record)
26
28
  record.transaction_number = @transaction_number
27
29
  @records << record
28
- recalculate_output_sequence_numbers
30
+ recalculate_entry_sequence_numbers
31
+ end
32
+
33
+ def dta_string
34
+ (@records.map(&:to_dta) << build_total_record.to_dta) * "\n" << "\n"
29
35
  end
30
36
 
31
37
  def self.create(path)
@@ -34,22 +40,23 @@ class DTAFile
34
40
  dta_file.write_file
35
41
  dta_file
36
42
  end
37
-
43
+
38
44
  private
39
-
40
- def recalculate_output_sequence_numbers
45
+
46
+ def recalculate_entry_sequence_numbers
41
47
  start = 1
42
48
  @records.each do |record|
43
- record.output_sequence_number = start
49
+ record.entry_sequence_number = start
44
50
  start += 1
45
51
  end
46
52
  end
47
-
53
+
48
54
  def build_total_record
49
55
  TotalRecord.new(
50
56
  :total_amount => total,
57
+ :entry_sequence_number => @records.count + 1,
51
58
  :data_file_sender_identification => @records.first.data_file_sender_identification
52
59
  )
53
60
  end
54
61
 
55
- end
62
+ end
@@ -21,7 +21,7 @@ class BankChequePayment < DTA::Payments::Base
21
21
  end
22
22
 
23
23
  def payment_amount_value
24
- @data[:payment_amount].to_s.ljust(15)
24
+ super(15)
25
25
  end
26
26
 
27
27
  def payment_amount_value_date
@@ -5,17 +5,17 @@ module DTA
5
5
  module Payments
6
6
  class Base
7
7
  include DTA::CharacterConversion
8
-
8
+
9
9
  def initialize(data = {})
10
- @data = data
10
+ @data = CharacterConversionHash[data]
11
11
  end
12
-
12
+
13
13
  def to_dta
14
14
  dta_string(record)
15
15
  end
16
16
 
17
17
  def segment1
18
- @segment1 ||= build_segment1
18
+ @segment1 ||= build_segment1
19
19
  end
20
20
 
21
21
  def segment2
@@ -25,7 +25,7 @@ module DTA
25
25
  def segment3
26
26
  @segment3 ||= build_segment3
27
27
  end
28
-
28
+
29
29
  def segment4
30
30
  @segment4 ||= build_segment4
31
31
  end
@@ -37,7 +37,7 @@ module DTA
37
37
  def segment6
38
38
  @segment6 ||= build_segment6
39
39
  end
40
-
40
+
41
41
  def record
42
42
  @record ||= segment1 + segment2 + segment3 + segment4 + segment5 + segment6
43
43
  end
@@ -45,7 +45,7 @@ module DTA
45
45
  def header
46
46
  @header ||= build_header
47
47
  end
48
-
48
+
49
49
  def requested_processing_date
50
50
  @data[:requested_processing_date].to_s
51
51
  end
@@ -55,11 +55,7 @@ module DTA
55
55
  end
56
56
 
57
57
  def output_sequence_number
58
- @output_sequence_number.to_s.rjust(5,'0')
59
- end
60
-
61
- def output_sequence_number=(output_sequence_number)
62
- @output_sequence_number = output_sequence_number
58
+ '00000'
63
59
  end
64
60
 
65
61
  def creation_date
@@ -67,7 +63,7 @@ module DTA
67
63
  end
68
64
 
69
65
  def ordering_party_bank_clearing_number
70
- @data[:ordering_party_bank_clearing_number].to_s.ljust(7,'0')
66
+ @data[:ordering_party_bank_clearing_number].to_s.ljust(7,' ')
71
67
  end
72
68
 
73
69
  def data_file_sender_identification
@@ -82,6 +78,10 @@ module DTA
82
78
  @data[:entry_sequence_number].to_s.rjust(5,'0')
83
79
  end
84
80
 
81
+ def entry_sequence_number=(entry_sequence_number)
82
+ @data[:entry_sequence_number] = entry_sequence_number
83
+ end
84
+
85
85
  def payment_type
86
86
  '1'
87
87
  end
@@ -105,11 +105,11 @@ module DTA
105
105
  def reference_number
106
106
  issuer_identification + transaction_number
107
107
  end
108
-
108
+
109
109
  def account_to_be_debited
110
110
  @data[:account_to_be_debited].to_s.ljust(24)
111
111
  end
112
-
112
+
113
113
  def payment_amount
114
114
  payment_amount_value_date + payment_amount_currency + payment_amount_value
115
115
  end
@@ -126,8 +126,8 @@ module DTA
126
126
  @data[:payment_amount]
127
127
  end
128
128
 
129
- def payment_amount_value
130
- @data[:payment_amount].to_s.ljust(12)
129
+ def payment_amount_value(size=12)
130
+ @data[:payment_amount].to_s.ljust(size).gsub('.', ',')
131
131
  end
132
132
 
133
133
  def ordering_partys_address(line_size=24)
@@ -155,19 +155,19 @@ module DTA
155
155
  end
156
156
 
157
157
  def beneficiary_address_line1(line_size=24)
158
- @data[:beneficiary_address_line1].to_s.ljust(line_size)
158
+ @data[:beneficiary_address_line1].to_s.ljust(line_size)[0, line_size]
159
159
  end
160
160
 
161
161
  def beneficiary_address_line2(line_size=24)
162
- @data[:beneficiary_address_line2].to_s.ljust(line_size)
162
+ @data[:beneficiary_address_line2].to_s.ljust(line_size)[0, line_size]
163
163
  end
164
164
 
165
165
  def beneficiary_address_line3(line_size=24)
166
- @data[:beneficiary_address_line3].to_s.ljust(line_size)
166
+ @data[:beneficiary_address_line3].to_s.ljust(line_size)[0, line_size]
167
167
  end
168
168
 
169
169
  def beneficiary_address_line4(line_size=24)
170
- @data[:beneficiary_address_line4].to_s.ljust(line_size)
170
+ @data[:beneficiary_address_line4].to_s.ljust(line_size)[0, line_size]
171
171
  end
172
172
 
173
173
  def reason_for_payment_message(line_size=24)
@@ -189,11 +189,11 @@ module DTA
189
189
  def reason_for_payment_message_line4(line_size=24)
190
190
  @data[:reason_for_payment_message_line4].to_s.ljust(line_size)
191
191
  end
192
-
192
+
193
193
  def bank_payment_instructions
194
194
  @data[:bank_payment_instructions].to_s.ljust(120)
195
195
  end
196
-
196
+
197
197
  def identification_bank_address
198
198
  @data[:identification_bank_address].to_s
199
199
  end
@@ -229,11 +229,11 @@ module DTA
229
229
  def beneficiary_institution_address_line4
230
230
  @data[:beneficiary_institution_address_line4].to_s.ljust(24)
231
231
  end
232
-
232
+
233
233
  def beneficiary_iban_number
234
234
  @data[:beneficiary_iban_number].to_s.ljust(34)
235
235
  end
236
-
236
+
237
237
  def identification_purpose
238
238
  @data[:identification_purpose].to_s[0,1]
239
239
  end
@@ -249,7 +249,7 @@ module DTA
249
249
  def rule_of_charge
250
250
  @data[:rule_of_charge].to_s[0,1]
251
251
  end
252
-
252
+
253
253
  protected
254
254
 
255
255
  def build_segment1
@@ -263,7 +263,7 @@ module DTA
263
263
  def build_segment3
264
264
  '03'
265
265
  end
266
-
266
+
267
267
  def build_segment4
268
268
  '04'
269
269
  end
@@ -271,18 +271,18 @@ module DTA
271
271
  def build_segment5
272
272
  '05'
273
273
  end
274
-
274
+
275
275
  def build_segment6
276
276
  '06'
277
277
  end
278
-
278
+
279
279
  def build_header
280
- requested_processing_date + beneficiary_bank_clearing_number + output_sequence_number + creation_date + ordering_party_bank_clearing_number + data_file_sender_identification + entry_sequence_number + transaction_type + payment_type + processing_flag
280
+ requested_processing_date + beneficiary_bank_clearing_number + output_sequence_number + creation_date + ordering_party_bank_clearing_number + data_file_sender_identification + entry_sequence_number + transaction_type + payment_type + processing_flag
281
281
  end
282
-
282
+
283
283
  def reserve_field(length = 14)
284
284
  ''.ljust(length)
285
285
  end
286
- end
286
+ end
287
287
  end
288
- end
288
+ end
@@ -17,7 +17,7 @@ class FinancialInstitutionPayment < DTA::Payments::Base
17
17
  end
18
18
 
19
19
  def payment_amount_value
20
- @data[:payment_amount].to_s.ljust(15)
20
+ super(15)
21
21
  end
22
22
 
23
23
  def payment_amount_value_date
@@ -25,7 +25,7 @@ class IBANPayment < DTA::Payments::Base
25
25
  end
26
26
 
27
27
  def payment_amount_value
28
- @data[:payment_amount].to_s.ljust(15)
28
+ super(15)
29
29
  end
30
30
 
31
31
  def convertion_rate
@@ -25,7 +25,7 @@ class SpecialFinancialInstitutionPayment < DTA::Payments::Base
25
25
  end
26
26
 
27
27
  def payment_amount_value
28
- @data[:payment_amount].to_s.ljust(15)
28
+ super(15)
29
29
  end
30
30
 
31
31
  def payment_amount_value_date
@@ -4,28 +4,29 @@ class TotalRecord < DTA::Payments::Base
4
4
  def segment1
5
5
  super + total_amount + reserve_field(59)
6
6
  end
7
-
7
+
8
8
  def record
9
9
  segment1
10
10
  end
11
-
11
+
12
12
  def total_amount
13
- @data[:total_amount].to_s.gsub(/\./,',').ljust(16)
13
+ number = BigDecimal.new(@data[:total_amount].to_s, 16).round(3)
14
+ number.to_s('F').gsub(/\./,',').ljust(16)
14
15
  end
15
-
16
+
16
17
  def ordering_party_bank_clearing_number
17
18
  ''.ljust(7)
18
19
  end
19
-
20
+
20
21
  def transaction_type
21
22
  '890'
22
23
  end
23
-
24
+
24
25
  def payment_type
25
26
  '0'
26
27
  end
27
-
28
+
28
29
  def requested_processing_date
29
30
  '000000'
30
31
  end
31
- end
32
+ end