singapore_cpf_calculator 1.1.1 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.github/workflows/build.yml +33 -0
- data/Gemfile +1 -0
- data/README.md +17 -5
- data/lib/singapore_cpf_calculator/age_group.rb +60 -15
- data/lib/singapore_cpf_calculator/base_calculator.rb +60 -8
- data/lib/singapore_cpf_calculator/cpf_contribution.rb +14 -3
- data/lib/singapore_cpf_calculator/null_contribution_calculator.rb +4 -2
- data/lib/singapore_cpf_calculator/requirements/group_55_years_and_below.rb +13 -0
- data/lib/singapore_cpf_calculator/requirements/group_above_65_to_70_years.rb +13 -0
- data/lib/singapore_cpf_calculator/requirements/group_above_70_years.rb +13 -0
- data/lib/singapore_cpf_calculator/requirements.rb +4 -0
- data/lib/singapore_cpf_calculator/residency_module_common.rb +5 -1
- data/lib/singapore_cpf_calculator/version.rb +1 -1
- data/lib/singapore_cpf_calculator/year_2012_to_2015_aw_ceiling_module.rb +7 -0
- data/lib/singapore_cpf_calculator/year_2014/base.rb +1 -0
- data/lib/singapore_cpf_calculator/year_2014/citizen_or_spr_3/citzen_or_spr3_base.rb +8 -0
- data/lib/singapore_cpf_calculator/year_2015/base.rb +1 -0
- data/lib/singapore_cpf_calculator/year_2015/citizen_or_spr_3/age_50_below_contribution_calculator.rb +1 -1
- data/lib/singapore_cpf_calculator/year_2015/citizen_or_spr_3/age_50_to_55_contribution_calculator.rb +1 -1
- data/lib/singapore_cpf_calculator/year_2015/citizen_or_spr_3/age_55_to_60_contribution_calculator.rb +1 -1
- data/lib/singapore_cpf_calculator/year_2015/citizen_or_spr_3/age_60_to_65_contribution_calculator.rb +1 -1
- data/lib/singapore_cpf_calculator/year_2015/citizen_or_spr_3/age_65_up_contribution_calculator.rb +1 -1
- data/lib/singapore_cpf_calculator/year_2015/citizen_or_spr_3/citizen_or_spr3_base.rb +9 -0
- data/lib/singapore_cpf_calculator/year_2015/citizen_or_spr_3.rb +1 -0
- data/lib/singapore_cpf_calculator/year_2015.rb +1 -1
- data/lib/singapore_cpf_calculator/year_2016/base.rb +21 -0
- data/lib/singapore_cpf_calculator/year_2016/citizen_or_spr_3/age_55_below_contribution_calculator.rb +32 -0
- data/lib/singapore_cpf_calculator/year_2016/citizen_or_spr_3/age_55_to_60_contribution_calculator.rb +32 -0
- data/lib/singapore_cpf_calculator/year_2016/citizen_or_spr_3/age_60_to_65_contribution_calculator.rb +32 -0
- data/lib/singapore_cpf_calculator/year_2016/citizen_or_spr_3/age_65_up_contribution_calculator.rb +32 -0
- data/lib/singapore_cpf_calculator/year_2016/citizen_or_spr_3/citizen_or_spr3_base.rb +9 -0
- data/lib/singapore_cpf_calculator/year_2016/citizen_or_spr_3.rb +34 -0
- data/lib/singapore_cpf_calculator/year_2016/spr_1_fg/age_55_below_contribution_calculator.rb +32 -0
- data/lib/singapore_cpf_calculator/year_2016/spr_1_fg/age_55_to_60_contribution_calculator.rb +32 -0
- data/lib/singapore_cpf_calculator/year_2016/spr_1_fg/age_60_to_65_contribution_calculator.rb +32 -0
- data/lib/singapore_cpf_calculator/year_2016/spr_1_fg/age_65_up_contribution_calculator.rb +32 -0
- data/lib/singapore_cpf_calculator/year_2016/spr_1_fg.rb +35 -0
- data/lib/singapore_cpf_calculator/year_2016/spr_1_gg/age_55_below_contribution_calculator.rb +32 -0
- data/lib/singapore_cpf_calculator/year_2016/spr_1_gg/age_55_to_60_contribution_calculator.rb +14 -0
- data/lib/singapore_cpf_calculator/year_2016/spr_1_gg/age_60_to_65_contribution_calculator.rb +32 -0
- data/lib/singapore_cpf_calculator/year_2016/spr_1_gg/age_65_up_contribution_calculator.rb +14 -0
- data/lib/singapore_cpf_calculator/year_2016/spr_1_gg.rb +34 -0
- data/lib/singapore_cpf_calculator/year_2016/spr_2_fg/age_55_below_contribution_calculator.rb +32 -0
- data/lib/singapore_cpf_calculator/year_2016/spr_2_fg/age_55_to_60_contribution_calculator.rb +32 -0
- data/lib/singapore_cpf_calculator/year_2016/spr_2_fg/age_60_to_65_contribution_calculator.rb +32 -0
- data/lib/singapore_cpf_calculator/year_2016/spr_2_fg/age_65_up_contribution_calculator.rb +32 -0
- data/lib/singapore_cpf_calculator/year_2016/spr_2_fg.rb +34 -0
- data/lib/singapore_cpf_calculator/year_2016/spr_2_gg/age_55_below_contribution_calculator.rb +32 -0
- data/lib/singapore_cpf_calculator/year_2016/spr_2_gg/age_55_to_60_contribution_calculator.rb +32 -0
- data/lib/singapore_cpf_calculator/year_2016/spr_2_gg/age_60_to_65_contribution_calculator.rb +32 -0
- data/lib/singapore_cpf_calculator/year_2016/spr_2_gg/age_65_up_contribution_calculator.rb +32 -0
- data/lib/singapore_cpf_calculator/year_2016/spr_2_gg.rb +34 -0
- data/lib/singapore_cpf_calculator/year_2016.rb +38 -0
- data/lib/singapore_cpf_calculator/year_2022/citizen_or_spr_3/age_55_below_contribution_calculator.rb +8 -0
- data/lib/singapore_cpf_calculator/year_2022/citizen_or_spr_3/age_55_to_60_contribution_calculator.rb +32 -0
- data/lib/singapore_cpf_calculator/year_2022/citizen_or_spr_3/age_60_to_65_contribution_calculator.rb +32 -0
- data/lib/singapore_cpf_calculator/year_2022/citizen_or_spr_3/age_65_to_70_contribution_calculator.rb +32 -0
- data/lib/singapore_cpf_calculator/year_2022/citizen_or_spr_3/age_70_up_contribution_calculator.rb +32 -0
- data/lib/singapore_cpf_calculator/year_2022/citizen_or_spr_3/citizen_or_spr3_base.rb +9 -0
- data/lib/singapore_cpf_calculator/year_2022/citizen_or_spr_3.rb +40 -0
- data/lib/singapore_cpf_calculator/year_2022/spr_1_fg/age_55_below_contribution_calculator.rb +11 -0
- data/lib/singapore_cpf_calculator/year_2022/spr_1_fg/age_55_to_60_contribution_calculator.rb +32 -0
- data/lib/singapore_cpf_calculator/year_2022/spr_1_fg/age_60_to_65_contribution_calculator.rb +32 -0
- data/lib/singapore_cpf_calculator/year_2022/spr_1_fg/age_65_to_70_contribution_calculator.rb +32 -0
- data/lib/singapore_cpf_calculator/year_2022/spr_1_fg/age_70_up_contribution_calculator.rb +32 -0
- data/lib/singapore_cpf_calculator/year_2022/spr_1_fg.rb +40 -0
- data/lib/singapore_cpf_calculator/year_2022/spr_1_gg/age_55_below_contribution_calculator.rb +11 -0
- data/lib/singapore_cpf_calculator/year_2022/spr_1_gg/age_55_to_60_contribution_calculator.rb +12 -0
- data/lib/singapore_cpf_calculator/year_2022/spr_1_gg/age_60_to_65_contribution_calculator.rb +11 -0
- data/lib/singapore_cpf_calculator/year_2022/spr_1_gg/age_65_up_contribution_calculator.rb +14 -0
- data/lib/singapore_cpf_calculator/year_2022/spr_1_gg.rb +34 -0
- data/lib/singapore_cpf_calculator/year_2022/spr_2_fg/age_55_below_contribution_calculator.rb +11 -0
- data/lib/singapore_cpf_calculator/year_2022/spr_2_fg/age_55_to_60_contribution_calculator.rb +32 -0
- data/lib/singapore_cpf_calculator/year_2022/spr_2_fg/age_60_to_65_contribution_calculator.rb +32 -0
- data/lib/singapore_cpf_calculator/year_2022/spr_2_fg/age_65_to_70_contribution_calculator.rb +32 -0
- data/lib/singapore_cpf_calculator/year_2022/spr_2_fg/age_70_up_contribution_calculator.rb +32 -0
- data/lib/singapore_cpf_calculator/year_2022/spr_2_fg.rb +40 -0
- data/lib/singapore_cpf_calculator/year_2022/spr_2_gg/age_55_below_contribution_calculator.rb +11 -0
- data/lib/singapore_cpf_calculator/year_2022/spr_2_gg/age_55_to_60_contribution_calculator.rb +11 -0
- data/lib/singapore_cpf_calculator/year_2022/spr_2_gg/age_60_to_65_contribution_calculator.rb +11 -0
- data/lib/singapore_cpf_calculator/year_2022/spr_2_gg/age_65_up_contribution_calculator.rb +11 -0
- data/lib/singapore_cpf_calculator/year_2022/spr_2_gg.rb +34 -0
- data/lib/singapore_cpf_calculator/year_2022.rb +35 -0
- data/lib/singapore_cpf_calculator.rb +36 -15
- data/singapore_cpf_calculator.gemspec +3 -4
- data/spec/acceptance/company_a.csv +1367 -1365
- data/spec/acceptance/company_a_spec.rb +6 -4
- data/spec/singapore_cpf_calculator/age_group_spec.rb +15 -3
- data/spec/singapore_cpf_calculator/year_2014/citizen_or_spr_3/age_50_below_contribution_calculator_spec.rb +10 -10
- data/spec/singapore_cpf_calculator/year_2015/citizen_or_spr_3_spec.rb +45 -10
- data/spec/singapore_cpf_calculator/year_2015/spr_1_fg_spec.rb +10 -10
- data/spec/singapore_cpf_calculator/year_2015/spr_1_gg_spec.rb +11 -11
- data/spec/singapore_cpf_calculator/year_2015/spr_2_fg_spec.rb +11 -11
- data/spec/singapore_cpf_calculator/year_2015/spr_2_gg/age_55_to_60_contribution_calculator_spec.rb +8 -8
- data/spec/singapore_cpf_calculator/year_2015/spr_2_gg_spec.rb +11 -11
- data/spec/singapore_cpf_calculator/year_2015_spec.rb +3 -3
- data/spec/singapore_cpf_calculator/year_2016/citizen_or_spr_3/age_55_below_contribution_calculator_spec.rb +63 -0
- data/spec/singapore_cpf_calculator/year_2016/citizen_or_spr_3/age_55_to_60_contribution_calculator_spec.rb +63 -0
- data/spec/singapore_cpf_calculator/year_2016/citizen_or_spr_3/age_60_to_65_contribution_calculator_spec.rb +63 -0
- data/spec/singapore_cpf_calculator/year_2016/citizen_or_spr_3/age_65_up_contribution_calculator_spec.rb +63 -0
- data/spec/singapore_cpf_calculator/year_2016/citizen_or_spr_3_spec.rb +224 -0
- data/spec/singapore_cpf_calculator/year_2016/spr_1_fg/age_55_below_contribution_calculator_spec.rb +63 -0
- data/spec/singapore_cpf_calculator/year_2016/spr_1_fg/age_55_to_60_contribution_calculator_spec.rb +63 -0
- data/spec/singapore_cpf_calculator/year_2016/spr_1_fg/age_60_to_65_contribution_calculator_spec.rb +63 -0
- data/spec/singapore_cpf_calculator/year_2016/spr_1_fg/age_65_up_contribution_calculator_spec.rb +63 -0
- data/spec/singapore_cpf_calculator/year_2016/spr_1_fg_spec.rb +158 -0
- data/spec/singapore_cpf_calculator/year_2016/spr_1_gg/age_55_below_contribution_calculator_spec.rb +63 -0
- data/spec/singapore_cpf_calculator/year_2016/spr_1_gg/age_55_to_60_contribution_calculator_spec.rb +63 -0
- data/spec/singapore_cpf_calculator/year_2016/spr_1_gg/age_60_to_65_contribution_calculator_spec.rb +63 -0
- data/spec/singapore_cpf_calculator/year_2016/spr_1_gg/age_65_up_contribution_calculator_spec.rb +63 -0
- data/spec/singapore_cpf_calculator/year_2016/spr_1_gg_spec.rb +158 -0
- data/spec/singapore_cpf_calculator/year_2016/spr_2_fg/age_55_below_contribution_calculator_spec.rb +63 -0
- data/spec/singapore_cpf_calculator/year_2016/spr_2_fg/age_55_to_60_contribution_calculator_spec.rb +63 -0
- data/spec/singapore_cpf_calculator/year_2016/spr_2_fg/age_60_to_65_contribution_calculator_spec.rb +63 -0
- data/spec/singapore_cpf_calculator/year_2016/spr_2_fg/age_65_up_contribution_calculator_spec.rb +63 -0
- data/spec/singapore_cpf_calculator/year_2016/spr_2_fg_spec.rb +158 -0
- data/spec/singapore_cpf_calculator/year_2016/spr_2_gg/age_55_below_contribution_calculator_spec.rb +63 -0
- data/spec/singapore_cpf_calculator/year_2016/spr_2_gg/age_55_to_60_contribution_calculator_spec.rb +63 -0
- data/spec/singapore_cpf_calculator/year_2016/spr_2_gg/age_60_to_65_contribution_calculator_spec.rb +63 -0
- data/spec/singapore_cpf_calculator/year_2016/spr_2_gg/age_65_up_contribution_calculator_spec.rb +63 -0
- data/spec/singapore_cpf_calculator/year_2016/spr_2_gg_spec.rb +158 -0
- data/spec/singapore_cpf_calculator/year_2016_spec.rb +187 -0
- data/spec/singapore_cpf_calculator/year_2022/citizen_or_spr_3/age_55_below_contribution_calculator_spec.rb +63 -0
- data/spec/singapore_cpf_calculator/year_2022/citizen_or_spr_3/age_55_to_60_contribution_calculator_spec.rb +63 -0
- data/spec/singapore_cpf_calculator/year_2022/citizen_or_spr_3/age_60_to_65_contribution_calculator_spec.rb +63 -0
- data/spec/singapore_cpf_calculator/year_2022/citizen_or_spr_3/age_65_to_70_contribution_calculator_spec.rb +63 -0
- data/spec/singapore_cpf_calculator/year_2022/citizen_or_spr_3/age_70_up_contribution_spec.rb +63 -0
- data/spec/singapore_cpf_calculator/year_2022/citizen_or_spr_3_spec.rb +242 -0
- data/spec/singapore_cpf_calculator/year_2022/spr_1_fg/age_55_below_contribution_calculator_spec.rb +63 -0
- data/spec/singapore_cpf_calculator/year_2022/spr_1_fg/age_55_to_60_contribution_calculator_spec.rb +63 -0
- data/spec/singapore_cpf_calculator/year_2022/spr_1_fg/age_60_to_65_contribution_calculator_spec.rb +63 -0
- data/spec/singapore_cpf_calculator/year_2022/spr_1_fg/age_65_to_70_contribution_calculator_spec.rb +63 -0
- data/spec/singapore_cpf_calculator/year_2022/spr_1_fg/age_70_up_contribution_calculator_spec.rb +63 -0
- data/spec/singapore_cpf_calculator/year_2022/spr_1_fg_spec.rb +176 -0
- data/spec/singapore_cpf_calculator/year_2022/spr_1_gg/age_55_below_contribution_calculator_spec.rb +63 -0
- data/spec/singapore_cpf_calculator/year_2022/spr_1_gg/age_55_to_60_contribution_calculator_spec.rb +63 -0
- data/spec/singapore_cpf_calculator/year_2022/spr_1_gg/age_60_to_65_contribution_calculator_spec.rb +63 -0
- data/spec/singapore_cpf_calculator/year_2022/spr_1_gg/age_65_up_contribution_calculator_spec.rb +63 -0
- data/spec/singapore_cpf_calculator/year_2022/spr_1_gg_spec.rb +158 -0
- data/spec/singapore_cpf_calculator/year_2022/spr_2_fg/age_55_below_contribution_calculator_spec.rb +63 -0
- data/spec/singapore_cpf_calculator/year_2022/spr_2_fg/age_55_to_60_contribution_calculator_spec.rb +63 -0
- data/spec/singapore_cpf_calculator/year_2022/spr_2_fg/age_60_to_65_contribution_calculator_spec.rb +63 -0
- data/spec/singapore_cpf_calculator/year_2022/spr_2_fg/age_65_to_70_contribution_calculator_spec.rb +63 -0
- data/spec/singapore_cpf_calculator/year_2022/spr_2_fg/age_70_up_contribution_calculator_spec.rb +63 -0
- data/spec/singapore_cpf_calculator/year_2022/spr_2_fg_spec.rb +176 -0
- data/spec/singapore_cpf_calculator/year_2022/spr_2_gg/age_55_below_contribution_calculator_spec.rb +63 -0
- data/spec/singapore_cpf_calculator/year_2022/spr_2_gg/age_55_to_60_contribution_calculator_spec.rb +63 -0
- data/spec/singapore_cpf_calculator/year_2022/spr_2_gg/age_60_to_65_contribution_calculator_spec.rb +63 -0
- data/spec/singapore_cpf_calculator/year_2022/spr_2_gg/age_65_up_contribution_calculator_spec.rb +63 -0
- data/spec/singapore_cpf_calculator/year_2022/spr_2_gg_spec.rb +158 -0
- data/spec/singapore_cpf_calculator/year_2022_spec.rb +192 -0
- data/spec/singapore_cpf_calculator_spec.rb +87 -2
- data/spec/spec_helper.rb +17 -10
- metadata +183 -23
- data/circle.yml +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 6ab4079969915c3c23853647786c1c5efd8dc25d2d6a6eec899a0a1010507d4e
|
4
|
+
data.tar.gz: e3f883954c14bca4c37229c775569fdb35ea0b44214ead4e3f0d47c70f707d30
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5edca58bb84bb05da19a45ef8a55b24ba001f1127adbb62496248676a4bbd1851beae44b7ac462861278a951690017254ec8723c7b166bd1b718984c0b461a6f
|
7
|
+
data.tar.gz: e5bd02a156326d4439ba542d7222e8a274f543ccbe43fd01c1fafe305d570dd5f06d055005f1cd34b2adbd3174440401dd96a37960bba6f6f8af2ee5186dacce
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# This workflow uses actions that are not certified by GitHub.
|
2
|
+
# They are provided by a third-party and are governed by
|
3
|
+
# separate terms of service, privacy policy, and support
|
4
|
+
# documentation.
|
5
|
+
# This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
|
6
|
+
# For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
|
7
|
+
|
8
|
+
name: build
|
9
|
+
|
10
|
+
on: [push, pull_request]
|
11
|
+
|
12
|
+
jobs:
|
13
|
+
test:
|
14
|
+
runs-on: ubuntu-20.04
|
15
|
+
strategy:
|
16
|
+
fail-fast: false
|
17
|
+
matrix:
|
18
|
+
ruby:
|
19
|
+
- '3.1'
|
20
|
+
- '3.0'
|
21
|
+
- 2.7
|
22
|
+
- 2.6
|
23
|
+
- 2.5
|
24
|
+
- jruby-9.2.17.0
|
25
|
+
- jruby-9.3.3.0
|
26
|
+
|
27
|
+
steps:
|
28
|
+
- uses: actions/checkout@v2
|
29
|
+
- uses: ruby/setup-ruby@v1
|
30
|
+
with:
|
31
|
+
ruby-version: ${{ matrix.ruby }}
|
32
|
+
bundler-cache: true
|
33
|
+
- run: bundle exec rspec
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -11,6 +11,7 @@ Central Provident Fund (CPF) contributions.
|
|
11
11
|
|
12
12
|
## Support
|
13
13
|
|
14
|
+
* [Year 2022](https://www.cpf.gov.sg/content/dam/web/employer/employer-obligations/documents/CPFContributionRatesTable_1Jan2022.pdf)
|
14
15
|
* [Year 2015](http://mycpf.cpf.gov.sg/NR/rdonlyres/9F38419D-1342-4426-820E-32BA8FDE5C6D/0/CPFContributionandAllocationRatesfrom1January2015.pdf)
|
15
16
|
* Singapore Citizens or Singapore Permanent Residents (3rd Year Onwards)
|
16
17
|
* Singapore Permanent Residents (SPRs) during 1st Year of SPR Status
|
@@ -44,9 +45,10 @@ Or install it yourself as:
|
|
44
45
|
|
45
46
|
## Usage
|
46
47
|
|
47
|
-
Use {SingaporeCPFCalculator.calculate} to calculate for CPF contribution. The method
|
48
|
+
Use {SingaporeCPFCalculator.calculate} to calculate for CPF contribution. The method returns a
|
48
49
|
{SingaporeCPFCalculator::CPFContribution} object responding to {SingaporeCPFCalculator::CPFContribution#employee},
|
49
|
-
{SingaporeCPFCalculator::CPFContribution#employer}
|
50
|
+
{SingaporeCPFCalculator::CPFContribution#employer}, {SingaporeCPFCalculator::CPFContribution#total},
|
51
|
+
{SingaporeCPFCalculator::CPFContribution#ow_subject_to_cpf} and {SingaporeCPFCalculator::CPFContribution#aw_subject_to_cpf}.
|
50
52
|
|
51
53
|
```ruby
|
52
54
|
require "singapore_cpf_calculator"
|
@@ -58,12 +60,16 @@ Use {SingaporeCPFCalculator.calculate} to calculate for CPF contribution. The me
|
|
58
60
|
ordinary_wages: 700.00,
|
59
61
|
additional_wages: 252.00,
|
60
62
|
employee_contribution_type: "full",
|
61
|
-
employer_contribution_type: "full"
|
63
|
+
employer_contribution_type: "full",
|
64
|
+
ytd_additional_wages: 20_000,
|
65
|
+
ytd_ow_subject_to_cpf: 80_000
|
62
66
|
|
63
67
|
result # => #<SingaporeCPFCalculator::CPFContribution ...>
|
64
68
|
result.employee # => 190.00
|
65
69
|
result.employer # => 153.00
|
66
70
|
result.total # => 343.00
|
71
|
+
result.ow_subject_to_cpf # => 700.0 (the ordinary wages which were under the wage cap)
|
72
|
+
result.aw_subject_to_cpf # => 252.0 (the additional wages which were under the additional wage ceiling)
|
67
73
|
```
|
68
74
|
|
69
75
|
The following parameters needs to be specified:
|
@@ -78,15 +84,21 @@ The following parameters needs to be specified:
|
|
78
84
|
* required if the `residency_status` is `permanent_resident`
|
79
85
|
* see: [Year of Singapore Permanent Resident (SPR) Status](http://mycpf.cpf.gov.sg/NR/exeres/3D0D66F9-0085-4FD5-9CB5-35B55C0ADA53,frameless.htm)
|
80
86
|
* **ordinary_wages** :
|
81
|
-
* see : [ordinary wages definition](
|
87
|
+
* see : [ordinary wages definition](https://mycpf.cpf.gov.sg/Employers/EmployerGuides/employer-guides/hiring-employees/cpf-contributions-for-your-employees)
|
82
88
|
* **additional_wages** :
|
83
|
-
* see : [additional wages definition](
|
89
|
+
* see : [additional wages definition](https://mycpf.cpf.gov.sg/Employers/EmployerGuides/employer-guides/hiring-employees/cpf-contributions-for-your-employees)
|
84
90
|
* **employee\_contribution\_type** : type of rates to use for the employee's contribution
|
85
91
|
* accepted values : `"full"`, `"graduated"`
|
86
92
|
* note: *full* rates is not supported if the employer's contribution type is *graduated*
|
87
93
|
* **employer\_contribution\_type** : type of rates to use
|
88
94
|
* accepted values : `"full"`, `"graduated"` type of rates to use for the employer's contribution
|
89
95
|
* note: *graduated* rates is not supported if the employee's contribution type is *full*
|
96
|
+
* **ytd_additional_wages : Year to Date Additional Wages which were subject to CPF
|
97
|
+
* notes:
|
98
|
+
* this is for calculating the additional wage ceiling.
|
99
|
+
* **ytd_ow_subject_to_cpf: Year to Date Ordinary Wages which were subject to CPF
|
100
|
+
* notes:
|
101
|
+
* this is for calculating the additional wage ceiling.
|
90
102
|
|
91
103
|
## Contributing
|
92
104
|
|
@@ -11,46 +11,48 @@ module SingaporeCPFCalculator
|
|
11
11
|
# @param [Date] birthdate
|
12
12
|
# @return [Symbol] the symbol representation of the age group
|
13
13
|
# - :group_50_years_and_below
|
14
|
+
# - :group_55_years_and_below
|
14
15
|
# - :group_above_50_to_55_years
|
15
16
|
# - :group_above_55_to_60_years
|
16
17
|
# - :group_above_60_to_65_years
|
17
18
|
# - :group_above_65_years
|
18
|
-
|
19
|
-
|
19
|
+
# - :group_above_65_to_70_years
|
20
|
+
# - :group_above_70_years
|
21
|
+
def get(current_date, birthdate:, has_70_up: false)
|
22
|
+
new(current_date, birthdate: birthdate, has_70_up: has_70_up).get
|
20
23
|
end
|
21
24
|
end
|
22
25
|
|
23
26
|
# @param [Date] current_date
|
24
27
|
# @param [Date] birthdate:
|
25
|
-
def initialize(current_date, birthdate:)
|
28
|
+
def initialize(current_date, birthdate:, has_70_up:)
|
26
29
|
@current_date = current_date
|
27
30
|
@birthdate = birthdate
|
31
|
+
@has_70_up = has_70_up
|
28
32
|
end
|
29
33
|
|
30
34
|
# @return [Symbol] the symbol representation of the age group
|
31
35
|
# - :group_50_years_and_below
|
36
|
+
# - :group_55_years_and_below
|
32
37
|
# - :group_above_50_to_55_years
|
33
38
|
# - :group_above_55_to_60_years
|
34
39
|
# - :group_above_60_to_65_years
|
35
40
|
# - :group_above_65_years
|
41
|
+
# - :group_above_65_to_70_years
|
42
|
+
# - :group_above_70_years
|
36
43
|
def get
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
:group_above_55_to_60_years
|
44
|
-
when 60 <= age && age < 65
|
45
|
-
:group_above_60_to_65_years
|
46
|
-
else # 65 <= age
|
47
|
-
:group_above_65_years
|
44
|
+
if current_date.year <= 2015
|
45
|
+
age_grouping_for_2015_and_earlier
|
46
|
+
elsif current_date.year <= 2021 || !has_70_up
|
47
|
+
age_grouping_for_2016_and_later
|
48
|
+
else
|
49
|
+
age_grouping_for_2022_and_later
|
48
50
|
end
|
49
51
|
end
|
50
52
|
|
51
53
|
private
|
52
54
|
|
53
|
-
attr_reader :current_date, :birthdate
|
55
|
+
attr_reader :current_date, :birthdate, :has_70_up
|
54
56
|
|
55
57
|
def age
|
56
58
|
@age ||= effective_age
|
@@ -66,6 +68,49 @@ module SingaporeCPFCalculator
|
|
66
68
|
end
|
67
69
|
end
|
68
70
|
|
71
|
+
def age_grouping_for_2015_and_earlier
|
72
|
+
case
|
73
|
+
when age < 50
|
74
|
+
:group_50_years_and_below
|
75
|
+
when 50 <= age && age < 55
|
76
|
+
:group_above_50_to_55_years
|
77
|
+
when 55 <= age && age < 60
|
78
|
+
:group_above_55_to_60_years
|
79
|
+
when 60 <= age && age < 65
|
80
|
+
:group_above_60_to_65_years
|
81
|
+
else # 65 <= age
|
82
|
+
:group_above_65_years
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def age_grouping_for_2016_and_later
|
87
|
+
case
|
88
|
+
when age < 55
|
89
|
+
:group_55_years_and_below
|
90
|
+
when 55 <= age && age < 60
|
91
|
+
:group_above_55_to_60_years
|
92
|
+
when 60 <= age && age < 65
|
93
|
+
:group_above_60_to_65_years
|
94
|
+
else # 65 <= age
|
95
|
+
:group_above_65_years
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def age_grouping_for_2022_and_later
|
100
|
+
case
|
101
|
+
when age < 55
|
102
|
+
:group_55_years_and_below
|
103
|
+
when 55 <= age && age < 60
|
104
|
+
:group_above_55_to_60_years
|
105
|
+
when 60 <= age && age < 65
|
106
|
+
:group_above_60_to_65_years
|
107
|
+
when 65 <= age && age < 70
|
108
|
+
:group_above_65_to_70_years
|
109
|
+
else # 70 <= age
|
110
|
+
:group_above_70_years
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
69
114
|
end
|
70
115
|
|
71
116
|
end
|
@@ -5,8 +5,8 @@ module SingaporeCPFCalculator
|
|
5
5
|
class << self
|
6
6
|
# @param [Fixnum] age
|
7
7
|
# @return [true, false] returns true if the calculator applies to the employee's age.
|
8
|
-
def applies_to?(date, birthdate:)
|
9
|
-
AgeGroup.get(date, birthdate: birthdate) == required_age_group
|
8
|
+
def applies_to?(date, birthdate:, has_70_up:)
|
9
|
+
AgeGroup.get(date, birthdate: birthdate, has_70_up: has_70_up) == required_age_group
|
10
10
|
end
|
11
11
|
|
12
12
|
# @param [BigDecimal] ordinary_wages:
|
@@ -18,37 +18,57 @@ module SingaporeCPFCalculator
|
|
18
18
|
# month, such as annual bonus and leave pay. These and other incentive payments may be made at
|
19
19
|
# intervals of more than a month.
|
20
20
|
#
|
21
|
+
# @param [BigDecimal] ytd_additional_wages The year to date additional wages
|
22
|
+
# @param [BigDecimal] ytd_ow_subject_to_cpf The year to date ordinary wages
|
21
23
|
# @return [Hash] returns the total, employee, employer amounts for the CPF contribution
|
22
|
-
def calculate(ordinary_wages:, additional_wages:
|
23
|
-
|
24
|
+
def calculate(ordinary_wages:, additional_wages:, ytd_additional_wages: 0.0, ytd_ow_subject_to_cpf: 0.0,
|
25
|
+
estimated_yearly_ow: 0.0)
|
26
|
+
new(ordinary_wages: ordinary_wages, additional_wages: additional_wages,
|
27
|
+
ytd_ow_subject_to_cpf: ytd_ow_subject_to_cpf, ytd_additional_wages: ytd_additional_wages,
|
28
|
+
estimated_yearly_ow: estimated_yearly_ow).calculate
|
24
29
|
end
|
25
30
|
|
26
31
|
private
|
27
32
|
|
28
33
|
def required_age_group
|
34
|
+
# :nocov:
|
29
35
|
raise NotImplementedError, "sub classes needs to implement .required_age_group"
|
36
|
+
# :nocov:
|
30
37
|
end
|
31
38
|
end
|
32
39
|
|
33
|
-
def initialize(ordinary_wages:, additional_wages:
|
40
|
+
def initialize(ordinary_wages:, additional_wages:, ytd_additional_wages: 0.0, ytd_ow_subject_to_cpf: 0.0,
|
41
|
+
estimated_yearly_ow: 0.0)
|
34
42
|
@ordinary_wages = ordinary_wages
|
43
|
+
@ytd_ow_subject_to_cpf = ytd_ow_subject_to_cpf
|
44
|
+
@ytd_additional_wages = ytd_additional_wages
|
45
|
+
@estimated_yearly_ow = estimated_yearly_ow
|
35
46
|
@additional_wages = additional_wages
|
47
|
+
clip_additional_wages_based_on_ceiling()
|
36
48
|
end
|
37
49
|
|
38
50
|
# @return [Hash] returns the total, employee, employer amounts for the CPF contribution
|
39
51
|
def calculate
|
40
52
|
CPFContribution.new total: total_contribution,
|
41
|
-
employee: employee_contribution
|
53
|
+
employee: employee_contribution,
|
54
|
+
aw_subject_to_cpf: additional_wages,
|
55
|
+
ow_subject_to_cpf: capped_ordinary_wages
|
42
56
|
end
|
43
57
|
|
44
58
|
private
|
45
59
|
|
46
|
-
attr_reader :ordinary_wages, :additional_wages
|
60
|
+
attr_reader :ordinary_wages, :additional_wages, :ytd_additional_wages, :ytd_ow_subject_to_cpf,
|
61
|
+
:estimated_yearly_ow
|
47
62
|
|
48
63
|
def total_contribution
|
49
64
|
@total_contribution ||= calculated_total_contribution.round(0, :half_up)
|
50
65
|
end
|
51
66
|
|
67
|
+
# Steps to compute CPF contribution:
|
68
|
+
# a. Compute the total CPF contribution (rounded to the nearest dollar). An amount of 50 cents
|
69
|
+
# should be regarded as an additional dollar.
|
70
|
+
# b. Compute the employee’s share of CPF contribution (cents should be dropped)
|
71
|
+
# c. Employer’s share = Total contribution – Employee’s share
|
52
72
|
def employee_contribution
|
53
73
|
@employee_contribution ||= calculated_employee_contribution.round(0, :truncate)
|
54
74
|
end
|
@@ -61,6 +81,22 @@ module SingaporeCPFCalculator
|
|
61
81
|
ordinary_wages + additional_wages
|
62
82
|
end
|
63
83
|
|
84
|
+
def clip_additional_wages_based_on_ceiling
|
85
|
+
unless additional_wage_ceiling.blank?
|
86
|
+
@additional_wages = [additional_wages, calculated_remaining_wage_ceiling, estimated_remaining_wage_ceiling].min
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def calculated_remaining_wage_ceiling
|
91
|
+
max_remaining = additional_wage_ceiling - ytd_ow_subject_to_cpf - capped_ordinary_wages - ytd_additional_wages
|
92
|
+
[max_remaining, d('0.0')].max
|
93
|
+
end
|
94
|
+
|
95
|
+
def estimated_remaining_wage_ceiling
|
96
|
+
estimated_remaining = additional_wage_ceiling - estimated_yearly_ow - ytd_additional_wages
|
97
|
+
[estimated_remaining, d('0.0')].max
|
98
|
+
end
|
99
|
+
|
64
100
|
def calculated_total_contribution
|
65
101
|
case
|
66
102
|
when total_wages <= d("50.00")
|
@@ -85,29 +121,45 @@ module SingaporeCPFCalculator
|
|
85
121
|
end
|
86
122
|
end
|
87
123
|
|
124
|
+
# generally applies only to spr3 and citizens
|
125
|
+
def additional_wage_ceiling
|
126
|
+
nil
|
127
|
+
end
|
128
|
+
|
129
|
+
# TC Rate 1 is
|
88
130
|
def tc_rate_1
|
131
|
+
# :nocov:
|
89
132
|
raise NotImplementedError, "sub classes needs to implement #tc_rate_1"
|
133
|
+
# :nocov:
|
90
134
|
end
|
91
135
|
|
92
136
|
def tc_rate_2
|
137
|
+
# :nocov:
|
93
138
|
raise NotImplementedError, "sub classes needs to implement #tc_rate_2"
|
139
|
+
# :nocov:
|
94
140
|
end
|
95
141
|
|
96
142
|
def ec_rate
|
143
|
+
# :nocov:
|
97
144
|
raise NotImplementedError, "sub classes needs to implement #ec_rate"
|
145
|
+
# :nocov:
|
98
146
|
end
|
99
147
|
|
100
148
|
def adjustment_rate
|
149
|
+
# :nocov:
|
101
150
|
raise NotImplementedError, "sub classes needs to implement #adjustment_rate"
|
151
|
+
# :nocov:
|
102
152
|
end
|
103
153
|
|
104
154
|
def capped_ordinary_wages
|
155
|
+
# :nocov:
|
105
156
|
raise NotImplementedError, "sub classes needs to implement #capped_ordinary_wages"
|
157
|
+
# :nocov:
|
106
158
|
end
|
107
159
|
|
108
160
|
# precision helper
|
109
161
|
def d(val)
|
110
|
-
BigDecimal
|
162
|
+
BigDecimal(val)
|
111
163
|
end
|
112
164
|
|
113
165
|
end
|
@@ -4,13 +4,17 @@ module SingaporeCPFCalculator
|
|
4
4
|
class CPFContribution
|
5
5
|
|
6
6
|
# @return [BigDecimal]
|
7
|
-
attr_reader :total, :employee
|
7
|
+
attr_reader :total, :employee, :ow_subject_to_cpf, :aw_subject_to_cpf
|
8
8
|
|
9
9
|
# @param [BigDecimal] total the total contribution amount
|
10
10
|
# @param [BigDecimal] employee the employee contribution amount
|
11
|
-
|
11
|
+
# @param [BigDecimal] ow_subject_to_cpf Ordinary Wages which were subject to CPF
|
12
|
+
# @param [BigDecimal] aw_subject_to_cpf Additional Wages which were subject to CPF
|
13
|
+
def initialize(total:, employee:, ow_subject_to_cpf:, aw_subject_to_cpf:)
|
12
14
|
@total = total
|
13
15
|
@employee = employee
|
16
|
+
@ow_subject_to_cpf = ow_subject_to_cpf
|
17
|
+
@aw_subject_to_cpf = aw_subject_to_cpf
|
14
18
|
end
|
15
19
|
|
16
20
|
# @return [BigDecimal] difference between the total and employee contributions
|
@@ -21,7 +25,14 @@ module SingaporeCPFCalculator
|
|
21
25
|
# @param [CPFContribution] other
|
22
26
|
# @return [TrueClass, FalseClass]
|
23
27
|
def ==(other)
|
24
|
-
total == other.total && employee == other.employee
|
28
|
+
other.kind_of?(CPFContribution) && total == other.total && employee == other.employee &&
|
29
|
+
(ow_subject_to_cpf == other.ow_subject_to_cpf) &&
|
30
|
+
(aw_subject_to_cpf == other.aw_subject_to_cpf)
|
31
|
+
end
|
32
|
+
|
33
|
+
def inspect
|
34
|
+
{total: total.to_s, employee: employee.to_s,
|
35
|
+
ow_subject_to_cpf: ow_subject_to_cpf.to_s, aw_subject_to_cpf: aw_subject_to_cpf.to_s}.to_json
|
25
36
|
end
|
26
37
|
|
27
38
|
end
|
@@ -7,8 +7,10 @@ module SingaporeCPFCalculator
|
|
7
7
|
|
8
8
|
# returns zero value
|
9
9
|
def calculate(*)
|
10
|
-
CPFContribution.new total: BigDecimal
|
11
|
-
employee: BigDecimal
|
10
|
+
CPFContribution.new total: BigDecimal("0.0"),
|
11
|
+
employee: BigDecimal("0.0"),
|
12
|
+
ow_subject_to_cpf: BigDecimal('0.0'),
|
13
|
+
aw_subject_to_cpf: BigDecimal('0.0')
|
12
14
|
end
|
13
15
|
|
14
16
|
end
|
@@ -4,7 +4,11 @@ module SingaporeCPFCalculator
|
|
4
4
|
end
|
5
5
|
|
6
6
|
require_relative "requirements/group_50_years_and_below"
|
7
|
+
require_relative "requirements/group_55_years_and_below"
|
7
8
|
require_relative "requirements/group_above_50_to_55_years"
|
8
9
|
require_relative "requirements/group_above_55_to_60_years"
|
9
10
|
require_relative "requirements/group_above_60_to_65_years"
|
11
|
+
require_relative "requirements/group_above_65_to_70_years"
|
10
12
|
require_relative "requirements/group_above_65_years"
|
13
|
+
require_relative "requirements/group_above_70_years"
|
14
|
+
|
@@ -5,7 +5,11 @@ module SingaporeCPFCalculator
|
|
5
5
|
# @param [Date] birthdate
|
6
6
|
# @return [#calculator] returns the CPF calculator that matches the age.
|
7
7
|
def calculator_for(date, birthdate:)
|
8
|
-
calculators.find { |calculator| calculator.applies_to? date, birthdate: birthdate }
|
8
|
+
calculators.find { |calculator| calculator.applies_to? date, birthdate: birthdate, has_70_up: has_70_up }
|
9
|
+
end
|
10
|
+
|
11
|
+
def has_70_up
|
12
|
+
false
|
9
13
|
end
|
10
14
|
|
11
15
|
end
|
data/lib/singapore_cpf_calculator/year_2015/citizen_or_spr_3/age_50_below_contribution_calculator.rb
CHANGED
@@ -3,7 +3,7 @@ module SingaporeCPFCalculator
|
|
3
3
|
module CitizenOrSPR3
|
4
4
|
|
5
5
|
# Payment calculator for Singapore's Central Provident Fund for employee's age 50 and below.
|
6
|
-
class Age50BelowContributionCalculator <
|
6
|
+
class Age50BelowContributionCalculator < CitizenOrSpr3Base
|
7
7
|
|
8
8
|
extend Requirements::Group50YearsAndBelow
|
9
9
|
|
data/lib/singapore_cpf_calculator/year_2015/citizen_or_spr_3/age_50_to_55_contribution_calculator.rb
CHANGED
@@ -3,7 +3,7 @@ module SingaporeCPFCalculator
|
|
3
3
|
module CitizenOrSPR3
|
4
4
|
|
5
5
|
# Payment calculator for Singapore's Central Provident Fund for employee's age 50 to 55.
|
6
|
-
class Age50To55ContributionCalculator <
|
6
|
+
class Age50To55ContributionCalculator < CitizenOrSpr3Base
|
7
7
|
|
8
8
|
extend Requirements::GroupAbove50To55Years
|
9
9
|
|
data/lib/singapore_cpf_calculator/year_2015/citizen_or_spr_3/age_55_to_60_contribution_calculator.rb
CHANGED
@@ -3,7 +3,7 @@ module SingaporeCPFCalculator
|
|
3
3
|
module CitizenOrSPR3
|
4
4
|
|
5
5
|
# Payment calculator for Singapore's Central Provident Fund for employee's age 55 to 60.
|
6
|
-
class Age55To60ContributionCalculator <
|
6
|
+
class Age55To60ContributionCalculator < CitizenOrSpr3Base
|
7
7
|
|
8
8
|
extend Requirements::GroupAbove55To60Years
|
9
9
|
|
data/lib/singapore_cpf_calculator/year_2015/citizen_or_spr_3/age_60_to_65_contribution_calculator.rb
CHANGED
@@ -3,7 +3,7 @@ module SingaporeCPFCalculator
|
|
3
3
|
module CitizenOrSPR3
|
4
4
|
|
5
5
|
# Payment calculator for Singapore's Central Provident Fund for employee's age 60 to 65.
|
6
|
-
class Age60To65ContributionCalculator <
|
6
|
+
class Age60To65ContributionCalculator < CitizenOrSpr3Base
|
7
7
|
|
8
8
|
extend Requirements::GroupAbove60To65Years
|
9
9
|
|
data/lib/singapore_cpf_calculator/year_2015/citizen_or_spr_3/age_65_up_contribution_calculator.rb
CHANGED
@@ -3,7 +3,7 @@ module SingaporeCPFCalculator
|
|
3
3
|
module CitizenOrSPR3
|
4
4
|
|
5
5
|
# Payment calculator for Singapore's Central Provident Fund for employee's age 65 and above.
|
6
|
-
class Age65UpContributionCalculator <
|
6
|
+
class Age65UpContributionCalculator < CitizenOrSpr3Base
|
7
7
|
|
8
8
|
extend Requirements::GroupAbove65Years
|
9
9
|
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require_relative 'citizen_or_spr_3/citizen_or_spr3_base'
|
1
2
|
require_relative "citizen_or_spr_3/age_50_below_contribution_calculator"
|
2
3
|
require_relative "citizen_or_spr_3/age_50_to_55_contribution_calculator"
|
3
4
|
require_relative "citizen_or_spr_3/age_55_to_60_contribution_calculator"
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module SingaporeCPFCalculator
|
2
|
+
module Year2016
|
3
|
+
|
4
|
+
# Base class for 2014 CPF calculators.
|
5
|
+
class Base < BaseCalculator
|
6
|
+
|
7
|
+
private
|
8
|
+
|
9
|
+
def additional_wage_ceiling
|
10
|
+
d('102_000')
|
11
|
+
end
|
12
|
+
|
13
|
+
def capped_ordinary_wages
|
14
|
+
[d("6_000"), ordinary_wages].min
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|