loan_creator 0.6.1.1 → 0.6.2

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
- SHA256:
3
- metadata.gz: af7d0ce0dc0202794a3f37abf13b9f0af74e214a3d5629779d312acb1f5d02f0
4
- data.tar.gz: c7304d6eb2ecc855702c2e403378860ad029b30180054e7658bfc86980fc7fb0
2
+ SHA1:
3
+ metadata.gz: 8dff90f00c1b47c09fd2ac97d4a0e3a28e12fbd5
4
+ data.tar.gz: '078e7ad135c712ef0fb767208cc99557718b99b1'
5
5
  SHA512:
6
- metadata.gz: a3991a0c94c5445bf179d8c363a56926c9bb8b90bddf23ae1d220dd74eed7d9ec225174fd06c2033a85fde23502af09346d1196f2755ac7cae26a625f6396669
7
- data.tar.gz: d080c6fe10ad761bc19947edbe701736f80ab38fded009ea2bce40292440878141e4a06e8a6fc4988b956ee8918a058e3b24345f3b39d152d03b543fec18aefc
6
+ metadata.gz: e318e46a05d49caa450705cb5a6e234c7b3e497dad501961c1339638c0641cc76f88dafb00f07af80b9b9cdc6d5ba1d0b5e761133f863f7a6034d479ddb0f012
7
+ data.tar.gz: bc258a7bd58a783c033c7c81857b467966e2e4ee25b091cc73cf1de1f5ec94a94f889fb2c32f5be072668503295564a841beb0573585c509b867dc9b0025cbe1
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 3.2.5
1
+ ruby-2.3.7
data/CHANGELOG.md CHANGED
@@ -1,4 +1,10 @@
1
- v0.6.1.1
1
+ v0.6.2
2
+ -------------------------
3
+
4
+ - add `:initial_values` for loans initialization
5
+ - add and compute `capitalized_interests` for `LoanCreator::Bullet` terms
6
+
7
+ v0.6.1
2
8
  -------------------------
3
9
 
4
10
  - fix homepage url
data/README.md CHANGED
@@ -46,6 +46,19 @@ Each instance of one of the previous classes has the following attributes:
46
46
  :duration_in_periods
47
47
  :deferred_in_periods (default to zero)
48
48
  :interests_start_date (optional)
49
+ :initial_values (to generate a timetable from a previous term or at a given state)
50
+ ```
51
+
52
+ Initial values must be a hash with specific keys, like so:
53
+
54
+ ```ruby
55
+ {
56
+ paid_capital: 0,
57
+ paid_interests: 11000.0,
58
+ accrued_delta_interests: 0,
59
+ starting_index: 2,
60
+ capitalized_interests: 0
61
+ }
49
62
  ```
50
63
 
51
64
  There is also a `LoanCreator::Timetable` class dedicated to record the data of the loans' terms. Each instance of `LoanCreator::Timetable` represents an array of `LoanCreator::Term` records, each having the following attributes:
@@ -34,7 +34,7 @@ module LoanCreator
34
34
  term = BORROWER_FINANCIAL_ATTRIBUTES.each_with_object({}) do |k, h|
35
35
  h[k] = arr.inject(bigd('0')) { |sum, tt| sum + tt.send(k) }
36
36
  end
37
- borrower_timetable << LoanCreator::Term.new(**all_zero.merge(term))
37
+ borrower_timetable << LoanCreator::Term.new(all_zero.merge(term))
38
38
  end
39
39
  borrower_timetable
40
40
  end
@@ -7,7 +7,7 @@ module LoanCreator
7
7
  reset_current_term
8
8
  @crd_beginning_of_period = amount
9
9
  @crd_end_of_period = amount
10
- (duration_in_periods - 1).times { timetable << current_term }
10
+ (duration_in_periods - 1).times { |period| compute_term(timetable, period + 1) }
11
11
  compute_last_term
12
12
  timetable << current_term
13
13
  timetable
@@ -16,25 +16,22 @@ module LoanCreator
16
16
  private
17
17
 
18
18
  def compute_last_term
19
- @crd_end_of_period = bigd('0')
20
- @period_interests = total_interests
21
- @period_capital = @crd_beginning_of_period
22
- @total_paid_capital_end_of_period = @period_capital
19
+ @crd_end_of_period = bigd('0')
20
+ @period_interests = compute_capitalized_interests(duration_in_periods)
21
+ @period_capital = @crd_beginning_of_period
22
+ @total_paid_capital_end_of_period = @period_capital
23
23
  @total_paid_interests_end_of_period = @period_interests
24
- @period_amount_to_pay = @period_capital + @period_interests
24
+ @period_amount_to_pay = @period_capital + @period_interests
25
+ @capitalized_interests = compute_capitalized_interests(duration_in_periods)
25
26
  end
26
27
 
27
- # Capital * (periodic_interests_rate ^(total_terms))
28
- #
29
- def total_payment
30
- amount.mult(
31
- (bigd(1) + periodic_interests_rate) ** bigd(duration_in_periods),
32
- BIG_DECIMAL_DIGITS
33
- )
28
+ def compute_capitalized_interests(period)
29
+ amount.mult((bigd(1) + periodic_interests_rate) ** period, BIG_DECIMAL_DIGITS) - amount
34
30
  end
35
31
 
36
- def total_interests
37
- total_payment - amount
32
+ def compute_term(timetable, period)
33
+ @capitalized_interests = compute_capitalized_interests(period)
34
+ timetable << current_term
38
35
  end
39
36
  end
40
37
  end
@@ -21,6 +21,7 @@ module LoanCreator
21
21
  # attribute: default_value
22
22
  deferred_in_periods: 0,
23
23
  interests_start_date: nil,
24
+ initial_values: {}
24
25
  }.freeze
25
26
 
26
27
  attr_reader *REQUIRED_ATTRIBUTES
@@ -32,6 +33,8 @@ module LoanCreator
32
33
  reinterpret_attributes
33
34
  set_attributes
34
35
  validate_attributes
36
+ set_initial_values
37
+ validate_initial_values
35
38
  end
36
39
 
37
40
  def periodic_interests_rate_percentage
@@ -90,53 +93,82 @@ module LoanCreator
90
93
  validate(:deferred_in_periods) { |v| v.is_a?(Integer) && v >= 0 && v < duration_in_periods }
91
94
  end
92
95
 
96
+ def validate_initial_values
97
+ return if initial_values.blank?
98
+
99
+ validate(:total_paid_capital_end_of_period) { |v| v.is_a?(BigDecimal) && v >= 0 }
100
+ validate(:total_paid_interests_end_of_period) { |v| v.is_a?(BigDecimal) && v >= 0 }
101
+ validate(:accrued_delta_interests) { |v| v.is_a?(BigDecimal) }
102
+ validate(:starting_index) { |v| v.is_a?(Integer) && v >= 0 }
103
+ end
104
+
105
+ def set_initial_values
106
+ @starting_index = initial_values[:starting_index] || 1
107
+
108
+ return if initial_values.blank?
109
+
110
+ (@total_paid_capital_end_of_period = bigd(initial_values[:paid_capital]))
111
+ (@total_paid_interests_end_of_period = bigd(initial_values[:paid_interests]))
112
+ (@accrued_delta_interests = bigd(initial_values[:accrued_delta_interests]))
113
+ end
114
+
93
115
  def reset_current_term
94
- @crd_beginning_of_period = bigd('0')
95
- @crd_end_of_period = bigd('0')
96
- @period_theoric_interests = bigd('0')
97
- @delta_interests = bigd('0')
98
- @accrued_delta_interests = bigd('0')
99
- @amount_to_add = bigd('0')
100
- @period_interests = bigd('0')
101
- @period_capital = bigd('0')
102
- @total_paid_capital_end_of_period = bigd('0')
103
- @total_paid_interests_end_of_period = bigd('0')
104
- @period_amount_to_pay = bigd('0')
105
- @due_on = nil
106
- @index = nil
116
+ @crd_beginning_of_period = bigd('0')
117
+ @crd_end_of_period = bigd('0')
118
+ @period_theoric_interests = bigd('0')
119
+ @capitalized_interests = bigd('0')
120
+ @delta_interests = bigd('0')
121
+ @accrued_delta_interests = @accrued_delta_interests || bigd('0')
122
+ @amount_to_add = bigd('0')
123
+ @period_interests = bigd('0')
124
+ @period_capital = bigd('0')
125
+ @total_paid_capital_end_of_period = @total_paid_capital_end_of_period || bigd('0')
126
+ @total_paid_interests_end_of_period = @total_paid_interests_end_of_period || bigd('0')
127
+ @period_amount_to_pay = bigd('0')
128
+ @due_on = nil
107
129
  end
108
130
 
109
131
  def current_term
110
132
  LoanCreator::Term.new(
111
- crd_beginning_of_period: @crd_beginning_of_period,
112
- crd_end_of_period: @crd_end_of_period,
113
- period_theoric_interests: @period_theoric_interests,
114
- delta_interests: @delta_interests,
115
- accrued_delta_interests: @accrued_delta_interests,
116
- amount_to_add: @amount_to_add,
117
- period_interests: @period_interests,
118
- period_capital: @period_capital,
119
- total_paid_capital_end_of_period: @total_paid_capital_end_of_period,
133
+ crd_beginning_of_period: @crd_beginning_of_period,
134
+ crd_end_of_period: @crd_end_of_period,
135
+ period_theoric_interests: @period_theoric_interests,
136
+ delta_interests: @delta_interests,
137
+ accrued_delta_interests: @accrued_delta_interests,
138
+ capitalized_interests: @capitalized_interests,
139
+ amount_to_add: @amount_to_add,
140
+ period_interests: @period_interests,
141
+ period_capital: @period_capital,
142
+ total_paid_capital_end_of_period: @total_paid_capital_end_of_period,
120
143
  total_paid_interests_end_of_period: @total_paid_interests_end_of_period,
121
- period_amount_to_pay: @period_amount_to_pay,
122
- due_on: @due_on,
123
- index: @index
144
+ period_amount_to_pay: @period_amount_to_pay,
145
+ due_on: @due_on,
146
+ index: compute_index
124
147
  )
125
148
  end
126
149
 
127
150
  def new_timetable
128
- LoanCreator::Timetable.new(starts_on: starts_on, period: period, interests_start_date: interests_start_date)
151
+ LoanCreator::Timetable.new(
152
+ starts_on: starts_on,
153
+ period: period,
154
+ interests_start_date: interests_start_date,
155
+ starting_index: @starting_index
156
+ )
157
+ end
158
+
159
+ def compute_index
160
+ @index ? (@starting_index + @index - 1) : nil
129
161
  end
130
162
 
131
163
  def compute_term_zero
132
- @crd_beginning_of_period = @crd_end_of_period
133
- @period_theoric_interests = term_zero_interests
134
- @delta_interests = @period_theoric_interests - @period_theoric_interests.round(2)
135
- @accrued_delta_interests += @delta_interests
136
- @period_interests = @period_theoric_interests.round(2)
137
- @total_paid_interests_end_of_period += @period_interests
138
- @period_amount_to_pay = @period_interests
139
- @index = 0
164
+ @crd_beginning_of_period = @crd_end_of_period
165
+ @period_theoric_interests = term_zero_interests
166
+ @delta_interests = @period_theoric_interests - @period_theoric_interests.round(2)
167
+ @accrued_delta_interests += @delta_interests
168
+ @period_interests = @period_theoric_interests.round(2)
169
+ @total_paid_interests_end_of_period += @period_interests
170
+ @period_amount_to_pay = @period_interests
171
+ @index = 0
140
172
  end
141
173
 
142
174
  def term_zero_interests
@@ -4,7 +4,7 @@ module LoanCreator
4
4
  # Thus we're generating a Linear loan instead of rewriting already existing code.
5
5
  def lender_timetable
6
6
  options = @options.merge(deferred_in_periods: duration_in_periods - 1)
7
- LoanCreator::Linear.new(**options).lender_timetable
7
+ LoanCreator::Linear.new(options).lender_timetable
8
8
  end
9
9
  end
10
10
  end
@@ -17,6 +17,7 @@ module LoanCreator
17
17
  compute_current_term(idx)
18
18
  timetable << current_term
19
19
  end
20
+
20
21
  timetable
21
22
  end
22
23
 
@@ -17,6 +17,9 @@ module LoanCreator
17
17
  # Accrued interests' delta
18
18
  :accrued_delta_interests,
19
19
 
20
+ # Capitalized interests (Bullet only)
21
+ :capitalized_interests,
22
+
20
23
  # Adjustment of -0.01, 0 or +0.01 cent depending on accrued_delta_interests
21
24
  :amount_to_add,
22
25
 
@@ -11,12 +11,13 @@ module LoanCreator
11
11
 
12
12
  attr_reader :terms, :starts_on, :period #, :interests_start_date
13
13
 
14
- def initialize(starts_on:, period:, interests_start_date: nil)
14
+ def initialize(starts_on:, period:, interests_start_date: nil, starting_index: 1)
15
15
  raise ArgumentError.new(:period) unless PERIODS.keys.include?(period)
16
16
 
17
- @terms = []
18
- @starts_on = (starts_on.is_a?(Date) ? starts_on : Date.parse(starts_on))
19
- @period = period
17
+ @terms = []
18
+ @starts_on = (starts_on.is_a?(Date) ? starts_on : Date.parse(starts_on))
19
+ @period = period
20
+ @starting_index = starting_index
20
21
 
21
22
  if interests_start_date
22
23
  @interests_start_date = (interests_start_date.is_a?(Date) ? interests_start_date : Date.parse(interests_start_date))
@@ -45,7 +46,7 @@ module LoanCreator
45
46
  private
46
47
 
47
48
  def autoincrement_index
48
- @current_index = @current_index.nil? ? 1 : @current_index + 1
49
+ @current_index = (@current_index.nil? ? @starting_index : @current_index + 1)
49
50
  end
50
51
 
51
52
  def date_for(index)
@@ -1,3 +1,3 @@
1
1
  module LoanCreator
2
- VERSION = '0.6.1.1'.freeze
2
+ VERSION = '0.6.2'.freeze
3
3
  end
data/loan_creator.gemspec CHANGED
@@ -19,8 +19,8 @@ Gem::Specification.new do |spec|
19
19
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
20
  spec.require_paths = ['lib']
21
21
 
22
- spec.add_development_dependency 'bundler'
23
- spec.add_development_dependency 'rake'
22
+ spec.add_development_dependency 'bundler', '~> 1.13'
23
+ spec.add_development_dependency 'rake', '~> 10.0'
24
24
  spec.add_development_dependency 'rspec', '~> 3.0'
25
25
  spec.add_development_dependency 'simplecov', '~> 0.16'
26
26
  spec.add_development_dependency 'byebug', '~> 11.0'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: loan_creator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.1.1
4
+ version: 0.6.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - thibaulth
@@ -9,39 +9,39 @@ authors:
9
9
  - younes.serraj
10
10
  - Antoine Becquet
11
11
  - Jerome Drevet
12
- autorequire:
12
+ autorequire:
13
13
  bindir: exe
14
14
  cert_chain: []
15
- date: 2024-09-02 00:00:00.000000000 Z
15
+ date: 2020-12-08 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: bundler
19
19
  requirement: !ruby/object:Gem::Requirement
20
20
  requirements:
21
- - - ">="
21
+ - - "~>"
22
22
  - !ruby/object:Gem::Version
23
- version: '0'
23
+ version: '1.13'
24
24
  type: :development
25
25
  prerelease: false
26
26
  version_requirements: !ruby/object:Gem::Requirement
27
27
  requirements:
28
- - - ">="
28
+ - - "~>"
29
29
  - !ruby/object:Gem::Version
30
- version: '0'
30
+ version: '1.13'
31
31
  - !ruby/object:Gem::Dependency
32
32
  name: rake
33
33
  requirement: !ruby/object:Gem::Requirement
34
34
  requirements:
35
- - - ">="
35
+ - - "~>"
36
36
  - !ruby/object:Gem::Version
37
- version: '0'
37
+ version: '10.0'
38
38
  type: :development
39
39
  prerelease: false
40
40
  version_requirements: !ruby/object:Gem::Requirement
41
41
  requirements:
42
- - - ">="
42
+ - - "~>"
43
43
  - !ruby/object:Gem::Version
44
- version: '0'
44
+ version: '10.0'
45
45
  - !ruby/object:Gem::Dependency
46
46
  name: rspec
47
47
  requirement: !ruby/object:Gem::Requirement
@@ -112,7 +112,7 @@ dependencies:
112
112
  - - ">="
113
113
  - !ruby/object:Gem::Version
114
114
  version: '0'
115
- description:
115
+ description:
116
116
  email:
117
117
  - thibault@capsens.eu
118
118
  - nicolas.besnard@capsens.eu
@@ -157,7 +157,7 @@ homepage: https://github.com/CapSens/loan-creator
157
157
  licenses:
158
158
  - MIT
159
159
  metadata: {}
160
- post_install_message:
160
+ post_install_message:
161
161
  rdoc_options: []
162
162
  require_paths:
163
163
  - lib
@@ -172,8 +172,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
172
172
  - !ruby/object:Gem::Version
173
173
  version: '0'
174
174
  requirements: []
175
- rubygems_version: 3.5.18
176
- signing_key:
175
+ rubyforge_project:
176
+ rubygems_version: 2.5.2.3
177
+ signing_key:
177
178
  specification_version: 4
178
179
  summary: Create and update timetables from input data
179
180
  test_files: []