Skip to content

Commit

Permalink
Updates to Paternity Leave logic (#223)
Browse files Browse the repository at this point in the history
* Update Paternity Leave logic in visual planner and accessible planner (#220)

* SPL-286 - update text on the partner table of the ‘Leave summary’ table

* SPL-286 - allow paternity leave any time

* SPL-287 - allow paternity leave any time in accessible planner

* SPL-285 allow gap in paternity leave

* SPL-285 - fix: summary now displays correct paternity leave when non-consecutive

* SPL-285 - fix: correctly calculate non-consecutive pat leave length

* SPL-285 - restrict paternity leave to be within the range of maternity leave, else show shared

* SPL-285 - allow paternity leave gap in accessible planner

* SPL-285 - fix: restrict paternity leave to maternity leave bounds correctly

* Update help text for Paternity Leave in Visual Planner (#221)

* Add additional text for paternity leave entitlement

* Update Paternity Leave and Pay information

* run linter

* sass-lint fixes

* Update block tests

* Update workflow to monitor changes to PR base branch

* Specify buildpack version for Node 16.x.x
  • Loading branch information
lambley authored Mar 7, 2024
1 parent b1ce383 commit 8833668
Show file tree
Hide file tree
Showing 17 changed files with 189 additions and 60 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/planner.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Spl-planner-continuous-check

on:
pull_request:
types: [opened, edited, reopened, ready_for_review, review_requested, auto_merge_enabled]
types: [opened, synchronize, edited, reopened, ready_for_review, review_requested, auto_merge_enabled]
branches:
- 'master'

Expand Down
7 changes: 6 additions & 1 deletion app/filters.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const delve = require('dlv')
const { getWeeksArray, parseWeeksFromData } = require('./utils')
const Day = require('../common/lib/day')
const { parseEligibilityFromData } = require('./lib/eligibility')
const { getBlockLength, getRemainingLeaveAllowance, getRemainingPayAllowance, parseLeaveBlocks, parseSplLeaveBlocks } = require('./lib/blocks')
const { getBlockLength, getPaternalBlockLength, getRemainingLeaveAllowance, getRemainingPayAllowance, parseLeaveBlocks, parseSplLeaveBlocks } = require('./lib/blocks')
const _ = require('lodash')

// Existing filters can be imported from env using env.getFilter(name)
Expand Down Expand Up @@ -138,6 +138,10 @@ module.exports = function (env) {
return getBlockLength(block)
}

function paternalBlockLength (block) {
return getPaternalBlockLength(block)
}

function remainingLeaveAllowance (leaveBlocksDataObject) {
const leaveBlocks = parseLeaveBlocks(leaveBlocksDataObject)
return getRemainingLeaveAllowance(leaveBlocks)
Expand Down Expand Up @@ -189,6 +193,7 @@ module.exports = function (env) {
blocksToDates,
htmlAttributesFromObject,
blockLength,
paternalBlockLength,
remainingLeaveAllowance,
remainingPayAllowance,
hasTakenSpl,
Expand Down
15 changes: 13 additions & 2 deletions app/lib/blocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ function getLeaveBlocks (weeks) {

function getParentLeaveBlocks (weeks, parent) {
const blocks = {
initial: null,
initial: [],
spl: []
}

Expand All @@ -28,7 +28,7 @@ function getParentLeaveBlocks (weeks, parent) {

function store (block) {
if (block && ['maternity', 'paternity', 'adoption'].includes(block.leave)) {
blocks.initial = block
blocks.initial.push(block)
} else {
blocks.spl.push(block)
}
Expand Down Expand Up @@ -273,6 +273,16 @@ function getBlockLength (block) {
return parseInt(block.end) - parseInt(block.start) + 1
}

function getPaternalBlockLength (block) {
if (!block || block.length === 0) {
return 0
} else if (block.length === 2) {
return 2
} else if (block.length === 1) {
return parseInt(block[0].end) - parseInt(block[0].start) + 1
}
}

function isBlockDataObject (obj) {
return _.isObject(obj) &&
obj.leave !== undefined &&
Expand Down Expand Up @@ -357,5 +367,6 @@ module.exports = {
getRemainingLeaveAllowance,
getRemainingPayAllowance,
getBlockLength,
getPaternalBlockLength,
parseLeaveBlocksIntoLeaveAndPay
}
4 changes: 4 additions & 0 deletions app/lib/leaveTracker.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ class LeaveTracker {
this.initialBlockStarted = false
this.initialBlockEnded = false
this.initialBlockLength = 0
this.totalLeaveWeeks = 0
}

next (isLeave, weekNumber) {
Expand All @@ -17,6 +18,9 @@ class LeaveTracker {
if (this.initialBlockStarted && !this.initialBlockEnded) {
this.initialBlockLength++
}
if (isLeave) {
this.totalLeaveWeeks++
}
}

getLeaveBoundaries () {
Expand Down
43 changes: 32 additions & 11 deletions app/lib/weeks.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,16 @@ class Weeks {
const secondaryLeaveTracker = new LeaveTracker()
let hasCurtailedPrimaryPay = false
let primarySplHasStarted = false
for (let i = this.minimumWeek; i <= 52; i++) {
const week = this._getBaseWeek(i)
const weekLeaveAndPay = this._getWeekLeaveAndPay(i)
for (let weekNumber = this.minimumWeek; weekNumber <= 52; weekNumber++) {
const week = this._getBaseWeek(weekNumber)
const weekLeaveAndPay = this._getWeekLeaveAndPay(weekNumber)

primaryLeaveTracker.next(weekLeaveAndPay.primary.leave, i)
primaryLeaveTracker.next(weekLeaveAndPay.primary.leave, weekNumber)
if (weekLeaveAndPay.primary.leave) {
if (!primarySplHasStarted) {
const startSplBecauseOfBreak = primaryLeaveTracker.initialBlockEnded
const startSplBecauseOfPayAfterCurtailment = hasCurtailedPrimaryPay && weekLeaveAndPay.primary.pay
const startSplBecauseOfUserSelect = this.primary.firstSplWeek <= i
const startSplBecauseOfUserSelect = this.primary.firstSplWeek <= weekNumber
primarySplHasStarted = startSplBecauseOfBreak || startSplBecauseOfPayAfterCurtailment || startSplBecauseOfUserSelect
}
dset(week.primary, 'leave.text', !primarySplHasStarted ? this.primaryLeaveType : 'shared')
Expand All @@ -51,16 +51,32 @@ class Weeks {
}

if (!week.secondary.disabled) {
secondaryLeaveTracker.next(weekLeaveAndPay.secondary.leave, i)
secondaryLeaveTracker.next(weekLeaveAndPay.secondary.leave, weekNumber)
if (weekLeaveAndPay.secondary.leave) {
const maxCellsDisplayedAsPaternity = this.eligibility.secondary.spl || this.eligibility.secondary.shpp ? 2 : 8
const usePaternityLeave = i < 8 && !secondaryLeaveTracker.initialBlockEnded && secondaryLeaveTracker.initialBlockLength <= maxCellsDisplayedAsPaternity
dset(week.secondary, 'leave.text', usePaternityLeave ? 'paternity' : 'shared')
const maxCellsDisplayedAsPaternity = 2
const usePaternityLeave = secondaryLeaveTracker.totalLeaveWeeks <= maxCellsDisplayedAsPaternity

const latestPrimaryWeekLeave = this._getLatestPrimaryMaternityWeekLeave()

// determine whether to display paternity or shared pay label
// the label should say "Paternity" if there are enough weeks left e.g. totalLeaveWeeks <= 2
// and the selected week is within the range of the mother's leave
if (usePaternityLeave && weekNumber <= latestPrimaryWeekLeave && week.primary.leave.text === 'maternity') {
dset(week.secondary, 'leave.text', 'paternity')
} else {
dset(week.secondary, 'leave.text', 'shared')
}

// determine whether to display pay label
if (weekLeaveAndPay.secondary.pay) {
dset(week.secondary, 'pay.text', this.payRates.secondary.statutory)
}

// determine whether to display pay checkbox
dset(week.secondary, 'pay.eligible', this._weekEligibleForSecondaryPay(week))
}

// determine whether to display leave checkbox
dset(week.secondary, 'leave.eligible', this._weekEligibleForSecondaryLeave(week))
}

Expand Down Expand Up @@ -89,7 +105,7 @@ class Weeks {
if (this.eligibility.secondary.spl) {
return true
} else if (this.eligibility.secondary.statutoryLeave) {
return week.secondary.leave.text === 'paternity' && week.number < 8
return week.secondary.leave.text === 'paternity' && week.number < 52
} else {
return false
}
Expand All @@ -116,7 +132,7 @@ class Weeks {
} else if (!this.eligibility.secondary.statutoryPay) {
return false
} else if (!this.eligibility.secondary.spl) {
return week.number < 8
return week.number < 52
} else {
return week.secondary.leave.text === 'paternity'
}
Expand Down Expand Up @@ -212,6 +228,11 @@ class Weeks {
const payAsFloat = parseFloat(pay)
return isNaN(payAsFloat) ? pay : ('£' + (+payAsFloat.toFixed(2)).toLocaleString('en-US'))
}

_getLatestPrimaryMaternityWeekLeave () {
const primaryLeaveWeeks = this.primary.leaveWeeks
return primaryLeaveWeeks.length > 0 ? Math.max(...primaryLeaveWeeks) : 0
}
}

module.exports = Weeks
9 changes: 2 additions & 7 deletions app/paths.js
Original file line number Diff line number Diff line change
Expand Up @@ -200,11 +200,6 @@ class Paths {
url: '/planner/paternity-leave/start',
workFlowPage: true,
workflowParentPath: '/planner/paternity-leave'
},
end: {
url: '/planner/paternity-leave/end',
workFlowPage: true,
workflowParentPath: '/planner/paternity-leave/start'
}
},
'shared-parental-leave': {
Expand All @@ -213,10 +208,10 @@ class Paths {
workflowParentPath: (data, isForValidator) => {
if (isForValidator) {
// Prevent circular reference when validating page history.
return '/planner/paternity-leave/end'
return '/planner/paternity-leave/start'
}
const splBlockPlanningOrder = dataUtils.splBlockPlanningOrder(data)
return splBlockPlanningOrder.length > 0 ? '/planner/shared-parental-leave/end' : '/planner/paternity-leave/end'
return splBlockPlanningOrder.length > 0 ? '/planner/shared-parental-leave/end' : '/planner/paternity-leave/start'
},
start: {
url: '/planner/shared-parental-leave/start',
Expand Down
25 changes: 16 additions & 9 deletions app/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -248,15 +248,22 @@ router.route(paths.getPath('planner.paternity-leave.start'))
res.render('accessible-planner/paternity-leave-start')
})
.post(function (req, res) {
res.redirect(paths.getPath('planner.paternity-leave.end'))
})

router.route(paths.getPath('planner.paternity-leave.end'))
.get(function (req, res) {
clearLaterLeaveBlockAnswers(req, 'secondary.initial.end')
res.render('accessible-planner/paternity-leave-end')
})
.post(function (req, res) {
const startData = delve(req.session.data, 'leave-blocks.secondary.initial.start')
const updatedData = {
initial: [
{
start: startData[0],
end: parseInt(startData[0]) + 1,
leave: 'paternity'
},
{
start: startData[1],
end: parseInt(startData[1]) + 1,
leave: 'paternity'
}
]
}
dset(req.session.data, 'leave-blocks.secondary.initial', updatedData.initial)
res.redirect(paths.getPath('planner.shared-parental-leave'))
})

Expand Down
17 changes: 11 additions & 6 deletions app/views/accessible-planner/answers-so-far/macro.njk
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@
<h2 class="govuk-heading-m">
Your answers so far
</h2>
<p>
Leave{{ leaveBlocks["secondary"]["initial"][0].start }}
Leave{{ leaveBlocks["secondary"]["initial"][1].start }}
</p>

{{ govukSummaryList({
rows: [
{
Expand Down Expand Up @@ -76,10 +81,10 @@
},
{
key: {
text: "Paternity Leave start"
text: "Paternity Leave start (week 1)"
},
value: {
text: date(data, leaveBlocks["secondary"]["initial"]["start"])
text: date(data, leaveBlocks["secondary"]["initial"][0]["start"])
},
actions: {
items: [
Expand All @@ -93,17 +98,17 @@
},
{
key: {
text: "Paternity Leave end"
text: "Paternity Leave start (week 2)"
},
value: {
text: dateEnd(data, leaveBlocks["secondary"]["initial"]["end"])
text: date(data, leaveBlocks["secondary"]["initial"][1]["start"])
},
actions: {
items: [
{
href: "/planner/paternity-leave/end",
href: "/planner/paternity-leave/start",
text: "Change",
visuallyHiddenText: "Paternity Leave end"
visuallyHiddenText: "Paternity Leave start"
}
]
}
Expand Down
2 changes: 1 addition & 1 deletion app/views/accessible-planner/paternity-leave-end.njk
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
{% set isOverseasAdoption = (data | isOverseasAdoption) %}
{% set zeroWeek = (data | zeroWeek) %}
{% set firstWeekOfLeave = (data["leave-blocks"]["secondary"]["initial"]["start"] | int) %}
{% set options = range(firstWeekOfLeave, firstWeekOfLeave + 2 if firstWeekOfLeave < 7 else 8) %}
{% set options = range(firstWeekOfLeave, firstWeekOfLeave + 2 if firstWeekOfLeave < 51 else 52) %}

{% macro optionText(weekNumber) %}
{% set totalWeeks = weekNumber - firstWeekOfLeave + 1 %}
Expand Down
16 changes: 13 additions & 3 deletions app/views/accessible-planner/paternity-leave-start.njk
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@
{% set zeroWeek = (data | zeroWeek) %}
{% set isAdoption = (data | isAdoption) %}
{% set birthOrPlacement= (data | birthOrPlacement) %}
{% set primaryLeaveEnd = data["leave-blocks"]["primary"]["initial"]["end"] %}
{% set primaryLeaveEnd = data["leave-blocks"]["primary"]["initial"]["end"] | float %}

{% set options = range(0, 8) %}
{% set options = range(primaryLeaveEnd + 1) %}

{% macro optionText(weekNumber) %}
{% if (weekNumber === 0) %}
Expand All @@ -49,7 +49,17 @@
id: "primary-leave-start",
name: "leave-blocks[secondary][initial][start]",
label: {
text: "When will Paternity Leave start?",
text: "When will the first week of Paternity Leave start?",
classes: "govuk-label--l",
isPageHeading: true
},
items: options | mapValuesToSelectOptions(optionText)
}) }}
{{ govukSelect({
id: "primary-leave-start",
name: "leave-blocks[secondary][initial][start]",
label: {
text: "When will the second week of Paternity Leave start?",
classes: "govuk-label--l",
isPageHeading: true
},
Expand Down
3 changes: 1 addition & 2 deletions app/views/accessible-planner/paternity-leave.njk
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,7 @@
{% call appendHiddenFields(data) %}
{% set hint %}
<p class="govuk-hint">
A partner can take up to 2 weeks of Paternity Leave in the first 8 weeks after {{ birthOrPlacement }}.
Weeks must be taken together, without breaks.
A partner can take up to 2 weeks of Paternity Leave in the first year after {{ birthOrPlacement }}.
</p>
{% if (remainingLeaveAllowance > 0) %}
<p class="govuk-hint">
Expand Down
42 changes: 42 additions & 0 deletions app/views/components/paternity-leave-block-summary.njk
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{% from "summary-list/macro.njk" import govukSummaryList %}

{% macro paternityLeaveBlockSummary(options) %}
{{ govukSummaryList({
classes: "summary-block-print-margin",
rows: [
{
key: {
text: options.name + " starts (week 1)"
},
value: {
text: "week starting " + options.data | startDay | startOfWeek | offsetWeeks(options.block[0].start) | formatForDisplay
}
},
{
key: {
text: options.name + " starts (week 2)"
},
value: {
text: "week starting " + options.data | startDay | startOfWeek | offsetWeeks(options.block[1].start) | formatForDisplay
}
} if options.block.length > 1 else "",
{
key: {
text: "Length"
},
value: {
text: options.block | paternalBlockLength | weeks
}
},
{
key: {
text: "Notify employers"
},
value: {
html: "by " + (options.notify.date | formatForDisplay) + ("*" if options.notify.asterisk) + "<br>" +
"(" + options.notify.explanation + ")"
}
}
]
}) }}
{% endmacro %}
Loading

0 comments on commit 8833668

Please sign in to comment.