module SingaporeCPFCalculator

Constants

VERSION

Public Class Methods

calculate(date:, birthdate:, residency_status:, spr_start_date: nil, ordinary_wages:, additional_wages:, employee_contribution_type: nil, employer_contribution_type: nil, ytd_additional_wages: 0.0, ytd_ow_subject_to_cpf: 0.0, estimated_yearly_ow: 0.0) click to toggle source

@example:

result = SingaporeCPFCalculator.calculate age: 32,
                                          date: Date.new(2014, 11, 15),
                                          residency_status: "permanent_resident",
                                          spr_start_date: Date.new(2014, 11, 15),
                                          ordinary_wages: 700.00,
                                          additional_wages: 252.00,
                                          employee_contribution_type: "full",
                                          employer_contribution_type: "full",
                                          ytd_additional_wages: 20_000,
                                          ytd_ow_subject_to_cpf: 60_000

result # => #<SingaporeCPFCalculator::CPFContribution ...>
result.employee # => 190.00
result.employer # => 153.00
result.total # => 343.00

@param [Date] date: relevant date when the CPF contribution is being calculated @param [Date] birthdate: @param [String] residency_status: [“citizen”, “permanent_resident”] @param [Date] spr_start_date: date when the employee became a Singapore permanent resident @param [String] employee_contribution_type: [“full”, “graduated”] @param [String] employer_contribution_type: [“full”, “graduated”] @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:

Cumulative Additional Wages for the year (YTD)

@param [BigDecimal] ytd_ow_subject_to_cpf:

The Year to Date Ordinary Wages which have been subject to CPF.

@return [CPFContribution]

# File lib/singapore_cpf_calculator.rb, line 44
def calculate(date:,
              birthdate:,
              residency_status:,
              spr_start_date: nil,
              ordinary_wages:,
              additional_wages:,
              employee_contribution_type: nil,
              employer_contribution_type: nil,
              ytd_additional_wages: 0.0,
              ytd_ow_subject_to_cpf: 0.0,
              estimated_yearly_ow: 0.0)
  validate_params(date: date,
                  employee_contribution_type: employee_contribution_type,
                  employer_contribution_type: employer_contribution_type,
                  residency_status: residency_status,
                  spr_start_date: spr_start_date)

  module_for_date(date).
    module_for_residency(
      status: residency_status,
      spr_start_date: spr_start_date,
      current_date: date,
      employee_contribution_type: employee_contribution_type,
      employer_contribution_type: employer_contribution_type
    ).calculator_for(date, birthdate: birthdate).
    calculate ordinary_wages: ordinary_wages,
              additional_wages: additional_wages,
              ytd_additional_wages: ytd_additional_wages,
              ytd_ow_subject_to_cpf: ytd_ow_subject_to_cpf,
              estimated_yearly_ow: estimated_yearly_ow
end

Private Class Methods

contribution_types_required?(date, spr_start_date) click to toggle source
# File lib/singapore_cpf_calculator.rb, line 102
def contribution_types_required?(date, spr_start_date)
  date <= (spr_start_date + 2.years)
end
date_modules() click to toggle source
# File lib/singapore_cpf_calculator.rb, line 111
def date_modules
  [
    Year2014,
    Year2015,
    Year2016
  ]
end
module_for_date(date) click to toggle source
# File lib/singapore_cpf_calculator.rb, line 106
def module_for_date(date)
  date_modules.find { |mod| mod.applies_to? date } or
    raise ArgumentError, "could not find date module for #{ date }"
end
validate_params( date:, employee_contribution_type:, employer_contribution_type:, residency_status:, spr_start_date: ) click to toggle source
# File lib/singapore_cpf_calculator.rb, line 78
def validate_params(
  date:,
  employee_contribution_type:,
  employer_contribution_type:,
  residency_status:,
  spr_start_date:
)
  if residency_status == "permanent_resident"
    raise ArgumentError, "spr_start_date: must be set" if spr_start_date.nil?
    if contribution_types_required?(date, spr_start_date)
      if employee_contribution_type.nil?
        raise ArgumentError, "employee_contribution_type: must be set"
      end
      if employer_contribution_type.nil?
        raise ArgumentError, "employer_contribution_type: must be set"
      end
    end
  end

  unless ["citizen", "permanent_resident"].include? residency_status
    raise ArgumentError, "unsupported residency status: #{ residency_status }"
  end
end