Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
5ec4618
DTSCCI-3902: Update COSC Generation Rules to use a Calendar Month Ins…
rishikrsharma Mar 19, 2026
455b9df
Merge branch 'master' into DTSCCI-3902-cosc
rishikrsharma Mar 23, 2026
fefa4ad
DTSCCI-3902: Update COSC Generation logic
rishikrsharma Mar 23, 2026
daa7555
DTSCCI-3902: Update COSC Generation logic
rishikrsharma Mar 23, 2026
47ed8f5
DTSCCI-3902: Update COSC Generation logic
rishikrsharma Mar 23, 2026
fc0a635
DTSCCI-3902: Update COSC Generation logic
rishikrsharma Mar 23, 2026
79cb60a
Merge branch 'master' into DTSCCI-3902-cosc
rishikrsharma Mar 23, 2026
22656d4
DTSCCI-3902: Update COSC Generation logic
rishikrsharma Mar 23, 2026
6a4eb33
DTSCCI-3902: Update COSC Generation logic
rishikrsharma Mar 24, 2026
cf22637
DTSCCI-3902: Update COSC Generation logic
rishikrsharma Mar 24, 2026
0fce195
Merge branch 'master' into DTSCCI-3902-cosc
rishikrsharma Mar 24, 2026
d0307d5
DTSCCI-3902: Update COSC Generation logic
rishikrsharma Mar 25, 2026
21d566a
Merge branch 'master' into DTSCCI-3902-cosc
rishikrsharma Mar 25, 2026
34785fc
DTSCCI-3902: Update COSC Generation logic
rishikrsharma Mar 25, 2026
1d949b7
Merge branch 'master' into DTSCCI-3902-cosc
rishikrsharma Mar 25, 2026
0a5da44
DTSCCI-3902: Update COSC Generation logic
rishikrsharma Mar 25, 2026
ce32398
DTSCCI-3902: Update COSC Generation logic
rishikrsharma Mar 25, 2026
2ba45e3
DTSCCI-3902: Update COSC Generation logic
rishikrsharma Mar 25, 2026
153ef1f
DTSCCI-3902: Update COSC Generation logic
rishikrsharma Mar 25, 2026
0b83764
DTSCCI-3902: Update COSC Generation logic
rishikrsharma Mar 25, 2026
37a5e05
Merge branch 'master' into DTSCCI-3902-cosc
rishikrsharma Mar 25, 2026
25db6fe
DTSCCI-3902: Update COSC Generation logic
rishikrsharma Mar 26, 2026
3187ac3
DTSCCI-3902: Update COSC Generation logic
rishikrsharma Mar 26, 2026
f5fc142
DTSCCI-3902: Update COSC Generation logic
rishikrsharma Mar 26, 2026
0d4914d
Merge branch 'master' into DTSCCI-3902-cosc
krishnanuthalapati Mar 30, 2026
d7b17a9
Merge branch 'master' into DTSCCI-3902-cosc
krishnanuthalapati Mar 31, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -642,7 +642,8 @@ public enum CaseEvent {
UPLOAD_TRANSLATED_DOCUMENT_HEARING_SCHEDULED(CAMUNDA),
ADD_APPLICATION_TO_TRANSLATION_COLLECTION(CAMUNDA),
UPLOAD_TRANSLATED_DOCUMENT_FOR_FREE_FEE_APPLICATION(CAMUNDA),
UPLOAD_TRANSLATED_DOCUMENT_FINAL_ORDER(CAMUNDA);
UPLOAD_TRANSLATED_DOCUMENT_FINAL_ORDER(CAMUNDA),
UPDATE_COSC_VARIABLE(CAMUNDA);

private final UserType userType;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,9 @@ public enum DashboardScenarios {
SCENARIO_AAA6_CLAIMANT_CONFIRMATION_JUDGMENT_PAID_IN_FULL_DEFENDANT("Scenario.AAA6.ProofOfDebtPayment.Confirmation.Defendant"),
SCENARIO_AAA6_DEFENDANT_NOTICE_OF_CHANGE_JBA_CLAIM_MOVES_OFFLINE_CLAIMANT("Scenario.AAA6.DefendantNoticeOfChange.JudgmentByAdmissionClaimMovesOffline.Claimant"),

SCENARIO_AAA6_MARK_PAID_IN_FULL_CLAIMANT("Scenario.AAA6.MarkPaidInFull.Confirmation.Claimant"),
SCENARIO_AAA6_MARK_PAID_IN_FULL_DEFENDANT("Scenario.AAA6.MarkPaidInFull.Confirmation.Defendant"),

//General Application
SCENARIO_AAA6_GENERAL_APPLICATION_SUBMITTED_NONURGENT_RESPONDENT("Scenario.AAA6.GeneralApps.NonUrgentApplicationMade.Respondent"),
SCENARIO_AAA6_GENERAL_APPLICATION_SUBMITTED_URGENT_RESPONDENT("Scenario.AAA6.GeneralApps.UrgentApplicationMade.Respondent"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

import static uk.gov.hmcts.reform.civil.callback.CaseEvent.UPDATE_DASHBOARD_NOTIFICATIONS_JUDGMENT_PAID_CLAIMANT;
import static uk.gov.hmcts.reform.civil.handler.callback.camunda.dashboardnotifications.DashboardScenarios.SCENARIO_AAA6_CLAIMANT_CONFIRMATION_JUDGMENT_PAID_IN_FULL_CLAIMANT;
import static uk.gov.hmcts.reform.civil.handler.callback.camunda.dashboardnotifications.DashboardScenarios.SCENARIO_AAA6_MARK_PAID_IN_FULL_CLAIMANT;
import static uk.gov.hmcts.reform.civil.utils.MarkPaidInFullUtil.checkMarkPaidInFull;

@Service
public class JudgmentPaidClaimantNotificationHandler extends DashboardCallbackHandler {
Expand All @@ -39,6 +41,9 @@ public List<CaseEvent> handledEvents() {

@Override
public String getScenario(CaseData caseData) {
if (checkMarkPaidInFull(caseData)) {
return SCENARIO_AAA6_MARK_PAID_IN_FULL_CLAIMANT.getScenario();
}
return SCENARIO_AAA6_CLAIMANT_CONFIRMATION_JUDGMENT_PAID_IN_FULL_CLAIMANT.getScenario();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

import static uk.gov.hmcts.reform.civil.callback.CaseEvent.UPDATE_DASHBOARD_NOTIFICATIONS_JUDGMENT_PAID_DEFENDANT;
import static uk.gov.hmcts.reform.civil.handler.callback.camunda.dashboardnotifications.DashboardScenarios.SCENARIO_AAA6_CLAIMANT_CONFIRMATION_JUDGMENT_PAID_IN_FULL_DEFENDANT;
import static uk.gov.hmcts.reform.civil.handler.callback.camunda.dashboardnotifications.DashboardScenarios.SCENARIO_AAA6_MARK_PAID_IN_FULL_DEFENDANT;
import static uk.gov.hmcts.reform.civil.utils.MarkPaidInFullUtil.checkMarkPaidInFull;

@Service
public class JudgmentPaidDefendantNotificationHandler extends DashboardCallbackHandler {
Expand All @@ -39,6 +41,9 @@ public List<CaseEvent> handledEvents() {

@Override
public String getScenario(CaseData caseData) {
if (checkMarkPaidInFull(caseData)) {
return SCENARIO_AAA6_MARK_PAID_IN_FULL_DEFENDANT.getScenario();
}
return SCENARIO_AAA6_CLAIMANT_CONFIRMATION_JUDGMENT_PAID_IN_FULL_DEFENDANT.getScenario();
}

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

import java.util.Map;
import java.util.Objects;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
Expand All @@ -17,16 +14,19 @@
import uk.gov.hmcts.reform.civil.callback.CaseEvent;
import uk.gov.hmcts.reform.civil.exceptions.InvalidCaseDataException;
import uk.gov.hmcts.reform.civil.helpers.CaseDetailsConverter;
import uk.gov.hmcts.reform.civil.model.ExternalTaskData;
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.service.CoreCaseDataService;
import uk.gov.hmcts.reform.civil.service.FeatureToggleService;
import uk.gov.hmcts.reform.civil.service.data.ExternalTaskInput;
import uk.gov.hmcts.reform.civil.service.flowstate.FlowState;
import uk.gov.hmcts.reform.civil.service.flowstate.IStateFlowEngine;
import uk.gov.hmcts.reform.civil.service.robotics.support.RoboticsEventTextFormatter;

import java.util.Map;
import java.util.Objects;

import static java.lang.String.format;
import static java.util.Optional.ofNullable;
import static uk.gov.hmcts.reform.civil.enums.CaseCategory.SPEC_CLAIM;
Expand All @@ -40,6 +40,7 @@
import static uk.gov.hmcts.reform.civil.enums.UnrepresentedOrUnregisteredScenario.UNREPRESENTED;
import static uk.gov.hmcts.reform.civil.enums.UnrepresentedOrUnregisteredScenario.getDefendantNames;
import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES;
import static uk.gov.hmcts.reform.civil.utils.MarkPaidInFullUtil.checkMarkPaidInFull;

@RequiredArgsConstructor
@Component
Expand Down Expand Up @@ -91,6 +92,7 @@ public VariableMap getVariableMap(ExternalTaskData externalTaskData) {
var stateFlow = stateFlowEngine.getStateFlow(data);
variables.putValue(FLOW_STATE, stateFlow.getState().getName());
variables.putValue(FLOW_FLAGS, stateFlow.getFlags());
variables.putValue("isJudgmentMarkedPaidInFull", checkMarkPaidInFull(data));
return variables;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,13 @@ public JudgmentDetails addUpdateActiveJudgment(CaseData caseData) {
}

protected JudgmentState getJudgmentState(CaseData caseData, LocalDate paymentDate) {
boolean paidAfter31Days = JudgmentsOnlineHelper.checkIfDateDifferenceIsGreaterThan31Days(
caseData.getActiveJudgment().getIssueDate(),
LocalDate issueDate = caseData.getActiveJudgment().getIssueDate();
log.info("Getting Judgment State based on issueDate date: {}, eligible days: {}", issueDate, issueDate.lengthOfMonth());
boolean paidAfterEligibleDays = JudgmentsOnlineHelper.checkIfDateDifferenceIsGreaterThanDaysInMonth(
issueDate,
nonNull(paymentDate) ? paymentDate : caseData.getJoJudgmentPaidInFull().getDateOfFullPaymentMade()
);
return paidAfter31Days ? JudgmentState.SATISFIED : JudgmentState.CANCELLED;
return paidAfterEligibleDays ? JudgmentState.SATISFIED : JudgmentState.CANCELLED;
}

protected JudgmentState getJudgmentState(CaseData caseData) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public class JudgmentsOnlineHelper {
private static final String ERROR_MESSAGE_DATE_FIRST_INSTALMENT_MUST_BE_IN_FUTURE = "Date of first instalment must be in the future";
private static final String ERROR_MESSAGE_DATE_ORDER_MUST_BE_IN_PAST = "Date judge made the order must be in the past";

private static final String regex = "[ˆ`´¨]";
private static final String REGEX = "[ˆ`´¨]";

private JudgmentsOnlineHelper() {
}
Expand All @@ -39,8 +39,8 @@ public static boolean validateIfFutureDate(LocalDate date) {
return date.isAfter(today);
}

public static boolean checkIfDateDifferenceIsGreaterThan31Days(LocalDate firstDate, LocalDate secondDate) {
return ChronoUnit.DAYS.between(firstDate, secondDate) > 31;
public static boolean checkIfDateDifferenceIsGreaterThanDaysInMonth(LocalDate firstDate, LocalDate secondDate) {
return ChronoUnit.DAYS.between(firstDate, secondDate) > firstDate.lengthOfMonth();
}

public static List<String> validateMidCallbackData(CaseData caseData) {
Expand Down Expand Up @@ -295,7 +295,7 @@ public static JudgmentAddress getJudgmentAddress(Address address, RoboticsAddres
}

public static String removeWelshCharacters(String input) {
return input != null ? input.replaceAll(regex, "") : input;
return input != null ? input.replaceAll(REGEX, "") : input;
}

private static String trimDownTo35(String input) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package uk.gov.hmcts.reform.civil.utils;

import uk.gov.hmcts.reform.civil.model.CaseData;

import java.util.Objects;

public class MarkPaidInFullUtil {

private MarkPaidInFullUtil() {
//no op
}

public static boolean checkMarkPaidInFull(CaseData data) {
return (Objects.nonNull(data.getActiveJudgment())
&& data.getActiveJudgment().getFullyPaymentMadeDate() != null
&& Objects.nonNull(data.getCertOfSC())
&& data.getCertOfSC().getDefendantFinalPaymentDate() != null);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* Add scenario to delete claimant notification
*/
INSERT INTO dbs.scenario (name, notifications_to_delete, notifications_to_create)
VALUES ('Scenario.AAA6.MarkPaidInFull.Confirmation.Claimant',
'{
"Notice.AAA6.ProofofDebtPayment.Application.Claimant",
"Notice.AAA6.JudgmentsOnline.DefaultJudgmentIssued.Claimant",
"Notice.AAA6.JudgmentsOnline.IssuedCCJ.Claimant"
}',
'{"Notice.AAA6.JudgmentsOnline.PaidInFull.Claimant": []}');

/**
* Add scenario to delete defendant notification
*/

INSERT INTO dbs.scenario (name, notifications_to_delete, notifications_to_create)
VALUES ('Scenario.AAA6.MarkPaidInFull.Confirmation.Defendant',
'{
"Notice.AAA6.ProofofDebtPayment.Application.Defendant",
"Notice.AAA6.JudgmentsOnline.IssuedCCJ.Defendant",
"Notice.AAA6.JudgmentsOnline.DefaultJudgmentIssued.Defendant"
}',
'{"Notice.AAA6.ProofofDebtPayment.ApplicationProcessed.Defendant": []}');


Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
import uk.gov.hmcts.reform.civil.handler.callback.BaseCallbackHandlerTest;
import uk.gov.hmcts.reform.civil.model.CaseData;
import uk.gov.hmcts.reform.civil.model.citizenui.CaseDataLiP;
import uk.gov.hmcts.reform.civil.model.citizenui.CertOfSC;
import uk.gov.hmcts.reform.civil.model.judgmentonline.JudgmentDetails;
import uk.gov.hmcts.reform.civil.sampledata.CallbackParamsBuilder;
import uk.gov.hmcts.reform.civil.sampledata.CaseDataBuilder;
import uk.gov.hmcts.reform.civil.service.FeatureToggleService;
Expand All @@ -31,6 +33,7 @@
import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_SUBMIT;
import static uk.gov.hmcts.reform.civil.callback.CaseEvent.UPDATE_DASHBOARD_NOTIFICATIONS_JUDGMENT_PAID_CLAIMANT;
import static uk.gov.hmcts.reform.civil.handler.callback.camunda.dashboardnotifications.DashboardScenarios.SCENARIO_AAA6_CLAIMANT_CONFIRMATION_JUDGMENT_PAID_IN_FULL_CLAIMANT;
import static uk.gov.hmcts.reform.civil.handler.callback.camunda.dashboardnotifications.DashboardScenarios.SCENARIO_AAA6_MARK_PAID_IN_FULL_CLAIMANT;

@ExtendWith(MockitoExtension.class)
public class JudgmentPaidClaimantNotificationHandlerTest extends BaseCallbackHandlerTest {
Expand Down Expand Up @@ -114,5 +117,37 @@ void shouldRecordScenario_whenInvoked_whenClaimantRepresented() {
new ScenarioRequestParams(scenarioParams)
);
}

@Test
void shouldRecordScenario_whenInvoked_whenClaimantRepresented_And_MarkedPaid_And_Def_Mark_Paid_In_Full() {
CaseDataLiP caseDataLiP = new CaseDataLiP();
caseDataLiP.setApplicant1SettleClaim(YesOrNo.YES);
caseDataLiP.setApplicant1ClaimSettledDate(LocalDate.now());
CaseData caseData = CaseDataBuilder.builder().atStateClaimSubmittedSmallClaim()
.caseDataLip(caseDataLiP)
.applicant1Represented(YesOrNo.NO).build();
caseData.setCaseDocumentUploadDate(LocalDateTime.now());

CaseData.CaseDataBuilder<?, ?> caseData2 = caseData.toBuilder();
caseData2.activeJudgment(new JudgmentDetails().setFullyPaymentMadeDate(LocalDate.now()));
caseData2.certOfSC(new CertOfSC().setDefendantFinalPaymentDate(LocalDate.now()));

HashMap<String, Object> scenarioParams = new HashMap<>();
when(mapper.mapCaseDataToParams(any())).thenReturn(scenarioParams);

CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_SUBMIT, caseData2.build()).request(
CallbackRequest.builder().eventId(UPDATE_DASHBOARD_NOTIFICATIONS_JUDGMENT_PAID_CLAIMANT.name()).build()
).build();

when(featureToggleService.isLipVLipEnabled()).thenReturn(true);

handler.handle(params);
verify(dashboardScenariosService).recordScenarios(
"BEARER_TOKEN",
SCENARIO_AAA6_MARK_PAID_IN_FULL_CLAIMANT.getScenario(),
caseData.getCcdCaseReference().toString(),
new ScenarioRequestParams(scenarioParams)
);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
import uk.gov.hmcts.reform.civil.handler.callback.BaseCallbackHandlerTest;
import uk.gov.hmcts.reform.civil.model.CaseData;
import uk.gov.hmcts.reform.civil.model.citizenui.CaseDataLiP;
import uk.gov.hmcts.reform.civil.model.citizenui.CertOfSC;
import uk.gov.hmcts.reform.civil.model.judgmentonline.JudgmentDetails;
import uk.gov.hmcts.reform.civil.sampledata.CallbackParamsBuilder;
import uk.gov.hmcts.reform.civil.sampledata.CaseDataBuilder;
import uk.gov.hmcts.reform.civil.service.FeatureToggleService;
Expand All @@ -31,6 +33,7 @@
import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_SUBMIT;
import static uk.gov.hmcts.reform.civil.callback.CaseEvent.UPDATE_DASHBOARD_NOTIFICATIONS_JUDGMENT_PAID_DEFENDANT;
import static uk.gov.hmcts.reform.civil.handler.callback.camunda.dashboardnotifications.DashboardScenarios.SCENARIO_AAA6_CLAIMANT_CONFIRMATION_JUDGMENT_PAID_IN_FULL_DEFENDANT;
import static uk.gov.hmcts.reform.civil.handler.callback.camunda.dashboardnotifications.DashboardScenarios.SCENARIO_AAA6_MARK_PAID_IN_FULL_DEFENDANT;

@ExtendWith(MockitoExtension.class)
public class JudgmentPaidDefendantNotificationHandlerTest extends BaseCallbackHandlerTest {
Expand Down Expand Up @@ -116,5 +119,38 @@ void shouldRecordScenario_whenInvoked_whenDefendantRepresented() {
new ScenarioRequestParams(scenarioParams)
);
}

@Test
void shouldRecordScenario_whenInvoked_whenDefendantRepresented_And_MarkedPaid_And_Def_Mark_Paid_In_Full() {
CaseDataLiP caseDataLiP = new CaseDataLiP();
caseDataLiP.setApplicant1SettleClaim(YesOrNo.YES);
caseDataLiP.setApplicant1ClaimSettledDate(LocalDate.now());

CaseData caseData = CaseDataBuilder.builder().atStateClaimSubmittedSmallClaim()
.caseDataLip(caseDataLiP)
.respondent1Represented(YesOrNo.NO).build();
caseData.setCaseDocumentUploadDate(LocalDateTime.now());

CaseData.CaseDataBuilder<?, ?> caseData2 = caseData.toBuilder();
caseData2.activeJudgment(new JudgmentDetails().setFullyPaymentMadeDate(LocalDate.now()));
caseData2.certOfSC(new CertOfSC().setDefendantFinalPaymentDate(LocalDate.now()));

HashMap<String, Object> scenarioParams = new HashMap<>();
when(mapper.mapCaseDataToParams(any())).thenReturn(scenarioParams);

CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_SUBMIT, caseData2.build()).request(
CallbackRequest.builder().eventId(UPDATE_DASHBOARD_NOTIFICATIONS_JUDGMENT_PAID_DEFENDANT.name()).build()
).build();

when(featureToggleService.isLipVLipEnabled()).thenReturn(true);

handler.handle(params);
verify(dashboardScenariosService).recordScenarios(
"BEARER_TOKEN",
SCENARIO_AAA6_MARK_PAID_IN_FULL_DEFENDANT.getScenario(),
caseData.getCcdCaseReference().toString(),
new ScenarioRequestParams(scenarioParams)
);
}
}
}
Loading
Loading