class SingaporeCPFCalculator::BaseCalculator
Base class for CPF calculators.
Attributes
additional_wages[R]
estimated_yearly_ow[R]
ordinary_wages[R]
ytd_additional_wages[R]
ytd_ow_subject_to_cpf[R]
Public Class Methods
applies_to?(date, birthdate:)
click to toggle source
@param [Fixnum] age @return [true, false] returns true if the calculator applies to the employee's age.
# File lib/singapore_cpf_calculator/base_calculator.rb, line 8 def applies_to?(date, birthdate:) AgeGroup.get(date, birthdate: birthdate) == required_age_group end
calculate(ordinary_wages:, additional_wages:, ytd_additional_wages: 0.0, ytd_ow_subject_to_cpf: 0.0, estimated_yearly_ow: 0.0)
click to toggle source
@param [BigDecimal] ordinary_wages
:
Ordinary wages are wages due or granted in respect of employment and include allowances (e.g. food allowance and overtime payments) earned by an employee in the month and payable before the due date for payment of CPF contributions for that month.
@param [BigDecimal] additional_wages
:
Additional wages are wage supplements which are not granted wholly and exclusively for the month, such as annual bonus and leave pay. These and other incentive payments may be made at intervals of more than a month.
@param [BigDecimal] ytd_additional_wages
The year to date additional wages @param [BigDecimal] ytd_ow_subject_to_cpf
The year to date ordinary wages @return [Hash] returns the total, employee, employer amounts for the CPF contribution
# File lib/singapore_cpf_calculator/base_calculator.rb, line 24 def calculate(ordinary_wages:, additional_wages:, ytd_additional_wages: 0.0, ytd_ow_subject_to_cpf: 0.0, estimated_yearly_ow: 0.0) new(ordinary_wages: ordinary_wages, additional_wages: additional_wages, ytd_ow_subject_to_cpf: ytd_ow_subject_to_cpf, ytd_additional_wages: ytd_additional_wages, estimated_yearly_ow: estimated_yearly_ow).calculate end
new(ordinary_wages:, additional_wages:, ytd_additional_wages: 0.0, ytd_ow_subject_to_cpf: 0.0, estimated_yearly_ow: 0.0)
click to toggle source
# File lib/singapore_cpf_calculator/base_calculator.rb, line 38 def initialize(ordinary_wages:, additional_wages:, ytd_additional_wages: 0.0, ytd_ow_subject_to_cpf: 0.0, estimated_yearly_ow: 0.0) @ordinary_wages = ordinary_wages @ytd_ow_subject_to_cpf = ytd_ow_subject_to_cpf @ytd_additional_wages = ytd_additional_wages @estimated_yearly_ow = estimated_yearly_ow @additional_wages = additional_wages clip_additional_wages_based_on_ceiling() end
Private Class Methods
required_age_group()
click to toggle source
# File lib/singapore_cpf_calculator/base_calculator.rb, line 33 def required_age_group raise NotImplementedError, "sub classes needs to implement .required_age_group" end
Public Instance Methods
calculate()
click to toggle source
@return [Hash] returns the total, employee, employer amounts for the CPF contribution
# File lib/singapore_cpf_calculator/base_calculator.rb, line 49 def calculate CPFContribution.new total: total_contribution, employee: employee_contribution, aw_subject_to_cpf: additional_wages, ow_subject_to_cpf: capped_ordinary_wages end
Private Instance Methods
additional_wage_ceiling()
click to toggle source
generally applies only to spr3 and citizens
# File lib/singapore_cpf_calculator/base_calculator.rb, line 123 def additional_wage_ceiling nil end
adjustment_rate()
click to toggle source
# File lib/singapore_cpf_calculator/base_calculator.rb, line 140 def adjustment_rate raise NotImplementedError, "sub classes needs to implement #adjustment_rate" end
calculated_employee_contribution()
click to toggle source
# File lib/singapore_cpf_calculator/base_calculator.rb, line 111 def calculated_employee_contribution case when total_wages < d("500.0000") d("0.0") when total_wages < d("750.0000") (d(adjustment_rate) * (total_wages - d("500.00"))) else # >= $750 (d(ec_rate) * capped_ordinary_wages) + (d(ec_rate) * additional_wages) end end
calculated_remaining_wage_ceiling()
click to toggle source
# File lib/singapore_cpf_calculator/base_calculator.rb, line 88 def calculated_remaining_wage_ceiling max_remaining = additional_wage_ceiling - ytd_ow_subject_to_cpf - capped_ordinary_wages - ytd_additional_wages [max_remaining, d('0.0')].max end
calculated_total_contribution()
click to toggle source
# File lib/singapore_cpf_calculator/base_calculator.rb, line 98 def calculated_total_contribution case when total_wages <= d("50.00") d("0.0") when total_wages <= d("500.00") d(tc_rate_1) * total_wages when total_wages < d("750.0000") (d(tc_rate_1) * total_wages) + (d(adjustment_rate) * (total_wages - d("500.00"))) else # >= $750 (d(tc_rate_2) * capped_ordinary_wages) + (d(tc_rate_2) * additional_wages) end end
capped_ordinary_wages()
click to toggle source
# File lib/singapore_cpf_calculator/base_calculator.rb, line 144 def capped_ordinary_wages raise NotImplementedError, "sub classes needs to implement #capped_ordinary_wages" end
clip_additional_wages_based_on_ceiling()
click to toggle source
# File lib/singapore_cpf_calculator/base_calculator.rb, line 82 def clip_additional_wages_based_on_ceiling unless additional_wage_ceiling.blank? @additional_wages = [additional_wages, calculated_remaining_wage_ceiling, estimated_remaining_wage_ceiling].min end end
d(val)
click to toggle source
precision helper
# File lib/singapore_cpf_calculator/base_calculator.rb, line 149 def d(val) BigDecimal(val) end
ec_rate()
click to toggle source
# File lib/singapore_cpf_calculator/base_calculator.rb, line 136 def ec_rate raise NotImplementedError, "sub classes needs to implement #ec_rate" end
employee_contribution()
click to toggle source
Steps to compute CPF contribution:
a. Compute the total CPF contribution (rounded to the nearest dollar). An amount of 50 cents should be regarded as an additional dollar. b. Compute the employee’s share of CPF contribution (cents should be dropped) c. Employer’s share = Total contribution – Employee’s share
# File lib/singapore_cpf_calculator/base_calculator.rb, line 70 def employee_contribution @employee_contribution ||= calculated_employee_contribution.round(0, :truncate) end
employer_contribution()
click to toggle source
# File lib/singapore_cpf_calculator/base_calculator.rb, line 74 def employer_contribution @employer_contribution ||= total_contribution - employee_contribution end
estimated_remaining_wage_ceiling()
click to toggle source
# File lib/singapore_cpf_calculator/base_calculator.rb, line 93 def estimated_remaining_wage_ceiling estimated_remaining = additional_wage_ceiling - estimated_yearly_ow - ytd_additional_wages [estimated_remaining, d('0.0')].max end
tc_rate_1()
click to toggle source
TC Rate 1 is
# File lib/singapore_cpf_calculator/base_calculator.rb, line 128 def tc_rate_1 raise NotImplementedError, "sub classes needs to implement #tc_rate_1" end
tc_rate_2()
click to toggle source
# File lib/singapore_cpf_calculator/base_calculator.rb, line 132 def tc_rate_2 raise NotImplementedError, "sub classes needs to implement #tc_rate_2" end
total_contribution()
click to toggle source
# File lib/singapore_cpf_calculator/base_calculator.rb, line 61 def total_contribution @total_contribution ||= calculated_total_contribution.round(0, :half_up) end
total_wages()
click to toggle source
# File lib/singapore_cpf_calculator/base_calculator.rb, line 78 def total_wages ordinary_wages + additional_wages end