Skip to content

Commit

Permalink
Merge branch 'master' into CIV-15956
Browse files Browse the repository at this point in the history
  • Loading branch information
rajakm authored Dec 17, 2024
2 parents 59c1dc9 + e423a9b commit 80cb030
Show file tree
Hide file tree
Showing 15 changed files with 583 additions and 22 deletions.
6 changes: 3 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ def versions = [
junitPlatform : '1.11.3',
springBoot : springBoot.class.package.implementationVersion,
springStatemachine: '4.0.0',
lombok : '1.18.34',
lombok : '1.18.36',
springSecurity : '5.8.15',
camunda : '7.20.0',
jackson : '2.18.0',
jackson : '2.18.2',
testcontainers : '1.20.3',
pdfbox : '3.0.2',
tika : '2.9.2'
Expand Down Expand Up @@ -435,7 +435,7 @@ dependencies {
testImplementation group: 'org.mockito', name: 'mockito-core', version: '4.11.0'
testImplementation group: 'org.mockito', name: 'mockito-junit-jupiter', version: '4.11.0'
testImplementation group: 'org.mockito', name: 'mockito-inline', version: '4.11.0'
testImplementation group: 'net.bytebuddy', name: 'byte-buddy', version: '1.15.10'
testImplementation group: 'net.bytebuddy', name: 'byte-buddy', version: '1.15.11'
testImplementation group: 'net.bytebuddy', name: 'byte-buddy-agent', version: '1.15.10'

testAnnotationProcessor group: 'org.projectlombok', name: 'lombok', version: versions.lombok
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,7 @@ public enum CaseEvent {
SEND_HEARING_TO_LIP_DEFENDANT(CAMUNDA),
SEND_HEARING_TO_LIP_CLAIMANT(CAMUNDA),
SEND_FINAL_ORDER_TO_LIP_DEFENDANT(CAMUNDA),
UPDATE_CONFIRM_REVIEW_ORDER_EVENT(CAMUNDA),
SEND_FINAL_ORDER_TO_LIP_CLAIMANT(CAMUNDA),
SEND_TRANSLATED_ORDER_TO_LIP_DEFENDANT(CAMUNDA),
SEND_TRANSLATED_ORDER_TO_LIP_CLAIMANT(CAMUNDA),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package uk.gov.hmcts.reform.civil.enums;

import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter
@RequiredArgsConstructor
public enum ObligationReason {
UNLESS_ORDER("Unless order"),
STAY_A_CASE("Stay a case"),
LIFT_A_STAY("Lift a stay"),
DISMISS_CASE("Dismiss case"),
PRE_TRIAL_CHECKLIST("Pre trial checklist"),
GENERAL_ORDER("General order"),
RESERVE_JUDGMENT("Reserve Judgment"),
OTHER("Other");

private final String displayedValue;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package uk.gov.hmcts.reform.civil.handler.callback.camunda.caseevents;

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import uk.gov.hmcts.reform.civil.callback.Callback;
import uk.gov.hmcts.reform.civil.callback.CallbackHandler;
import uk.gov.hmcts.reform.civil.callback.CallbackParams;
import uk.gov.hmcts.reform.civil.callback.CaseEvent;

import java.util.List;
import java.util.Map;

import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_SUBMIT;
import static uk.gov.hmcts.reform.civil.callback.CaseEvent.UPDATE_CONFIRM_REVIEW_ORDER_EVENT;

@Service
@RequiredArgsConstructor
public class UpdateConfirmOrderReviewCallbackHandler extends CallbackHandler {

private static final List<CaseEvent> EVENTS = List.of(UPDATE_CONFIRM_REVIEW_ORDER_EVENT);
public static final String TASK_ID = "UpdateConfirmOrderReviewEvent";

@Override
protected Map<String, Callback> callbacks() {
return Map.of(callbackKey(ABOUT_TO_SUBMIT), this::emptyCallbackResponse);
}

@Override
public String camundaActivityId(CallbackParams callbackParams) {
return TASK_ID;
}

@Override
public List<CaseEvent> handledEvents() {
return EVENTS;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ public boolean shouldRecordScenario(CaseData caseData) {

@Override
public String getScenario(CaseData caseData) {

if (caseData.getRespondent1ClaimResponseTypeForSpec() == null) {
return null;
}
return switch (caseData.getRespondent1ClaimResponseTypeForSpec()) {
case FULL_DEFENCE -> getFullDefenceScenario(caseData);
case FULL_ADMISSION -> getFullAdmissionScenario(caseData);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,25 @@
import uk.gov.hmcts.reform.civil.callback.CallbackHandler;
import uk.gov.hmcts.reform.civil.callback.CallbackParams;
import uk.gov.hmcts.reform.civil.callback.CaseEvent;
import uk.gov.hmcts.reform.civil.enums.CaseState;
import uk.gov.hmcts.reform.civil.enums.YesOrNo;
import uk.gov.hmcts.reform.civil.model.BusinessProcess;
import uk.gov.hmcts.reform.civil.model.CaseData;
import uk.gov.hmcts.reform.civil.model.ObligationData;
import uk.gov.hmcts.reform.civil.model.common.Element;
import uk.gov.hmcts.reform.civil.service.FeatureToggleService;

import java.time.LocalDate;
import java.util.ArrayList;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

import static java.lang.String.format;
import static java.util.Objects.nonNull;
import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_START;
import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_SUBMIT;
import static uk.gov.hmcts.reform.civil.callback.CallbackType.MID;
Expand All @@ -35,7 +43,6 @@ public class ConfirmOrderReviewCallbackHandler extends CallbackHandler {
private static final List<CaseEvent> EVENTS = Collections.singletonList(CONFIRM_ORDER_REVIEW);

private final FeatureToggleService featureToggleService;

private final ObjectMapper objectMapper;
private static final String HEADER_CONFIRMATION = "# The order review has been completed";
private static final String BODY_CONFIRMATION_NO_OBLIGATION = "&nbsp;";
Expand All @@ -45,13 +52,15 @@ public class ConfirmOrderReviewCallbackHandler extends CallbackHandler {
private static final String TASKS_LEFT_ERROR_1 = "Order review not completed.";
private static final String TASKS_LEFT_ERROR_2 = "You must complete the tasks in the order before you can submit your order review.";
private static final String TASKS_LEFT_ERROR_3 = "Once you have completed the task you can submit your order review by clicking on the link on your task list.";
private static final String OBLIGATION_DATE_ERROR = "The obligation date must be in the future";

@Override
protected Map<String, Callback> callbacks() {

if (featureToggleService.isCaseEventsEnabled()) {
return Map.of(
callbackKey(ABOUT_TO_START), this::emptyCallbackResponse,
callbackKey(ABOUT_TO_START), this::cleanObligationData,
callbackKey(MID, "validate-obligation-date"), this:: validateObligationDate,
callbackKey(MID, "validate-tasks-left"), this:: validateTasksLeft,
callbackKey(ABOUT_TO_SUBMIT), this::confirmOrderReview,
callbackKey(SUBMITTED), this::fillConfirmationScreen
Expand All @@ -70,6 +79,37 @@ public List<CaseEvent> handledEvents() {
return EVENTS;
}

private CallbackResponse cleanObligationData(CallbackParams callbackParams) {
CaseData caseData = callbackParams.getCaseData();
CaseData.CaseDataBuilder<?, ?> caseDataBuilder = caseData.toBuilder();

caseDataBuilder
.obligationDatePresent(null)
.courtStaffNextSteps(null);

return AboutToStartOrSubmitCallbackResponse.builder()
.data(caseDataBuilder.build().toMap(objectMapper))
.build();
}

private CallbackResponse validateObligationDate(CallbackParams callbackParams) {
CaseData caseData = callbackParams.getCaseData();

var obligationList = caseData.getObligationData();

List<String> errors =
obligationList.stream()
.filter(element -> element != null && element.getValue() != null)
.map(Element::getValue)
.filter(data -> data.getObligationDate() == null || !data.getObligationDate().isAfter(
LocalDate.now()))
.map(data -> OBLIGATION_DATE_ERROR).collect(Collectors.toList());

return AboutToStartOrSubmitCallbackResponse.builder()
.errors(errors)
.build();
}

private CallbackResponse validateTasksLeft(CallbackParams callbackParams) {
CaseData caseData = callbackParams.getCaseData();
ArrayList<String> errors = new ArrayList<>();
Expand All @@ -87,14 +127,34 @@ private CallbackResponse validateTasksLeft(CallbackParams callbackParams) {

private CallbackResponse confirmOrderReview(CallbackParams callbackParams) {
CaseData caseData = callbackParams.getCaseData();
CaseData.CaseDataBuilder<?, ?> updatedCaseData = caseData.toBuilder();

CaseData updatedCaseData = caseData.toBuilder()
.obligationDatePresent(null)
.courtStaffNextSteps(null)
.build();
if (YesOrNo.YES.equals(caseData.getObligationDatePresent())) {
updatedCaseData.businessProcess(BusinessProcess.ready(CONFIRM_ORDER_REVIEW));
}

if (nonNull(caseData.getObligationData())) {

List<Element<ObligationData>> storedObligationData = Optional.ofNullable(caseData.getStoredObligationData())
.orElse(Collections.emptyList());

List<Element<ObligationData>> combinedData = new ArrayList<>();
combinedData.addAll(storedObligationData);
combinedData.addAll(caseData.getObligationData());

updatedCaseData.obligationData(null)
.storedObligationData(combinedData);
}

if (YesOrNo.YES.equals(caseData.getIsFinalOrder())) {
return AboutToStartOrSubmitCallbackResponse.builder()
.data(updatedCaseData.build().toMap(objectMapper))
.state(CaseState.All_FINAL_ORDERS_ISSUED.toString())
.build();
}

return AboutToStartOrSubmitCallbackResponse.builder()
.data(updatedCaseData.toMap(objectMapper))
.data(updatedCaseData.build().toMap(objectMapper))
.build();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
package uk.gov.hmcts.reform.civil.handler.tasks;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import org.camunda.bpm.client.exception.ValueMapperException;
import org.camunda.bpm.client.task.ExternalTask;
import org.springframework.stereotype.Component;
import uk.gov.hmcts.reform.ccd.client.model.CaseDataContent;
import uk.gov.hmcts.reform.ccd.client.model.Event;
import uk.gov.hmcts.reform.ccd.client.model.StartEventResponse;
import uk.gov.hmcts.reform.civil.callback.CaseEvent;
import uk.gov.hmcts.reform.civil.enums.ObligationReason;
import uk.gov.hmcts.reform.civil.exceptions.InvalidCaseDataException;
import uk.gov.hmcts.reform.civil.helpers.CaseDetailsConverter;
import uk.gov.hmcts.reform.civil.model.BusinessProcess;
import uk.gov.hmcts.reform.civil.model.CaseData;
import uk.gov.hmcts.reform.civil.model.ExternalTaskData;
import uk.gov.hmcts.reform.civil.model.ObligationData;
import uk.gov.hmcts.reform.civil.service.CoreCaseDataService;
import uk.gov.hmcts.reform.civil.service.data.ExternalTaskInput;

import java.util.Collections;
import java.util.Optional;
import java.util.stream.Collectors;

import static java.util.Optional.ofNullable;

/**
* Handles the external camunda task for updating contact information.
* This task handler retrieves caseId and caseEvent from the external task variables and the businessProcess
*/
@RequiredArgsConstructor
@Component
public class ConfirmOrderReviewTaskHandler extends BaseExternalTaskHandler {

private final CoreCaseDataService coreCaseDataService;
private final CaseDetailsConverter caseDetailsConverter;
private final ObjectMapper mapper;

@Override
public ExternalTaskData handleTask(ExternalTask externalTask) {
try {
ExternalTaskInput taskVariables = parseExternalTaskVariables(externalTask);

String caseIdentifier = validateCaseId(taskVariables.getCaseId());
CaseEvent event = validateCaseEvent(taskVariables.getCaseEvent());

StartEventResponse startEvent = coreCaseDataService.startUpdate(caseIdentifier, event);

coreCaseDataService.submitUpdate(caseIdentifier, caseDataContent(startEvent, externalTask));

return ExternalTaskData.builder().build();
} catch (ValueMapperException | IllegalArgumentException ex) {
throw new InvalidCaseDataException("Mapper conversion failed due to incompatible types", ex);
}
}

private ExternalTaskInput parseExternalTaskVariables(ExternalTask externalTask) {
return mapper.convertValue(externalTask.getAllVariables(), ExternalTaskInput.class);
}

private String validateCaseId(String caseId) {
return ofNullable(caseId)
.orElseThrow(() -> new InvalidCaseDataException("The caseId was not provided"));
}

private CaseEvent validateCaseEvent(CaseEvent caseEvent) {
return ofNullable(caseEvent)
.orElseThrow(() -> new InvalidCaseDataException("The case event was not provided"));
}

private CaseDataContent caseDataContent(StartEventResponse startEventResponse, ExternalTask externalTask) {
CaseData caseData = caseDetailsConverter.toCaseData(startEventResponse.getCaseDetails());
BusinessProcess businessProcess = updateProcessInstanceId(caseData.getBusinessProcess(), externalTask);

String obligationReasons = getObligationReasons(caseData);
String obligationActions = obligationActions(caseData);

return CaseDataContent.builder()
.eventToken(startEventResponse.getToken())
.event(Event.builder()
.id(startEventResponse.getEventId())
.description(obligationActions)
.summary(obligationReasons)
.build())
.data(caseData.toBuilder()
.businessProcess(businessProcess)
.build().toMap(mapper))
.build();
}

private BusinessProcess updateProcessInstanceId(BusinessProcess businessProcess, ExternalTask externalTask) {
return businessProcess.hasSameProcessInstanceId(externalTask.getProcessInstanceId())
? businessProcess : businessProcess.updateProcessInstanceId(externalTask.getProcessInstanceId());
}

private String getObligationReasons(CaseData caseData) {
return Optional.ofNullable(caseData.getStoredObligationData())
.orElse(Collections.emptyList())
.stream()
.map(element -> {
ObligationData data = element.getValue();
ObligationReason reason = data.getObligationReason();

if (reason == ObligationReason.OTHER) {
return reason.getDisplayedValue() + ": " + data.getOtherObligationReason();
}
return reason.getDisplayedValue();
})
.collect(Collectors.joining(" --- "));
}

private String obligationActions(CaseData caseData) {
return Optional.ofNullable(caseData.getStoredObligationData())
.orElse(Collections.emptyList())
.stream()
.map(element -> element.getValue().getObligationAction())
.collect(Collectors.joining(" --- "));
}
}
4 changes: 4 additions & 0 deletions src/main/java/uk/gov/hmcts/reform/civil/model/CaseData.java
Original file line number Diff line number Diff line change
Expand Up @@ -753,6 +753,10 @@ public boolean hasNoOngoingBusinessProcess() {
//Caseworker events
private YesOrNo obligationDatePresent;
private CourtStaffNextSteps courtStaffNextSteps;
private List<Element<ObligationData>> obligationData;
private List<Element<ObligationData>> storedObligationData;
private YesOrNo isFinalOrder;

private SendAndReplyOption sendAndReplyOption;
private SendMessageMetadata sendMessageMetadata;
private String sendMessageContent;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -527,9 +527,11 @@ public boolean isRespondentResponseBilingual() {

@JsonIgnore
public boolean hasClaimantAgreedToFreeMediation() {
return Optional.ofNullable(getCaseDataLiP())
.map(CaseDataLiP::getApplicant1ClaimMediationSpecRequiredLip)
.filter(ClaimantMediationLip::hasClaimantAgreedToFreeMediation).isPresent();
Optional<CaseDataLiP> caseDataLiP1 = Optional.ofNullable(getCaseDataLiP());
return caseDataLiP1.map(CaseDataLiP::getApplicant1ClaimMediationSpecRequiredLip)
.filter(ClaimantMediationLip::hasClaimantAgreedToFreeMediation).isPresent()
|| caseDataLiP1.map(CaseDataLiP::getApplicant1LiPResponseCarm)
.filter(carm -> carm.getIsMediationEmailCorrect() == YES).isPresent();
}

@JsonIgnore
Expand Down
21 changes: 21 additions & 0 deletions src/main/java/uk/gov/hmcts/reform/civil/model/ObligationData.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package uk.gov.hmcts.reform.civil.model;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import uk.gov.hmcts.reform.civil.enums.ObligationReason;

import java.time.LocalDate;

@Data
@Builder(toBuilder = true)
@NoArgsConstructor
@AllArgsConstructor
public class ObligationData {

private LocalDate obligationDate;
private ObligationReason obligationReason;
private String otherObligationReason;
private String obligationAction;
}
Loading

0 comments on commit 80cb030

Please sign in to comment.