From 8b349b168be2f1f8da337b2ff23748ba853c8223 Mon Sep 17 00:00:00 2001 From: Pavilion Sahota Date: Wed, 7 Feb 2024 09:43:40 +0000 Subject: [PATCH 1/9] View tagged bail screen --- server/@types/adjustments/index.d.ts | 2 +- server/model/taggedBailViewModel.ts | 82 +++++++++++++++++++ server/routes/index.ts | 1 + server/routes/taggedBailRoutes.ts | 28 +++++++ .../pages/adjustments/tagged-bail/view.njk | 49 +++++++++++ 5 files changed, 161 insertions(+), 1 deletion(-) create mode 100644 server/model/taggedBailViewModel.ts create mode 100644 server/views/pages/adjustments/tagged-bail/view.njk diff --git a/server/@types/adjustments/index.d.ts b/server/@types/adjustments/index.d.ts index eff339ab..1fd21ff7 100644 --- a/server/@types/adjustments/index.d.ts +++ b/server/@types/adjustments/index.d.ts @@ -215,7 +215,7 @@ export interface components { */ prisonId?: string /** - * @description The name name of the prison where the prisoner was located at the time the adjustment was created + * @description The name of the prison where the prisoner was located at the time the adjustment was created * @example Leeds */ prisonName?: string diff --git a/server/model/taggedBailViewModel.ts b/server/model/taggedBailViewModel.ts new file mode 100644 index 00000000..8bcff148 --- /dev/null +++ b/server/model/taggedBailViewModel.ts @@ -0,0 +1,82 @@ +import { PrisonApiOffenderSentenceAndOffences, PrisonApiPrisoner } from '../@types/prisonApi/prisonClientTypes' +import { Adjustment } from '../@types/adjustments/adjustmentsTypes' +import { AdjustmentType } from './adjustmentTypes' + +export default class TaggedBailViewModel { + constructor( + public prisonerDetail: PrisonApiPrisoner, + public adjustments: Adjustment[], + public adjustmentType: AdjustmentType, + public sentencesAndOffences: PrisonApiOffenderSentenceAndOffences[], + ) {} + + public backlink(): string { + return `/${this.prisonerDetail.offenderNo}` + } + + public columnHeadings() { + return [ + { text: 'Court name' }, + { text: 'Case reference' }, + { text: 'Days'}, + { text: 'Actions' }, + ] + } + + public rows() { + return this.adjustments.map(it => { + return [ + { text: this.getCourtName(it.taggedBail.caseSequence) }, + { text: this.getCaseReference(it.taggedBail.caseSequence) }, + { text: it.days || it.daysBetween || it.effectiveDays }, + this.actionCell(it), + ] + }) + } + + public table() { + return { + head: this.columnHeadings(), + rows: this.rows().concat(this.totalRow()), + attributes: { 'data-qa': 'view-table' }, + } + } + + public totalRow() { + const total = this.adjustments.map(it => it.days || it.daysBetween || it.effectiveDays).reduce((a, b) => a + b, 0) + return [[{ html: 'Total days' }, { html: '' }, { html: `${total}` }, { text: '' }]] + } + + private getCourtName(caseSequence: number): string { + const sentenceAndOffence = this.sentencesAndOffences.find(it => it.caseSequence === caseSequence) + if (sentenceAndOffence) { + return sentenceAndOffence.courtDescription + } + + return null + } + + private getCaseReference(caseSequence: number): string { + const sentenceAndOffence = this.sentencesAndOffences.find(it => it.caseSequence === caseSequence) + if (sentenceAndOffence) { + return sentenceAndOffence.caseReference + } + + return null + } + + private actionCell(adjustment: Adjustment) { + return { + html: ` +
+
+ Edit
+
+
+ Delete
+
+
+ `, + } + } +} diff --git a/server/routes/index.ts b/server/routes/index.ts index c657e5e2..5fa4c849 100644 --- a/server/routes/index.ts +++ b/server/routes/index.ts @@ -79,6 +79,7 @@ export default function routes(service: Services): Router { get('/:nomsId/remand/no-applicable-sentences', remandRoutes.noApplicableSentences) get('/:nomsId/tagged-bail/add', taggedBailRoutes.add) + get('/:nomsId/tagged-bail/view', taggedBailRoutes.view) get('/:nomsId/tagged-bail/select-case/:addOrEdit/:id', taggedBailRoutes.selectCase) get('/:nomsId/tagged-bail/days/:addOrEdit/:id', taggedBailRoutes.days) post('/:nomsId/tagged-bail/days/:addOrEdit/:id', taggedBailRoutes.submitDays) diff --git a/server/routes/taggedBailRoutes.ts b/server/routes/taggedBailRoutes.ts index 7052052a..8094ac19 100644 --- a/server/routes/taggedBailRoutes.ts +++ b/server/routes/taggedBailRoutes.ts @@ -7,6 +7,9 @@ import TaggedBailDaysModel from '../model/taggedBailDaysModel' import TaggedBailDaysForm from '../model/taggedBailDaysForm' import TaggedBailReviewModel from '../model/taggedBailReviewModel' import { Message } from '../model/adjustmentsHubViewModel' +import adjustmentTypes from "../model/adjustmentTypes"; +import ViewModel from "../model/viewModel"; +import TaggedBailViewModel from "../model/taggedBailViewModel"; export default class TaggedBailRoutes { constructor( @@ -79,6 +82,31 @@ export default class TaggedBailRoutes { return res.redirect(`/${nomsId}/tagged-bail/review/${addOrEdit}/${id}`) } + public view: RequestHandler = async (req, res): Promise => { + const { caseloads, token, roles } = res.locals.user + const { nomsId, adjustmentTypeUrl } = req.params + const prisonerDetail = await this.prisonerService.getPrisonerDetail(nomsId, caseloads, token) + const adjustments = await this.adjustmentsService.findByPerson(nomsId, token) + const taggedBailAdjustments = adjustments.filter(it => it.adjustmentType === 'TAGGED_BAIL') + if (!taggedBailAdjustments) { + return res.redirect(`/${nomsId}`) + } + + const adjustmentType = adjustmentTypes.find(it => it.url === 'tagged-bail') + if (!adjustmentType) { + return res.redirect(`/${nomsId}`) + } + + const sentencesAndOffences = await this.prisonerService.getSentencesAndOffencesFilteredForRemand( + prisonerDetail.bookingId, + token, + ) + + return res.render('pages/adjustments/tagged-bail/view', { + model: new TaggedBailViewModel(prisonerDetail, taggedBailAdjustments, adjustmentType, sentencesAndOffences), + }) + } + public review: RequestHandler = async (req, res): Promise => { const { caseloads, token } = res.locals.user const { nomsId, addOrEdit, id } = req.params diff --git a/server/views/pages/adjustments/tagged-bail/view.njk b/server/views/pages/adjustments/tagged-bail/view.njk new file mode 100644 index 00000000..1eae88ad --- /dev/null +++ b/server/views/pages/adjustments/tagged-bail/view.njk @@ -0,0 +1,49 @@ +{% extends "../../../partials/layout.njk" %} +{% from "govuk/components/table/macro.njk" import govukTable %} +{% from "govuk/components/button/macro.njk" import govukButton %} +{% from "govuk/components/back-link/macro.njk" import govukBackLink %} + +{% set pageTitle = applicationName + " - view " + model.adjustmentType.shortText %} +{% set mainClasses = "app-container govuk-body" %} + +{% block beforeContent %} +{{ super() }} + +{% endblock %} + +{% block content %} +
+
+

+ Adjust release dates + Tagged bail overview +

+
+
+
+
+

+ Tagged Bail details +

+
+
+
+
+ {{ govukTable( + model.table() + ) }} +
+ {{ govukButton({ + text: "Add new", + href: "/" + model.prisonerDetail.offenderNo + "/tagged-bail/add" + }) }} +
+ Return to dashboard +
+
+{% endblock %} \ No newline at end of file From 692cdb7ba5f0bbbbb688ee3d9f425c19fb47d0db Mon Sep 17 00:00:00 2001 From: Pavilion Sahota Date: Wed, 7 Feb 2024 09:43:53 +0000 Subject: [PATCH 2/9] WIP View tagged bail tests --- server/routes/taggedBailRoutes.test.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/server/routes/taggedBailRoutes.test.ts b/server/routes/taggedBailRoutes.test.ts index b3f45dd0..9b838dc4 100644 --- a/server/routes/taggedBailRoutes.test.ts +++ b/server/routes/taggedBailRoutes.test.ts @@ -146,9 +146,23 @@ describe('Tagged bail routes tests', () => { }) }) + it('GET /{nomsId}/tagged-bail/view shows correct information', () => { + prisonerService.getPrisonerDetail.mockResolvedValue(stubbedPrisonerData) + prisonerService.getSentencesAndOffences.mockResolvedValue(stubbedSentencesAndOffences) + adjustmentsService.findByPerson.mockResolvedValue([blankAdjustment]) + adjustmentsStoreService.getById.mockReturnValue(blankAdjustment) + return request(app) + .get(`/${NOMS_ID}/tagged-bail/view`) + .expect(200) + .expect(res => { + expect(res.text).toContain('Tagged bail overview') + }) + }) + it('GET /{nomsId}/tagged-bail/review/add shows correct information', () => { prisonerService.getPrisonerDetail.mockResolvedValue(stubbedPrisonerData) prisonerService.getSentencesAndOffences.mockResolvedValue(stubbedSentencesAndOffences) + prisonerService.getSentencesAndOffencesFilteredForRemand.mockResolvedValue(stubbedSentencesAndOffences) adjustmentsStoreService.getById.mockReturnValue(populatedAdjustment) return request(app) .get(`/${NOMS_ID}/tagged-bail/review/add/${SESSION_ID}`) From 5ada5af68ac30cdc5942d536d96c9812db236bcb Mon Sep 17 00:00:00 2001 From: Pavilion Sahota Date: Wed, 7 Feb 2024 16:11:36 +0000 Subject: [PATCH 3/9] Fixed unit test for view tagged-bail --- server/routes/taggedBailRoutes.test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/routes/taggedBailRoutes.test.ts b/server/routes/taggedBailRoutes.test.ts index 9b838dc4..ce9d9d93 100644 --- a/server/routes/taggedBailRoutes.test.ts +++ b/server/routes/taggedBailRoutes.test.ts @@ -148,9 +148,9 @@ describe('Tagged bail routes tests', () => { it('GET /{nomsId}/tagged-bail/view shows correct information', () => { prisonerService.getPrisonerDetail.mockResolvedValue(stubbedPrisonerData) - prisonerService.getSentencesAndOffences.mockResolvedValue(stubbedSentencesAndOffences) - adjustmentsService.findByPerson.mockResolvedValue([blankAdjustment]) - adjustmentsStoreService.getById.mockReturnValue(blankAdjustment) + prisonerService.getSentencesAndOffencesFilteredForRemand.mockResolvedValue(stubbedSentencesAndOffences) + adjustmentsService.findByPerson.mockResolvedValue([populatedAdjustment]) + adjustmentsStoreService.getById.mockReturnValue(populatedAdjustment) return request(app) .get(`/${NOMS_ID}/tagged-bail/view`) .expect(200) From 9b94631a20421751abcc706609c81c122e2b4b55 Mon Sep 17 00:00:00 2001 From: Pavilion Sahota Date: Wed, 7 Feb 2024 16:16:07 +0000 Subject: [PATCH 4/9] Added more assertions to the view tagged-bail test --- server/routes/taggedBailRoutes.test.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server/routes/taggedBailRoutes.test.ts b/server/routes/taggedBailRoutes.test.ts index ce9d9d93..5106a8c1 100644 --- a/server/routes/taggedBailRoutes.test.ts +++ b/server/routes/taggedBailRoutes.test.ts @@ -156,6 +156,8 @@ describe('Tagged bail routes tests', () => { .expect(200) .expect(res => { expect(res.text).toContain('Tagged bail overview') + expect(res.text).toContain('Court 1') + expect(res.text).toContain('CASE001') }) }) From 23c9164395b949e46c874d774fdf1bdbc59e6cbf Mon Sep 17 00:00:00 2001 From: Pavilion Sahota Date: Wed, 7 Feb 2024 16:37:23 +0000 Subject: [PATCH 5/9] Fixed lint errors --- server/model/taggedBailViewModel.ts | 7 +------ server/views/partials/breadCrumb.njk | 25 ------------------------- 2 files changed, 1 insertion(+), 31 deletions(-) delete mode 100644 server/views/partials/breadCrumb.njk diff --git a/server/model/taggedBailViewModel.ts b/server/model/taggedBailViewModel.ts index 8bcff148..4eb5ac4b 100644 --- a/server/model/taggedBailViewModel.ts +++ b/server/model/taggedBailViewModel.ts @@ -15,12 +15,7 @@ export default class TaggedBailViewModel { } public columnHeadings() { - return [ - { text: 'Court name' }, - { text: 'Case reference' }, - { text: 'Days'}, - { text: 'Actions' }, - ] + return [{ text: 'Court name' }, { text: 'Case reference' }, { text: 'Days' }, { text: 'Actions' }] } public rows() { diff --git a/server/views/partials/breadCrumb.njk b/server/views/partials/breadCrumb.njk deleted file mode 100644 index a7acb914..00000000 --- a/server/views/partials/breadCrumb.njk +++ /dev/null @@ -1,25 +0,0 @@ -{% from "govuk/components/breadcrumbs/macro.njk" import govukBreadcrumbs %} - -{% macro breadCrumb(pageTitle, breadCrumbList) %} - - {% set rows = [ - { - text: "Home", - href: '/' - } - ] - %} - - {% for item in breadCrumbList %} - {% set rows = (rows.push({text: item.title, href: item.href}), rows) %} - {% endfor %} - - {% set completedRows = (rows.push({text: pageTitle}), rows) %} - - {{ govukBreadcrumbs({ - collapseOnMobile: true, - items: completedRows, - classes: "govuk-!-display-none-print" -}) }} - -{% endmacro %} \ No newline at end of file From dd86500358866a818d2b7e370baf02321fa62db4 Mon Sep 17 00:00:00 2001 From: Pavilion Sahota Date: Wed, 7 Feb 2024 16:39:27 +0000 Subject: [PATCH 6/9] Fixed lint errors --- server/routes/taggedBailRoutes.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/server/routes/taggedBailRoutes.ts b/server/routes/taggedBailRoutes.ts index 8094ac19..248c1f39 100644 --- a/server/routes/taggedBailRoutes.ts +++ b/server/routes/taggedBailRoutes.ts @@ -7,9 +7,8 @@ import TaggedBailDaysModel from '../model/taggedBailDaysModel' import TaggedBailDaysForm from '../model/taggedBailDaysForm' import TaggedBailReviewModel from '../model/taggedBailReviewModel' import { Message } from '../model/adjustmentsHubViewModel' -import adjustmentTypes from "../model/adjustmentTypes"; -import ViewModel from "../model/viewModel"; -import TaggedBailViewModel from "../model/taggedBailViewModel"; +import adjustmentTypes from '../model/adjustmentTypes' +import TaggedBailViewModel from '../model/taggedBailViewModel' export default class TaggedBailRoutes { constructor( From 5c9366144cbf9e566747e599edf7d51843bb19ea Mon Sep 17 00:00:00 2001 From: Pavilion Sahota Date: Wed, 7 Feb 2024 16:57:38 +0000 Subject: [PATCH 7/9] Fixed lint errors --- server/routes/taggedBailRoutes.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/routes/taggedBailRoutes.ts b/server/routes/taggedBailRoutes.ts index 248c1f39..0fe060dd 100644 --- a/server/routes/taggedBailRoutes.ts +++ b/server/routes/taggedBailRoutes.ts @@ -82,8 +82,8 @@ export default class TaggedBailRoutes { } public view: RequestHandler = async (req, res): Promise => { - const { caseloads, token, roles } = res.locals.user - const { nomsId, adjustmentTypeUrl } = req.params + const { caseloads, token } = res.locals.user + const { nomsId } = req.params const prisonerDetail = await this.prisonerService.getPrisonerDetail(nomsId, caseloads, token) const adjustments = await this.adjustmentsService.findByPerson(nomsId, token) const taggedBailAdjustments = adjustments.filter(it => it.adjustmentType === 'TAGGED_BAIL') From 580f5abc4f92908c8c5ae0d860f9455fea999161 Mon Sep 17 00:00:00 2001 From: Pavilion Sahota Date: Thu, 8 Feb 2024 13:19:43 +0000 Subject: [PATCH 8/9] Undone comment change --- server/@types/adjustments/index.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/@types/adjustments/index.d.ts b/server/@types/adjustments/index.d.ts index 1fd21ff7..eff339ab 100644 --- a/server/@types/adjustments/index.d.ts +++ b/server/@types/adjustments/index.d.ts @@ -215,7 +215,7 @@ export interface components { */ prisonId?: string /** - * @description The name of the prison where the prisoner was located at the time the adjustment was created + * @description The name name of the prison where the prisoner was located at the time the adjustment was created * @example Leeds */ prisonName?: string From 860976b50b6df9a049aa13cb6013014a4503cf2c Mon Sep 17 00:00:00 2001 From: Pavilion Sahota Date: Thu, 8 Feb 2024 13:20:21 +0000 Subject: [PATCH 9/9] Peer review changes // General refactoring --- server/model/taggedBailSelectCaseModel.ts | 29 ++++++----------------- server/model/taggedBailViewModel.ts | 23 ++++++++++++------ server/routes/taggedBailRoutes.test.ts | 4 ++-- server/routes/taggedBailRoutes.ts | 7 ++---- server/utils/utils.ts | 29 +++++++++++++++++++++++ 5 files changed, 56 insertions(+), 36 deletions(-) diff --git a/server/model/taggedBailSelectCaseModel.ts b/server/model/taggedBailSelectCaseModel.ts index bbd5db5a..8057b8e4 100644 --- a/server/model/taggedBailSelectCaseModel.ts +++ b/server/model/taggedBailSelectCaseModel.ts @@ -1,21 +1,21 @@ import { PrisonApiOffenderSentenceAndOffences, PrisonApiPrisoner } from '../@types/prisonApi/prisonClientTypes' import SessionAdjustment from '../@types/AdjustmentTypes' - -type SentencesByCaseSequence = { - caseSequence: number - sentences: PrisonApiOffenderSentenceAndOffences[] -} +import { getActiveSentencesByCaseSequence, SentencesByCaseSequence } from '../utils/utils' type SentenceWithCaseDetails = PrisonApiOffenderSentenceAndOffences & { selected: boolean; selectCaseHref: string } export default class TaggedBailSelectCaseModel { + private sentencesByCaseSequence: SentencesByCaseSequence[] + constructor( public prisonerDetail: PrisonApiPrisoner, private sentencesAndOffences: PrisonApiOffenderSentenceAndOffences[], private addOrEdit: string, private id: string, public adjustment: SessionAdjustment, - ) {} + ) { + this.sentencesByCaseSequence = getActiveSentencesByCaseSequence(this.sentencesAndOffences) + } public backlink(): string { if (this.adjustment.complete) { @@ -26,8 +26,7 @@ export default class TaggedBailSelectCaseModel { // returns the sentence data for each unique case sequence; i.e. the record that has the earliest sentence date when multiple ones exist public activeSentences(): SentenceWithCaseDetails[] { - const sentencesBySequenceNumber = this.getSentencesByCaseSequence() - return sentencesBySequenceNumber.map(it => { + return this.sentencesByCaseSequence.map(it => { return { ...it.sentences.sort((a, b) => new Date(a.sentenceDate).getTime() - new Date(b.sentenceDate).getTime())[0], selected: this.adjustment.taggedBail?.caseSequence === it.caseSequence, @@ -37,18 +36,4 @@ export default class TaggedBailSelectCaseModel { } }) } - - private getSentencesByCaseSequence(): SentencesByCaseSequence[] { - return this.sentencesAndOffences - .filter(it => it.sentenceStatus === 'A') - .reduce((acc: SentencesByCaseSequence[], cur) => { - if (acc.some(it => it.caseSequence === cur.caseSequence)) { - const record = acc.find(it => it.caseSequence === cur.caseSequence) - record.sentences.push(cur) - } else { - acc.push({ caseSequence: cur.caseSequence, sentences: [cur] } as SentencesByCaseSequence) - } - return acc - }, []) - } } diff --git a/server/model/taggedBailViewModel.ts b/server/model/taggedBailViewModel.ts index 4eb5ac4b..408185d6 100644 --- a/server/model/taggedBailViewModel.ts +++ b/server/model/taggedBailViewModel.ts @@ -1,14 +1,19 @@ import { PrisonApiOffenderSentenceAndOffences, PrisonApiPrisoner } from '../@types/prisonApi/prisonClientTypes' import { Adjustment } from '../@types/adjustments/adjustmentsTypes' import { AdjustmentType } from './adjustmentTypes' +import { getActiveSentencesByCaseSequence, SentencesByCaseSequence } from '../utils/utils' export default class TaggedBailViewModel { + private sentencesByCaseSequence: SentencesByCaseSequence[] + constructor( public prisonerDetail: PrisonApiPrisoner, public adjustments: Adjustment[], public adjustmentType: AdjustmentType, public sentencesAndOffences: PrisonApiOffenderSentenceAndOffences[], - ) {} + ) { + this.sentencesByCaseSequence = getActiveSentencesByCaseSequence(this.sentencesAndOffences) + } public backlink(): string { return `/${this.prisonerDetail.offenderNo}` @@ -43,18 +48,22 @@ export default class TaggedBailViewModel { } private getCourtName(caseSequence: number): string { - const sentenceAndOffence = this.sentencesAndOffences.find(it => it.caseSequence === caseSequence) - if (sentenceAndOffence) { - return sentenceAndOffence.courtDescription + const sentencesForCaseSequence = this.sentencesByCaseSequence.find(it => it.caseSequence === caseSequence) + if (sentencesForCaseSequence) { + return sentencesForCaseSequence.sentences.sort( + (a, b) => new Date(a.sentenceDate).getTime() - new Date(b.sentenceDate).getTime(), + )[0].courtDescription } return null } private getCaseReference(caseSequence: number): string { - const sentenceAndOffence = this.sentencesAndOffences.find(it => it.caseSequence === caseSequence) - if (sentenceAndOffence) { - return sentenceAndOffence.caseReference + const sentencesForCaseSequence = this.sentencesByCaseSequence.find(it => it.caseSequence === caseSequence) + if (sentencesForCaseSequence) { + return sentencesForCaseSequence.sentences.sort( + (a, b) => new Date(a.sentenceDate).getTime() - new Date(b.sentenceDate).getTime(), + )[0].caseReference } return null diff --git a/server/routes/taggedBailRoutes.test.ts b/server/routes/taggedBailRoutes.test.ts index 090581cc..504611fc 100644 --- a/server/routes/taggedBailRoutes.test.ts +++ b/server/routes/taggedBailRoutes.test.ts @@ -148,7 +148,7 @@ describe('Tagged bail routes tests', () => { it('GET /{nomsId}/tagged-bail/view shows correct information', () => { prisonerService.getPrisonerDetail.mockResolvedValue(stubbedPrisonerData) - prisonerService.getSentencesAndOffencesFilteredForRemand.mockResolvedValue(stubbedSentencesAndOffences) + prisonerService.getSentencesAndOffences.mockResolvedValue(stubbedSentencesAndOffences) adjustmentsService.findByPerson.mockResolvedValue([populatedAdjustment]) adjustmentsStoreService.getById.mockReturnValue(populatedAdjustment) return request(app) @@ -156,7 +156,7 @@ describe('Tagged bail routes tests', () => { .expect(200) .expect(res => { expect(res.text).toContain('Tagged bail overview') - expect(res.text).toContain('Court 1') + expect(res.text).toContain('Court 2') expect(res.text).toContain('CASE001') }) }) diff --git a/server/routes/taggedBailRoutes.ts b/server/routes/taggedBailRoutes.ts index 0fe060dd..224d68ef 100644 --- a/server/routes/taggedBailRoutes.ts +++ b/server/routes/taggedBailRoutes.ts @@ -87,7 +87,7 @@ export default class TaggedBailRoutes { const prisonerDetail = await this.prisonerService.getPrisonerDetail(nomsId, caseloads, token) const adjustments = await this.adjustmentsService.findByPerson(nomsId, token) const taggedBailAdjustments = adjustments.filter(it => it.adjustmentType === 'TAGGED_BAIL') - if (!taggedBailAdjustments) { + if (!taggedBailAdjustments.length) { return res.redirect(`/${nomsId}`) } @@ -96,10 +96,7 @@ export default class TaggedBailRoutes { return res.redirect(`/${nomsId}`) } - const sentencesAndOffences = await this.prisonerService.getSentencesAndOffencesFilteredForRemand( - prisonerDetail.bookingId, - token, - ) + const sentencesAndOffences = await this.prisonerService.getSentencesAndOffences(prisonerDetail.bookingId, token) return res.render('pages/adjustments/tagged-bail/view', { model: new TaggedBailViewModel(prisonerDetail, taggedBailAdjustments, adjustmentType, sentencesAndOffences), diff --git a/server/utils/utils.ts b/server/utils/utils.ts index 06a7f102..d4c23bbf 100644 --- a/server/utils/utils.ts +++ b/server/utils/utils.ts @@ -123,6 +123,35 @@ export function offencesForAdjustment( }) } +/** + * Type used to organise sentences and offences by caseSequence. + */ +export type SentencesByCaseSequence = { + caseSequence: number + sentences: PrisonApiOffenderSentenceAndOffences[] +} + +/** + * Takes a list of sentences and offences and converts them to a collection of active sentences for each case sequence. + * @param sentencesAndOffences sentences and offences to be converted. + * @returns a collection of active sentences for each case sequence. + */ +export function getActiveSentencesByCaseSequence( + sentencesAndOffences: PrisonApiOffenderSentenceAndOffences[], +): SentencesByCaseSequence[] { + return sentencesAndOffences + .filter(it => it.sentenceStatus === 'A') + .reduce((acc: SentencesByCaseSequence[], cur) => { + if (acc.some(it => it.caseSequence === cur.caseSequence)) { + const record = acc.find(it => it.caseSequence === cur.caseSequence) + record.sentences.push(cur) + } else { + acc.push({ caseSequence: cur.caseSequence, sentences: [cur] } as SentencesByCaseSequence) + } + return acc + }, []) +} + export function remandRelatedValidationSummary(messages: CalculateReleaseDatesValidationMessage[]) { const remandRelatedValidationCodes = ['REMAND_OVERLAPS_WITH_REMAND', 'REMAND_OVERLAPS_WITH_SENTENCE']