From 46ed6a5f5d9db26821af3156e3a5f29e2ab7b7c9 Mon Sep 17 00:00:00 2001 From: akikrahman1 <149579836+akikrahman1@users.noreply.github.com> Date: Fri, 13 Dec 2024 14:01:37 +0000 Subject: [PATCH] Interim 6 (#825) * task/JS-170 Jury attendance audit number is incorrect (#823) * Task/JS-158 Confirmed attendances go missing (#822) * task/JS-158 Cannot update confirmed attendance * Update JurorAppearanceServiceImpl.java * updating tests need to check if we want to apply the check for confirmed jurors as an exception or just skip them * Update JurorManagementControllerITest.java * task/JS-167 Failing to resend Initial Summons Letters (#821) * Update MojException.java * task/JS-171 (#826) --- .../JurorManagementControllerITest.java | 58 ++++++++++++++++++- .../moj/controller/LetterControllerITest.java | 18 +++--- .../UpdateAttendanceDetails.sql | 9 ++- .../UpdateAttendanceDetailsCheckInAll.sql | 57 ++++++++++++++++++ .../moj/enumeration/letter/LetterType.java | 2 +- .../juror/api/moj/exception/MojException.java | 4 +- .../moj/service/PoolRequestServiceImpl.java | 3 +- .../JurorAppearanceServiceImpl.java | 25 +++++++- .../ManageDeferralsServiceTest.java | 2 +- .../JurorAppearanceServiceTest.java | 2 +- 10 files changed, 160 insertions(+), 20 deletions(-) create mode 100644 src/integration-test/resources/db/jurormanagement/UpdateAttendanceDetailsCheckInAll.sql diff --git a/src/integration-test/java/uk/gov/hmcts/juror/api/moj/controller/JurorManagementControllerITest.java b/src/integration-test/java/uk/gov/hmcts/juror/api/moj/controller/JurorManagementControllerITest.java index fc51e013f..420875fed 100644 --- a/src/integration-test/java/uk/gov/hmcts/juror/api/moj/controller/JurorManagementControllerITest.java +++ b/src/integration-test/java/uk/gov/hmcts/juror/api/moj/controller/JurorManagementControllerITest.java @@ -97,6 +97,7 @@ class JurorManagementControllerITest extends AbstractIntegrationTest { private static final String JUROR7 = "777777777"; private static final String JUROR8 = "888888888"; private static final String JUROR9 = "999999999"; + private static final String JUROR10 = "101010101"; private static final String URL_ATTENDANCE = "/api/v1/moj/juror-management/attendance"; private static final String HTTP_STATUS_OK_MESSAGE = "Expect the HTTP status to be OK"; @@ -720,6 +721,24 @@ void updateAttendanceCheckOutSingleJuror() { } } + + @Test + @DisplayName("PATCH Update attendance - check out single juror but already confirmed - unhappy path") + @Sql({"/db/mod/truncate.sql", "/db/jurormanagement/UpdateAttendanceDetails.sql"}) + void updateAttendanceCheckOutSingleJurorAlreadyConfirmed() { + List jurors = new ArrayList<>(); + jurors.add(JUROR10); + UpdateAttendanceDto request = buildUpdateAttendanceDto(jurors); + request.getCommonData().setSingleJuror(Boolean.TRUE); + + ResponseEntity response = + restTemplate.exchange(new RequestEntity<>(request, httpHeaders, PATCH, + URI.create(URL_ATTENDANCE)), AttendanceDetailsResponse.class); + + assertThat(response.getStatusCode()).as("Unprocessable Entity").isEqualTo(UNPROCESSABLE_ENTITY); + + } + @Test @DisplayName("PATCH Update attendance - checkout multiple jurors in list") @Sql({"/db/mod/truncate.sql", "/db/jurormanagement/UpdateAttendanceDetails.sql"}) @@ -915,7 +934,7 @@ void updateAttendanceCheckOutAllPanelledJurorsInList() { @Test @DisplayName("PATCH Update attendance - check in all jurors updated ") - @Sql({"/db/mod/truncate.sql", "/db/jurormanagement/UpdateAttendanceDetails.sql"}) + @Sql({"/db/mod/truncate.sql", "/db/jurormanagement/UpdateAttendanceDetailsCheckInAll.sql"}) void updateAttendanceCheckIn() { UpdateAttendanceDto request = buildUpdateAttendanceDto(null); request.getCommonData().setStatus(UpdateAttendanceStatus.CHECK_IN); @@ -974,6 +993,22 @@ void updateAttendanceCheckIn() { } } + @Test + @DisplayName("PATCH Update attendance - check in all jurors updated one already confirmed - unhappy path") + @Sql({"/db/mod/truncate.sql", "/db/jurormanagement/UpdateAttendanceDetails.sql"}) + void updateAttendanceCheckInAlreadyConfirmed() { + UpdateAttendanceDto request = buildUpdateAttendanceDto(null); + request.getCommonData().setStatus(UpdateAttendanceStatus.CHECK_IN); + request.getCommonData().setCheckOutTime(null); + + ResponseEntity response = + restTemplate.exchange(new RequestEntity<>(request, httpHeaders, PATCH, + URI.create(URL_ATTENDANCE)), AttendanceDetailsResponse.class); + + assertThat(response.getStatusCode()).as("Unprocessable entity").isEqualTo(UNPROCESSABLE_ENTITY); + + } + @Test @DisplayName("PATCH Update attendance - check in and out of juror updated") @Sql({"/db/mod/truncate.sql", "/db/jurormanagement/UpdateAttendanceDetails.sql"}) @@ -1026,6 +1061,27 @@ void updateAttendanceCheckInAndOut() { } } + @Test + @DisplayName("PATCH Update attendance - check in and out of juror confirmed juror - unhappy path") + @Sql({"/db/mod/truncate.sql", "/db/jurormanagement/UpdateAttendanceDetails.sql"}) + void updateAttendanceCheckInAndOutAlreadyConfirmed() { + List jurors = new ArrayList<>(); + jurors.add(JUROR10); + UpdateAttendanceDto request = buildUpdateAttendanceDto(jurors); + request.getCommonData().setStatus(UpdateAttendanceStatus.CHECK_IN_AND_OUT); + request.getCommonData().setCheckInTime(LocalTime.of(9, 30)); + request.getCommonData().setCheckOutTime(LocalTime.of(17, 30)); + request.getCommonData().setSingleJuror(Boolean.TRUE); + + ResponseEntity response = + restTemplate.exchange(new RequestEntity<>(request, httpHeaders, PATCH, + URI.create(URL_ATTENDANCE)), AttendanceDetailsResponse.class); + + assertThat(response.getStatusCode()).as("Unprocessable entity").isEqualTo(UNPROCESSABLE_ENTITY); + + } + + @Test @DisplayName("PATCH Update attendance - confirm attendance (no shows)") @Sql({"/db/mod/truncate.sql", "/db/jurormanagement/UpdateAttendanceDetails.sql", diff --git a/src/integration-test/java/uk/gov/hmcts/juror/api/moj/controller/LetterControllerITest.java b/src/integration-test/java/uk/gov/hmcts/juror/api/moj/controller/LetterControllerITest.java index a5269eef9..e057e28b2 100644 --- a/src/integration-test/java/uk/gov/hmcts/juror/api/moj/controller/LetterControllerITest.java +++ b/src/integration-test/java/uk/gov/hmcts/juror/api/moj/controller/LetterControllerITest.java @@ -2711,9 +2711,9 @@ private void verifyHeadingsAndTypesSummons(ReissueLetterListResponseDto reissueL List headings = reissueLetterListResponseDto.getHeadings(); assertThat(headings).isNotNull(); assertThat(headings.size()).as("Expect there to be 9 headings").isEqualTo(9); - assertThat(headings.get(0)).isEqualTo("Pool Number"); - assertThat(headings.get(1)).isEqualTo("Summons date"); - assertThat(headings.get(2)).isEqualTo("Juror number"); + assertThat(headings.get(0)).isEqualTo("Juror number"); + assertThat(headings.get(1)).isEqualTo("Pool Number"); + assertThat(headings.get(2)).isEqualTo("Summons date"); assertThat(headings.get(3)).isEqualTo("First name"); assertThat(headings.get(4)).isEqualTo("Last name"); assertThat(headings.get(5)).isEqualTo("Postcode"); @@ -2768,10 +2768,10 @@ void reissueInitialSummonsLetterListByJurorNumber() throws Exception { List> data = reissueLetterListResponseDto.getData(); assertThat(data).isNotNull(); assertThat(data.size()).isEqualTo(1); + assertThat(data.get(0).get(0)).isEqualTo("555555561"); assertThat(data.get(0).size()).isEqualTo(9); - assertThat(data.get(0).get(0)).isEqualTo("415241001"); - assertThat(data.get(0).get(1)).isEqualTo("TUESDAY 8 OCTOBER, 2024"); - assertThat(data.get(0).get(2)).isEqualTo("555555561"); + assertThat(data.get(0).get(1)).isEqualTo("415241001"); + assertThat(data.get(0).get(2)).isEqualTo("TUESDAY 8 OCTOBER, 2024"); assertThat(data.get(0).get(3)).isEqualTo("FNAMEFIVEFOURZERO"); assertThat(data.get(0).get(4)).isEqualTo("LNAMEFIVEFOURZERO"); assertThat(data.get(0).get(5)).isEqualTo("CH1 2AN"); @@ -2847,9 +2847,9 @@ void reissueInitialSummonsLetterListByJurorNumberWelsh() throws Exception { assertThat(data).isNotNull(); assertThat(data.size()).isEqualTo(1); assertThat(data.get(0).size()).isEqualTo(9); - assertThat(data.get(0).get(0)).isEqualTo("415241001"); - assertThat(data.get(0).get(1)).isEqualTo("TUESDAY 8 OCTOBER, 2024"); - assertThat(data.get(0).get(2)).isEqualTo("555555562"); + assertThat(data.get(0).get(0)).isEqualTo("555555562"); + assertThat(data.get(0).get(1)).isEqualTo("415241001"); + assertThat(data.get(0).get(2)).isEqualTo("TUESDAY 8 OCTOBER, 2024"); assertThat(data.get(0).get(3)).isEqualTo("FNAMEFIVEFOURZERO"); assertThat(data.get(0).get(4)).isEqualTo("LNAMEFIVEFOURZERO"); assertThat(data.get(0).get(5)).isEqualTo("CH1 2AN"); diff --git a/src/integration-test/resources/db/jurormanagement/UpdateAttendanceDetails.sql b/src/integration-test/resources/db/jurormanagement/UpdateAttendanceDetails.sql index 140efb6c4..26c075d6b 100644 --- a/src/integration-test/resources/db/jurormanagement/UpdateAttendanceDetails.sql +++ b/src/integration-test/resources/db/jurormanagement/UpdateAttendanceDetails.sql @@ -28,7 +28,8 @@ insert into juror_mod.juror (juror_number, last_name, first_name, dob, addre ('666666666', 'SIX', 'TEST', NULL, '540 STREET NAME', 'ANYTOWN', 'CH1 2AN', TRUE), ('777777777', 'SEVEN', 'TEST', NULL, '540 STREET NAME', 'ANYTOWN', 'CH1 2AN', TRUE), ('888888888', 'EIGHT', 'TEST', NULL, '540 STREET NAME', 'ANYTOWN', 'CH1 2AN', TRUE), -('999999999', 'NINE', 'TEST', NULL, '540 STREET NAME', 'ANYTOWN', 'CH1 2AN', TRUE); +('999999999', 'NINE', 'TEST', NULL, '540 STREET NAME', 'ANYTOWN', 'CH1 2AN', TRUE), +('101010101', 'TEN', 'TEST', NULL, '540 STREET NAME', 'ANYTOWN', 'CH1 2AN', TRUE); --JUROR_MOD.JUROR_POOL insert into juror_mod.juror_pool (owner, juror_number, pool_number, next_date, def_date, status, is_active, was_deferred) values @@ -40,7 +41,8 @@ insert into juror_mod.juror_pool (owner, juror_number, pool_number, next_date, d ('415', '666666666', '415230101', current_date - interval '2 weeks', NULL, 2, TRUE, FALSE), ('415', '777777777', '415230101', current_date - interval '2 weeks', NULL, 2, TRUE, FALSE), ('415', '888888888', '415230101', current_date - interval '2 days', NULL, 2, TRUE, FALSE), -('415', '999999999', '415230101', current_date - interval '2 days', NULL, 2, TRUE, FALSE); +('415', '999999999', '415230101', current_date - interval '2 days', NULL, 2, TRUE, FALSE), +('415', '101010101', '415230101', current_date - interval '2 days', NULL, 2, TRUE, FALSE); --JUROR_MOD.APPEARANCE insert into juror_mod.appearance (attendance_date,juror_number,loc_code,time_in,time_out,non_attendance,appearance_stage,attendance_type, trial_number) values @@ -50,7 +52,8 @@ insert into juror_mod.appearance (attendance_date,juror_number,loc_code,time_in, (current_date - interval '2 days','333333333','415','09:30:00',null,false,'CHECKED_IN','FULL_DAY','T10000000'), (current_date - interval '2 days','555555555','415','06:30:00',null,false,'CHECKED_IN','FULL_DAY',null), (current_date - interval '2 days','666666666','415','09:30:00',null,false,'CHECKED_IN','FULL_DAY',null), -(current_date - interval '2 days','777777777','415','12:30','15:50',false,'CHECKED_IN','FULL_DAY',null); +(current_date - interval '2 days','777777777','415','12:30','15:50',false,'CHECKED_IN','FULL_DAY',null), +(current_date - interval '2 days','101010101','415','09:31:00','16:00',false,'EXPENSE_ENTERED','FULL_DAY',null); INSERT INTO juror_mod.juror_trial (loc_code, juror_number, trial_number, rand_number, date_selected, "result",completed, empanelled_date) values ('415', '222222222', 'T10000000', 10,current_date - interval '2 days' + time '09:00:00', 'J', null, current_date - interval '2 days'), diff --git a/src/integration-test/resources/db/jurormanagement/UpdateAttendanceDetailsCheckInAll.sql b/src/integration-test/resources/db/jurormanagement/UpdateAttendanceDetailsCheckInAll.sql new file mode 100644 index 000000000..140efb6c4 --- /dev/null +++ b/src/integration-test/resources/db/jurormanagement/UpdateAttendanceDetailsCheckInAll.sql @@ -0,0 +1,57 @@ +alter sequence attendance_audit_seq restart with 10000000; +ALTER SEQUENCE juror_mod.judge_id_seq +RESTART WITH 1; +ALTER SEQUENCE juror_mod.courtroom_id_seq +RESTART WITH 1; + +insert into juror_mod.judge (owner, code, description) values +('415', '9999', 'judge jose'); + +insert into juror_mod.courtroom (loc_code, room_number, description) values +('415', '99995', 'big room'); + +insert into juror_mod.trial (trial_number, loc_code, description, judge, trial_type, trial_start_date, anonymous,courtroom) +values ('T10000000', '415', 'TEST DEFENDANT', 1, 'CIV', current_date - 2, false, 1); + +--JUROR_MOD.POOL +insert into juror_mod.pool (owner, pool_no, return_date, total_no_required, no_requested, pool_type,loc_code, new_request, last_update) values +('415', '415230101', current_date - interval '2 weeks', 10, 10, 'CRO','415', 'N', TIMESTAMP'2022-02-02 09:22:09.0'), +('415', '415230102', current_date - interval '2 weeks', 10, 10, 'CRO','415', 'N', TIMESTAMP'2022-02-02 09:22:09.0'); + +--JUROR_MOD.JUROR +insert into juror_mod.juror (juror_number, last_name, first_name, dob, address_line_1, address_line_4, postcode, responded) values +('111111111', 'LASTNAME', 'TEST', NULL, '540 STREET NAME', 'ANYTOWN', 'CH1 2AN', TRUE), +('222222222', 'TWO', 'TEST', NULL, '540 STREET NAME', 'ANYTOWN', 'CH1 2AN', TRUE), +('333333333', 'THREE', 'TEST', NULL, '540 STREET NAME', 'ANYTOWN', 'CH1 2AN', TRUE), +('444444444', 'FOUR', 'TEST', NULL, '540 STREET NAME', 'ANYTOWN', 'CH1 2AN', TRUE), +('555555555', 'FIVE', 'TEST', NULL, '540 STREET NAME', 'ANYTOWN', 'CH1 2AN', TRUE), +('666666666', 'SIX', 'TEST', NULL, '540 STREET NAME', 'ANYTOWN', 'CH1 2AN', TRUE), +('777777777', 'SEVEN', 'TEST', NULL, '540 STREET NAME', 'ANYTOWN', 'CH1 2AN', TRUE), +('888888888', 'EIGHT', 'TEST', NULL, '540 STREET NAME', 'ANYTOWN', 'CH1 2AN', TRUE), +('999999999', 'NINE', 'TEST', NULL, '540 STREET NAME', 'ANYTOWN', 'CH1 2AN', TRUE); + +--JUROR_MOD.JUROR_POOL +insert into juror_mod.juror_pool (owner, juror_number, pool_number, next_date, def_date, status, is_active, was_deferred) values +('415', '111111111', '415230101', current_date - interval '2 weeks', NULL, 2, TRUE, FALSE), +('415', '222222222', '415230101', current_date - interval '2 weeks', NULL, 4, TRUE, TRUE), +('415', '333333333', '415230101', current_date - interval '2 weeks', NULL, 3, TRUE, TRUE), +('415', '444444444', '415230101', current_date - interval '2 weeks', NULL, 1, TRUE, FALSE), +('415', '555555555', '415230101', current_date - interval '2 weeks', NULL, 2, TRUE, FALSE), +('415', '666666666', '415230101', current_date - interval '2 weeks', NULL, 2, TRUE, FALSE), +('415', '777777777', '415230101', current_date - interval '2 weeks', NULL, 2, TRUE, FALSE), +('415', '888888888', '415230101', current_date - interval '2 days', NULL, 2, TRUE, FALSE), +('415', '999999999', '415230101', current_date - interval '2 days', NULL, 2, TRUE, FALSE); + +--JUROR_MOD.APPEARANCE +insert into juror_mod.appearance (attendance_date,juror_number,loc_code,time_in,time_out,non_attendance,appearance_stage,attendance_type, trial_number) values +(current_date - interval '1 day','111111111','415','09:31:00',null,false,'CHECKED_IN','FULL_DAY',null), +(current_date - interval '2 days','111111111','415','09:30:00',null,false,'CHECKED_IN','FULL_DAY',null), +(current_date - interval '2 days','222222222','415','09:30:00',null,false,'CHECKED_IN','FULL_DAY','T10000000'), +(current_date - interval '2 days','333333333','415','09:30:00',null,false,'CHECKED_IN','FULL_DAY','T10000000'), +(current_date - interval '2 days','555555555','415','06:30:00',null,false,'CHECKED_IN','FULL_DAY',null), +(current_date - interval '2 days','666666666','415','09:30:00',null,false,'CHECKED_IN','FULL_DAY',null), +(current_date - interval '2 days','777777777','415','12:30','15:50',false,'CHECKED_IN','FULL_DAY',null); + +INSERT INTO juror_mod.juror_trial (loc_code, juror_number, trial_number, rand_number, date_selected, "result",completed, empanelled_date) values +('415', '222222222', 'T10000000', 10,current_date - interval '2 days' + time '09:00:00', 'J', null, current_date - interval '2 days'), +('415', '333333333', 'T10000000', 10,current_date - interval '2 days' + time '09:00:00', null, null, null); diff --git a/src/main/java/uk/gov/hmcts/juror/api/moj/enumeration/letter/LetterType.java b/src/main/java/uk/gov/hmcts/juror/api/moj/enumeration/letter/LetterType.java index cac6f6c64..bd39c1c0f 100644 --- a/src/main/java/uk/gov/hmcts/juror/api/moj/enumeration/letter/LetterType.java +++ b/src/main/java/uk/gov/hmcts/juror/api/moj/enumeration/letter/LetterType.java @@ -20,9 +20,9 @@ public enum LetterType { SUMMONS(List.of(FormCode.ENG_SUMMONS, FormCode.BI_SUMMONS), List.of( + ReissueLetterService.DataType.JUROR_NUMBER, ReissueLetterService.DataType.SUMMONS_POOL_NUMBER, ReissueLetterService.DataType.SUMMONS_DATE, - ReissueLetterService.DataType.JUROR_NUMBER, ReissueLetterService.DataType.JUROR_FIRST_NAME, ReissueLetterService.DataType.JUROR_LAST_NAME, ReissueLetterService.DataType.JUROR_POSTCODE, diff --git a/src/main/java/uk/gov/hmcts/juror/api/moj/exception/MojException.java b/src/main/java/uk/gov/hmcts/juror/api/moj/exception/MojException.java index e48402680..ff36462c0 100644 --- a/src/main/java/uk/gov/hmcts/juror/api/moj/exception/MojException.java +++ b/src/main/java/uk/gov/hmcts/juror/api/moj/exception/MojException.java @@ -98,8 +98,10 @@ public enum ErrorCode { CANNOT_DEFER_TO_EXISTING_POOL, CANNOT_DEFER_JUROR_WITH_APPEARANCE, CANNOT_PROCESS_EMPANELLED_JUROR, + CANNOT_UPDATE_CONFIRMED_ATTENDANCE, CANNOT_RE_ADD_JUROR_TO_PANEL, - UNCONFIRMED_ATTENDANCE_EXISTS + UNCONFIRMED_ATTENDANCE_EXISTS, + INVALID_JUROR_STATUS } } diff --git a/src/main/java/uk/gov/hmcts/juror/api/moj/service/PoolRequestServiceImpl.java b/src/main/java/uk/gov/hmcts/juror/api/moj/service/PoolRequestServiceImpl.java index ce31c1092..9ca760e7e 100644 --- a/src/main/java/uk/gov/hmcts/juror/api/moj/service/PoolRequestServiceImpl.java +++ b/src/main/java/uk/gov/hmcts/juror/api/moj/service/PoolRequestServiceImpl.java @@ -339,7 +339,8 @@ public PoolsAtCourtLocationListDto getAllActivePoolsAtCourtLocation(String locCo return new PoolsAtCourtLocationListDto(data); } - private static void populatePoolsListing(List poolsListing, List data) { + private static void populatePoolsListing(List poolsListing, + List data) { poolsListing.forEach(pool -> { List poolDetails = Arrays.asList(pool.split(",")); diff --git a/src/main/java/uk/gov/hmcts/juror/api/moj/service/jurormanagement/JurorAppearanceServiceImpl.java b/src/main/java/uk/gov/hmcts/juror/api/moj/service/jurormanagement/JurorAppearanceServiceImpl.java index ed3051148..0fc7f0253 100644 --- a/src/main/java/uk/gov/hmcts/juror/api/moj/service/jurormanagement/JurorAppearanceServiceImpl.java +++ b/src/main/java/uk/gov/hmcts/juror/api/moj/service/jurormanagement/JurorAppearanceServiceImpl.java @@ -58,6 +58,7 @@ import java.time.LocalDate; import java.time.LocalTime; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; @@ -68,6 +69,8 @@ import static uk.gov.hmcts.juror.api.moj.exception.MojException.BusinessRuleViolation.ErrorCode.APPEARANCE_RECORD_BEFORE_SERVICE_START_DATE; import static uk.gov.hmcts.juror.api.moj.exception.MojException.BusinessRuleViolation.ErrorCode.ATTENDANCE_RECORD_ALREADY_EXISTS; import static uk.gov.hmcts.juror.api.moj.exception.MojException.BusinessRuleViolation.ErrorCode.CANNOT_PROCESS_EMPANELLED_JUROR; +import static uk.gov.hmcts.juror.api.moj.exception.MojException.BusinessRuleViolation.ErrorCode.CANNOT_UPDATE_CONFIRMED_ATTENDANCE; +import static uk.gov.hmcts.juror.api.moj.exception.MojException.BusinessRuleViolation.ErrorCode.INVALID_JUROR_STATUS; import static uk.gov.hmcts.juror.api.moj.utils.CourtLocationUtils.getNextWorkingDay; import static uk.gov.hmcts.juror.api.moj.utils.DataUtils.isEmptyOrNull; import static uk.gov.hmcts.juror.api.moj.utils.JurorUtils.checkOwnershipForCurrentUser; @@ -79,6 +82,9 @@ @Service @RequiredArgsConstructor(onConstructor = @__({@Autowired})) public class JurorAppearanceServiceImpl implements JurorAppearanceService { + + public static final String CANNOT_UPDATE_CONFIRMED_JUROR = "Cannot update confirmed juror "; + private final TrialRepository trialRepository; private final JurorPoolRepository jurorPoolRepository; private final AppearanceRepository appearanceRepository; @@ -611,6 +617,7 @@ public void confirmJuryAttendance(UpdateAttendanceDto request) { juryAttendanceNumber = appearances.stream() .map(Appearance::getAttendanceAuditNumber) .filter(ObjectUtils::isNotEmpty) + .filter(auditNumber -> auditNumber.startsWith(juryAttendancePrefix)) .findFirst().orElse(getAttendanceAuditNumber(juryAttendancePrefix)); } else { juryAttendanceNumber = getAttendanceAuditNumber(juryAttendancePrefix); @@ -974,6 +981,8 @@ private AttendanceDetailsResponse updateCheckIn(UpdateAttendanceDto request, Str Appearance appearance = retrieveExistingAppearanceDetails(commonData.getLocationCode(), jurorNumber, commonData.getAttendanceDate()); + checkConfirmedAttendance(jurorNumber, appearance); + // validate and update the relevant values in the Appearance entity based on the attendance status appearance.setTimeIn(commonData.getCheckInTime()); appearance.setAppearanceStage(AppearanceStage.CHECKED_IN); @@ -995,6 +1004,14 @@ private AttendanceDetailsResponse updateCheckIn(UpdateAttendanceDto request, Str return response; } + private void checkConfirmedAttendance(String jurorNumber, Appearance appearance) { + if (!Arrays.asList(AppearanceStage.CHECKED_IN, AppearanceStage.CHECKED_OUT) + .contains(appearance.getAppearanceStage())) { + throw new MojException.BusinessRuleViolation(CANNOT_UPDATE_CONFIRMED_JUROR + jurorNumber, + CANNOT_UPDATE_CONFIRMED_ATTENDANCE); + } + } + private AttendanceDetailsResponse updateCheckOut(UpdateAttendanceDto request, String owner) { validateTheNumberOfJurorsToUpdate(request); @@ -1026,6 +1043,8 @@ private AttendanceDetailsResponse updateCheckOut(UpdateAttendanceDto request, St // retrieve the existing Appearance record Appearance appearance = retrieveExistingAppearanceDetails(locCode, jurorNumber, appearanceDate); + checkConfirmedAttendance(jurorNumber, appearance); + // validate and update the relevant values in the Appearance entity based on the attendance status validateCheckInNotNull(appearance.getTimeIn()); validateCheckOutNotBeforeCheckIn(appearance.getTimeIn(), commonData.getCheckOutTime()); @@ -1065,6 +1084,8 @@ private AttendanceDetailsResponse updateCheckInAndOut(UpdateAttendanceDto reques Appearance appearance = retrieveExistingAppearanceDetails(commonData.getLocationCode(), jurorNumber, commonData.getAttendanceDate()); + checkConfirmedAttendance(jurorNumber, appearance); + // validate and update the relevant values in the Appearance entity based on the attendance status validateBothCheckInAndOutTimeNotNull(commonData.getCheckInTime(), commonData.getCheckOutTime()); validateCheckOutNotBeforeCheckIn(commonData.getCheckInTime(), commonData.getCheckOutTime()); @@ -1184,8 +1205,8 @@ private JurorPool validateJurorStatus(Juror juror, boolean isCompleted) { private void validateJurorStatus(int status, boolean isCompleted) { if (status != IJurorStatus.RESPONDED && status != IJurorStatus.PANEL && status != IJurorStatus.JUROR && !(status == IJurorStatus.COMPLETED && isCompleted)) { - throw new MojException.BadRequest("Cannot check in or out a juror with an invalid status", - null); + throw new MojException.BusinessRuleViolation("Cannot process a juror with an invalid status: " + + JurorStatusEnum.fromStatus(status), INVALID_JUROR_STATUS); } } diff --git a/src/test/java/uk/gov/hmcts/juror/api/moj/service/deferralmaintenance/ManageDeferralsServiceTest.java b/src/test/java/uk/gov/hmcts/juror/api/moj/service/deferralmaintenance/ManageDeferralsServiceTest.java index 169eb23f8..294e75be4 100644 --- a/src/test/java/uk/gov/hmcts/juror/api/moj/service/deferralmaintenance/ManageDeferralsServiceTest.java +++ b/src/test/java/uk/gov/hmcts/juror/api/moj/service/deferralmaintenance/ManageDeferralsServiceTest.java @@ -603,7 +603,7 @@ void deleteDeferralHappyPathBureauUser() { assertThat(jurorPool.getDeferralDate()).isNull(); assertThat(juror.getExcusalDate()).isNull(); assertThat(jurorPool.getDeferralCode()).isNull(); - // assertThat(jurorPool.getPool().getReturnDate()).isNotNull(); + // assertThat(jurorPool.getPool().getReturnDate()).isNotNull(); assertThat(jurorPool.getNextDate()).isEqualTo(jurorPool.getPool().getReturnDate()); assertThat(juror.getNoDefPos()).isEqualTo(0L); assertThat(jurorPool.getStatus().getStatus()).isEqualTo(IJurorStatus.RESPONDED); diff --git a/src/test/java/uk/gov/hmcts/juror/api/moj/service/jurormanagement/JurorAppearanceServiceTest.java b/src/test/java/uk/gov/hmcts/juror/api/moj/service/jurormanagement/JurorAppearanceServiceTest.java index 02fc91218..066f7f81d 100644 --- a/src/test/java/uk/gov/hmcts/juror/api/moj/service/jurormanagement/JurorAppearanceServiceTest.java +++ b/src/test/java/uk/gov/hmcts/juror/api/moj/service/jurormanagement/JurorAppearanceServiceTest.java @@ -578,7 +578,7 @@ void testCheckInJurorInvalidJurorStatus() { doReturn(Optional.of(courtLocation)).when(courtLocationRepository).findById(anyString()); JurorAppearanceDto jurorAppearanceDto = buildJurorAppearanceDto(); - assertThatExceptionOfType(MojException.BadRequest.class).isThrownBy(() -> + assertThatExceptionOfType(MojException.BusinessRuleViolation.class).isThrownBy(() -> jurorAppearanceService.processAppearance(buildPayload("415", Arrays.asList("415", "462", "767")), jurorAppearanceDto));