metro_2 1.2.3 → 1.2.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bd854adc4eb6506c3723faddb4af8c465661ca124b45c71ee0d145c671acf4da
4
- data.tar.gz: a834b02f5e35a4525723a887acc63becdc730ac9440eedf5286480bffae2248d
3
+ metadata.gz: d01632b27a1c846c37db947bfb4502ef109d0aa987daf598ffcbd8a810f6fd2b
4
+ data.tar.gz: 4212d0fced1d05b500db2aac38d16a0e0fd935f25933824f9b7a99a8e6c2f9e0
5
5
  SHA512:
6
- metadata.gz: b2a79f917988c78c2c50845d88ebe8f2d566e51d46e2efae46cad9946e2abf298c1249730b7eac3f895a33bfabd4d7e7605cf6526c0f74633914d687dafc6e3f
7
- data.tar.gz: d7bf507c8a3f7b8f845e0bb819b955028eaa62df04024790b3947fa919cf3ee8ea43d2e8c1c9ae138139e61e1fb3ead21f1190ee9f6fc60e6630f8156ffe0622
6
+ metadata.gz: f2680086eed4bd35915d66076af44bb77eb7c8db254b24df7d406e7a3268e76896fbd0c979d41c56845d0f71e55bb241c89d4e5a6f21406c7200d468e2387236
7
+ data.tar.gz: 11e923f3641cf71cf6e572d6255385b853105627fa04cf94be157948ed29bdec2daf1ab68ce89e6d9717bcc6268c54ebef43135f39fe7144ba03b5c2031fab5e
data/.rubocop.yml ADDED
@@ -0,0 +1,4 @@
1
+ ---
2
+ Layout/LineLength:
3
+ Max: 120
4
+ Description: Limit lines to 120 characters
data/CHANGELOG.md ADDED
@@ -0,0 +1,7 @@
1
+ # Changelog
2
+
3
+ Metro_2 gem versions
4
+
5
+ # 1.2.5
6
+ 1. Adds account types and ECOA codes for business loans
7
+ 2. Adds J2 segment appendage
@@ -0,0 +1,4 @@
1
+ # Repository Ownership
2
+ Repository Owner - @teamupstart/borrower-squad
3
+
4
+ Slack Channel ID - C08UGTUG1
@@ -61,11 +61,20 @@ module Metro2::Records
61
61
  @k2_segment
62
62
  end
63
63
 
64
+ def j2_segment
65
+ @j2_segment
66
+ end
67
+
64
68
  def k2_segment=(segment)
65
69
  @k2_segment = segment
66
70
  @appendages << @k2_segment
67
71
  end
68
72
 
73
+ def j2_segment=(segment)
74
+ @j2_segment = segment
75
+ @appendages << @j2_segment
76
+ end
77
+
69
78
  def to_metro2
70
79
  @appendages.compact!
71
80
  set_record_descriptor_word
@@ -0,0 +1,29 @@
1
+ module Metro2::Records
2
+ class J2Segment < Record
3
+ LENGTH = 200
4
+
5
+ @fields = []
6
+
7
+ alphanumeric_const_field :segment_identifier, 2, "J2"
8
+ alphanumeric_const_field :reserved, 1, nil # reserved - blank fill
9
+ alphanumeric_field :surname, 25, Metro2::ALPHANUMERIC_PLUS_DASH
10
+ alphanumeric_field :first_name, 20, Metro2::ALPHANUMERIC_PLUS_DASH
11
+ alphanumeric_field :middle_name, 20, Metro2::ALPHANUMERIC_PLUS_DASH
12
+ alphanumeric_field :generation_code, 1
13
+ numeric_field :social_security_number, 9
14
+ date_field :date_of_birth
15
+ numeric_field :telephone_number, 10
16
+ alphanumeric_field :ecoa_code, 1
17
+ alphanumeric_field :consumer_information_indicator, 2
18
+ alphanumeric_field :country_code, 2
19
+ alphanumeric_field :address_1, 32, Metro2::ALPHANUMERIC_PLUS_DOT_DASH_SLASH
20
+ alphanumeric_field :address_2, 32, Metro2::ALPHANUMERIC_PLUS_DOT_DASH_SLASH
21
+ alphanumeric_field :city, 20, Metro2::ALPHANUMERIC_PLUS_DOT_DASH_SLASH
22
+ alphanumeric_field :state, 2
23
+ alphanumeric_field :postal_code, 9
24
+ alphanumeric_field :address_indicator, 1
25
+ alphanumeric_field :residence_code, 1
26
+ alphanumeric_const_field :reserved2, 2, nil # reserved - blank fill
27
+ end
28
+
29
+ end
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Metro2
2
- VERSION = "1.2.3"
4
+ VERSION = '1.2.5'
3
5
 
4
6
  def self.version_string
5
7
  str = VERSION.split('.')
data/lib/metro_2.rb CHANGED
@@ -1,7 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'metro_2/version'
2
4
 
3
5
  module Metro2
4
-
5
6
  PORTFOLIO_TYPE = {
6
7
  line_of_credit: 'C',
7
8
  installment: 'I',
@@ -11,31 +12,42 @@ module Metro2
11
12
  }.freeze
12
13
 
13
14
  ACCOUNT_TYPE = {
15
+ auto: '00',
14
16
  unsecured: '01',
15
- education: '12'
17
+ education: '12',
18
+ business_individual_personally_liable: '10'
16
19
  # TODO: add other account types
17
20
  }.freeze
18
21
 
19
22
  ECOA_CODE = {
20
23
  individual: '1',
21
24
  deceased: 'X',
22
- delete: 'Z'
25
+ delete: 'Z',
26
+ comaker_or_guarantor: '5',
27
+ business: 'W'
23
28
  # TODO: add other ECOA codes
24
29
  }.freeze
25
30
 
26
31
  SPECIAL_COMMENT_CODE = {
32
+ election_of_remedy: 'I',
33
+ paid_through_insurance: 'AB',
27
34
  partial_payment_agreement: 'AC',
28
35
  purchased_by_another_company: 'AH',
36
+ voluntarily_surrendered: 'AO',
29
37
  paid_in_full_less_than_full_balance: 'AU',
30
38
  affected_by_natural_or_declared_disaster: 'AW',
39
+ redeemed_or_reinstated_repossession: 'AZ',
40
+ involuntary_repossession: 'BI',
41
+ involuntary_repossession_obligation_satisfied: 'BJ',
42
+ involuntary_repossession_balance_owing: 'BK',
31
43
  loan_modified: 'CO',
32
- forbearance: 'CP',
44
+ forbearance: 'CP'
33
45
  # TODO: add other special comment codes
34
46
  }.freeze
35
47
 
36
48
  COMPLIANCE_CONDITION_CODE = {
37
49
  in_dispute: 'XB',
38
- previously_in_dispute_now_resolved: 'XH',
50
+ previously_in_dispute_now_resolved: 'XH'
39
51
  # TODO: add other compliance condition codes
40
52
  }.freeze
41
53
 
@@ -161,8 +173,8 @@ module Metro2
161
173
  withdrawn_ch7: 'M',
162
174
  withdrawn_ch11: 'N',
163
175
  withdrawn_ch12: 'O',
164
- withdrawn_ch13: 'P',
165
- }
176
+ withdrawn_ch13: 'P'
177
+ }.freeze
166
178
 
167
179
  # K2 Segment constants
168
180
  PURCHASED_FROM_SOLD_TO_INDICATOR = {
@@ -171,10 +183,10 @@ module Metro2
171
183
  remove_previous: 9
172
184
  }.freeze
173
185
 
174
- ALPHANUMERIC = /\A([[:alnum:]]|\s)+\z/
175
- ALPHANUMERIC_PLUS_DASH = /\A([[:alnum:]]|\s|\-)+\z/
176
- ALPHANUMERIC_PLUS_DOT_DASH_SLASH = /\A([[:alnum:]]|\s|\-|\.|\\|\/)+\z/
177
- NUMERIC = /\A\d+\.?\d*\z/
186
+ ALPHANUMERIC = /\A([[:alnum:]]|\s)+\z/.freeze
187
+ ALPHANUMERIC_PLUS_DASH = /\A([[:alnum:]]|\s|\-)+\z/.freeze
188
+ ALPHANUMERIC_PLUS_DOT_DASH_SLASH = %r{\A([[:alnum:]]|\s|\-|\.|\\|/)+\z}.freeze
189
+ NUMERIC = /\A\d+\.?\d*\z/.freeze
178
190
 
179
191
  FIXED_LENGTH = 426
180
192
 
@@ -189,14 +201,14 @@ module Metro2
189
201
  # Left justified and blank-filled
190
202
  val = val.to_s
191
203
 
192
- return ' ' * required_length if val.empty?
204
+ return ' ' * required_length if val.empty?
193
205
 
194
206
  unless !!(val =~ permitted_chars)
195
- raise ArgumentError.new("Content (#{val}) contains invalid characters in field '#{name}'")
207
+ raise ArgumentError, "Content (#{val}) contains invalid characters in field '#{name}'"
196
208
  end
197
209
 
198
210
  if val.size > required_length
199
- val[0..(required_length-1)]
211
+ val[0..(required_length - 1)]
200
212
  else
201
213
  val + (' ' * (required_length - val.size))
202
214
  end
@@ -205,7 +217,7 @@ module Metro2
205
217
  def self.numeric_to_metro2(val, required_length,
206
218
  is_monetary: false, name: nil, possible_values: nil)
207
219
  unless possible_values.nil? || possible_values.include?(val)
208
- raise ArgumentError.new("field #{name} has unsupported value: #{val}")
220
+ raise ArgumentError, "field #{name} has unsupported value: #{val}"
209
221
  end
210
222
 
211
223
  # Right justified and zero-filled
@@ -213,17 +225,15 @@ module Metro2
213
225
 
214
226
  return '0' * required_length if val.empty?
215
227
 
216
- unless !!(val =~ Metro2::NUMERIC)
217
- raise ArgumentError.new("field (#{val}) must be numeric")
218
- end
228
+ raise ArgumentError, "field (#{val}) must be numeric" unless !!(val =~ Metro2::NUMERIC)
219
229
 
220
230
  decimal_index = val.index('.')
221
231
  val = val[0..(decimal_index - 1)] if decimal_index
222
232
 
223
233
  # any value above 1 billion gets set to 999,999,999
224
- return '9' * required_length if is_monetary && val.to_f >= 1000000000
234
+ return '9' * required_length if is_monetary && val.to_f >= 1_000_000_000
225
235
  if val.size > required_length
226
- raise ArgumentError.new("numeric field (#{val}) is too long (max #{required_length})")
236
+ raise ArgumentError, "numeric field (#{val}) is too long (max #{required_length})"
227
237
  end
228
238
 
229
239
  ('0' * (required_length - val.size)) + val
@@ -237,5 +247,5 @@ require 'metro_2/metro2_file'
237
247
  require 'metro_2/records/record'
238
248
 
239
249
  Dir.new(File.dirname(__FILE__) + '/metro_2/records').each do |file|
240
- require('metro_2/records/' + File.basename(file)) if File.extname(file) == ".rb"
250
+ require('metro_2/records/' + File.basename(file)) if File.extname(file) == '.rb'
241
251
  end
data/metro_2.gemspec CHANGED
@@ -1,24 +1,25 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
3
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
5
  require 'metro_2/version'
5
6
 
6
7
  Gem::Specification.new do |spec|
7
- spec.name = "metro_2"
8
+ spec.name = 'metro_2'
8
9
  spec.version = Metro2::VERSION
9
- spec.authors = ["Brian Mascarenhas"]
10
- spec.email = ["brian@upstart.com"]
11
- spec.summary = "Create Metro 2 format files for credit reporting"
12
- spec.description = "Create Metro 2 format files for credit reporting"
13
- spec.homepage = ""
14
- spec.license = "MIT"
10
+ spec.authors = ['Brian Mascarenhas']
11
+ spec.email = ['brian@upstart.com']
12
+ spec.summary = 'Create Metro 2 format files for credit reporting'
13
+ spec.description = 'Create Metro 2 format files for credit reporting'
14
+ spec.homepage = ''
15
+ spec.license = 'MIT'
15
16
 
16
17
  spec.files = `git ls-files -z`.split("\x0")
17
18
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
19
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
- spec.require_paths = ["lib"]
20
+ spec.require_paths = ['lib']
20
21
 
21
- spec.add_development_dependency "bundler", "~> 1.6"
22
- spec.add_development_dependency "rake", "~> 10.0"
23
- spec.add_development_dependency "rspec", "~> 2.13"
22
+ spec.add_development_dependency 'bundler', '~> 2.1'
23
+ spec.add_development_dependency 'rake', '~> 10.0'
24
+ spec.add_development_dependency 'rspec', '~> 2.13'
24
25
  end
@@ -36,9 +36,11 @@ describe Metro2::Records::BaseSegment do
36
36
  @base.address_indicator = 'N'
37
37
  @base.residence_code = 'O'
38
38
  @base.k2_segment = k2_segment
39
+ @base.j2_segment = j2_segment
39
40
  end
40
41
 
41
42
  let(:k2_segment) { nil }
43
+ let(:j2_segment) { nil }
42
44
 
43
45
  context '#to_metro2' do
44
46
  let(:expected) do
@@ -115,6 +117,29 @@ describe Metro2::Records::BaseSegment do
115
117
  expect(base_str[0..3].to_i).to eql(expected_length)
116
118
  end
117
119
  end
120
+
121
+ context 'with a J2 segment' do
122
+ let(:j2_segment) do
123
+ j2 = Metro2::Records::J2Segment.new
124
+ j2.surname = "Business Name"
125
+ j2.social_security_number = '333224444'
126
+ j2.date_of_birth = Date.new(1987, 4, 19)
127
+ j2.ecoa_code = 'W'
128
+ j2.country_code = 'US'
129
+ j2.address_1 = '742 Evergreen Terrace'
130
+ j2.city = 'Springfield'
131
+ j2.state = 'IL'
132
+ j2.postal_code = '54321'
133
+ j2
134
+ end
135
+
136
+ it 'should output the j2 segment in its string and update set_record_descriptor_word' do
137
+ base_str = @base.to_metro2
138
+ expected_length = Metro2::Records::BaseSegment::LENGTH + Metro2::Records::J2Segment::LENGTH
139
+ expect(base_str.size).to eql(expected_length)
140
+ expect(base_str[0..3].to_i).to eql(expected_length)
141
+ end
142
+ end
118
143
  end
119
144
 
120
145
  context 'alphanumerics' do
@@ -32,7 +32,7 @@ describe Metro2::Records::HeaderSegment do
32
32
  '123 Report Dr Address CA 91111'.ljust(96, ' '),
33
33
  '5555555555',
34
34
  'Upstart Engineer metro 2 gem'.ljust(40, ' '),
35
- '01203',
35
+ '01204',
36
36
  ' ' * 156
37
37
  ]
38
38
  header_str = @header.to_metro2
@@ -0,0 +1,53 @@
1
+ require "spec_helper"
2
+
3
+ describe Metro2::Records::BaseSegment do
4
+ before do
5
+ @j2_segment = Metro2::Records::J2Segment.new
6
+ @j2_segment.surname = business_name
7
+ @j2_segment.social_security_number = "333224444"
8
+ @j2_segment.date_of_birth = Date.new(1987, 4, 19)
9
+ @j2_segment.ecoa_code = "W"
10
+ @j2_segment.country_code = 'US'
11
+ @j2_segment.address_1 = '742 Evergreen Terrace'
12
+ @j2_segment.city = 'Springfield'
13
+ @j2_segment.state = 'IL'
14
+ @j2_segment.postal_code = '54321'
15
+ end
16
+
17
+ context "#to_metro2" do
18
+ let(:expected) do
19
+ [
20
+ "J2",
21
+ " ",
22
+ business_name.to_s.ljust(25, ' '),
23
+ " " * 20,
24
+ " " * 20,
25
+ " ",
26
+ "333224444",
27
+ "04191987",
28
+ "0" * 10,
29
+ "W",
30
+ " " * 2,
31
+ "US",
32
+ "742 Evergreen Terrace".ljust(32, ' '),
33
+ " " * 32,
34
+ "Springfield".ljust(20, ' '),
35
+ "IL",
36
+ "54321".ljust(9, ' '),
37
+ " ",
38
+ " ",
39
+ " " * 2
40
+ ]
41
+ end
42
+
43
+ context "with valid attributes set" do
44
+ let(:business_name) { "Business Name" }
45
+
46
+ it "should create output string that matches expected" do
47
+ j2_segment_str = @j2_segment.to_metro2
48
+ expect(j2_segment_str).to eql(expected.join)
49
+ expect(j2_segment_str.size).to eql(Metro2::Records::J2Segment::LENGTH)
50
+ end
51
+ end
52
+ end
53
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metro_2
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.3
4
+ version: 1.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Mascarenhas
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-10-19 00:00:00.000000000 Z
11
+ date: 2022-09-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.6'
19
+ version: '2.1'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.6'
26
+ version: '2.1'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -61,15 +61,19 @@ extra_rdoc_files: []
61
61
  files:
62
62
  - ".gitignore"
63
63
  - ".rspec"
64
+ - ".rubocop.yml"
65
+ - CHANGELOG.md
64
66
  - Gemfile
65
67
  - LICENSE.txt
66
68
  - README.md
67
69
  - Rakefile
70
+ - Repositoryowner.md
68
71
  - lib/metro_2.rb
69
72
  - lib/metro_2/fields.rb
70
73
  - lib/metro_2/metro2_file.rb
71
74
  - lib/metro_2/records/base_segment.rb
72
75
  - lib/metro_2/records/header_segment.rb
76
+ - lib/metro_2/records/j2_segment.rb
73
77
  - lib/metro_2/records/k2_segment.rb
74
78
  - lib/metro_2/records/record.rb
75
79
  - lib/metro_2/records/trailer_segment.rb
@@ -77,6 +81,7 @@ files:
77
81
  - metro_2.gemspec
78
82
  - spec/records/base_segment_spec.rb
79
83
  - spec/records/header_segment_spec.rb
84
+ - spec/records/j2_segment_spec.rb
80
85
  - spec/records/k2_segment_spec.rb
81
86
  - spec/records/trailer_segment_spec.rb
82
87
  - spec/spec_helper.rb
@@ -99,14 +104,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
99
104
  - !ruby/object:Gem::Version
100
105
  version: '0'
101
106
  requirements: []
102
- rubyforge_project:
103
- rubygems_version: 2.7.6
107
+ rubygems_version: 3.1.4
104
108
  signing_key:
105
109
  specification_version: 4
106
110
  summary: Create Metro 2 format files for credit reporting
107
111
  test_files:
108
112
  - spec/records/base_segment_spec.rb
109
113
  - spec/records/header_segment_spec.rb
114
+ - spec/records/j2_segment_spec.rb
110
115
  - spec/records/k2_segment_spec.rb
111
116
  - spec/records/trailer_segment_spec.rb
112
117
  - spec/spec_helper.rb