From d40ee56b1b896156f08b77247a1898a592751731 Mon Sep 17 00:00:00 2001 From: Pavilion Sahota Date: Thu, 29 Feb 2024 14:32:22 +0000 Subject: [PATCH 1/2] Added logic to hide save button if no changes were made --- server/model/remandChangeModel.ts | 28 +++++++++++++++++++ server/routes/remandRoutes.ts | 4 ++- .../views/pages/adjustments/remand/edit.njk | 6 ++-- 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/server/model/remandChangeModel.ts b/server/model/remandChangeModel.ts index b6a44d5f..6e4f5fc6 100644 --- a/server/model/remandChangeModel.ts +++ b/server/model/remandChangeModel.ts @@ -6,6 +6,7 @@ import { offencesForAdjustment, remandRelatedValidationSummary } from '../utils/ export default class RemandChangeModel { constructor( public adjustment: Adjustment, + private dbAdjustment: Adjustment, private sentencesAndOffences: PrisonApiOffenderSentenceAndOffences[], private calculatedUnusedDeductions: UnusedDeductionCalculationResponse, public showUnusedMessage: boolean, @@ -18,4 +19,31 @@ export default class RemandChangeModel { public remandRelatedValidationSummary() { return remandRelatedValidationSummary(this.calculatedUnusedDeductions?.validationMessages) } + + public isModified(): boolean { + let modified = false + if (this.dbAdjustment) { + if (this.adjustment.remand.chargeId.length !== this.dbAdjustment.remand.chargeId.length) { + modified = true + } else { + const sessionAdjustmentCharges = this.adjustment.remand.chargeId.sort((a, b) => a - b) + const dbAdjustmentCharges = this.dbAdjustment.remand.chargeId.sort((a, b) => a - b) + + for (let i = 0; i < sessionAdjustmentCharges.length; i += 1) { + if (sessionAdjustmentCharges[i] !== dbAdjustmentCharges[i]) { + modified = true + } + } + } + + if ( + !modified && + (this.adjustment.toDate !== this.dbAdjustment.toDate || this.adjustment.fromDate !== this.dbAdjustment.fromDate) + ) { + modified = true + } + } + + return modified + } } diff --git a/server/routes/remandRoutes.ts b/server/routes/remandRoutes.ts index f3b21f58..3a5204cb 100644 --- a/server/routes/remandRoutes.ts +++ b/server/routes/remandRoutes.ts @@ -297,7 +297,7 @@ export default class RemandRoutes { ) return res.render('pages/adjustments/remand/remove', { - model: new RemandChangeModel(adjustment, sentencesAndOffences, unusedDeductions, showUnusedMessage), + model: new RemandChangeModel(adjustment, null, sentencesAndOffences, unusedDeductions, showUnusedMessage), }) } @@ -305,6 +305,7 @@ export default class RemandRoutes { const { token } = res.locals.user const { nomsId, id } = req.params const { bookingId } = res.locals.prisoner + const dbAdjustment = await this.adjustmentsService.get(id, token) let sessionAdjustment = this.adjustmentsStoreService.getById(req, nomsId, id) sessionAdjustment = sessionAdjustment || (await this.adjustmentsService.get(id, token)) this.adjustmentsStoreService.store(req, nomsId, id, sessionAdjustment) @@ -334,6 +335,7 @@ export default class RemandRoutes { ...sessionAdjustment, days: daysBetween(new Date(sessionAdjustment.fromDate), new Date(sessionAdjustment.toDate)), }, + dbAdjustment, sentencesAndOffences, unusedDeductions, showUnusedMessage, diff --git a/server/views/pages/adjustments/remand/edit.njk b/server/views/pages/adjustments/remand/edit.njk index 854f1c78..f6a1d3dd 100644 --- a/server/views/pages/adjustments/remand/edit.njk +++ b/server/views/pages/adjustments/remand/edit.njk @@ -57,8 +57,6 @@ isEdit: true }) }} -

Now save the remand time

- {% if model.showUnusedMessage %}

The updates will change the amount of unused deductions. Check the unused remand alert on NOMIS.

{% endif %} @@ -66,9 +64,9 @@
- {% if not model.remandRelatedValidationSummary().errorList.length %} + {% if not model.remandRelatedValidationSummary().errorList.length and model.isModified() %} {{ govukButton({ - text: "Save", + text: "Confirm and save", type: submit, preventDoubleClick: true }) }} From b29d05b62402f6e5433edc7313022e32453ae92d Mon Sep 17 00:00:00 2001 From: Pavilion Sahota Date: Fri, 1 Mar 2024 11:53:26 +0000 Subject: [PATCH 2/2] Refactored modification check function and wrote unit tests --- server/model/remandChangeModel.ts | 33 +++++++++----------------- server/routes/remandRoutes.test.ts | 37 ++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 22 deletions(-) diff --git a/server/model/remandChangeModel.ts b/server/model/remandChangeModel.ts index 6e4f5fc6..01c09b3f 100644 --- a/server/model/remandChangeModel.ts +++ b/server/model/remandChangeModel.ts @@ -21,29 +21,18 @@ export default class RemandChangeModel { } public isModified(): boolean { - let modified = false - if (this.dbAdjustment) { - if (this.adjustment.remand.chargeId.length !== this.dbAdjustment.remand.chargeId.length) { - modified = true - } else { - const sessionAdjustmentCharges = this.adjustment.remand.chargeId.sort((a, b) => a - b) - const dbAdjustmentCharges = this.dbAdjustment.remand.chargeId.sort((a, b) => a - b) - - for (let i = 0; i < sessionAdjustmentCharges.length; i += 1) { - if (sessionAdjustmentCharges[i] !== dbAdjustmentCharges[i]) { - modified = true - } - } - } - - if ( - !modified && - (this.adjustment.toDate !== this.dbAdjustment.toDate || this.adjustment.fromDate !== this.dbAdjustment.fromDate) - ) { - modified = true - } + if (!this.dbAdjustment) { + return false } - return modified + const sessionCharges = this.adjustment.remand.chargeId.sort((a, b) => a - b) + const dbCharges = this.dbAdjustment.remand.chargeId.sort((a, b) => a - b) + + const chargeIdModified = !sessionCharges.every((chargeId, index) => chargeId === dbCharges[index]) + + const dateModified = + this.adjustment.toDate !== this.dbAdjustment.toDate || this.adjustment.fromDate !== this.dbAdjustment.fromDate + + return chargeIdModified || dateModified } } diff --git a/server/routes/remandRoutes.test.ts b/server/routes/remandRoutes.test.ts index 22f71130..80cfa567 100644 --- a/server/routes/remandRoutes.test.ts +++ b/server/routes/remandRoutes.test.ts @@ -712,6 +712,43 @@ describe('Remand routes tests', () => { .expect('Location', `/${NOMS_ID}/success?message=%7B%22action%22:%22REMAND_UPDATED%22%7D`) }) + it('GET /{nomsId}/remand/edit/:id No save button because of no changes made', () => { + const adjustments: Record = {} + adjustments[SESSION_ID] = adjustmentWithDatesAndCharges + prisonerService.getSentencesAndOffencesFilteredForRemand.mockResolvedValue(stubbedSentencesAndOffences) + adjustmentsService.findByPersonOutsideSentenceEnvelope.mockResolvedValue([]) + adjustmentsStoreService.getById.mockReturnValue(adjustmentWithDatesAndCharges) + adjustmentsStoreService.getAll.mockReturnValue(adjustments) + adjustmentsService.getAdjustmentsExceptOneBeingEdited.mockResolvedValue([adjustmentWithDatesAndCharges]) + + return request(app) + .get(`/${NOMS_ID}/remand/edit/${SESSION_ID}`) + .expect(200) + .expect(res => { + expect(res.text).not.toContain('Confirm and save') + }) + }) + + it('GET /{nomsId}/remand/edit/:id Save button visible because of changes made', () => { + const adjustments: Record = {} + adjustments[SESSION_ID] = adjustmentWithDatesAndCharges + prisonerService.getSentencesAndOffencesFilteredForRemand.mockResolvedValue(stubbedSentencesAndOffences) + adjustmentsService.findByPersonOutsideSentenceEnvelope.mockResolvedValue([]) + adjustmentsStoreService.getById.mockReturnValue(adjustmentWithDatesAndCharges) + adjustmentsStoreService.getAll.mockReturnValue(adjustments) + adjustmentsService.getAdjustmentsExceptOneBeingEdited.mockResolvedValue([adjustmentWithDatesAndCharges]) + const modifiedAdjustmentWithDatesAndCharges = { ...adjustmentWithDatesAndCharges } + modifiedAdjustmentWithDatesAndCharges.fromDate = '2023-01-07' + adjustmentsService.get.mockResolvedValue(modifiedAdjustmentWithDatesAndCharges) + + return request(app) + .get(`/${NOMS_ID}/remand/edit/${SESSION_ID}`) + .expect(200) + .expect(res => { + expect(res.text).toContain('Confirm and save') + }) + }) + it('GET /{nomsId}/remand/edit with CRD error', () => { const adjustments: Record = {} adjustments[SESSION_ID] = adjustmentWithDatesAndCharges