amortizy 1.0.0 → 2.0.0

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
  SHA256:
3
- metadata.gz: '098cde951446da868e5cc5790b832794a09dd7ba991ffb34125f02053e59489e'
4
- data.tar.gz: 923b3440f1046b7c0c92483997c24934623f234c5e47f78333b9d87ca8536bfa
3
+ metadata.gz: e1bf3cd11455f5c2c301066d64f911a15e696dd1b033c2b865a5d7ddaff93e05
4
+ data.tar.gz: 34482d2f3553108c4ad04d3dd238ff486e3c72aa266fd4f19582607720df98ff
5
5
  SHA512:
6
- metadata.gz: 01c8a63684018625527eb633d6b7febc03b92d37ed20221b6138dc66080908ba4d5a0ef4649ae65172cbe67a9d1cb6c455ad70d95804ef9b64e9df083c75ec1b
7
- data.tar.gz: d57d565cf0631f7f7016776111b1c1fe680549ae1a7583f30ba2c0cdf7b44bf2650e029a43e1593368f162c9209c1c5bca2d93c3eb5e7e95e96c98571b5d2de8
6
+ metadata.gz: e1d49aaa154f7dbce6a7f5e9fddf77c04a4f6ea90af9662b4cfa1c6ed787a70672277cd6a8425346277067fef6af76ac2d3ec32ddfd2f7b3d972f049cdd43846
7
+ data.tar.gz: 94aaf0a040ba624cedc10ea49db5a873712b8682a6f6191439088eb02df8f74d27bb86c14cb9288607a51217d9f091ab643b3d4108fb83b3e04dcf8e28a11dd3
data/CHANGELOG.md CHANGED
@@ -1,5 +1,144 @@
1
- ## [Unreleased]
1
+ # Changelog
2
2
 
3
- ## [0.1.0] - 2025-12-02
3
+ All notable changes to this project will be documented in this file.
4
4
 
5
- - Initial release
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [2.0.0] - 2026-04-19
9
+
10
+ ### Added
11
+
12
+ #### Dynamic Payment Engine
13
+ - **Monthly payment frequency** - the most common loan payment type, now supported
14
+ - **Bi-weekly payment frequency** - every 14 days
15
+ - **`num_payments` input** - specify exact payment count instead of term length
16
+ - **Any term length** - no longer restricted to 6, 9, 12, 15, 18 months
17
+ - Dynamic payment count calculation based on frequency and term
18
+
19
+ #### Public API
20
+ - `#schedule` - returns frozen array of payment hashes (replaces private `generate_schedule_data`)
21
+ - `#summary` - returns hash with loan totals, dates, and payment info
22
+ - `#end_date` - last payment date
23
+ - `#total_interest` - sum of all interest payments
24
+ - `#total_paid` - sum of all payments
25
+ - `#payment_amount` - regular payment amount
26
+
27
+ #### Code Organization
28
+ - Extracted `ConsoleFormatter` for terminal output
29
+ - Extracted `CsvFormatter` for CSV export
30
+ - Engine class now focused on amortization math only
31
+
32
+ ### Changed
33
+ - `term_months` is now optional (provide `term_months` OR `num_payments`, not both)
34
+ - Removed hardcoded payment count lookup table - all counts calculated dynamically
35
+ - Minimum Ruby version bumped to 3.0
36
+
37
+ ### Breaking Changes
38
+ - `term_months` is no longer a required keyword argument
39
+ - **Daily frequency payment counts changed significantly.** v1.0 used a hardcoded lookup table with business-day-approximate counts (e.g., 248 payments for 12 months). v2.0 calculates dynamically using calendar days (365 for 12 months) unless `bank_days_only: true` is set. This is a ~47% increase in payment count for daily-frequency loans without `bank_days_only`. If your application relied on v1.0 daily payment counts, set `bank_days_only: true` to get business-day counts, or use `num_payments` to specify the exact count.
40
+ - Weekly frequency payment counts may differ by 0-1 due to rounding in dynamic calculation
41
+ - `principal` must now be positive (zero and negative values raise `ArgumentError`)
42
+
43
+ ## [1.0.0] - 2024-12-02
44
+
45
+ ### Added
46
+
47
+ #### Core Features
48
+ - Initial release of Amortizy gem
49
+ - Daily payment frequency support
50
+ - Weekly payment frequency support
51
+ - Flexible loan terms: 6, 9, 12, 15, and 18 months
52
+ - Simple interest calculation method (accrued daily)
53
+ - Precomputed interest calculation method (fixed per payment)
54
+
55
+ #### Advanced Loan Features
56
+ - Grace period handling with automatic interest capitalization
57
+ - Interest-only payment periods
58
+ - Origination fee support (added to principal)
59
+ - Additional fee support with three treatment options:
60
+ - Distributed across all payments
61
+ - Added to principal upfront
62
+ - Collected as separate first payment
63
+
64
+ #### Bank Day Calculations
65
+ - Weekend skipping (Saturday/Sunday)
66
+ - US Federal Reserve holiday support (11 holidays)
67
+ - Automatic weekend observation rules for holidays
68
+
69
+ #### Output Options
70
+ - Console output with formatted tables
71
+ - CSV export functionality
72
+ - Programmatic access to schedule data
73
+
74
+ #### Testing
75
+ - Comprehensive RSpec test suite with 29 test cases
76
+ - 100% test pass rate
77
+ - Coverage of all features and edge cases
78
+
79
+ #### Documentation
80
+ - Complete README with API reference
81
+ - Usage examples for common scenarios
82
+ - Detailed parameter documentation
83
+ - Contributing guidelines
84
+
85
+ ### Dependencies
86
+ - holidays gem (~> 8.0) for federal holiday detection
87
+ - RSpec (~> 3.0) for testing
88
+
89
+ ### Requirements
90
+ - Ruby 2.7 or higher
91
+
92
+ ---
93
+
94
+ ## Version History
95
+
96
+ ### [1.0.0] - 2024-12-02
97
+ Initial public release
98
+
99
+ ---
100
+
101
+ ## Upgrade Guide
102
+
103
+ ### From Pre-release to 1.0.0
104
+
105
+ If you were testing pre-release versions, upgrade by:
106
+
107
+ ```bash
108
+ gem uninstall amortizy
109
+ gem install amortizy
110
+ ```
111
+
112
+ Or in your Gemfile:
113
+
114
+ ```ruby
115
+ gem 'amortizy', '~> 1.0'
116
+ ```
117
+
118
+ Then run:
119
+
120
+ ```bash
121
+ bundle update amortizy
122
+ ```
123
+
124
+ ---
125
+
126
+ ## Future Plans
127
+
128
+ Potential features for future releases:
129
+
130
+ - Additional payment frequencies (monthly, bi-weekly)
131
+ - More interest calculation methods
132
+ - Support for additional holiday calendars (state, international)
133
+ - Balloon payment support
134
+ - Variable interest rates
135
+ - Payment modification capabilities
136
+ - Enhanced reporting formats
137
+
138
+ ---
139
+
140
+ ## Links
141
+
142
+ - [RubyGems](https://rubygems.org/gems/amortizy)
143
+ - [GitHub Repository](https://github.com/zapatify/amortizy)
144
+ - [Issue Tracker](https://github.com/zapatify/amortizy/issues)
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,290 @@
1
+ # Contributing to Amortizy
2
+
3
+ First off, thank you for considering contributing to Amortizy! It's people like you that make Amortizy such a great tool.
4
+
5
+ ## Code of Conduct
6
+
7
+ This project and everyone participating in it is governed by the principle of respect and professionalism. By participating, you are expected to uphold this standard.
8
+
9
+ ## How Can I Contribute?
10
+
11
+ ### Reporting Bugs
12
+
13
+ Before creating bug reports, please check the [existing issues](https://github.com/zapatify/amortizy/issues) to avoid duplicates.
14
+
15
+ When you are creating a bug report, please include as many details as possible:
16
+
17
+ * **Use a clear and descriptive title**
18
+ * **Describe the exact steps to reproduce the problem**
19
+ * **Provide specific examples** - Include code snippets, loan parameters, or output
20
+ * **Describe the behavior you observed** and what you expected to see
21
+ * **Include your environment details**:
22
+ - Ruby version (`ruby -v`)
23
+ - Amortizy version (`gem list amortizy`)
24
+ - Operating system
25
+
26
+ **Example Bug Report:**
27
+
28
+ ```
29
+ Title: Grace period interest not capitalizing correctly for weekly frequency
30
+
31
+ Description:
32
+ When using weekly payment frequency with a 7-day grace period, the interest
33
+ is not being properly capitalized into the principal.
34
+
35
+ Steps to Reproduce:
36
+ 1. Create schedule with weekly frequency
37
+ 2. Set grace_period_days to 7
38
+ 3. Generate schedule
39
+ 4. Check effective principal
40
+
41
+ Expected: Principal should increase by ~7 days of interest
42
+ Actual: Principal remains unchanged
43
+
44
+ Environment:
45
+ - Ruby 3.2.0
46
+ - Amortizy 1.0.0
47
+ - macOS Sonoma
48
+ ```
49
+
50
+ ### Suggesting Enhancements
51
+
52
+ Enhancement suggestions are tracked as GitHub issues. When creating an enhancement suggestion, please include:
53
+
54
+ * **Use a clear and descriptive title**
55
+ * **Provide a detailed description** of the suggested enhancement
56
+ * **Explain why this enhancement would be useful** to most Amortizy users
57
+ * **List any similar features** in other tools if applicable
58
+
59
+ **Example Enhancement Request:**
60
+
61
+ ```
62
+ Title: Add monthly payment frequency option
63
+
64
+ Description:
65
+ Currently Amortizy supports daily and weekly frequencies. Adding monthly
66
+ would be useful for traditional mortgage-style loans.
67
+
68
+ Use Case:
69
+ Many personal and business loans use monthly payments. This would make
70
+ Amortizy useful for a broader range of applications.
71
+
72
+ Similar Features:
73
+ - Most online loan calculators support monthly
74
+ - Banking systems typically use monthly
75
+ ```
76
+
77
+ ### Pull Requests
78
+
79
+ Pull requests are the best way to propose changes to the codebase.
80
+
81
+ 1. **Fork the repo** and create your branch from `main`
82
+ 2. **Make your changes**
83
+ 3. **Add tests** if you've added code that should be tested
84
+ 4. **Ensure the test suite passes** (`bundle exec rspec`)
85
+ 5. **Update documentation** if needed
86
+ 6. **Write a clear commit message**
87
+ 7. **Open a Pull Request**
88
+
89
+ #### Pull Request Guidelines
90
+
91
+ * Follow the existing code style
92
+ * Write clear, descriptive commit messages
93
+ * Include tests for new functionality
94
+ * Update README.md if adding features
95
+ * Update CHANGELOG.md under [Unreleased]
96
+ * Keep PRs focused - one feature/fix per PR
97
+
98
+ **Example PR Description:**
99
+
100
+ ```
101
+ ## Description
102
+ Adds support for bi-weekly payment frequency
103
+
104
+ ## Changes
105
+ - Added :biweekly to frequency validation
106
+ - Updated payment calculations for bi-weekly schedules
107
+ - Added tests for bi-weekly frequency
108
+ - Updated README with bi-weekly examples
109
+
110
+ ## Testing
111
+ - All existing tests pass
112
+ - Added 3 new tests for bi-weekly functionality
113
+ - Manually tested with various loan parameters
114
+
115
+ ## Documentation
116
+ - Updated README.md with bi-weekly examples
117
+ - Updated API reference table
118
+ - Added to CHANGELOG.md
119
+ ```
120
+
121
+ ## Development Setup
122
+
123
+ ### Prerequisites
124
+
125
+ ```bash
126
+ # Install Ruby 2.7 or higher
127
+ ruby -v
128
+
129
+ # Install Bundler
130
+ gem install bundler
131
+ ```
132
+
133
+ ### Setup
134
+
135
+ ```bash
136
+ # Clone your fork
137
+ git clone https://github.com/YOUR_USERNAME/amortizy.git
138
+ cd amortizy
139
+
140
+ # Install dependencies
141
+ bundle install
142
+
143
+ # Run tests
144
+ bundle exec rspec
145
+
146
+ # Run the CLI
147
+ bundle exec exe/amortizy
148
+ ```
149
+
150
+ ### Running Tests
151
+
152
+ ```bash
153
+ # Run all tests
154
+ bundle exec rspec
155
+
156
+ # Run specific test file
157
+ bundle exec rspec spec/engine_spec.rb
158
+
159
+ # Run with coverage (if configured)
160
+ COVERAGE=true bundle exec rspec
161
+ ```
162
+
163
+ ### Code Style
164
+
165
+ * Follow Ruby community style guidelines
166
+ * Use 2 spaces for indentation (not tabs)
167
+ * Keep lines under 100 characters when reasonable
168
+ * Use meaningful variable and method names
169
+ * Add comments for complex logic
170
+
171
+ **Good Example:**
172
+ ```ruby
173
+ def calculate_daily_interest(principal, annual_rate)
174
+ # Convert annual rate to daily and multiply by principal
175
+ (principal * annual_rate) / 365.0
176
+ end
177
+ ```
178
+
179
+ **Bad Example:**
180
+ ```ruby
181
+ def calc(p,r)
182
+ p*r/365.0 # calculate interest
183
+ end
184
+ ```
185
+
186
+ ## Project Structure
187
+
188
+ ```
189
+ amortizy/
190
+ ├── lib/
191
+ │ ├── amortizy.rb # Main entry point
192
+ │ └── amortizy/
193
+ │ ├── version.rb # Version number
194
+ │ └── engine.rb # Core logic
195
+ ├── spec/
196
+ │ ├── spec_helper.rb # RSpec configuration
197
+ │ └── engine_spec.rb # Main test file
198
+ └── amortizy.gemspec # Gem specification
199
+ ```
200
+
201
+ ## Testing Guidelines
202
+
203
+ ### Writing Tests
204
+
205
+ * Use descriptive test names
206
+ * Follow Arrange-Act-Assert pattern
207
+ * Test both happy paths and edge cases
208
+ * Mock external dependencies when appropriate
209
+
210
+ **Example Test:**
211
+ ```ruby
212
+ describe 'grace period' do
213
+ it 'capitalizes interest during grace period' do
214
+ # Arrange
215
+ schedule = Amortizy::AmortizationSchedule.new(
216
+ start_date: "2025-01-15",
217
+ principal: 100000.00,
218
+ term_months: 12,
219
+ annual_rate: 10.0,
220
+ frequency: :daily,
221
+ grace_period_days: 5
222
+ )
223
+
224
+ # Act
225
+ effective_principal = schedule.send(:effective_principal)
226
+
227
+ # Assert
228
+ expect(effective_principal).to be > 100000.00
229
+ expect(effective_principal).to be < 100200.00
230
+ end
231
+ end
232
+ ```
233
+
234
+ ## Commit Message Guidelines
235
+
236
+ Write clear, concise commit messages that explain what and why:
237
+
238
+ ```bash
239
+ # Good commit messages
240
+ git commit -m "Add bi-weekly payment frequency support"
241
+ git commit -m "Fix interest calculation for leap years"
242
+ git commit -m "Update README with precomputed interest examples"
243
+
244
+ # Bad commit messages
245
+ git commit -m "fix bug"
246
+ git commit -m "updates"
247
+ git commit -m "wip"
248
+ ```
249
+
250
+ For larger commits, use multi-line messages:
251
+
252
+ ```bash
253
+ git commit -m "Add support for adjustable rate mortgages
254
+
255
+ - Add rate_changes parameter to accept rate change schedule
256
+ - Update interest calculation to handle variable rates
257
+ - Add comprehensive tests for ARM scenarios
258
+ - Update documentation with ARM examples
259
+
260
+ Closes #42"
261
+ ```
262
+
263
+ ## Documentation
264
+
265
+ When adding features, update:
266
+
267
+ 1. **README.md** - Add usage examples
268
+ 2. **CHANGELOG.md** - Add to [Unreleased] section
269
+ 3. **Code comments** - Explain complex logic
270
+ 4. **RDoc/YARD** - Document public methods (if applicable)
271
+
272
+ ## Release Process
273
+
274
+ (For maintainers)
275
+
276
+ 1. Update version in `lib/amortizy/version.rb`
277
+ 2. Update CHANGELOG.md with release date
278
+ 3. Commit changes: `git commit -am "Bump version to X.Y.Z"`
279
+ 4. Create tag: `git tag -a vX.Y.Z -m "Version X.Y.Z"`
280
+ 5. Push: `git push && git push --tags`
281
+ 6. Build: `gem build amortizy.gemspec`
282
+ 7. Publish: `gem push amortizy-X.Y.Z.gem`
283
+
284
+ ## Questions?
285
+
286
+ Feel free to open an issue with the label "question" or reach out to the maintainers.
287
+
288
+ ## Thank You!
289
+
290
+ Your contributions to open source, large or small, make projects like this possible. Thank you for taking the time to contribute.
data/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2025 Zapata
3
+ Copyright (c) 2025 Rich Zapata
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal