nacha 0.1.10 → 0.1.14

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 (83) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +63 -0
  3. data/.gitignore +2 -0
  4. data/.rubocop.yml +4 -2
  5. data/.ruby-version +1 -1
  6. data/CHANGELOG.md +42 -0
  7. data/README.md +10 -2
  8. data/exe/nacha +46 -29
  9. data/lib/nacha/aba_number.rb +33 -24
  10. data/lib/nacha/ach_date.rb +15 -8
  11. data/lib/nacha/field.rb +62 -77
  12. data/lib/nacha/formatter/base.rb +52 -0
  13. data/lib/nacha/formatter/html_formatter.rb +119 -0
  14. data/lib/nacha/formatter/json_formatter.rb +49 -0
  15. data/lib/nacha/formatter/markdown_formatter.rb +57 -0
  16. data/lib/nacha/formatter.rb +24 -0
  17. data/lib/nacha/has_errors.rb +12 -8
  18. data/lib/nacha/numeric.rb +13 -10
  19. data/lib/nacha/parser.rb +32 -31
  20. data/lib/nacha/parser_context.rb +4 -9
  21. data/lib/nacha/record/ack_entry_detail.rb +15 -8
  22. data/lib/nacha/record/addenda_record_type.rb +8 -1
  23. data/lib/nacha/record/adv_batch_control.rb +12 -7
  24. data/lib/nacha/record/adv_entry_detail.rb +3 -2
  25. data/lib/nacha/record/adv_file_control.rb +9 -5
  26. data/lib/nacha/record/adv_file_header.rb +11 -6
  27. data/lib/nacha/record/arc_entry_detail.rb +2 -2
  28. data/lib/nacha/record/base.rb +124 -106
  29. data/lib/nacha/record/batch_control.rb +13 -7
  30. data/lib/nacha/record/batch_header.rb +20 -11
  31. data/lib/nacha/record/batch_header_record_type.rb +5 -4
  32. data/lib/nacha/record/boc_entry_detail.rb +3 -2
  33. data/lib/nacha/record/ccd_addenda.rb +2 -2
  34. data/lib/nacha/record/ccd_entry_detail.rb +3 -2
  35. data/lib/nacha/record/cie_addenda.rb +2 -2
  36. data/lib/nacha/record/cie_entry_detail.rb +5 -3
  37. data/lib/nacha/record/ctx_addenda.rb +2 -2
  38. data/lib/nacha/record/ctx_corporate_entry_detail.rb +2 -2
  39. data/lib/nacha/record/detail_record_type.rb +4 -1
  40. data/lib/nacha/record/dne_addenda.rb +2 -2
  41. data/lib/nacha/record/dne_entry_detail.rb +6 -4
  42. data/lib/nacha/record/enr_addenda.rb +3 -2
  43. data/lib/nacha/record/enr_entry_detail.rb +4 -3
  44. data/lib/nacha/record/fifth_iat_addenda.rb +8 -4
  45. data/lib/nacha/record/file_control.rb +9 -5
  46. data/lib/nacha/record/file_control_record_type.rb +1 -1
  47. data/lib/nacha/record/file_header.rb +12 -8
  48. data/lib/nacha/record/file_header_record_type.rb +1 -1
  49. data/lib/nacha/record/filler.rb +3 -3
  50. data/lib/nacha/record/filler_record_type.rb +3 -1
  51. data/lib/nacha/record/first_iat_addenda.rb +4 -3
  52. data/lib/nacha/record/fourth_iat_addenda.rb +7 -4
  53. data/lib/nacha/record/iat_batch_header.rb +5 -3
  54. data/lib/nacha/record/iat_entry_detail.rb +9 -6
  55. data/lib/nacha/record/iat_foreign_coorespondent_bank_information_addenda.rb +10 -6
  56. data/lib/nacha/record/iat_remittance_information_addenda.rb +3 -2
  57. data/lib/nacha/record/mte_addenda.rb +4 -3
  58. data/lib/nacha/record/mte_entry_detail.rb +5 -3
  59. data/lib/nacha/record/pop_entry_detail.rb +3 -2
  60. data/lib/nacha/record/pos_addenda.rb +6 -3
  61. data/lib/nacha/record/pos_entry_detail.rb +5 -3
  62. data/lib/nacha/record/ppd_addenda.rb +3 -2
  63. data/lib/nacha/record/ppd_entry_detail.rb +5 -3
  64. data/lib/nacha/record/rck_entry_detail.rb +3 -2
  65. data/lib/nacha/record/second_iat_addenda.rb +3 -2
  66. data/lib/nacha/record/seventh_iat_addenda.rb +3 -2
  67. data/lib/nacha/record/shr_addenda.rb +5 -3
  68. data/lib/nacha/record/shr_entry_detail.rb +3 -2
  69. data/lib/nacha/record/sixth_iat_addenda.rb +5 -3
  70. data/lib/nacha/record/tel_entry_detail.rb +5 -3
  71. data/lib/nacha/record/third_iat_addenda.rb +3 -2
  72. data/lib/nacha/record/trc_entry_detail.rb +3 -2
  73. data/lib/nacha/record/trx_addenda.rb +3 -2
  74. data/lib/nacha/record/trx_entry_detail.rb +5 -3
  75. data/lib/nacha/record/validations/field_validations.rb +26 -14
  76. data/lib/nacha/record/validations/record_validations.rb +2 -1
  77. data/lib/nacha/record/web_addenda.rb +3 -2
  78. data/lib/nacha/record/web_entry_detail.rb +5 -3
  79. data/lib/nacha/record/xck_entry_detail.rb +3 -2
  80. data/lib/nacha/version.rb +4 -1
  81. data/lib/nacha.rb +21 -14
  82. data/nacha.gemspec +14 -16
  83. metadata +42 -8
@@ -4,42 +4,47 @@ require 'json'
4
4
  require 'nacha/field'
5
5
  require 'nacha/record/validations/field_validations'
6
6
 
7
+ # :reek:TooManyInstanceVariables, :reek:TooManyMethods
7
8
  module Nacha
8
9
  module Record
10
+ # Base class for all Nacha records.
9
11
  class Base
10
12
  include Validations::FieldValidations
11
13
 
12
- attr_accessor :children, :parent, :fields
13
- attr_reader :name, :validations, :errors, :original_input_line
14
- attr_accessor :line_number
14
+ attr_reader :children, :name, :validations, :original_input_line, :fields
15
+ # :reek:Attribute
16
+ attr_accessor :parent, :line_number
15
17
 
18
+ # :reek:ManualDispatch
16
19
  def initialize(opts = {})
17
20
  @children = []
21
+ @parent = nil
18
22
  @errors = []
19
23
  @original_input_line = nil
24
+ @line_number = nil
25
+ @dirty = false
26
+ @fields = {}
20
27
  create_fields_from_definition
21
- opts.each do |k, v|
22
- setter = "#{k}="
23
- next unless respond_to? setter
24
-
28
+ opts.each do |key, value|
29
+ setter = "#{key}="
25
30
  # rubocop:disable GitlabSecurity/PublicSend
26
- send(setter, v) unless v.nil?
31
+ public_send(setter, value) if value && respond_to?(setter)
27
32
  # rubocop:enable GitlabSecurity/PublicSend
28
33
  end
29
34
  end
30
35
 
31
36
  class << self
37
+ # :reek:LongParameterList, :reek:ManualDispatch
32
38
  def nacha_field(name, inclusion:, contents:, position:)
33
39
  Nacha.add_ach_record_type(self)
34
40
  definition[name] = { inclusion: inclusion,
35
41
  contents: contents,
36
42
  position: position,
37
- name: name}
38
- validation_method = "valid_#{name}".to_sym
43
+ name: name }
44
+ validation_method = :"valid_#{name}"
39
45
  return unless respond_to?(validation_method)
40
46
 
41
- validations[name] ||= []
42
- validations[name] << validation_method
47
+ (validations[name] ||= []) << validation_method
43
48
  end
44
49
 
45
50
  def definition
@@ -51,72 +56,54 @@ module Nacha
51
56
  end
52
57
 
53
58
  def unpack_str
54
- @unpack_str ||= definition.values.collect do |d|
55
- Nacha::Field.unpack_str(d)
59
+ @unpack_str ||= definition.values
60
+ .sort { |a, b| a[:position].first <=> b[:position].first }
61
+ .collect do |field_def|
62
+ Nacha::Field.unpack_str(field_def)
56
63
  end.join.freeze
57
64
  end
58
65
 
59
- def old_matcher
60
- @matcher ||=
61
- Regexp.new('\A' + definition.values.collect do |d|
62
- if d[:contents] =~ /\AC(.+)\z/ || d['contents'] =~ /\AC(.+)\z/
63
- Regexp.last_match(1)
64
- else
65
- '.' * (d[:position] || d['position']).size
66
- end
67
- end.join + '\z')
68
- end
69
-
70
- # A more strict matcher that accounts for numeric and date fields
71
- # and allows for spaces in those fields, but not alphabetic characters
72
- # Also matches strings that might not be long enough.
73
- #
74
- # Processes the definition in reverse order to allow later fields to be
75
- # skipped if they are not present in the input string.
66
+ # :reek:TooManyStatements
67
+ # rubocop:disable Layout/BlockAlignment,
68
+ # rubocop:disable Style/StringConcatenation:
76
69
  def matcher
77
- return @matcher if @matcher
78
-
79
- output_started = false
80
- skipped_output = false
81
- @matcher ||=
82
- Regexp.new('\A' + definition.values.reverse.collect do |d|
83
- if d[:contents] =~ /\AC(.+)\z/
70
+ @matcher ||= begin
71
+ output_started = false
72
+ skipped_output = false
73
+ Regexp.new('\A' + definition.values
74
+ .sort { |a,b| a[:position].first <=> b[:position].first }.reverse.collect do |field|
75
+ contents = field[:contents]
76
+ position = field[:position]
77
+ size = position.size
78
+ if contents =~ /\AC(.+)\z/
84
79
  last_match = Regexp.last_match(1)
85
- if last_match =~ /\A *\z/
80
+ if last_match.match?(/ */) && !output_started
86
81
  skipped_output = true
87
82
  ''
88
83
  else
89
84
  output_started = true
90
85
  last_match
91
86
  end
92
- elsif d[:contents] =~ /\ANumeric\z/
87
+ elsif contents.match?(/\ANumeric\z/) || contents.match?(/\AYYMMDD\z/)
93
88
  output_started = true
94
- '[0-9 ]' + "{#{(d[:position] || d['position']).size}}"
95
- elsif d[:contents] =~ /\AYYMMDD\z/
96
- if output_started
97
- '[0-9 ]' + "{#{(d[:position] || d['position']).size}}"
98
- else
99
- skipped_output = true
100
- ''
101
- end
89
+ "[0-9 ]{#{size}}"
90
+ elsif output_started
91
+ ".{#{size}}"
102
92
  else
103
- if output_started
104
- '.' + "{#{(d[:position] || d['position']).size}}"
105
- else
106
- skipped_output = true
107
- ''
108
- end
93
+ skipped_output = true
94
+ ''
109
95
  end
110
96
  end.reverse.join + (skipped_output ? '.*' : '') + '\z')
97
+ end
111
98
  end
112
-
99
+ # rubocop:enable Layout/BlockAlignment,
100
+ # rubocop:enable Style/StringConcatenation:
113
101
 
114
102
  def parse(ach_str)
115
- rec = new
103
+ rec = new(original_input_line: ach_str)
116
104
  ach_str.unpack(unpack_str).zip(rec.fields.values) do |input_data, field|
117
105
  field.data = input_data
118
106
  end
119
- rec.original_input_line = ach_str
120
107
  rec.validate
121
108
  rec
122
109
  end
@@ -124,14 +111,35 @@ module Nacha
124
111
  def record_type
125
112
  Nacha.record_name(self)
126
113
  end
127
- end # end class methods
128
114
 
115
+ # :reek:ManualDispatch, :reek:TooManyStatements
116
+ def to_h
117
+ fields = definition.transform_values do |field_def|
118
+ {
119
+ inclusion: field_def[:inclusion],
120
+ contents: field_def[:contents],
121
+ position: field_def[:position].to_s
122
+ }
123
+ end
124
+
125
+ fields[:child_record_types] = child_record_types.to_a
126
+ fields[:child_record_types] ||= []
127
+ fields[:klass] = name.to_s
128
+
129
+ { record_type.to_sym => fields }
130
+ end
131
+
132
+ def to_json(*_args)
133
+ JSON.pretty_generate(to_h)
134
+ end
135
+ end
136
+
137
+ # :reek:FeatureEnvy
129
138
  def original_input_line=(line)
130
139
  @original_input_line = line.dup if line.is_a?(String)
131
140
  end
132
141
 
133
142
  def create_fields_from_definition
134
- @fields ||= {}
135
143
  definition.each_pair do |field_name, field_def|
136
144
  @fields[field_name.to_sym] = Nacha::Field.new(field_def)
137
145
  end
@@ -152,11 +160,10 @@ module Nacha
152
160
  errors: errors,
153
161
  line_number: @line_number,
154
162
  original_input_line: original_input_line
155
- }
156
- }.merge(
157
- @fields.keys.map do |key|
158
- [key, @fields[key].to_json_output]
159
- end.to_h)
163
+ } }.merge(
164
+ @fields.keys.to_h do |key|
165
+ [key, @fields[key].to_json_output]
166
+ end)
160
167
  end
161
168
 
162
169
  def to_json(*_args)
@@ -169,17 +176,18 @@ module Nacha
169
176
  end.join
170
177
  end
171
178
 
172
- def to_html(opts = {})
179
+ def to_html(_opts = {})
173
180
  record_error_class = nil
174
181
 
175
- field_html = @fields.keys.collect do |key|
176
- record_error_class ||= 'error' if @fields[key].errors.any?
177
- @fields[key].to_html
182
+ field_html = @fields.values.collect do |field|
183
+ record_error_class ||= 'error' if field.errors.any?
184
+ field.to_html
178
185
  end.join
179
- "<div class=\"nacha-record tooltip #{record_type} #{record_error_class}\">" +
180
- "<span class=\"nacha-field\" data-name=\"record-number\">#{"%05d" % [line_number]}&nbsp;|&nbsp</span>" +
181
- field_html +
182
- "<span class=\"record-type\" data-name=\"record-type\">#{human_name}</span>" +
186
+ "<div class=\"nacha-record tooltip #{record_type} #{record_error_class}\">" \
187
+ "<span class=\"nacha-record-number\" data-name=\"record-number\">#{format('%05d',
188
+ line_number)}&nbsp;|&nbsp</span>" \
189
+ "#{field_html}" \
190
+ "<span class=\"record-type\" data-name=\"record-type\">#{human_name}</span>" \
183
191
  "</div>"
184
192
  end
185
193
 
@@ -193,19 +201,10 @@ module Nacha
193
201
 
194
202
  def validate
195
203
  # Run field-level validations first
196
- @fields.values.each(&:validate)
197
-
204
+ @fields.each_value(&:validate)
198
205
  # Then run record-level validations that might depend on multiple fields
199
- self.class.definition.keys.each do |field|
200
- next unless self.class.validations[field]
201
-
202
- # rubocop:disable GitlabSecurity/PublicSend
203
- field_data = send(field)
204
-
205
- self.class.validations[field].map do |validation_method|
206
- self.class.send(validation_method, field_data)
207
- end
208
- # rubocop:enable GitlabSecurity/PublicSend
206
+ self.class.definition.each_key do |field|
207
+ run_record_level_validations_for(field)
209
208
  end
210
209
  end
211
210
 
@@ -229,7 +228,8 @@ module Nacha
229
228
  # # Assuming transaction_code is "201" and DEBIT_TRANSACTION_CODES includes "201"
230
229
  # debit? #=> true
231
230
  #
232
- # # Assuming transaction_code is "100" and DEBIT_TRANSACTION_CODES does not include "100"
231
+ # # Assuming transaction_code is "100" and DEBIT_TRANSACTION_CODES
232
+ # # does not include "100"
233
233
  # debit? #=> false
234
234
  #
235
235
  # # Assuming transaction_code is nil
@@ -268,7 +268,8 @@ module Nacha
268
268
  # # Assuming transaction_code is "101" and CREDIT_TRANSACTION_CODES includes "101"
269
269
  # credit? #=> true
270
270
  #
271
- # # Assuming transaction_code is "200" and CREDIT_TRANSACTION_CODES does not include "200"
271
+ # # Assuming transaction_code is "200" and CREDIT_TRANSACTION_CODES
272
+ # # does not include "200"
272
273
  # credit? #=> false
273
274
  #
274
275
  # # Assuming transaction_code is nil
@@ -294,37 +295,54 @@ module Nacha
294
295
  end
295
296
 
296
297
  def errors
297
- (@errors + @fields.values.map { |field| field.errors }).flatten
298
+ (@errors + @fields.values.map(&:errors)).flatten
298
299
  end
299
300
 
300
-
301
301
  def add_error(err_string)
302
302
  @errors << err_string
303
303
  end
304
304
 
305
- def respond_to?(method_name, include_private = false)
306
- field_name = method_name.to_s.gsub(/=$/, '').to_sym
305
+ # :reek:TooManyStatements
306
+ def method_missing(method_name, *args, &block)
307
+ method = method_name.to_s
308
+ field_name = method.gsub(/=$/, '').to_sym
309
+ field = @fields[field_name]
310
+ return super unless field
307
311
 
308
- definition[field_name] || super
312
+ if method.end_with?('=')
313
+ assign_field_data(field, args)
314
+ else
315
+ field
316
+ end
309
317
  end
310
318
 
311
- def method_missing(method_name, *args, &block)
319
+ def respond_to_missing?(method_name, *)
312
320
  field_name = method_name.to_s.gsub(/=$/, '').to_sym
313
- is_assignment = (/[^=]*=$/o =~ method_name.to_s)
314
- if @fields[field_name]
315
- if is_assignment
316
- # @fields[field_name].send(:data=,*args)
317
- # rubocop:disable GitlabSecurity/PublicSend
318
- @fields[field_name].public_send(:data=, *args)
319
- # rubocop:enable GitlabSecurity/PublicSend
320
- @dirty = true
321
- else
322
- # @fields[field_name].data
323
- @fields[field_name]
324
- end
325
- else
326
- super
321
+ definition[field_name] || super
322
+ end
323
+
324
+ private
325
+
326
+ def assign_field_data(field, args)
327
+ # rubocop:disable GitlabSecurity/PublicSend
328
+ field.public_send(:data=, *args)
329
+ # rubocop:enable GitlabSecurity/PublicSend
330
+ @dirty = true
331
+ end
332
+
333
+ # :reek:TooManyStatements
334
+ def run_record_level_validations_for(field)
335
+ klass = self.class
336
+ validations = klass.validations[field]
337
+ return unless validations
338
+
339
+ # rubocop:disable GitlabSecurity/PublicSend
340
+ field_data = send(field)
341
+
342
+ validations.each do |validation_method|
343
+ klass.send(validation_method, field_data)
327
344
  end
345
+ # rubocop:enable GitlabSecurity/PublicSend
328
346
  end
329
347
  end
330
348
  end
@@ -1,23 +1,29 @@
1
1
  # coding: utf-8
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'nacha/record/base.rb'
5
- require 'nacha/record/batch_control_record_type.rb'
4
+ require 'nacha/record/base'
5
+ require 'nacha/record/batch_control_record_type'
6
6
 
7
7
  module Nacha
8
8
  module Record
9
9
  class BatchControl < Nacha::Record::Base
10
10
  include BatchControlRecordType
11
+
11
12
  nacha_field :record_type_code, inclusion: 'M', contents: 'C8', position: 1..1
12
13
  nacha_field :service_class_code, inclusion: 'M', contents: 'Numeric', position: 2..4
13
14
  nacha_field :entry_addenda_count, inclusion: 'M', contents: 'Numeric', position: 5..10
14
15
  nacha_field :entry_hash, inclusion: 'M', contents: 'Numeric', position: 11..20
15
- nacha_field :total_debit_entry_dollar_amount, inclusion: 'M', contents: '$$$$$$$$$$¢¢', position: 21..32
16
- nacha_field :total_credit_entry_dollar_amount, inclusion: 'M', contents: '$$$$$$$$$$¢¢', position: 33..44
17
- nacha_field :company_identification, inclusion: 'R', contents: 'Alphameric', position: 45..54
18
- nacha_field :message_authentication_code, inclusion: 'O', contents: 'Alphameric', position: 55..73
16
+ nacha_field :total_debit_entry_dollar_amount,
17
+ inclusion: 'M', contents: '$$$$$$$$$$¢¢', position: 21..32
18
+ nacha_field :total_credit_entry_dollar_amount,
19
+ inclusion: 'M', contents: '$$$$$$$$$$¢¢', position: 33..44
20
+ nacha_field :company_identification,
21
+ inclusion: 'R', contents: 'Alphameric', position: 45..54
22
+ nacha_field :message_authentication_code,
23
+ inclusion: 'O', contents: 'Alphameric', position: 55..73
19
24
  nacha_field :reserved, inclusion: 'O', contents: 'C ', position: 74..79
20
- nacha_field :originating_dfi_identification, inclusion: 'M', contents: 'TTTTAAAA', position: 80..87
25
+ nacha_field :originating_dfi_identification,
26
+ inclusion: 'M', contents: 'TTTTAAAA', position: 80..87
21
27
  nacha_field :batch_number, inclusion: 'M', contents: 'Numeric', position: 88..94
22
28
  end
23
29
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'nacha/record/base.rb'
4
- require 'nacha/record/batch_header_record_type.rb'
3
+ require 'nacha/record/base'
4
+ require 'nacha/record/batch_header_record_type'
5
5
 
6
6
  module Nacha
7
7
  module Record
@@ -11,15 +11,24 @@ module Nacha
11
11
  nacha_field :record_type_code, inclusion: 'M', contents: 'C5', position: 1..1
12
12
  nacha_field :service_class_code, inclusion: 'M', contents: 'Numeric', position: 2..4
13
13
  nacha_field :company_name, inclusion: 'M', contents: 'Alphameric', position: 5..20
14
- nacha_field :company_discretionary_data, inclusion: 'O', contents: 'Alphameric', position: 21..40
15
- nacha_field :company_identification, inclusion: 'M', contents: 'Alphameric', position: 41..50
16
- nacha_field :standard_entry_class_code, inclusion: 'M', contents: 'Alphameric', position: 51..53
17
- nacha_field :company_entry_description, inclusion: 'M', contents: 'Alphameric', position: 54..63
18
- nacha_field :company_descriptive_date, inclusion: 'O', contents: 'Alphameric', position: 64..69
19
- nacha_field :effective_entry_date, inclusion: 'R', contents: 'YYMMDD', position: 70..75
20
- nacha_field :settlement_date_julian, inclusion: 'O', contents: 'Numeric', position: 76..78
21
- nacha_field :originator_status_code, inclusion: 'M', contents: 'Alphameric', position: 79..79
22
- nacha_field :originating_dfi_identification, inclusion: 'M', contents: 'TTTTAAAA', position: 80..87
14
+ nacha_field :company_discretionary_data,
15
+ inclusion: 'O', contents: 'Alphameric', position: 21..40
16
+ nacha_field :company_identification,
17
+ inclusion: 'M', contents: 'Alphameric', position: 41..50
18
+ nacha_field :standard_entry_class_code,
19
+ inclusion: 'M', contents: 'Alphameric', position: 51..53
20
+ nacha_field :company_entry_description,
21
+ inclusion: 'M', contents: 'Alphameric', position: 54..63
22
+ nacha_field :company_descriptive_date,
23
+ inclusion: 'O', contents: 'Alphameric', position: 64..69
24
+ nacha_field :effective_entry_date,
25
+ inclusion: 'R', contents: 'YYMMDD', position: 70..75
26
+ nacha_field :settlement_date_julian,
27
+ inclusion: 'O', contents: 'Numeric', position: 76..78
28
+ nacha_field :originator_status_code,
29
+ inclusion: 'M', contents: 'Alphameric', position: 79..79
30
+ nacha_field :originating_dfi_identification,
31
+ inclusion: 'M', contents: 'TTTTAAAA', position: 80..87
23
32
  nacha_field :batch_number, inclusion: 'M', contents: 'Numeric', position: 88..94
24
33
  end
25
34
  end
@@ -9,16 +9,17 @@ module Nacha
9
9
 
10
10
  module ClassMethods
11
11
  def child_record_types
12
- []
12
+ [
13
+ 'Nacha::Record::BatchControl'
14
+ ]
13
15
  end
14
16
  end
15
17
 
16
18
  def child_record_types
17
19
  sec = standard_entry_class_code.to_s.capitalize
18
20
  [
19
- 'Nacha::Record::' + sec + 'EntryDetail',
20
- 'Nacha::Record::BatchControl'
21
- ]
21
+ "Nacha::Record::#{sec}EntryDetail"
22
+ ] + self.class.child_record_types
22
23
  end
23
24
  end
24
25
  end
@@ -1,13 +1,14 @@
1
1
  # coding: utf-8
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'nacha/record/base.rb'
5
- require 'nacha/record/detail_record_type.rb'
4
+ require 'nacha/record/base'
5
+ require 'nacha/record/detail_record_type'
6
6
 
7
7
  module Nacha
8
8
  module Record
9
9
  class BocEntryDetail < Nacha::Record::Base
10
10
  include DetailRecordType
11
+
11
12
  nacha_field :record_type_code, inclusion: 'M', contents: 'C6', position: 1..1
12
13
  nacha_field :transaction_code, inclusion: 'M', contents: 'Numeric', position: 2..3
13
14
  nacha_field :receiving_dfi_identification, inclusion: 'M', contents: 'TTTTAAAAC', position: 4..12
@@ -1,8 +1,8 @@
1
1
  # coding: utf-8
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'nacha/record/base.rb'
5
- require 'nacha/record/addenda_record_type.rb'
4
+ require 'nacha/record/base'
5
+ require 'nacha/record/addenda_record_type'
6
6
 
7
7
  module Nacha
8
8
  module Record
@@ -1,13 +1,14 @@
1
1
  # coding: utf-8
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'nacha/record/base.rb'
5
- require 'nacha/record/detail_record_type.rb'
4
+ require 'nacha/record/base'
5
+ require 'nacha/record/detail_record_type'
6
6
 
7
7
  module Nacha
8
8
  module Record
9
9
  class CcdEntryDetail < Nacha::Record::Base
10
10
  include DetailRecordType
11
+
11
12
  nacha_field :record_type_code, inclusion: 'M', contents: 'C6', position: 1..1
12
13
  nacha_field :transaction_code, inclusion: 'M', contents: 'Numeric', position: 2..3
13
14
  nacha_field :receiving_dfi_identification, inclusion: 'M', contents: 'TTTTAAAAC', position: 4..12
@@ -1,8 +1,8 @@
1
1
  # coding: utf-8
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'nacha/record/base.rb'
5
- require 'nacha/record/addenda_record_type.rb'
4
+ require 'nacha/record/base'
5
+ require 'nacha/record/addenda_record_type'
6
6
 
7
7
  module Nacha
8
8
  module Record
@@ -1,20 +1,22 @@
1
1
  # coding: utf-8
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'nacha/record/base.rb'
5
- require 'nacha/record/detail_record_type.rb'
4
+ require 'nacha/record/base'
5
+ require 'nacha/record/detail_record_type'
6
6
 
7
7
  module Nacha
8
8
  module Record
9
9
  class CieEntryDetail < Nacha::Record::Base
10
10
  include DetailRecordType
11
+
11
12
  nacha_field :record_type_code, inclusion: 'M', contents: 'C6', position: 1..1
12
13
  nacha_field :transaction_code, inclusion: 'M', contents: 'Numeric', position: 2..3
13
14
  nacha_field :receiving_dfi_identification, inclusion: 'M', contents: 'TTTTAAAAC', position: 4..12
14
15
  nacha_field :dfi_account_number, inclusion: 'R', contents: 'Alphameric', position: 13..29
15
16
  nacha_field :amount, inclusion: 'M', contents: '$$$$$$$$¢¢', position: 30..39
16
17
  nacha_field :individual_name, inclusion: 'R', contents: 'Alphameric', position: 40..54
17
- nacha_field :individual_identification_number, inclusion: 'M', contents: 'Alphameric', position: 55..76
18
+ nacha_field :individual_identification_number, inclusion: 'M', contents: 'Alphameric',
19
+ position: 55..76
18
20
  nacha_field :discretionary_data, inclusion: 'O', contents: 'Alphameric', position: 77..78
19
21
  nacha_field :addenda_record_indicator, inclusion: 'M', contents: 'Numeric', position: 79..79
20
22
  nacha_field :trace_number, inclusion: 'M', contents: 'Numeric', position: 80..94
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'nacha/record/base.rb'
4
- require 'nacha/record/addenda_record_type.rb'
3
+ require 'nacha/record/base'
4
+ require 'nacha/record/addenda_record_type'
5
5
  module Nacha
6
6
  module Record
7
7
  class CtxAddenda < Nacha::Record::Base
@@ -1,8 +1,8 @@
1
1
  # coding: utf-8
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'nacha/record/base.rb'
5
- require 'nacha/record/detail_record_type.rb'
4
+ require 'nacha/record/base'
5
+ require 'nacha/record/detail_record_type'
6
6
 
7
7
  module Nacha
8
8
  module Record
@@ -9,7 +9,10 @@ module Nacha
9
9
 
10
10
  module ClassMethods
11
11
  def child_record_types
12
- []
12
+ [
13
+ "Nacha::Record::FirstIatAddenda"
14
+ # Among other ...
15
+ ]
13
16
  end
14
17
 
15
18
  def next_record_types
@@ -1,8 +1,8 @@
1
1
  # coding: utf-8
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'nacha/record/base.rb'
5
- require 'nacha/record/addenda_record_type.rb'
4
+ require 'nacha/record/base'
5
+ require 'nacha/record/addenda_record_type'
6
6
 
7
7
  module Nacha
8
8
  module Record
@@ -1,20 +1,22 @@
1
1
  # coding: utf-8
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'nacha/record/base.rb'
5
- require 'nacha/record/detail_record_type.rb'
4
+ require 'nacha/record/base'
5
+ require 'nacha/record/detail_record_type'
6
6
 
7
7
  module Nacha
8
8
  module Record
9
+ # Represents a Death Notification Entry (DNE) detail record.
9
10
  class DneEntryDetail < Nacha::Record::Base
10
11
  include DetailRecordType
11
12
 
12
13
  nacha_field :record_type_code, inclusion: 'M', contents: 'C6', position: 1..1
13
14
  nacha_field :transaction_code, inclusion: 'M', contents: 'Numeric', position: 2..3
14
15
  nacha_field :receiving_dfi_identification, inclusion: 'M', contents: 'TTTTAAAAC', position: 4..12
15
- nacha_field :receiving_dfi_identification, inclusion: 'M', contents: 'Alphameric', position: 13..29
16
+ nacha_field :dfi_account_number, inclusion: 'M', contents: 'Alphameric', position: 13..29
16
17
  nacha_field :amount, inclusion: 'M', contents: '$$$$$$$$¢¢', position: 30..39
17
- nacha_field :individual_identification_number, inclusion: 'O', contents: 'Alphameric', position: 40..54
18
+ nacha_field :individual_identification_number, inclusion: 'O', contents: 'Alphameric',
19
+ position: 40..54
18
20
  nacha_field :individual_name, inclusion: 'R', contents: 'Alphameric', position: 55..76
19
21
  nacha_field :discretionary_data, inclusion: 'O', contents: 'Alphameric', position: 77..78
20
22
  nacha_field :addenda_record_indicator, inclusion: 'M', contents: 'Numeric', position: 79..79
@@ -1,11 +1,12 @@
1
1
  # coding: utf-8
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'nacha/record/base.rb'
5
- require 'nacha/record/addenda_record_type.rb'
4
+ require 'nacha/record/base'
5
+ require 'nacha/record/addenda_record_type'
6
6
 
7
7
  module Nacha
8
8
  module Record
9
+ # Represents an Automated Enrollment Entry (ENR) addenda record.
9
10
  class EnrAddenda < Nacha::Record::Base
10
11
  include AddendaRecordType
11
12