loan_creator 0.5.0 → 0.7.1

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
- SHA1:
3
- metadata.gz: ce94717f0c667263653597ea2037844157e6cebe
4
- data.tar.gz: e498fe9069ca0ff9c3d765083a182f28ddc3ca22
2
+ SHA256:
3
+ metadata.gz: 72a0b25211b0e4cff4c6089ed26ecde7f792eec8404ac58d459e769dcd275c87
4
+ data.tar.gz: ea1836c498d837e62a8cfa389fd6d0041c2a6f71861c2a062ecc780980692170
5
5
  SHA512:
6
- metadata.gz: da8108111a04280719eba3143444bd2ceac35abaade6521c2e9a5a3297266037c7d8e194156c3a373602fe766bbce49c23ebe515a2db1b64e1a35ac67a4aff06
7
- data.tar.gz: 5e49dd7114a25fc67e9230ea0d6120b7a12bb83b6b6c50d28eecbfb7c92cc7bbd68da4ca26d0bf7dffe0b7b1fc2a7ec9acbbbb9369bf2cdfb1eb6837625dd2be
6
+ metadata.gz: b45dd0f8944759ee36d58fb746522a7b2727ba8182a845b8387ff871c13df2494707ab7a7e03f8cd64f6b68d7495a25b1634ff980f81af57f31ee6f870374fe9
7
+ data.tar.gz: b5a70c0ffc639f8afe638f47a423170eddfa0557e44936366895f14a1db9608a2657442dcfcdf2190576416bb215bb1e73776e6a6727304b7e1b4fbb500d2041
@@ -0,0 +1,45 @@
1
+ version: 2.1
2
+ orbs:
3
+ ruby: circleci/ruby@0.1.2
4
+
5
+ jobs:
6
+ build:
7
+ docker:
8
+ - image: circleci/ruby:2.7-node
9
+ executor: ruby/default
10
+ steps:
11
+ - checkout
12
+ - run:
13
+ name: Bundle install
14
+ command: |
15
+ gem install bundler:2.1.4
16
+ bundle install --path vendor/bundle
17
+ - run:
18
+ name: Test
19
+ command: bundle exec rspec
20
+ - run:
21
+ name: Coding style
22
+ command: |
23
+ gem install rubocop
24
+ mkdir -p rubocop
25
+ rubocop --format html -o rubocop/rubocop.html || true
26
+ - run:
27
+ name: Notation
28
+ command: |
29
+ gem install sexp_processor -v 4.13.0
30
+ gem install rubycritic -v 4.3.2
31
+ rubycritic app --no-browser || true
32
+ - run:
33
+ name: "Axe d'optimisation"
34
+ command: |
35
+ gem install fasterer
36
+ fasterer || true
37
+ - run:
38
+ name: "Audit Securité du Gemfile"
39
+ command: |
40
+ gem install bundler-audit
41
+ bundle audit --update
42
+ - store_artifacts:
43
+ path: rubocop/rubocop.html
44
+ - store_artifacts:
45
+ path: tmp/rubycritic
@@ -1,5 +1,5 @@
1
1
  AllCops:
2
- TargetRubyVersion: 2.3
2
+ TargetRubyVersion: 2.7
3
3
  Exclude:
4
4
  - 'db/**/*'
5
5
  - 'vendor/**/*'
@@ -12,7 +12,7 @@ Metrics/BlockLength:
12
12
  Exclude:
13
13
  - spec/**/*
14
14
 
15
- Metrics/LineLength:
15
+ Layout/LineLength:
16
16
  Max: 120
17
17
 
18
18
  Metrics/MethodLength:
@@ -1 +1 @@
1
- ruby-2.3.7
1
+ ruby-2.7.1
@@ -0,0 +1,57 @@
1
+ v0.7.1
2
+ -------------------------
3
+
4
+ - fix `index` for `borrower_timetable` method that did not take into account starting index of `lender_timetables`
5
+
6
+ v0.7.0
7
+ -------------------------
8
+
9
+ - change `capitalized_interests` for `capitalized_interests_beginning_of_period`
10
+ and `capitalized_interests_end_of_period` in `LoanCreator::Term`
11
+ - add `capitalized_interests` in `:inital_values` for `LoanCreator::Bullet` loans
12
+
13
+ v0.6.2
14
+ -------------------------
15
+
16
+ - add `:initial_values` for loans initialization
17
+ - add and compute `capitalized_interests` for `LoanCreator::Bullet` terms
18
+
19
+ v0.6.1
20
+ -------------------------
21
+
22
+ - fix homepage url
23
+
24
+ v0.6.0
25
+ -------------------------
26
+
27
+ - add `LoanCreator::UncapitalizedBullet`
28
+
29
+ v0.5.0
30
+ -------------------------
31
+
32
+ - add `interests_start_date` in `LoanCreator::Common` attributes, replacing `first_term_date`
33
+
34
+ v0.3.0
35
+ -------------------------
36
+
37
+ - add `first_term_date` in `LoanCreator::Common` attributes
38
+
39
+ v0.2.3
40
+ -------------------------
41
+
42
+ - rename `starts_at` -> `starts_on`
43
+
44
+ v0.2.2
45
+ -------------------------
46
+
47
+ - rename `date` -> `due_on`
48
+
49
+ v0.2.1
50
+ -------------------------
51
+
52
+ - convert some options to their expected type by default
53
+
54
+ v0.2.0
55
+ -------------------------
56
+
57
+ - Huge rework : add `period`, rename `amount_in_cents` to `amount` and other breaking changes.
@@ -0,0 +1,73 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, sex characteristics, gender identity and expression,
9
+ level of experience, education, socio-economic status, nationality, personal
10
+ appearance, race, religion, or sexual identity and orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at development@capsens.eu. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72
+
73
+ [homepage]: https://www.contributor-covenant.org
data/README.md CHANGED
@@ -2,8 +2,6 @@
2
2
 
3
3
  `loan_creator` gem intends to provide a set of methods to allow automatic generation of loan timetables, for simulation, from a lender point of view and from a borrower point of view, regarding financial rounding differences. As of today, the gem makes the borrower support any rounding issue. In a later work, an option should be provided to decide who supports such issues.
4
4
 
5
- Link to Loan_Creator excel simulator [Click here] (Excel)
6
-
7
5
  ## Installation
8
6
 
9
7
  Add this line to your application's Gemfile:
@@ -35,6 +33,7 @@ There are four types of loans. All inherit from a `LoanCreator::Common` class.
35
33
  LoanCreator::Linear
36
34
  LoanCreator::InFine
37
35
  LoanCreator::Bullet
36
+ LoanCreator::UncapitalizedBullet
38
37
  ```
39
38
 
40
39
  Each instance of one of the previous classes has the following attributes:
@@ -47,6 +46,19 @@ Each instance of one of the previous classes has the following attributes:
47
46
  :duration_in_periods
48
47
  :deferred_in_periods (default to zero)
49
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
+ }
50
62
  ```
51
63
 
52
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:
@@ -137,6 +149,9 @@ Capital share shall be repaid in full at loan's end.
137
149
  Interests are capitalized, i.e. added to the borrowed capital on each term.\
138
150
  Capital share shall be repaid in full and all interests paid at loan's end.
139
151
 
152
+ `UncapitalizedBullet` same as bullet, the only difference is the interests\
153
+ are NOT capitalized.
154
+
140
155
  There is no deferred time for `InFine` and `Bullet` loans as it would be equivalent to increasing loan's duration.
141
156
 
142
157
  ### Attributes
@@ -155,10 +170,14 @@ There is no deferred time for `InFine` and `Bullet` loans as it would be equival
155
170
  capital is refunded, only interest. Only relevant for `Standard` and `Linear` loans.
156
171
 
157
172
  `interests_start_date`: Optional. To be used when the loan starts before the first full term date. This then compute an
158
- additional term with only interests for the time difference.
173
+ additional term with only interests for the time difference.
159
174
  For example, with a `start_at` in january 2020 and a `interests_start_date` in october 2019, the timetable will include a
160
175
  first term corresponding to 3 months of interests.
161
176
 
177
+ ## Calculation
178
+
179
+ An excel simulator for standard case can be found [here](CapSens_Loan.xlsx).
180
+
162
181
  ## Development
163
182
 
164
183
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `bundle exec rspec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -167,7 +186,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
167
186
 
168
187
  ## Contributing
169
188
 
170
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/loan_creator.
189
+ Bug reports and pull requests are welcome on GitHub at https://github.com/CapSens/loan_creator.
171
190
 
172
191
 
173
192
  ## License
@@ -7,13 +7,14 @@ require 'loan_creator/version'
7
7
  module LoanCreator
8
8
  BIG_DECIMAL_DIGITS = 14
9
9
 
10
- autoload :ExcelFormulas, 'loan_creator/excel_formulas'
11
- autoload :BorrowerTimetable, 'loan_creator/borrower_timetable'
12
- autoload :Common, 'loan_creator/common'
13
- autoload :Standard, 'loan_creator/standard'
14
- autoload :Linear, 'loan_creator/linear'
15
- autoload :InFine, 'loan_creator/in_fine'
16
- autoload :Bullet, 'loan_creator/bullet'
17
- autoload :Timetable, 'loan_creator/timetable'
18
- autoload :Term, 'loan_creator/term'
10
+ autoload :ExcelFormulas, 'loan_creator/excel_formulas'
11
+ autoload :BorrowerTimetable, 'loan_creator/borrower_timetable'
12
+ autoload :Common, 'loan_creator/common'
13
+ autoload :Standard, 'loan_creator/standard'
14
+ autoload :Linear, 'loan_creator/linear'
15
+ autoload :InFine, 'loan_creator/in_fine'
16
+ autoload :Bullet, 'loan_creator/bullet'
17
+ autoload :Timetable, 'loan_creator/timetable'
18
+ autoload :Term, 'loan_creator/term'
19
+ autoload :UncapitalizedBullet, 'loan_creator/uncapitalized_bullet'
19
20
  end
@@ -7,6 +7,8 @@ module LoanCreator
7
7
  :period_capital,
8
8
  :total_paid_capital_end_of_period,
9
9
  :total_paid_interests_end_of_period,
10
+ :capitalized_interests_beginning_of_period,
11
+ :capitalized_interests_end_of_period,
10
12
  :period_amount_to_pay
11
13
  ].freeze
12
14
 
@@ -18,6 +20,7 @@ module LoanCreator
18
20
  end
19
21
 
20
22
  borrower_timetable = LoanCreator::Timetable.new(
23
+ starting_index: lenders_timetables.first.starting_index,
21
24
  starts_on: lenders_timetables.first.starts_on,
22
25
  period: lenders_timetables.first.period
23
26
  )
@@ -34,7 +37,7 @@ module LoanCreator
34
37
  term = BORROWER_FINANCIAL_ATTRIBUTES.each_with_object({}) do |k, h|
35
38
  h[k] = arr.inject(bigd('0')) { |sum, tt| sum + tt.send(k) }
36
39
  end
37
- borrower_timetable << LoanCreator::Term.new(all_zero.merge(term))
40
+ borrower_timetable << LoanCreator::Term.new(**all_zero.merge(term))
38
41
  end
39
42
  borrower_timetable
40
43
  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) }
11
11
  compute_last_term
12
12
  timetable << current_term
13
13
  timetable
@@ -16,25 +16,24 @@ 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
23
- @total_paid_interests_end_of_period = @period_interests
24
- @period_amount_to_pay = @period_capital + @period_interests
19
+ @crd_end_of_period = bigd('0')
20
+ @capitalized_interests_beginning_of_period = @capitalized_interests_end_of_period
21
+ @period_interests = @capitalized_interests_end_of_period + compute_capitalized_interests
22
+ @capitalized_interests_end_of_period = 0
23
+ @period_capital = @crd_beginning_of_period
24
+ @total_paid_capital_end_of_period = @period_capital
25
+ @total_paid_interests_end_of_period = @period_interests
26
+ @period_amount_to_pay = @period_capital + @period_interests
25
27
  end
26
28
 
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
- )
29
+ def compute_capitalized_interests
30
+ (amount + @capitalized_interests_beginning_of_period).mult(periodic_interests_rate, BIG_DECIMAL_DIGITS)
34
31
  end
35
32
 
36
- def total_interests
37
- total_payment - amount
33
+ def compute_term(timetable)
34
+ @capitalized_interests_beginning_of_period = @capitalized_interests_end_of_period
35
+ @capitalized_interests_end_of_period += compute_capitalized_interests
36
+ timetable << current_term
38
37
  end
39
38
  end
40
39
  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,87 @@ 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
+ if self.is_a?(LoanCreator::Bullet)
114
+ (@capitalized_interests_beginning_of_period = bigd(initial_values[:capitalized_interests] || 0))
115
+ end
116
+ end
117
+
93
118
  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
119
+ @accrued_delta_interests ||= bigd('0')
120
+ @total_paid_capital_end_of_period ||= bigd('0')
121
+ @total_paid_interests_end_of_period ||= bigd('0')
122
+ @capitalized_interests_beginning_of_period ||= bigd('0')
123
+ @crd_beginning_of_period = bigd('0')
124
+ @crd_end_of_period = bigd('0')
125
+ @period_theoric_interests = bigd('0')
126
+ @capitalized_interests_end_of_period = @capitalized_interests_beginning_of_period
127
+ @delta_interests = bigd('0')
128
+ @amount_to_add = bigd('0')
129
+ @period_interests = bigd('0')
130
+ @period_capital = bigd('0')
131
+ @period_amount_to_pay = bigd('0')
132
+ @due_on = nil
107
133
  end
108
134
 
109
135
  def current_term
110
136
  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,
120
- 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
137
+ crd_beginning_of_period: @crd_beginning_of_period,
138
+ crd_end_of_period: @crd_end_of_period,
139
+ period_theoric_interests: @period_theoric_interests,
140
+ delta_interests: @delta_interests,
141
+ accrued_delta_interests: @accrued_delta_interests,
142
+ capitalized_interests_beginning_of_period: @capitalized_interests_beginning_of_period,
143
+ capitalized_interests_end_of_period: @capitalized_interests_end_of_period,
144
+ amount_to_add: @amount_to_add,
145
+ period_interests: @period_interests,
146
+ period_capital: @period_capital,
147
+ total_paid_capital_end_of_period: @total_paid_capital_end_of_period,
148
+ total_paid_interests_end_of_period: @total_paid_interests_end_of_period,
149
+ period_amount_to_pay: @period_amount_to_pay,
150
+ due_on: @due_on,
151
+ index: compute_index
124
152
  )
125
153
  end
126
154
 
127
155
  def new_timetable
128
- LoanCreator::Timetable.new(starts_on: starts_on, period: period, interests_start_date: interests_start_date)
156
+ LoanCreator::Timetable.new(
157
+ starts_on: starts_on,
158
+ period: period,
159
+ interests_start_date: interests_start_date,
160
+ starting_index: @starting_index
161
+ )
162
+ end
163
+
164
+ def compute_index
165
+ @index ? (@starting_index + @index - 1) : nil
129
166
  end
130
167
 
131
168
  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
169
+ @crd_beginning_of_period = @crd_end_of_period
170
+ @period_theoric_interests = term_zero_interests
171
+ @delta_interests = @period_theoric_interests - @period_theoric_interests.round(2)
172
+ @accrued_delta_interests += @delta_interests
173
+ @period_interests = @period_theoric_interests.round(2)
174
+ @total_paid_interests_end_of_period += @period_interests
175
+ @period_amount_to_pay = @period_interests
176
+ @index = 0
140
177
  end
141
178
 
142
179
  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,12 @@ module LoanCreator
17
17
  # Accrued interests' delta
18
18
  :accrued_delta_interests,
19
19
 
20
+ # Capitalized interests at the beginning of the term (Bullet only)
21
+ :capitalized_interests_beginning_of_period,
22
+
23
+ # Capitalized interests at the end of the term (Bullet only)
24
+ :capitalized_interests_end_of_period,
25
+
20
26
  # Adjustment of -0.01, 0 or +0.01 cent depending on accrued_delta_interests
21
27
  :amount_to_add,
22
28
 
@@ -9,14 +9,15 @@ module LoanCreator
9
9
  year: {years: 1}
10
10
  }
11
11
 
12
- attr_reader :terms, :starts_on, :period #, :interests_start_date
12
+ attr_reader :terms, :starts_on, :period, :starting_index #, :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)
@@ -0,0 +1,34 @@
1
+ module LoanCreator
2
+ class UncapitalizedBullet < LoanCreator::Common
3
+ def lender_timetable
4
+ raise ArgumentError.new(:deferred_in_periods) unless deferred_in_periods == 0
5
+ raise ArgumentError.new(:interests_start_date) unless interests_start_date.nil?
6
+ timetable = new_timetable
7
+ reset_current_term
8
+ @crd_beginning_of_period = amount
9
+ @crd_end_of_period = amount
10
+ (duration_in_periods - 1).times { timetable << current_term }
11
+ compute_last_term
12
+ timetable << current_term
13
+ timetable
14
+ end
15
+
16
+ private
17
+
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
23
+ @total_paid_interests_end_of_period = @period_interests
24
+ @period_amount_to_pay = @period_capital + @period_interests
25
+ end
26
+
27
+ def total_interests
28
+ amount.mult(
29
+ bigd(periodic_interests_rate) * bigd(duration_in_periods),
30
+ BIG_DECIMAL_DIGITS
31
+ )
32
+ end
33
+ end
34
+ end
@@ -1,3 +1,3 @@
1
1
  module LoanCreator
2
- VERSION = '0.5.0'.freeze
2
+ VERSION = '0.7.1'.freeze
3
3
  end
@@ -5,11 +5,11 @@ require 'loan_creator/version'
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = 'loan_creator'
7
7
  spec.version = LoanCreator::VERSION
8
- spec.authors = %w[thibaulth nicob younes.serraj]
9
- spec.email = ['thibault@capsens.eu', 'nicolas.besnard@capsens.eu', 'younes.serraj@gmail.com']
8
+ spec.authors = ["thibaulth", "nicob", "younes.serraj", "Antoine Becquet", "Jerome Drevet"]
9
+ spec.email = ['thibault@capsens.eu', 'nicolas.besnard@capsens.eu', 'younes.serraj@gmail.com', "antoine@capsens.eu", "jerome@capsens.eu"]
10
10
 
11
11
  spec.summary = 'Create and update timetables from input data'
12
- spec.homepage = 'https://capsens.githost.io/capsens/loan-creator'
12
+ spec.homepage = 'https://github.com/CapSens/loan-creator'
13
13
  spec.license = 'MIT'
14
14
 
15
15
  spec.files = `git ls-files -z`.split("\x0").reject do |f|
@@ -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', '~> 1.13'
23
- spec.add_development_dependency 'rake', '~> 10.0'
22
+ spec.add_development_dependency 'bundler', '~> 2.1.4'
23
+ spec.add_development_dependency 'rake', '~> 12.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,16 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: loan_creator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.7.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - thibaulth
8
8
  - nicob
9
9
  - younes.serraj
10
+ - Antoine Becquet
11
+ - Jerome Drevet
10
12
  autorequire:
11
13
  bindir: exe
12
14
  cert_chain: []
13
- date: 2020-09-16 00:00:00.000000000 Z
15
+ date: 2021-01-11 00:00:00.000000000 Z
14
16
  dependencies:
15
17
  - !ruby/object:Gem::Dependency
16
18
  name: bundler
@@ -18,28 +20,28 @@ dependencies:
18
20
  requirements:
19
21
  - - "~>"
20
22
  - !ruby/object:Gem::Version
21
- version: '1.13'
23
+ version: 2.1.4
22
24
  type: :development
23
25
  prerelease: false
24
26
  version_requirements: !ruby/object:Gem::Requirement
25
27
  requirements:
26
28
  - - "~>"
27
29
  - !ruby/object:Gem::Version
28
- version: '1.13'
30
+ version: 2.1.4
29
31
  - !ruby/object:Gem::Dependency
30
32
  name: rake
31
33
  requirement: !ruby/object:Gem::Requirement
32
34
  requirements:
33
35
  - - "~>"
34
36
  - !ruby/object:Gem::Version
35
- version: '10.0'
37
+ version: '12.0'
36
38
  type: :development
37
39
  prerelease: false
38
40
  version_requirements: !ruby/object:Gem::Requirement
39
41
  requirements:
40
42
  - - "~>"
41
43
  - !ruby/object:Gem::Version
42
- version: '10.0'
44
+ version: '12.0'
43
45
  - !ruby/object:Gem::Dependency
44
46
  name: rspec
45
47
  requirement: !ruby/object:Gem::Requirement
@@ -115,17 +117,21 @@ email:
115
117
  - thibault@capsens.eu
116
118
  - nicolas.besnard@capsens.eu
117
119
  - younes.serraj@gmail.com
120
+ - antoine@capsens.eu
121
+ - jerome@capsens.eu
118
122
  executables: []
119
123
  extensions: []
120
124
  extra_rdoc_files: []
121
125
  files:
126
+ - ".circleci/config.yml"
122
127
  - ".gitignore"
123
- - ".gitlab-ci.yml"
124
128
  - ".rspec"
125
129
  - ".rubocop.yml"
126
130
  - ".ruby-gemset"
127
131
  - ".ruby-version"
128
132
  - ".travis.yml"
133
+ - CHANGELOG.md
134
+ - CODE_OF_CONDUCT.md
129
135
  - CapSens_Loan.xlsx
130
136
  - Gemfile
131
137
  - LICENSE.txt
@@ -144,9 +150,10 @@ files:
144
150
  - lib/loan_creator/standard.rb
145
151
  - lib/loan_creator/term.rb
146
152
  - lib/loan_creator/timetable.rb
153
+ - lib/loan_creator/uncapitalized_bullet.rb
147
154
  - lib/loan_creator/version.rb
148
155
  - loan_creator.gemspec
149
- homepage: https://capsens.githost.io/capsens/loan-creator
156
+ homepage: https://github.com/CapSens/loan-creator
150
157
  licenses:
151
158
  - MIT
152
159
  metadata: {}
@@ -165,8 +172,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
165
172
  - !ruby/object:Gem::Version
166
173
  version: '0'
167
174
  requirements: []
168
- rubyforge_project:
169
- rubygems_version: 2.5.2.3
175
+ rubygems_version: 3.1.2
170
176
  signing_key:
171
177
  specification_version: 4
172
178
  summary: Create and update timetables from input data
@@ -1,11 +0,0 @@
1
- rspec:
2
- image: "ruby:2.3"
3
- before_script:
4
- # COMMANDS
5
- - ruby -v
6
- - which ruby
7
- # BUNDLER
8
- - gem install bundler --no-ri --no-rdoc
9
- - bundle install --jobs $(nproc) "${FLAGS[@]}"
10
- script:
11
- - bundle exec rspec --color --format documentation