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.
Files changed (156) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/build.yml +33 -0
  3. data/Gemfile +1 -0
  4. data/README.md +17 -5
  5. data/lib/singapore_cpf_calculator/age_group.rb +60 -15
  6. data/lib/singapore_cpf_calculator/base_calculator.rb +60 -8
  7. data/lib/singapore_cpf_calculator/cpf_contribution.rb +14 -3
  8. data/lib/singapore_cpf_calculator/null_contribution_calculator.rb +4 -2
  9. data/lib/singapore_cpf_calculator/requirements/group_55_years_and_below.rb +13 -0
  10. data/lib/singapore_cpf_calculator/requirements/group_above_65_to_70_years.rb +13 -0
  11. data/lib/singapore_cpf_calculator/requirements/group_above_70_years.rb +13 -0
  12. data/lib/singapore_cpf_calculator/requirements.rb +4 -0
  13. data/lib/singapore_cpf_calculator/residency_module_common.rb +5 -1
  14. data/lib/singapore_cpf_calculator/version.rb +1 -1
  15. data/lib/singapore_cpf_calculator/year_2012_to_2015_aw_ceiling_module.rb +7 -0
  16. data/lib/singapore_cpf_calculator/year_2014/base.rb +1 -0
  17. data/lib/singapore_cpf_calculator/year_2014/citizen_or_spr_3/citzen_or_spr3_base.rb +8 -0
  18. data/lib/singapore_cpf_calculator/year_2015/base.rb +1 -0
  19. data/lib/singapore_cpf_calculator/year_2015/citizen_or_spr_3/age_50_below_contribution_calculator.rb +1 -1
  20. data/lib/singapore_cpf_calculator/year_2015/citizen_or_spr_3/age_50_to_55_contribution_calculator.rb +1 -1
  21. data/lib/singapore_cpf_calculator/year_2015/citizen_or_spr_3/age_55_to_60_contribution_calculator.rb +1 -1
  22. data/lib/singapore_cpf_calculator/year_2015/citizen_or_spr_3/age_60_to_65_contribution_calculator.rb +1 -1
  23. data/lib/singapore_cpf_calculator/year_2015/citizen_or_spr_3/age_65_up_contribution_calculator.rb +1 -1
  24. data/lib/singapore_cpf_calculator/year_2015/citizen_or_spr_3/citizen_or_spr3_base.rb +9 -0
  25. data/lib/singapore_cpf_calculator/year_2015/citizen_or_spr_3.rb +1 -0
  26. data/lib/singapore_cpf_calculator/year_2015.rb +1 -1
  27. data/lib/singapore_cpf_calculator/year_2016/base.rb +21 -0
  28. data/lib/singapore_cpf_calculator/year_2016/citizen_or_spr_3/age_55_below_contribution_calculator.rb +32 -0
  29. data/lib/singapore_cpf_calculator/year_2016/citizen_or_spr_3/age_55_to_60_contribution_calculator.rb +32 -0
  30. data/lib/singapore_cpf_calculator/year_2016/citizen_or_spr_3/age_60_to_65_contribution_calculator.rb +32 -0
  31. data/lib/singapore_cpf_calculator/year_2016/citizen_or_spr_3/age_65_up_contribution_calculator.rb +32 -0
  32. data/lib/singapore_cpf_calculator/year_2016/citizen_or_spr_3/citizen_or_spr3_base.rb +9 -0
  33. data/lib/singapore_cpf_calculator/year_2016/citizen_or_spr_3.rb +34 -0
  34. data/lib/singapore_cpf_calculator/year_2016/spr_1_fg/age_55_below_contribution_calculator.rb +32 -0
  35. data/lib/singapore_cpf_calculator/year_2016/spr_1_fg/age_55_to_60_contribution_calculator.rb +32 -0
  36. data/lib/singapore_cpf_calculator/year_2016/spr_1_fg/age_60_to_65_contribution_calculator.rb +32 -0
  37. data/lib/singapore_cpf_calculator/year_2016/spr_1_fg/age_65_up_contribution_calculator.rb +32 -0
  38. data/lib/singapore_cpf_calculator/year_2016/spr_1_fg.rb +35 -0
  39. data/lib/singapore_cpf_calculator/year_2016/spr_1_gg/age_55_below_contribution_calculator.rb +32 -0
  40. data/lib/singapore_cpf_calculator/year_2016/spr_1_gg/age_55_to_60_contribution_calculator.rb +14 -0
  41. data/lib/singapore_cpf_calculator/year_2016/spr_1_gg/age_60_to_65_contribution_calculator.rb +32 -0
  42. data/lib/singapore_cpf_calculator/year_2016/spr_1_gg/age_65_up_contribution_calculator.rb +14 -0
  43. data/lib/singapore_cpf_calculator/year_2016/spr_1_gg.rb +34 -0
  44. data/lib/singapore_cpf_calculator/year_2016/spr_2_fg/age_55_below_contribution_calculator.rb +32 -0
  45. data/lib/singapore_cpf_calculator/year_2016/spr_2_fg/age_55_to_60_contribution_calculator.rb +32 -0
  46. data/lib/singapore_cpf_calculator/year_2016/spr_2_fg/age_60_to_65_contribution_calculator.rb +32 -0
  47. data/lib/singapore_cpf_calculator/year_2016/spr_2_fg/age_65_up_contribution_calculator.rb +32 -0
  48. data/lib/singapore_cpf_calculator/year_2016/spr_2_fg.rb +34 -0
  49. data/lib/singapore_cpf_calculator/year_2016/spr_2_gg/age_55_below_contribution_calculator.rb +32 -0
  50. data/lib/singapore_cpf_calculator/year_2016/spr_2_gg/age_55_to_60_contribution_calculator.rb +32 -0
  51. data/lib/singapore_cpf_calculator/year_2016/spr_2_gg/age_60_to_65_contribution_calculator.rb +32 -0
  52. data/lib/singapore_cpf_calculator/year_2016/spr_2_gg/age_65_up_contribution_calculator.rb +32 -0
  53. data/lib/singapore_cpf_calculator/year_2016/spr_2_gg.rb +34 -0
  54. data/lib/singapore_cpf_calculator/year_2016.rb +38 -0
  55. data/lib/singapore_cpf_calculator/year_2022/citizen_or_spr_3/age_55_below_contribution_calculator.rb +8 -0
  56. data/lib/singapore_cpf_calculator/year_2022/citizen_or_spr_3/age_55_to_60_contribution_calculator.rb +32 -0
  57. data/lib/singapore_cpf_calculator/year_2022/citizen_or_spr_3/age_60_to_65_contribution_calculator.rb +32 -0
  58. data/lib/singapore_cpf_calculator/year_2022/citizen_or_spr_3/age_65_to_70_contribution_calculator.rb +32 -0
  59. data/lib/singapore_cpf_calculator/year_2022/citizen_or_spr_3/age_70_up_contribution_calculator.rb +32 -0
  60. data/lib/singapore_cpf_calculator/year_2022/citizen_or_spr_3/citizen_or_spr3_base.rb +9 -0
  61. data/lib/singapore_cpf_calculator/year_2022/citizen_or_spr_3.rb +40 -0
  62. data/lib/singapore_cpf_calculator/year_2022/spr_1_fg/age_55_below_contribution_calculator.rb +11 -0
  63. data/lib/singapore_cpf_calculator/year_2022/spr_1_fg/age_55_to_60_contribution_calculator.rb +32 -0
  64. data/lib/singapore_cpf_calculator/year_2022/spr_1_fg/age_60_to_65_contribution_calculator.rb +32 -0
  65. data/lib/singapore_cpf_calculator/year_2022/spr_1_fg/age_65_to_70_contribution_calculator.rb +32 -0
  66. data/lib/singapore_cpf_calculator/year_2022/spr_1_fg/age_70_up_contribution_calculator.rb +32 -0
  67. data/lib/singapore_cpf_calculator/year_2022/spr_1_fg.rb +40 -0
  68. data/lib/singapore_cpf_calculator/year_2022/spr_1_gg/age_55_below_contribution_calculator.rb +11 -0
  69. data/lib/singapore_cpf_calculator/year_2022/spr_1_gg/age_55_to_60_contribution_calculator.rb +12 -0
  70. data/lib/singapore_cpf_calculator/year_2022/spr_1_gg/age_60_to_65_contribution_calculator.rb +11 -0
  71. data/lib/singapore_cpf_calculator/year_2022/spr_1_gg/age_65_up_contribution_calculator.rb +14 -0
  72. data/lib/singapore_cpf_calculator/year_2022/spr_1_gg.rb +34 -0
  73. data/lib/singapore_cpf_calculator/year_2022/spr_2_fg/age_55_below_contribution_calculator.rb +11 -0
  74. data/lib/singapore_cpf_calculator/year_2022/spr_2_fg/age_55_to_60_contribution_calculator.rb +32 -0
  75. data/lib/singapore_cpf_calculator/year_2022/spr_2_fg/age_60_to_65_contribution_calculator.rb +32 -0
  76. data/lib/singapore_cpf_calculator/year_2022/spr_2_fg/age_65_to_70_contribution_calculator.rb +32 -0
  77. data/lib/singapore_cpf_calculator/year_2022/spr_2_fg/age_70_up_contribution_calculator.rb +32 -0
  78. data/lib/singapore_cpf_calculator/year_2022/spr_2_fg.rb +40 -0
  79. data/lib/singapore_cpf_calculator/year_2022/spr_2_gg/age_55_below_contribution_calculator.rb +11 -0
  80. data/lib/singapore_cpf_calculator/year_2022/spr_2_gg/age_55_to_60_contribution_calculator.rb +11 -0
  81. data/lib/singapore_cpf_calculator/year_2022/spr_2_gg/age_60_to_65_contribution_calculator.rb +11 -0
  82. data/lib/singapore_cpf_calculator/year_2022/spr_2_gg/age_65_up_contribution_calculator.rb +11 -0
  83. data/lib/singapore_cpf_calculator/year_2022/spr_2_gg.rb +34 -0
  84. data/lib/singapore_cpf_calculator/year_2022.rb +35 -0
  85. data/lib/singapore_cpf_calculator.rb +36 -15
  86. data/singapore_cpf_calculator.gemspec +3 -4
  87. data/spec/acceptance/company_a.csv +1367 -1365
  88. data/spec/acceptance/company_a_spec.rb +6 -4
  89. data/spec/singapore_cpf_calculator/age_group_spec.rb +15 -3
  90. data/spec/singapore_cpf_calculator/year_2014/citizen_or_spr_3/age_50_below_contribution_calculator_spec.rb +10 -10
  91. data/spec/singapore_cpf_calculator/year_2015/citizen_or_spr_3_spec.rb +45 -10
  92. data/spec/singapore_cpf_calculator/year_2015/spr_1_fg_spec.rb +10 -10
  93. data/spec/singapore_cpf_calculator/year_2015/spr_1_gg_spec.rb +11 -11
  94. data/spec/singapore_cpf_calculator/year_2015/spr_2_fg_spec.rb +11 -11
  95. data/spec/singapore_cpf_calculator/year_2015/spr_2_gg/age_55_to_60_contribution_calculator_spec.rb +8 -8
  96. data/spec/singapore_cpf_calculator/year_2015/spr_2_gg_spec.rb +11 -11
  97. data/spec/singapore_cpf_calculator/year_2015_spec.rb +3 -3
  98. data/spec/singapore_cpf_calculator/year_2016/citizen_or_spr_3/age_55_below_contribution_calculator_spec.rb +63 -0
  99. data/spec/singapore_cpf_calculator/year_2016/citizen_or_spr_3/age_55_to_60_contribution_calculator_spec.rb +63 -0
  100. data/spec/singapore_cpf_calculator/year_2016/citizen_or_spr_3/age_60_to_65_contribution_calculator_spec.rb +63 -0
  101. data/spec/singapore_cpf_calculator/year_2016/citizen_or_spr_3/age_65_up_contribution_calculator_spec.rb +63 -0
  102. data/spec/singapore_cpf_calculator/year_2016/citizen_or_spr_3_spec.rb +224 -0
  103. data/spec/singapore_cpf_calculator/year_2016/spr_1_fg/age_55_below_contribution_calculator_spec.rb +63 -0
  104. data/spec/singapore_cpf_calculator/year_2016/spr_1_fg/age_55_to_60_contribution_calculator_spec.rb +63 -0
  105. data/spec/singapore_cpf_calculator/year_2016/spr_1_fg/age_60_to_65_contribution_calculator_spec.rb +63 -0
  106. data/spec/singapore_cpf_calculator/year_2016/spr_1_fg/age_65_up_contribution_calculator_spec.rb +63 -0
  107. data/spec/singapore_cpf_calculator/year_2016/spr_1_fg_spec.rb +158 -0
  108. data/spec/singapore_cpf_calculator/year_2016/spr_1_gg/age_55_below_contribution_calculator_spec.rb +63 -0
  109. data/spec/singapore_cpf_calculator/year_2016/spr_1_gg/age_55_to_60_contribution_calculator_spec.rb +63 -0
  110. data/spec/singapore_cpf_calculator/year_2016/spr_1_gg/age_60_to_65_contribution_calculator_spec.rb +63 -0
  111. data/spec/singapore_cpf_calculator/year_2016/spr_1_gg/age_65_up_contribution_calculator_spec.rb +63 -0
  112. data/spec/singapore_cpf_calculator/year_2016/spr_1_gg_spec.rb +158 -0
  113. data/spec/singapore_cpf_calculator/year_2016/spr_2_fg/age_55_below_contribution_calculator_spec.rb +63 -0
  114. data/spec/singapore_cpf_calculator/year_2016/spr_2_fg/age_55_to_60_contribution_calculator_spec.rb +63 -0
  115. data/spec/singapore_cpf_calculator/year_2016/spr_2_fg/age_60_to_65_contribution_calculator_spec.rb +63 -0
  116. data/spec/singapore_cpf_calculator/year_2016/spr_2_fg/age_65_up_contribution_calculator_spec.rb +63 -0
  117. data/spec/singapore_cpf_calculator/year_2016/spr_2_fg_spec.rb +158 -0
  118. data/spec/singapore_cpf_calculator/year_2016/spr_2_gg/age_55_below_contribution_calculator_spec.rb +63 -0
  119. data/spec/singapore_cpf_calculator/year_2016/spr_2_gg/age_55_to_60_contribution_calculator_spec.rb +63 -0
  120. data/spec/singapore_cpf_calculator/year_2016/spr_2_gg/age_60_to_65_contribution_calculator_spec.rb +63 -0
  121. data/spec/singapore_cpf_calculator/year_2016/spr_2_gg/age_65_up_contribution_calculator_spec.rb +63 -0
  122. data/spec/singapore_cpf_calculator/year_2016/spr_2_gg_spec.rb +158 -0
  123. data/spec/singapore_cpf_calculator/year_2016_spec.rb +187 -0
  124. data/spec/singapore_cpf_calculator/year_2022/citizen_or_spr_3/age_55_below_contribution_calculator_spec.rb +63 -0
  125. data/spec/singapore_cpf_calculator/year_2022/citizen_or_spr_3/age_55_to_60_contribution_calculator_spec.rb +63 -0
  126. data/spec/singapore_cpf_calculator/year_2022/citizen_or_spr_3/age_60_to_65_contribution_calculator_spec.rb +63 -0
  127. data/spec/singapore_cpf_calculator/year_2022/citizen_or_spr_3/age_65_to_70_contribution_calculator_spec.rb +63 -0
  128. data/spec/singapore_cpf_calculator/year_2022/citizen_or_spr_3/age_70_up_contribution_spec.rb +63 -0
  129. data/spec/singapore_cpf_calculator/year_2022/citizen_or_spr_3_spec.rb +242 -0
  130. data/spec/singapore_cpf_calculator/year_2022/spr_1_fg/age_55_below_contribution_calculator_spec.rb +63 -0
  131. data/spec/singapore_cpf_calculator/year_2022/spr_1_fg/age_55_to_60_contribution_calculator_spec.rb +63 -0
  132. data/spec/singapore_cpf_calculator/year_2022/spr_1_fg/age_60_to_65_contribution_calculator_spec.rb +63 -0
  133. data/spec/singapore_cpf_calculator/year_2022/spr_1_fg/age_65_to_70_contribution_calculator_spec.rb +63 -0
  134. data/spec/singapore_cpf_calculator/year_2022/spr_1_fg/age_70_up_contribution_calculator_spec.rb +63 -0
  135. data/spec/singapore_cpf_calculator/year_2022/spr_1_fg_spec.rb +176 -0
  136. data/spec/singapore_cpf_calculator/year_2022/spr_1_gg/age_55_below_contribution_calculator_spec.rb +63 -0
  137. data/spec/singapore_cpf_calculator/year_2022/spr_1_gg/age_55_to_60_contribution_calculator_spec.rb +63 -0
  138. data/spec/singapore_cpf_calculator/year_2022/spr_1_gg/age_60_to_65_contribution_calculator_spec.rb +63 -0
  139. data/spec/singapore_cpf_calculator/year_2022/spr_1_gg/age_65_up_contribution_calculator_spec.rb +63 -0
  140. data/spec/singapore_cpf_calculator/year_2022/spr_1_gg_spec.rb +158 -0
  141. data/spec/singapore_cpf_calculator/year_2022/spr_2_fg/age_55_below_contribution_calculator_spec.rb +63 -0
  142. data/spec/singapore_cpf_calculator/year_2022/spr_2_fg/age_55_to_60_contribution_calculator_spec.rb +63 -0
  143. data/spec/singapore_cpf_calculator/year_2022/spr_2_fg/age_60_to_65_contribution_calculator_spec.rb +63 -0
  144. data/spec/singapore_cpf_calculator/year_2022/spr_2_fg/age_65_to_70_contribution_calculator_spec.rb +63 -0
  145. data/spec/singapore_cpf_calculator/year_2022/spr_2_fg/age_70_up_contribution_calculator_spec.rb +63 -0
  146. data/spec/singapore_cpf_calculator/year_2022/spr_2_fg_spec.rb +176 -0
  147. data/spec/singapore_cpf_calculator/year_2022/spr_2_gg/age_55_below_contribution_calculator_spec.rb +63 -0
  148. data/spec/singapore_cpf_calculator/year_2022/spr_2_gg/age_55_to_60_contribution_calculator_spec.rb +63 -0
  149. data/spec/singapore_cpf_calculator/year_2022/spr_2_gg/age_60_to_65_contribution_calculator_spec.rb +63 -0
  150. data/spec/singapore_cpf_calculator/year_2022/spr_2_gg/age_65_up_contribution_calculator_spec.rb +63 -0
  151. data/spec/singapore_cpf_calculator/year_2022/spr_2_gg_spec.rb +158 -0
  152. data/spec/singapore_cpf_calculator/year_2022_spec.rb +192 -0
  153. data/spec/singapore_cpf_calculator_spec.rb +87 -2
  154. data/spec/spec_helper.rb +17 -10
  155. metadata +183 -23
  156. data/circle.yml +0 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: c10a9da895045667814bc945fe76c308fa58f61a
4
- data.tar.gz: 0c7815f181658ee0511bdf631822ef6c4871164f
2
+ SHA256:
3
+ metadata.gz: 6ab4079969915c3c23853647786c1c5efd8dc25d2d6a6eec899a0a1010507d4e
4
+ data.tar.gz: e3f883954c14bca4c37229c775569fdb35ea0b44214ead4e3f0d47c70f707d30
5
5
  SHA512:
6
- metadata.gz: d7bd99c5b7bdd11616e9773158838aa03f293e61a3d5555165185702ac423ddb1a4fa5bcc48ff4fc86dd7091f370c698f3e75aaf4f0c31fb2f708d66486fa363
7
- data.tar.gz: 976dec1337b458a379b4478b3db71e3ca7451ecdf1d5998db3bfc47769adfed4558036f87f1fbe0d7d1933f9e8cd951e15f87096693af7ed193a75602289f865
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
@@ -2,3 +2,4 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in singapore_cpf_calculator.gemspec
4
4
  gemspec
5
+ gem 'simplecov'
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 return a
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} and {SingaporeCPFCalculator::CPFContribution#total}.
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](http://mycpf.cpf.gov.sg/NR/exeres/24537890-6D8E-495E-80D5-E5EFEFCA1905,frameless.htm)
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](http://mycpf.cpf.gov.sg/Employers/Employers_Guide_to_CPF/Glossary/Glossary_Additional_Wages.htm)
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
- def get(current_date, birthdate:)
19
- new(current_date, birthdate: birthdate).get
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
- case
38
- when age < 50
39
- :group_50_years_and_below
40
- when 50 <= age && age < 55
41
- :group_above_50_to_55_years
42
- when 55 <= age && age < 60
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
- new(ordinary_wages: ordinary_wages, additional_wages: additional_wages).calculate
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.new val
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
- def initialize(total:, employee:)
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.new("0.0"),
11
- employee: BigDecimal.new("0.0")
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
@@ -0,0 +1,13 @@
1
+ module SingaporeCPFCalculator
2
+ module Requirements
3
+ module Group55YearsAndBelow
4
+
5
+ private
6
+
7
+ def required_age_group
8
+ :group_55_years_and_below
9
+ end
10
+
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ module SingaporeCPFCalculator
2
+ module Requirements
3
+ module GroupAbove65To70Years
4
+
5
+ private
6
+
7
+ def required_age_group
8
+ :group_above_65_to_70_years
9
+ end
10
+
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ module SingaporeCPFCalculator
2
+ module Requirements
3
+ module GroupAbove70Years
4
+
5
+ private
6
+
7
+ def required_age_group
8
+ :group_above_70_years
9
+ end
10
+
11
+ end
12
+ end
13
+ 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
@@ -1,3 +1,3 @@
1
1
  module SingaporeCPFCalculator
2
- VERSION = "1.1.1"
2
+ VERSION = "1.4.0"
3
3
  end
@@ -0,0 +1,7 @@
1
+ module SingaporeCPFCalculator
2
+ module Year2012To2015AwCeilingModule
3
+ def additional_wage_ceiling
4
+ d('85_000')
5
+ end
6
+ end
7
+ end
@@ -3,6 +3,7 @@ module SingaporeCPFCalculator
3
3
 
4
4
  # Base class for 2014 CPF calculators.
5
5
  class Base < BaseCalculator
6
+ include SingaporeCPFCalculator::Year2012To2015AwCeilingModule
6
7
 
7
8
  private
8
9
 
@@ -0,0 +1,8 @@
1
+ module SingaporeCPFCalculator
2
+ module Year2014
3
+ module CitizenOrSPR3
4
+ class CitizenOrSpr3Base < Year2014::Base
5
+ end
6
+ end
7
+ end
8
+ end
@@ -3,6 +3,7 @@ module SingaporeCPFCalculator
3
3
 
4
4
  # Base class for 2014 CPF calculators.
5
5
  class Base < BaseCalculator
6
+ include SingaporeCPFCalculator::Year2012To2015AwCeilingModule
6
7
 
7
8
  private
8
9
 
@@ -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 < Year2015::Base
6
+ class Age50BelowContributionCalculator < CitizenOrSpr3Base
7
7
 
8
8
  extend Requirements::Group50YearsAndBelow
9
9
 
@@ -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 < Year2015::Base
6
+ class Age50To55ContributionCalculator < CitizenOrSpr3Base
7
7
 
8
8
  extend Requirements::GroupAbove50To55Years
9
9
 
@@ -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 < Year2015::Base
6
+ class Age55To60ContributionCalculator < CitizenOrSpr3Base
7
7
 
8
8
  extend Requirements::GroupAbove55To60Years
9
9
 
@@ -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 < Year2015::Base
6
+ class Age60To65ContributionCalculator < CitizenOrSpr3Base
7
7
 
8
8
  extend Requirements::GroupAbove60To65Years
9
9
 
@@ -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 < Year2015::Base
6
+ class Age65UpContributionCalculator < CitizenOrSpr3Base
7
7
 
8
8
  extend Requirements::GroupAbove65Years
9
9
 
@@ -0,0 +1,9 @@
1
+ module SingaporeCPFCalculator
2
+ module Year2015
3
+ module CitizenOrSPR3
4
+ # Base calculator for citizen or spr3 in year 2015
5
+ class CitizenOrSpr3Base < Year2015::Base
6
+ end
7
+ end
8
+ end
9
+ end
@@ -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"
@@ -16,7 +16,7 @@ module SingaporeCPFCalculator
16
16
  # @param [Date] date when the CPF contribution is to be calculated for.
17
17
  # @return [true, false] true when the date's year is 2014
18
18
  def applies_to?(date)
19
- date.year >= 2015
19
+ date.year == 2015
20
20
  end
21
21
 
22
22
  private
@@ -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