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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ee3f1bb08891e146f840b4f3130faf3805955f37
4
- data.tar.gz: bd5a7faf570a7339197fff276a2f41213eb4db11
3
+ metadata.gz: b830f8ea9769cd85e6f39fd7d66abe9cf4ac2e2a
4
+ data.tar.gz: 8fd323371e39e8c440c5010d8e4f572d0437fe90
5
5
  SHA512:
6
- metadata.gz: c6abd4fb0f9c2b91706719c17154ce4ca6daeb580e58078c7601cea8676a080be0d3a262694d99f889700c87712c9a8c8d09747b8a77e711d052e7b8ed808623
7
- data.tar.gz: bbc229d9ea1f97da199e5490be38908da9c6bcebe46e964989c6a3067e56413e5cfda1c52cb3193f1e3ce7972f04d65e2919cd9307d1c683d21a76a610a23717
6
+ metadata.gz: f5234f2a94acf7dc6813e565520524003b07193e374121161b8bbc96603343f9ce84ac7406b11348c22276707bd40af95a7b32192fd4effd2d3e51357b685224
7
+ data.tar.gz: 3113a1b0fa68d26241158748fe3ccbe5a40dbe7f30e2e0d976b8d514f093c235f437a9fd48e78315f13de9b1fbe2ee10cda0b6c2c82ca885b9ca084422b3c398
@@ -24,7 +24,7 @@ module Metro2
24
24
 
25
25
  SPECIAL_COMMENT_CODE = {
26
26
  partial_payment_agreement: 'AC',
27
- purchased_by_other_company: 'AH',
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, is_monetary)
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
 
@@ -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 = false)
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, false)
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, false)
118
+ Metro2.numeric_to_metro2(val, 14)
119
119
  end
120
120
  end
121
121
  end
@@ -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
- numeric_const_field :record_descriptor_word, 4, Metro2::FIXED_LENGTH
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
@@ -12,8 +12,13 @@ module Metro2
12
12
  extend(Fields)
13
13
 
14
14
  def to_metro2
15
+ validate_fields
15
16
  self.class.fields.collect { |f| send("#{f}_to_metro2") }.join
16
17
  end
18
+
19
+ def validate_fields
20
+ # this should be implemented by each child
21
+ end
17
22
  end
18
23
  end
19
24
  end
@@ -1,5 +1,5 @@
1
1
  module Metro2
2
- VERSION = "1.1.9"
2
+ VERSION = "1.2.1"
3
3
 
4
4
  def self.version_string
5
5
  str = VERSION.split('.')
@@ -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
- it 'should generate base segment string' do
42
- exp = [
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(exp.join(''))
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
@@ -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
- '01109',
35
+ '01201',
36
36
  ' ' * 156
37
37
  ]
38
38
  header_str = @header.to_metro2
@@ -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
- '0' * 9,
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.9
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-02 00:00:00.000000000 Z
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
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file