Skip to content

Commit

Permalink
Statutory sick pay updates for 2015/16
Browse files Browse the repository at this point in the history
1) New SSP weekly rate £88.45
2) New lower Earnings limit £112
3) Refactoring: do not duplicate the latest rate values in a constant
4) Whitespace fixes in tests
  • Loading branch information
tadast committed Mar 26, 2015
1 parent 5060e34 commit 31cabba
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 50 deletions.
18 changes: 8 additions & 10 deletions lib/smart_answer/calculators/statutory_sick_pay_calculator_v2.rb
Expand Up @@ -3,12 +3,6 @@ module SmartAnswer::Calculators
class StatutorySickPayCalculatorV2
attr_reader :waiting_days, :normal_workdays, :pattern_days

# LEL changes on 6 April each year
# the two constants below are meant as 'safety' if the calculator gets a query for future dates past the latest known
# and should be updated to the latest known rate
LOWER_EARNING_LIMIT = 111.00
SSP_WEEKLY_RATE = 87.55

def initialize(prev_sick_days, sick_start_date, sick_end_date, days_of_the_week_worked)
@prev_sick_days = prev_sick_days
@waiting_days = (@prev_sick_days >= 3 ? 0 : 3 - @prev_sick_days)
Expand All @@ -26,14 +20,16 @@ def self.earning_limit_rates
{min: Date.parse("6 April 2011"), max: Date.parse("5 April 2012"), lower_earning_limit_rate: 102},
{min: Date.parse("6 April 2012"), max: Date.parse("5 April 2013"), lower_earning_limit_rate: 107},
{min: Date.parse("6 April 2013"), max: Date.parse("5 April 2014"), lower_earning_limit_rate: 109},
{min: Date.parse("6 April 2014"), max: Date.parse("5 April 2015"), lower_earning_limit_rate: 111}
{min: Date.parse("6 April 2014"), max: Date.parse("5 April 2015"), lower_earning_limit_rate: 111},
{min: Date.parse("6 April 2015"), max: Date.parse("5 April 2016"), lower_earning_limit_rate: 112}
]
end

# define as static so we don't have to instantiate the calculator too early in the flow
def self.lower_earning_limit_on(date)
earning_limit_rate = earning_limit_rates.find { |c| c[:min] <= date and c[:max] >= date }
(earning_limit_rate ? earning_limit_rate[:lower_earning_limit_rate] : LOWER_EARNING_LIMIT)
earning_limit_rate ||= earning_limit_rates.sort_by(&:max).last
earning_limit_rate[:lower_earning_limit_rate]
end

def self.months_between(start_date, end_date)
Expand Down Expand Up @@ -68,13 +64,15 @@ def ssp_rates
{min: Date.parse("6 April 2011"), max: Date.parse("5 April 2012"), ssp_weekly_rate: 81.60},
{min: Date.parse("6 April 2012"), max: Date.parse("5 April 2013"), ssp_weekly_rate: 85.85},
{min: Date.parse("6 April 2013"), max: Date.parse("5 April 2014"), ssp_weekly_rate: 86.70},
{min: Date.parse("6 April 2014"), max: Date.parse("5 April 2015"), ssp_weekly_rate: 87.55}
{min: Date.parse("6 April 2014"), max: Date.parse("5 April 2015"), ssp_weekly_rate: 87.55},
{min: Date.parse("6 April 2015"), max: Date.parse("5 April 2016"), ssp_weekly_rate: 88.45}
]
end

def weekly_rate_on(date)
rate = ssp_rates.find { |c| c[:min] <= date and c[:max] >= date }
rate ? rate[:ssp_weekly_rate] : SSP_WEEKLY_RATE
rate ||= ssp_rates.sort_by(&:max).last

This comment has been minimized.

Copy link
@jackscotti

jackscotti Mar 27, 2015

Contributor

What would happen if the next year rates will decrease? Will we need to change this method?

This comment has been minimized.

Copy link
@tadast

tadast Mar 27, 2015

Author Contributor

the max key is a date (a bit confusing when referring to max when sorting, I know), so it's going to increase next year unless someone invents a time machine.

This comment has been minimized.

Copy link
@jackscotti

jackscotti Mar 27, 2015

Contributor

oh, you are right. I thought it was looking for the highest rate. 👍

rate[:ssp_weekly_rate]
end

def daily_rate_from_weekly(weekly_rate, pattern_days)
Expand Down
115 changes: 75 additions & 40 deletions test/unit/calculators/statutory_sick_pay_calculator_v2_test.rb
Expand Up @@ -76,7 +76,7 @@ class StatutorySickPayCalculatorV2Test < ActiveSupport::TestCase
context "daily rate test for 7 days per week worked" do
setup do
@start_date = Date.parse("1 October 2012")
@calculator = StatutorySickPayCalculatorV2.new(5, @start_date, Date.parse("7 October 2012"), ['0', '1', '2', '3', '4', '5', '6'])
@calculator = StatutorySickPayCalculatorV2.new(5, @start_date, Date.parse("7 October 2012"), ['0', '1', '2', '3', '4', '5', '6'])
end

should "return daily rate of 12.2642" do
Expand All @@ -87,7 +87,7 @@ class StatutorySickPayCalculatorV2Test < ActiveSupport::TestCase
context "daily rate test for 6 days per week worked" do
setup do
@start_date = Date.parse("1 October 2012")
@calculator = StatutorySickPayCalculatorV2.new(5, @start_date, Date.parse("7 October 2012"), ['1', '2', '3', '4', '5', '6'])
@calculator = StatutorySickPayCalculatorV2.new(5, @start_date, Date.parse("7 October 2012"), ['1', '2', '3', '4', '5', '6'])
end

should "return daily rate of 14.3083" do
Expand All @@ -98,7 +98,7 @@ class StatutorySickPayCalculatorV2Test < ActiveSupport::TestCase
context "daily rate test for 2 days per week worked" do
setup do
@start_date = Date.parse("1 October 2012")
@calculator = StatutorySickPayCalculatorV2.new(5, @start_date, Date.parse("7 October 2012"), ['4', '5'])
@calculator = StatutorySickPayCalculatorV2.new(5, @start_date, Date.parse("7 October 2012"), ['4', '5'])
end

should "return daily rate of 42.9250" do
Expand Down Expand Up @@ -169,7 +169,7 @@ class StatutorySickPayCalculatorV2Test < ActiveSupport::TestCase
context "historic rate test 1" do
setup do
@start_date = Date.parse("5 April 2012")
@calculator = StatutorySickPayCalculatorV2.new(3, @start_date, Date.parse("10 April 2012"), ['1', '2', '3', '4', '5'])
@calculator = StatutorySickPayCalculatorV2.new(3, @start_date, Date.parse("10 April 2012"), ['1', '2', '3', '4', '5'])
end

should "use ssp rate and lel for 2011-12" do
Expand All @@ -182,7 +182,7 @@ class StatutorySickPayCalculatorV2Test < ActiveSupport::TestCase
context "test scenario 1 - M-F, no waiting days, cross tax years" do
setup do
@start_date = Date.parse("26 March 2012")
@calculator = StatutorySickPayCalculatorV2.new(0, @start_date, Date.parse("13 April 2012"), ['1', '2', '3', '4', '5'])
@calculator = StatutorySickPayCalculatorV2.new(0, @start_date, Date.parse("13 April 2012"), ['1', '2', '3', '4', '5'])
end

should "give correct ssp calculation" do # 15 days with 3 waiting days, so 6 days at lower weekly rate, 6 days at higher rate
Expand All @@ -193,10 +193,10 @@ class StatutorySickPayCalculatorV2Test < ActiveSupport::TestCase
end
end

context "test date in future" do
context "test date 4 May 2014" do
setup do
@start_date = Date.parse("4 May 2014")
@calculator = StatutorySickPayCalculatorV2.new(3, @start_date, Date.parse("3 August 2014"), ['1', '2', '3', '4', '5'])
@calculator = StatutorySickPayCalculatorV2.new(3, @start_date, Date.parse("3 August 2014"), ['1', '2', '3', '4', '5'])
end

should "use ssp rate and lel for 2014-15" do
Expand All @@ -205,6 +205,17 @@ class StatutorySickPayCalculatorV2Test < ActiveSupport::TestCase
end
end

context "weekly rate fallback. When date is not covered by any known ranges" do
setup do
@start_date = Date.parse("4 May 2054")
@calculator = StatutorySickPayCalculatorV2.new(3, @start_date, @start_date + 1.month, ['1', '2', '3', '4', '5'])
end

should "use ssp rate for the latest know fiscal year (2015-16)" do
assert_equal 88.45, @calculator.weekly_rate_on(@start_date)
end
end

# Tuesday to Friday
context "test scenario 2 - T-F, 7 waiting days, cross tax years" do
setup do
Expand Down Expand Up @@ -352,54 +363,78 @@ class StatutorySickPayCalculatorV2Test < ActiveSupport::TestCase
end
end

context "LEL test 1" do
setup do
@date = Date.parse("1 April 2012")
@lel = StatutorySickPayCalculatorV2.lower_earning_limit_on(@date)
end
context "lower earnings limit (LEL)" do
context "in 2011/2012" do
setup do
@date = Date.parse("1 April 2012")
@lel = StatutorySickPayCalculatorV2.lower_earning_limit_on(@date)
end

should "give correct LEL for date" do
assert_equal @lel, 102.00
should "be 102" do
assert_equal 102.00, @lel
end
end
end

context "LEL test 2" do
setup do
@date = Date.parse("6 April 2012")
@lel = StatutorySickPayCalculatorV2.lower_earning_limit_on(@date)
end
context "in the beginning of 2012/2013" do
setup do
@date = Date.parse("6 April 2012")
@lel = StatutorySickPayCalculatorV2.lower_earning_limit_on(@date)
end

should "give correct LEL for date" do
assert_equal @lel, 107.00
should "be 107" do
assert_equal 107.00, @lel
end
end
end

context "LEL test 3" do
setup do
@date = Date.parse("6 April 2013")
@lel = StatutorySickPayCalculatorV2.lower_earning_limit_on(@date)
context "in the beginning of 2013/2014" do
setup do
@date = Date.parse("6 April 2013")
@lel = StatutorySickPayCalculatorV2.lower_earning_limit_on(@date)
end

should "be 109" do
assert_equal 109.00, @lel
end
end

should "give correct LEL for date" do
assert_equal @lel, 109.00
context "in the beginning of 2014/2015" do
setup do
@date = Date.parse("6 April 2014")
@lel = StatutorySickPayCalculatorV2.lower_earning_limit_on(@date)
end

should "be 111" do
assert_equal 111.00, @lel
end
end
end

context "LEL test 4" do
setup do
@date = Date.parse("6 April 2014")
@lel = StatutorySickPayCalculatorV2.lower_earning_limit_on(@date)
context "in the beginning of 2015/2016" do
setup do
@date = Date.parse("6 April 2015")
@lel = StatutorySickPayCalculatorV2.lower_earning_limit_on(@date)
end

should "be 112" do
assert_equal 112.00, @lel
end
end

should "give correct LEL for date" do
assert_equal @lel, 111.00
context "fallback when no dates are matching" do
setup do
@date = Date.parse("6 April 2056")
@lel = StatutorySickPayCalculatorV2.lower_earning_limit_on(@date)
end

should "be the rate of the latest available fiscal year" do
assert_equal 112.00, @lel
end
end
end

context "sick_pay_weekly_dates" do
should "produce a list of Saturdays for the provided sick period" do
calculator = StatutorySickPayCalculatorV2.new(
42, Date.parse("7 January 2013"), Date.parse("3 May 2013"), ['2', '3', '4'])
42, Date.parse("7 January 2013"), Date.parse("3 May 2013"), ['2', '3', '4'])

assert_equal [Date.parse("12 Jan 2013"),
Date.parse("19 Jan 2013"),
Expand All @@ -425,7 +460,7 @@ class StatutorySickPayCalculatorV2Test < ActiveSupport::TestCase
context "sick_pay_weekly_amounts" do
should "return the payable weeks by taking into account the final SSP payment" do
calculator = StatutorySickPayCalculatorV2.new(
42, Date.parse("7 January 2013"), Date.parse("3 May 2013"), ['2', '3', '4'])
42, Date.parse("7 January 2013"), Date.parse("3 May 2013"), ['2', '3', '4'])

assert_equal [[Date.parse("12 Jan 2013"), 85.85],
[Date.parse("19 Jan 2013"), 85.85],
Expand All @@ -447,7 +482,7 @@ class StatutorySickPayCalculatorV2Test < ActiveSupport::TestCase

should "have the same reduced value as the ssp_payment value" do
calculator = StatutorySickPayCalculatorV2.new(
42, Date.parse("7 January 2013"), Date.parse("3 May 2013"), ['2', '3', '4'])
42, Date.parse("7 January 2013"), Date.parse("3 May 2013"), ['2', '3', '4'])

assert_equal calculator.ssp_payment,
calculator.weekly_payments.map(&:second).sum
Expand All @@ -457,7 +492,7 @@ class StatutorySickPayCalculatorV2Test < ActiveSupport::TestCase
context "formatted_sick_pay_weekly_amounts" do
should "produce a markdown (value) formatted string of weekly SSP dates and pay rates" do
calculator = StatutorySickPayCalculatorV2.new(
42, Date.parse("7 January 2013"), Date.parse("3 May 2013"), ['2', '3', '4'])
42, Date.parse("7 January 2013"), Date.parse("3 May 2013"), ['2', '3', '4'])

assert_equal ["12 January 2013|£85.85",
"19 January 2013|£85.85",
Expand Down

0 comments on commit 31cabba

Please sign in to comment.