metro_2 1.1.9 → 1.2.1
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.
- checksums.yaml +4 -4
- data/lib/metro_2.rb +14 -2
- data/lib/metro_2/fields.rb +7 -7
- data/lib/metro_2/metro2_file.rb +3 -0
- data/lib/metro_2/records/base_segment.rb +26 -1
- data/lib/metro_2/records/k2_segment.rb +21 -0
- data/lib/metro_2/records/record.rb +5 -0
- data/lib/metro_2/version.rb +1 -1
- data/spec/records/base_segment_spec.rb +24 -3
- data/spec/records/header_segment_spec.rb +1 -1
- data/spec/records/k2_segment_spec.rb +57 -0
- data/spec/records/trailer_segment_spec.rb +2 -1
- metadata +5 -11
- data/metro_2-1.1.0.gem +0 -0
- data/metro_2-1.1.1.gem +0 -0
- data/metro_2-1.1.2.gem +0 -0
- data/metro_2-1.1.3.gem +0 -0
- data/metro_2-1.1.4.gem +0 -0
- data/metro_2-1.1.5.gem +0 -0
- data/metro_2-1.1.6.gem +0 -0
- data/metro_2-1.1.7.gem +0 -0
- data/metro_2-1.1.8.gem +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b830f8ea9769cd85e6f39fd7d66abe9cf4ac2e2a
|
4
|
+
data.tar.gz: 8fd323371e39e8c440c5010d8e4f572d0437fe90
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f5234f2a94acf7dc6813e565520524003b07193e374121161b8bbc96603343f9ce84ac7406b11348c22276707bd40af95a7b32192fd4effd2d3e51357b685224
|
7
|
+
data.tar.gz: 3113a1b0fa68d26241158748fe3ccbe5a40dbe7f30e2e0d976b8d514f093c235f437a9fd48e78315f13de9b1fbe2ee10cda0b6c2c82ca885b9ca084422b3c398
|
data/lib/metro_2.rb
CHANGED
@@ -24,7 +24,7 @@ module Metro2
|
|
24
24
|
|
25
25
|
SPECIAL_COMMENT_CODE = {
|
26
26
|
partial_payment_agreement: 'AC',
|
27
|
-
|
27
|
+
purchased_by_another_company: 'AH',
|
28
28
|
paid_in_full_less_than_full_balance: 'AU',
|
29
29
|
affected_by_natural_or_declared_disaster: 'AW',
|
30
30
|
loan_modified: 'CO',
|
@@ -162,6 +162,13 @@ module Metro2
|
|
162
162
|
withdrawn_ch13: 'P',
|
163
163
|
}
|
164
164
|
|
165
|
+
# K2 Segment constants
|
166
|
+
PURCHASED_FROM_SOLD_TO_INDICATOR = {
|
167
|
+
purchased_from: 1,
|
168
|
+
sold_to: 2,
|
169
|
+
remove_previous: 9
|
170
|
+
}.freeze
|
171
|
+
|
165
172
|
ALPHANUMERIC = /\A([[:alnum:]]|\s)+\z/
|
166
173
|
ALPHANUMERIC_PLUS_DASH = /\A([[:alnum:]]|\s|\-)+\z/
|
167
174
|
ALPHANUMERIC_PLUS_DOT_DASH_SLASH = /\A([[:alnum:]]|\s|\-|\.|\\|\/)+\z/
|
@@ -193,7 +200,12 @@ module Metro2
|
|
193
200
|
end
|
194
201
|
end
|
195
202
|
|
196
|
-
def self.numeric_to_metro2(val, required_length,
|
203
|
+
def self.numeric_to_metro2(val, required_length,
|
204
|
+
is_monetary: false, name: nil, possible_values: nil)
|
205
|
+
unless possible_values.nil? || possible_values.include?(val)
|
206
|
+
raise ArgumentError.new("field #{name} has unsupported value: #{val}")
|
207
|
+
end
|
208
|
+
|
197
209
|
# Right justified and zero-filled
|
198
210
|
val = val.to_s
|
199
211
|
|
data/lib/metro_2/fields.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
module Metro2
|
2
2
|
module Fields
|
3
|
-
|
4
3
|
def alphanumeric_field(name, required_length, permitted_chars = Metro2::ALPHANUMERIC)
|
5
4
|
fields << name
|
6
5
|
|
@@ -21,7 +20,7 @@ module Metro2
|
|
21
20
|
end
|
22
21
|
end
|
23
22
|
|
24
|
-
def numeric_field(name, required_length, is_monetary
|
23
|
+
def numeric_field(name, required_length, is_monetary: false, possible_values: nil)
|
25
24
|
fields << name
|
26
25
|
|
27
26
|
# getter
|
@@ -37,7 +36,8 @@ module Metro2
|
|
37
36
|
# to_metro2
|
38
37
|
define_method "#{name}_to_metro2" do
|
39
38
|
val = instance_variable_get("@#{name}")
|
40
|
-
Metro2.numeric_to_metro2(val, required_length, is_monetary
|
39
|
+
Metro2.numeric_to_metro2(val, required_length, is_monetary: is_monetary,
|
40
|
+
name: name, possible_values: possible_values)
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
@@ -66,12 +66,12 @@ module Metro2
|
|
66
66
|
|
67
67
|
# to_metro2
|
68
68
|
define_method "#{name}_to_metro2" do
|
69
|
-
Metro2.numeric_to_metro2(val, required_length, is_monetary)
|
69
|
+
Metro2.numeric_to_metro2(val, required_length, is_monetary: is_monetary)
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
73
73
|
def monetary_field(name)
|
74
|
-
numeric_field(name, 9, true)
|
74
|
+
numeric_field(name, 9, is_monetary: true)
|
75
75
|
end
|
76
76
|
|
77
77
|
def date_field(name)
|
@@ -93,7 +93,7 @@ module Metro2
|
|
93
93
|
val = instance_variable_get("@#{name}")
|
94
94
|
val = val&.strftime('%m%d%Y')
|
95
95
|
|
96
|
-
Metro2.numeric_to_metro2(val, 8
|
96
|
+
Metro2.numeric_to_metro2(val, 8)
|
97
97
|
end
|
98
98
|
end
|
99
99
|
|
@@ -115,7 +115,7 @@ module Metro2
|
|
115
115
|
# Right justified and zero-filled
|
116
116
|
val = instance_variable_get("@#{name}")
|
117
117
|
val = val&.strftime('%m%d%Y%H%M%S')
|
118
|
-
Metro2.numeric_to_metro2(val, 14
|
118
|
+
Metro2.numeric_to_metro2(val, 14)
|
119
119
|
end
|
120
120
|
end
|
121
121
|
end
|
data/lib/metro_2/metro2_file.rb
CHANGED
@@ -29,6 +29,7 @@ module Metro2
|
|
29
29
|
num_dob = 0
|
30
30
|
num_telephone = 0
|
31
31
|
num_ecoa_code_z = 0
|
32
|
+
total_k2_segments = 0
|
32
33
|
|
33
34
|
@base_segments.each do |base|
|
34
35
|
status_code_count[base.account_status.upcase] += 1
|
@@ -36,6 +37,7 @@ module Metro2
|
|
36
37
|
num_dob += 1 if base.date_of_birth
|
37
38
|
num_telephone += 1 if base.telephone_number
|
38
39
|
num_ecoa_code_z += 1 if base.ecoa_code == 'Z'
|
40
|
+
total_k2_segments += 1 if base.k2_segment
|
39
41
|
end
|
40
42
|
|
41
43
|
trailer = Records::TrailerSegment.new
|
@@ -69,6 +71,7 @@ module Metro2
|
|
69
71
|
trailer.total_date_of_births = num_dob
|
70
72
|
trailer.total_date_of_births_in_base = num_dob
|
71
73
|
trailer.total_telephome_numbers = num_telephone
|
74
|
+
trailer.total_k2_segments = total_k2_segments
|
72
75
|
trailer
|
73
76
|
end
|
74
77
|
|
@@ -1,8 +1,10 @@
|
|
1
1
|
module Metro2::Records
|
2
2
|
class BaseSegment < Record
|
3
|
+
LENGTH = Metro2::FIXED_LENGTH
|
4
|
+
|
3
5
|
@fields = []
|
4
6
|
|
5
|
-
|
7
|
+
numeric_field :record_descriptor_word, 4
|
6
8
|
alphanumeric_const_field :processing_indicator, 1, 1 # always 1
|
7
9
|
timestamp_field :time_stamp
|
8
10
|
numeric_field :correction_indicator, 1
|
@@ -50,5 +52,28 @@ module Metro2::Records
|
|
50
52
|
alphanumeric_field :postal_code, 9
|
51
53
|
alphanumeric_field :address_indicator, 1
|
52
54
|
alphanumeric_field :residence_code, 1
|
55
|
+
|
56
|
+
def initialize
|
57
|
+
@appendages = []
|
58
|
+
end
|
59
|
+
|
60
|
+
def k2_segment
|
61
|
+
@k2_segment
|
62
|
+
end
|
63
|
+
|
64
|
+
def k2_segment=(segment)
|
65
|
+
@k2_segment = segment
|
66
|
+
@appendages << @k2_segment
|
67
|
+
end
|
68
|
+
|
69
|
+
def to_metro2
|
70
|
+
@appendages.compact!
|
71
|
+
set_record_descriptor_word
|
72
|
+
super + @appendages.map(&:to_metro2).join
|
73
|
+
end
|
74
|
+
|
75
|
+
def set_record_descriptor_word
|
76
|
+
self.record_descriptor_word = LENGTH + @appendages.sum { |appendage| appendage.class::LENGTH }
|
77
|
+
end
|
53
78
|
end
|
54
79
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Metro2::Records
|
2
|
+
class K2Segment < Record
|
3
|
+
LENGTH = 34
|
4
|
+
|
5
|
+
@fields = []
|
6
|
+
|
7
|
+
alphanumeric_const_field :segment_identifier, 2, "K2"
|
8
|
+
numeric_field :purchased_from_sold_to_indicator, 1,
|
9
|
+
possible_values: Metro2::PURCHASED_FROM_SOLD_TO_INDICATOR.values
|
10
|
+
alphanumeric_field :purchased_from_sold_to_name, 30, Metro2::ALPHANUMERIC_PLUS_DOT_DASH_SLASH
|
11
|
+
alphanumeric_const_field :reserved, 1, nil # reserved - blank fill
|
12
|
+
|
13
|
+
def validate_fields
|
14
|
+
if !purchased_from_sold_to_name.nil? &&
|
15
|
+
purchased_from_sold_to_indicator == Metro2::PURCHASED_FROM_SOLD_TO_INDICATOR[:remove_previous]
|
16
|
+
str = "purchased_from_sold_to_name must be blank if purchased_from_sold_to_indicator is 9"
|
17
|
+
raise ArgumentError.new(str)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/metro_2/version.rb
CHANGED
@@ -35,11 +35,14 @@ describe Metro2::Records::BaseSegment do
|
|
35
35
|
@base.postal_code = '54321'
|
36
36
|
@base.address_indicator = 'N'
|
37
37
|
@base.residence_code = 'O'
|
38
|
+
@base.k2_segment = k2_segment
|
38
39
|
end
|
39
40
|
|
41
|
+
let(:k2_segment) { nil }
|
42
|
+
|
40
43
|
context '#to_metro2' do
|
41
|
-
|
42
|
-
|
44
|
+
let(:expected) do
|
45
|
+
[
|
43
46
|
'0426',
|
44
47
|
'1',
|
45
48
|
'09152014170745',
|
@@ -90,10 +93,28 @@ describe Metro2::Records::BaseSegment do
|
|
90
93
|
'O',
|
91
94
|
''
|
92
95
|
]
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'should generate base segment string' do
|
93
99
|
base_str = @base.to_metro2
|
94
|
-
expect(base_str).to eql(
|
100
|
+
expect(base_str).to eql(expected.join(''))
|
95
101
|
expect(base_str.size).to eql(Metro2::FIXED_LENGTH)
|
96
102
|
end
|
103
|
+
|
104
|
+
context 'with a K2 segment' do
|
105
|
+
let(:k2_segment) do
|
106
|
+
k2 = Metro2::Records::K2Segment.new
|
107
|
+
k2.purchased_from_sold_to_indicator = 9
|
108
|
+
k2
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'should output the k2 segment in its string and update set_record_descriptor_word' do
|
112
|
+
base_str = @base.to_metro2
|
113
|
+
expected_length = Metro2::Records::BaseSegment::LENGTH + Metro2::Records::K2Segment::LENGTH
|
114
|
+
expect(base_str.size).to eql(expected_length)
|
115
|
+
expect(base_str[0..3].to_i).to eql(expected_length)
|
116
|
+
end
|
117
|
+
end
|
97
118
|
end
|
98
119
|
|
99
120
|
context 'alphanumerics' do
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Metro2::Records::BaseSegment do
|
4
|
+
before do
|
5
|
+
@k2_segment = Metro2::Records::K2Segment.new
|
6
|
+
@k2_segment.purchased_from_sold_to_indicator = indicator
|
7
|
+
@k2_segment.purchased_from_sold_to_name = company_name
|
8
|
+
end
|
9
|
+
|
10
|
+
context "#to_metro2" do
|
11
|
+
let(:expected) { ["K2", indicator.to_s, company_name.to_s.ljust(30, " "), " "] }
|
12
|
+
|
13
|
+
context "with valid attributes set" do
|
14
|
+
let(:indicator) { 1 }
|
15
|
+
let(:company_name) { "Loan Buying Company" }
|
16
|
+
|
17
|
+
it "should create output string that matches expected" do
|
18
|
+
k2_segment_str = @k2_segment.to_metro2
|
19
|
+
expect(k2_segment_str).to eql(expected.join)
|
20
|
+
expect(k2_segment_str.size).to eql(Metro2::Records::K2Segment::LENGTH)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context "with a 9 indicator" do
|
25
|
+
let(:indicator) { 9 }
|
26
|
+
|
27
|
+
context "with a blank purchased_from_sold_to_name" do
|
28
|
+
let(:company_name) { nil }
|
29
|
+
|
30
|
+
it "should create output string that matches expected" do
|
31
|
+
k2_segment_str = @k2_segment.to_metro2
|
32
|
+
expect(k2_segment_str).to eql(expected.join)
|
33
|
+
expect(k2_segment_str.size).to eql(Metro2::Records::K2Segment::LENGTH)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context "with purchased_from_sold_to_name that is not blank" do
|
38
|
+
let(:company_name) { "Loan Buying Company" }
|
39
|
+
|
40
|
+
it "should raise an error that the field should be blank" do
|
41
|
+
expect { @k2_segment.to_metro2 }.
|
42
|
+
to raise_error(/purchased_from_sold_to_name must be blank/)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context "with a non-supported indicator" do
|
48
|
+
let(:indicator) { 7 }
|
49
|
+
let(:company_name) { "Loan Buying Company" }
|
50
|
+
|
51
|
+
it "should raise an error that the value is unsupported" do
|
52
|
+
expect { @k2_segment.to_metro2 }.
|
53
|
+
to raise_error(/field purchased_from_sold_to_indicator has unsupported value/)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -10,6 +10,7 @@ describe Metro2::Records::TrailerSegment do
|
|
10
10
|
@trailer.total_date_of_births = 1
|
11
11
|
@trailer.total_date_of_births_in_base = 1
|
12
12
|
@trailer.total_telephome_numbers = 1
|
13
|
+
@trailer.total_k2_segments = 1
|
13
14
|
end
|
14
15
|
|
15
16
|
describe '#to_metro2' do
|
@@ -48,7 +49,7 @@ describe Metro2::Records::TrailerSegment do
|
|
48
49
|
'0' * 9,
|
49
50
|
'0' * 9,
|
50
51
|
'0' * 9,
|
51
|
-
'
|
52
|
+
'000000001',
|
52
53
|
'0' * 9,
|
53
54
|
'0' * 9,
|
54
55
|
'0' * 9,
|
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.1
|
4
|
+
version: 1.2.1
|
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-02-
|
11
|
+
date: 2018-02-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -70,21 +70,14 @@ files:
|
|
70
70
|
- lib/metro_2/metro2_file.rb
|
71
71
|
- lib/metro_2/records/base_segment.rb
|
72
72
|
- lib/metro_2/records/header_segment.rb
|
73
|
+
- lib/metro_2/records/k2_segment.rb
|
73
74
|
- lib/metro_2/records/record.rb
|
74
75
|
- lib/metro_2/records/trailer_segment.rb
|
75
76
|
- lib/metro_2/version.rb
|
76
|
-
- metro_2-1.1.0.gem
|
77
|
-
- metro_2-1.1.1.gem
|
78
|
-
- metro_2-1.1.2.gem
|
79
|
-
- metro_2-1.1.3.gem
|
80
|
-
- metro_2-1.1.4.gem
|
81
|
-
- metro_2-1.1.5.gem
|
82
|
-
- metro_2-1.1.6.gem
|
83
|
-
- metro_2-1.1.7.gem
|
84
|
-
- metro_2-1.1.8.gem
|
85
77
|
- metro_2.gemspec
|
86
78
|
- spec/records/base_segment_spec.rb
|
87
79
|
- spec/records/header_segment_spec.rb
|
80
|
+
- spec/records/k2_segment_spec.rb
|
88
81
|
- spec/records/trailer_segment_spec.rb
|
89
82
|
- spec/spec_helper.rb
|
90
83
|
homepage: ''
|
@@ -114,5 +107,6 @@ summary: Create Metro 2 format files for credit reporting
|
|
114
107
|
test_files:
|
115
108
|
- spec/records/base_segment_spec.rb
|
116
109
|
- spec/records/header_segment_spec.rb
|
110
|
+
- spec/records/k2_segment_spec.rb
|
117
111
|
- spec/records/trailer_segment_spec.rb
|
118
112
|
- spec/spec_helper.rb
|
data/metro_2-1.1.0.gem
DELETED
Binary file
|
data/metro_2-1.1.1.gem
DELETED
Binary file
|
data/metro_2-1.1.2.gem
DELETED
Binary file
|
data/metro_2-1.1.3.gem
DELETED
Binary file
|
data/metro_2-1.1.4.gem
DELETED
Binary file
|
data/metro_2-1.1.5.gem
DELETED
Binary file
|
data/metro_2-1.1.6.gem
DELETED
Binary file
|
data/metro_2-1.1.7.gem
DELETED
Binary file
|
data/metro_2-1.1.8.gem
DELETED
Binary file
|