From 9942e3bee5e9c25cac304342f65b4e12548d046e Mon Sep 17 00:00:00 2001 From: rajaram Date: Thu, 21 May 2026 16:25:37 +0100 Subject: [PATCH 001/100] Upgraded to case flags 2.1 version --- ...isationCaseEvent-CaseFlagsCaseLinking.json | 24 + ...isationCaseField-CaseFlagsCaseLinking.json | 450 ++++++ .../CaseEvent-CaseFlagsCaseLinking.json | 32 +- ...aseEventToFields-CaseFlagsCaseLinking.json | 852 +++++++++++- .../CaseField-CaseFlagsCaseLinking.json | 147 ++ .../CaseTypeTab-CaseFlagsCaseLinking.json | 216 ++- ...isationCaseEvent-CaseFlagsCaseLinking.json | 24 + ...isationCaseField-CaseFlagsCaseLinking.json | 450 ++++++ .../CaseEvent-CaseFlagsCaseLinking.json | 30 + ...aseEventToFields-CaseFlagsCaseLinking.json | 852 +++++++++++- .../CaseField-CaseFlagsCaseLinking.json | 147 ++ .../CaseTypeTab-CaseFlagsCaseLinking.json | 216 ++- docs/cftlib.md | 4 + .../hmcts/et/common/model/ccd/CaseData.java | 21 + .../model/ccd/items/FlagDetailType.java | 3 +- .../common/model/ccd/types/CaseFlagsType.java | 4 + .../wiremock/__files/prd/party-flags.json | 1202 +++++++++-------- .../CaseFlagsDataMigrationController.java | 17 + .../controllers/Et1ReppedController.java | 9 + .../docmosis/service/CaseFlagsService.java | 451 ++++++- .../Et1ReppedControllerFunctionalTest.java | 16 +- .../CaseFlagsDataMigrationControllerTest.java | 39 + .../controllers/Et1ReppedControllerTest.java | 48 + .../service/CaseFlagsServiceTest.java | 374 ++++- 24 files changed, 4979 insertions(+), 649 deletions(-) diff --git a/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseEvent/AuthorisationCaseEvent-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseEvent/AuthorisationCaseEvent-CaseFlagsCaseLinking.json index 82511ffeac..b8bcefa9a7 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseEvent/AuthorisationCaseEvent-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseEvent/AuthorisationCaseEvent-CaseFlagsCaseLinking.json @@ -23,6 +23,30 @@ "UserRole": "caseworker-employment-englandwales", "CRUD": "CRU" }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseEventID": "requestSupport", + "UserRole": "caseworker-employment-legalrep-solicitor", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseEventID": "manageSupport", + "UserRole": "caseworker-employment-legalrep-solicitor", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseEventID": "requestSupport", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseEventID": "manageSupport", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, { "CaseTypeId": "ET_EnglandWales", "CaseEventID": "migrateCaseFlags", diff --git a/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json index 1e96cd3378..43c1ac2988 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json @@ -70,5 +70,455 @@ "CaseFieldID": "respondentFlags", "UserRole": "caseworker-employment-englandwales", "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent1Flags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent1Flags", + "UserRole": "caseworker-employment-etjudge-englandwales", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent1Flags", + "UserRole": "caseworker-employment-englandwales", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent2Flags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent2Flags", + "UserRole": "caseworker-employment-etjudge-englandwales", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent2Flags", + "UserRole": "caseworker-employment-englandwales", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent3Flags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent3Flags", + "UserRole": "caseworker-employment-etjudge-englandwales", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent3Flags", + "UserRole": "caseworker-employment-englandwales", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent4Flags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent4Flags", + "UserRole": "caseworker-employment-etjudge-englandwales", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent4Flags", + "UserRole": "caseworker-employment-englandwales", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent5Flags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent5Flags", + "UserRole": "caseworker-employment-etjudge-englandwales", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent5Flags", + "UserRole": "caseworker-employment-englandwales", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent6Flags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent6Flags", + "UserRole": "caseworker-employment-etjudge-englandwales", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent6Flags", + "UserRole": "caseworker-employment-englandwales", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent7Flags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent7Flags", + "UserRole": "caseworker-employment-etjudge-englandwales", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent7Flags", + "UserRole": "caseworker-employment-englandwales", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent8Flags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent8Flags", + "UserRole": "caseworker-employment-etjudge-englandwales", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent8Flags", + "UserRole": "caseworker-employment-englandwales", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent9Flags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent9Flags", + "UserRole": "caseworker-employment-etjudge-englandwales", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent9Flags", + "UserRole": "caseworker-employment-englandwales", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "flagLauncherExternal", + "UserRole": "caseworker-employment-legalrep-solicitor", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "claimantExternalFlags", + "UserRole": "[CLAIMANTSOLICITOR]", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondentExternalFlags", + "UserRole": "[SOLICITORA]", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent1ExternalFlags", + "UserRole": "[SOLICITORB]", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent2ExternalFlags", + "UserRole": "[SOLICITORC]", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent3ExternalFlags", + "UserRole": "[SOLICITORD]", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent4ExternalFlags", + "UserRole": "[SOLICITORE]", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent5ExternalFlags", + "UserRole": "[SOLICITORF]", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent6ExternalFlags", + "UserRole": "[SOLICITORG]", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent7ExternalFlags", + "UserRole": "[SOLICITORH]", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent8ExternalFlags", + "UserRole": "[SOLICITORI]", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent9ExternalFlags", + "UserRole": "[SOLICITORJ]", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "flagLauncherExternal", + "UserRole": "caseworker-employment-englandwales", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "claimantExternalFlags", + "UserRole": "caseworker-employment-englandwales", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondentExternalFlags", + "UserRole": "caseworker-employment-englandwales", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent1ExternalFlags", + "UserRole": "caseworker-employment-englandwales", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent2ExternalFlags", + "UserRole": "caseworker-employment-englandwales", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent3ExternalFlags", + "UserRole": "caseworker-employment-englandwales", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent4ExternalFlags", + "UserRole": "caseworker-employment-englandwales", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent5ExternalFlags", + "UserRole": "caseworker-employment-englandwales", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent6ExternalFlags", + "UserRole": "caseworker-employment-englandwales", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent7ExternalFlags", + "UserRole": "caseworker-employment-englandwales", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent8ExternalFlags", + "UserRole": "caseworker-employment-englandwales", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent9ExternalFlags", + "UserRole": "caseworker-employment-englandwales", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "flagLauncherExternal", + "UserRole": "caseworker-employment-etjudge-englandwales", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "claimantExternalFlags", + "UserRole": "caseworker-employment-etjudge-englandwales", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondentExternalFlags", + "UserRole": "caseworker-employment-etjudge-englandwales", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent1ExternalFlags", + "UserRole": "caseworker-employment-etjudge-englandwales", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent2ExternalFlags", + "UserRole": "caseworker-employment-etjudge-englandwales", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent3ExternalFlags", + "UserRole": "caseworker-employment-etjudge-englandwales", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent4ExternalFlags", + "UserRole": "caseworker-employment-etjudge-englandwales", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent5ExternalFlags", + "UserRole": "caseworker-employment-etjudge-englandwales", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent6ExternalFlags", + "UserRole": "caseworker-employment-etjudge-englandwales", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent7ExternalFlags", + "UserRole": "caseworker-employment-etjudge-englandwales", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent8ExternalFlags", + "UserRole": "caseworker-employment-etjudge-englandwales", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent9ExternalFlags", + "UserRole": "caseworker-employment-etjudge-englandwales", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "flagLauncherExternal", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "claimantExternalFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondentExternalFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent1ExternalFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent2ExternalFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent3ExternalFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent4ExternalFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent5ExternalFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent6ExternalFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent7ExternalFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent8ExternalFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondent9ExternalFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" } ] diff --git a/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json index 1fc6cc7f0d..781128d76d 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json @@ -29,6 +29,36 @@ "CallBackURLAboutToSubmitEvent": "", "CallBackURLSubmittedEvent": "" }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "requestSupport", + "Name": "Request support", + "Description": "Request support", + "PreConditionState(s)": "*", + "PostConditionState": "*", + "SecurityClassification": "Public", + "ShowEventNotes": "N", + "ShowSummary": "Y", + "EventEnablingCondition": "", + "CallBackURLAboutToStartEvent": "", + "CallBackURLAboutToSubmitEvent": "", + "CallBackURLSubmittedEvent": "" + }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "manageSupport", + "Name": "Manage Support", + "Description": "Manage Support", + "PreConditionState(s)": "*", + "PostConditionState": "*", + "SecurityClassification": "Public", + "ShowEventNotes": "N", + "ShowSummary": "Y", + "EventEnablingCondition": "", + "CallBackURLAboutToStartEvent": "", + "CallBackURLAboutToSubmitEvent": "", + "CallBackURLSubmittedEvent": "" + }, { "CaseTypeID": "ET_EnglandWales", "ID": "createCaseLink", @@ -102,4 +132,4 @@ "CallBackURLAboutToSubmitEvent": "", "CallBackURLSubmittedEvent": "" } -] +] \ No newline at end of file diff --git a/ccd-definitions/jurisdictions/england-wales/json/CaseEventToFields/CaseEventToFields-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/england-wales/json/CaseEventToFields/CaseEventToFields-CaseFlagsCaseLinking.json index 3316af8196..8a894048b3 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/CaseEventToFields/CaseEventToFields-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/england-wales/json/CaseEventToFields/CaseEventToFields-CaseFlagsCaseLinking.json @@ -8,6 +8,8 @@ "PageDisplayOrder": 1, "PageFieldDisplayOrder": 1, "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", "RetainHiddenValue": "Yes" }, { @@ -19,6 +21,8 @@ "PageDisplayOrder": 1, "PageFieldDisplayOrder": 7, "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", "RetainHiddenValue": "Yes" }, { @@ -30,6 +34,8 @@ "PageDisplayOrder": 1, "PageFieldDisplayOrder": 4, "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", "RetainHiddenValue": "Yes" }, { @@ -41,6 +47,60 @@ "PageDisplayOrder": 1, "PageFieldDisplayOrder": 4, "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "createFlag", + "CaseFieldID": "claimantExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 4, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageFlags", + "CaseFieldID": "claimantExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 4, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "requestSupport", + "CaseFieldID": "claimantExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 4, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageSupport", + "CaseFieldID": "claimantExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 4, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", "RetainHiddenValue": "Yes" }, { @@ -48,20 +108,44 @@ "CaseEventID": "createFlag", "CaseFieldID": "flagLauncher", "DisplayContext": "OPTIONAL", - "DisplayContextParameter": "#ARGUMENT(CREATE)", + "DisplayContextParameter": "#ARGUMENT(CREATE,VERSION2.1)", "PageID": 1, "PageDisplayOrder": 1, - "PageFieldDisplayOrder": 2 + "PageFieldDisplayOrder": 2, + "ShowSummaryChangeOption": "Y" }, { "CaseTypeID": "ET_EnglandWales", "CaseEventID": "manageFlags", "CaseFieldID": "flagLauncher", "DisplayContext": "OPTIONAL", - "DisplayContextParameter": "#ARGUMENT(UPDATE)", + "DisplayContextParameter": "#ARGUMENT(UPDATE,VERSION2.1)", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 6, + "ShowSummaryChangeOption": "Y" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "requestSupport", + "CaseFieldID": "flagLauncherExternal", + "DisplayContext": "OPTIONAL", + "DisplayContextParameter": "#ARGUMENT(CREATE,EXTERNAL)", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 2, + "ShowSummaryChangeOption": "Y" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageSupport", + "CaseFieldID": "flagLauncherExternal", + "DisplayContext": "OPTIONAL", + "DisplayContextParameter": "#ARGUMENT(UPDATE,EXTERNAL)", "PageID": 1, "PageDisplayOrder": 1, - "PageFieldDisplayOrder": 6 + "PageFieldDisplayOrder": 6, + "ShowSummaryChangeOption": "Y" }, { "CaseTypeID": "ET_EnglandWales", @@ -72,6 +156,8 @@ "PageDisplayOrder": 1, "PageFieldDisplayOrder": 5, "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", "RetainHiddenValue": "Yes" }, { @@ -83,6 +169,762 @@ "PageDisplayOrder": 1, "PageFieldDisplayOrder": 3, "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageFlags", + "CaseFieldID": "respondent1Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "createFlag", + "CaseFieldID": "respondent1Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageFlags", + "CaseFieldID": "respondent2Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "createFlag", + "CaseFieldID": "respondent2Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageFlags", + "CaseFieldID": "respondent3Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "createFlag", + "CaseFieldID": "respondent3Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageFlags", + "CaseFieldID": "respondent4Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "createFlag", + "CaseFieldID": "respondent4Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageFlags", + "CaseFieldID": "respondent5Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "createFlag", + "CaseFieldID": "respondent5Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageFlags", + "CaseFieldID": "respondent6Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "createFlag", + "CaseFieldID": "respondent6Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageFlags", + "CaseFieldID": "respondent7Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "createFlag", + "CaseFieldID": "respondent7Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageFlags", + "CaseFieldID": "respondent8Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "createFlag", + "CaseFieldID": "respondent8Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageFlags", + "CaseFieldID": "respondent9Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "createFlag", + "CaseFieldID": "respondent9Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageFlags", + "CaseFieldID": "respondentExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "createFlag", + "CaseFieldID": "respondentExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageFlags", + "CaseFieldID": "respondent1ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "createFlag", + "CaseFieldID": "respondent1ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageFlags", + "CaseFieldID": "respondent2ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "createFlag", + "CaseFieldID": "respondent2ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageFlags", + "CaseFieldID": "respondent3ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "createFlag", + "CaseFieldID": "respondent3ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageFlags", + "CaseFieldID": "respondent4ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "createFlag", + "CaseFieldID": "respondent4ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageFlags", + "CaseFieldID": "respondent5ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "createFlag", + "CaseFieldID": "respondent5ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageFlags", + "CaseFieldID": "respondent6ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "createFlag", + "CaseFieldID": "respondent6ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageFlags", + "CaseFieldID": "respondent7ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "createFlag", + "CaseFieldID": "respondent7ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageFlags", + "CaseFieldID": "respondent8ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "createFlag", + "CaseFieldID": "respondent8ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageFlags", + "CaseFieldID": "respondent9ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "createFlag", + "CaseFieldID": "respondent9ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageSupport", + "CaseFieldID": "respondentExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "requestSupport", + "CaseFieldID": "respondentExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageSupport", + "CaseFieldID": "respondent1ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "requestSupport", + "CaseFieldID": "respondent1ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageSupport", + "CaseFieldID": "respondent2ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "requestSupport", + "CaseFieldID": "respondent2ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageSupport", + "CaseFieldID": "respondent3ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "requestSupport", + "CaseFieldID": "respondent3ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageSupport", + "CaseFieldID": "respondent4ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "requestSupport", + "CaseFieldID": "respondent4ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageSupport", + "CaseFieldID": "respondent5ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "requestSupport", + "CaseFieldID": "respondent5ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageSupport", + "CaseFieldID": "respondent6ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "requestSupport", + "CaseFieldID": "respondent6ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageSupport", + "CaseFieldID": "respondent7ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "requestSupport", + "CaseFieldID": "respondent7ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageSupport", + "CaseFieldID": "respondent8ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "requestSupport", + "CaseFieldID": "respondent8ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageSupport", + "CaseFieldID": "respondent9ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "requestSupport", + "CaseFieldID": "respondent9ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", "RetainHiddenValue": "Yes" }, { @@ -131,4 +973,4 @@ "PageDisplayOrder": 1, "ShowSummaryChangeOption": "N" } -] \ No newline at end of file +] diff --git a/ccd-definitions/jurisdictions/england-wales/json/CaseField/CaseField-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/england-wales/json/CaseField/CaseField-CaseFlagsCaseLinking.json index b2bef658c3..e7eb30f721 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/CaseField/CaseField-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/england-wales/json/CaseField/CaseField-CaseFlagsCaseLinking.json @@ -13,6 +13,13 @@ "FieldType": "Flags", "SecurityClassification": "Public" }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "claimantExternalFlags", + "Label": "Claimant External Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, { "CaseTypeID": "ET_EnglandWales", "ID": "flagLauncher", @@ -20,6 +27,13 @@ "FieldType": "FlagLauncher", "SecurityClassification": "Public" }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "flagLauncherExternal", + "Label": "Launch the external Flags screen", + "FieldType": "FlagLauncher", + "SecurityClassification": "Public" + }, { "CaseTypeID": "ET_EnglandWales", "ID": "respondentFlags", @@ -27,6 +41,139 @@ "FieldType": "Flags", "SecurityClassification": "Public" }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "respondent1Flags", + "Label": "Respondent 1 Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "respondent2Flags", + "Label": "Respondent 2 Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "respondent3Flags", + "Label": "Respondent 3 Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "respondent4Flags", + "Label": "Respondent 4 Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "respondent5Flags", + "Label": "Respondent 5 Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "respondent6Flags", + "Label": "Respondent 6 Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "respondent7Flags", + "Label": "Respondent 7 Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "respondent8Flags", + "Label": "Respondent 8 Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "respondent9Flags", + "Label": "Respondent 9 Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "respondentExternalFlags", + "Label": "Respondent External Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "respondent1ExternalFlags", + "Label": "Respondent 1 External Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "respondent2ExternalFlags", + "Label": "Respondent 2 External Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "respondent3ExternalFlags", + "Label": "Respondent 3 External Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "respondent4ExternalFlags", + "Label": "Respondent 4 External Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "respondent5ExternalFlags", + "Label": "Respondent 5 External Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "respondent6ExternalFlags", + "Label": "Respondent 6 External Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "respondent7ExternalFlags", + "Label": "Respondent 7 External Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "respondent8ExternalFlags", + "Label": "Respondent 8 External Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "respondent9ExternalFlags", + "Label": "Respondent 9 External Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, { "LiveFrom": "03/11/2022", "CaseTypeID": "ET_EnglandWales", diff --git a/ccd-definitions/jurisdictions/england-wales/json/CaseTypeTab/CaseTypeTab-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/england-wales/json/CaseTypeTab/CaseTypeTab-CaseFlagsCaseLinking.json index a4a314c22e..049f94e17f 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/CaseTypeTab/CaseTypeTab-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/england-wales/json/CaseTypeTab/CaseTypeTab-CaseFlagsCaseLinking.json @@ -46,6 +46,96 @@ "TabLabel": "Case Flags", "TabFieldDisplayOrder": 2 }, + { + "CaseFieldID": "respondent1Flags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 3 + }, + { + "CaseFieldID": "respondent2Flags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 4 + }, + { + "CaseFieldID": "respondent3Flags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 5 + }, + { + "CaseFieldID": "respondent4Flags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 6 + }, + { + "CaseFieldID": "respondent5Flags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 7 + }, + { + "CaseFieldID": "respondent6Flags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 8 + }, + { + "CaseFieldID": "respondent7Flags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 9 + }, + { + "CaseFieldID": "respondent8Flags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 10 + }, + { + "CaseFieldID": "respondent9Flags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 11 + }, { "CaseFieldID": "caseFlags", "CaseTypeID": "ET_EnglandWales", @@ -54,7 +144,7 @@ "TabDisplayOrder": 69, "TabID": "caseFlags", "TabLabel": "Case Flags", - "TabFieldDisplayOrder": 3 + "TabFieldDisplayOrder": 12 }, { "CaseFieldID": "flagLauncher", @@ -63,7 +153,127 @@ "TabDisplayOrder": 69, "TabID": "caseFlags", "TabLabel": "Case Flags", - "TabFieldDisplayOrder": 4, - "DisplayContextParameter": "#ARGUMENT(READ)" + "TabFieldDisplayOrder": 13, + "DisplayContextParameter": "#ARGUMENT(READ,VERSION2.1)" + }, + { + "CaseFieldID": "claimantExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 69, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 1 + }, + { + "CaseFieldID": "respondentExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 2 + }, + { + "CaseFieldID": "respondent1ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 3 + }, + { + "CaseFieldID": "respondent2ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 4 + }, + { + "CaseFieldID": "respondent3ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 5 + }, + { + "CaseFieldID": "respondent4ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 6 + }, + { + "CaseFieldID": "respondent5ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 7 + }, + { + "CaseFieldID": "respondent6ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 8 + }, + { + "CaseFieldID": "respondent7ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 9 + }, + { + "CaseFieldID": "respondent8ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 10 + }, + { + "CaseFieldID": "respondent9ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 11 + }, + { + "CaseFieldID": "flagLauncherExternal", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "TabDisplayOrder": 69, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 12, + "DisplayContextParameter": "#ARGUMENT(READ,EXTERNAL)" } ] diff --git a/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseEvent/AuthorisationCaseEvent-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseEvent/AuthorisationCaseEvent-CaseFlagsCaseLinking.json index 305bde2f60..d7c2281bfe 100644 --- a/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseEvent/AuthorisationCaseEvent-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseEvent/AuthorisationCaseEvent-CaseFlagsCaseLinking.json @@ -23,6 +23,30 @@ "UserRole": "caseworker-employment-scotland", "CRUD": "CRU" }, + { + "CaseTypeId": "ET_Scotland", + "CaseEventID": "requestSupport", + "UserRole": "caseworker-employment-legalrep-solicitor", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseEventID": "manageSupport", + "UserRole": "caseworker-employment-legalrep-solicitor", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseEventID": "requestSupport", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseEventID": "manageSupport", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, { "CaseTypeId": "ET_Scotland", "CaseEventID": "UPDATE_HUBLINK_STATUS", diff --git a/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json index 7e4e0abdcc..efda93b72a 100644 --- a/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json @@ -70,5 +70,455 @@ "CaseFieldID": "respondentFlags", "UserRole": "caseworker-employment-etjudge-scotland", "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent1Flags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent1Flags", + "UserRole": "caseworker-employment-etjudge-scotland", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent1Flags", + "UserRole": "caseworker-employment-scotland", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent2Flags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent2Flags", + "UserRole": "caseworker-employment-etjudge-scotland", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent2Flags", + "UserRole": "caseworker-employment-scotland", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent3Flags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent3Flags", + "UserRole": "caseworker-employment-etjudge-scotland", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent3Flags", + "UserRole": "caseworker-employment-scotland", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent4Flags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent4Flags", + "UserRole": "caseworker-employment-etjudge-scotland", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent4Flags", + "UserRole": "caseworker-employment-scotland", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent5Flags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent5Flags", + "UserRole": "caseworker-employment-etjudge-scotland", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent5Flags", + "UserRole": "caseworker-employment-scotland", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent6Flags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent6Flags", + "UserRole": "caseworker-employment-etjudge-scotland", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent6Flags", + "UserRole": "caseworker-employment-scotland", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent7Flags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent7Flags", + "UserRole": "caseworker-employment-etjudge-scotland", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent7Flags", + "UserRole": "caseworker-employment-scotland", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent8Flags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent8Flags", + "UserRole": "caseworker-employment-etjudge-scotland", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent8Flags", + "UserRole": "caseworker-employment-scotland", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent9Flags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent9Flags", + "UserRole": "caseworker-employment-etjudge-scotland", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent9Flags", + "UserRole": "caseworker-employment-scotland", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "flagLauncherExternal", + "UserRole": "caseworker-employment-legalrep-solicitor", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "claimantExternalFlags", + "UserRole": "[CLAIMANTSOLICITOR]", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondentExternalFlags", + "UserRole": "[SOLICITORA]", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent1ExternalFlags", + "UserRole": "[SOLICITORB]", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent2ExternalFlags", + "UserRole": "[SOLICITORC]", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent3ExternalFlags", + "UserRole": "[SOLICITORD]", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent4ExternalFlags", + "UserRole": "[SOLICITORE]", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent5ExternalFlags", + "UserRole": "[SOLICITORF]", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent6ExternalFlags", + "UserRole": "[SOLICITORG]", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent7ExternalFlags", + "UserRole": "[SOLICITORH]", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent8ExternalFlags", + "UserRole": "[SOLICITORI]", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent9ExternalFlags", + "UserRole": "[SOLICITORJ]", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "flagLauncherExternal", + "UserRole": "caseworker-employment-scotland", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "claimantExternalFlags", + "UserRole": "caseworker-employment-scotland", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondentExternalFlags", + "UserRole": "caseworker-employment-scotland", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent1ExternalFlags", + "UserRole": "caseworker-employment-scotland", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent2ExternalFlags", + "UserRole": "caseworker-employment-scotland", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent3ExternalFlags", + "UserRole": "caseworker-employment-scotland", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent4ExternalFlags", + "UserRole": "caseworker-employment-scotland", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent5ExternalFlags", + "UserRole": "caseworker-employment-scotland", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent6ExternalFlags", + "UserRole": "caseworker-employment-scotland", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent7ExternalFlags", + "UserRole": "caseworker-employment-scotland", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent8ExternalFlags", + "UserRole": "caseworker-employment-scotland", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent9ExternalFlags", + "UserRole": "caseworker-employment-scotland", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "flagLauncherExternal", + "UserRole": "caseworker-employment-etjudge-scotland", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "claimantExternalFlags", + "UserRole": "caseworker-employment-etjudge-scotland", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondentExternalFlags", + "UserRole": "caseworker-employment-etjudge-scotland", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent1ExternalFlags", + "UserRole": "caseworker-employment-etjudge-scotland", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent2ExternalFlags", + "UserRole": "caseworker-employment-etjudge-scotland", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent3ExternalFlags", + "UserRole": "caseworker-employment-etjudge-scotland", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent4ExternalFlags", + "UserRole": "caseworker-employment-etjudge-scotland", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent5ExternalFlags", + "UserRole": "caseworker-employment-etjudge-scotland", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent6ExternalFlags", + "UserRole": "caseworker-employment-etjudge-scotland", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent7ExternalFlags", + "UserRole": "caseworker-employment-etjudge-scotland", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent8ExternalFlags", + "UserRole": "caseworker-employment-etjudge-scotland", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent9ExternalFlags", + "UserRole": "caseworker-employment-etjudge-scotland", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "flagLauncherExternal", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "claimantExternalFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondentExternalFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent1ExternalFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent2ExternalFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent3ExternalFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent4ExternalFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent5ExternalFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent6ExternalFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent7ExternalFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent8ExternalFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondent9ExternalFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" } ] diff --git a/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json index b0931bbaea..02adb198f0 100644 --- a/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json @@ -29,6 +29,36 @@ "CallBackURLAboutToSubmitEvent": "", "CallBackURLSubmittedEvent": "" }, + { + "CaseTypeID": "ET_Scotland", + "ID": "requestSupport", + "Name": "Request support", + "Description": "Request support", + "PreConditionState(s)": "*", + "PostConditionState": "*", + "SecurityClassification": "Public", + "ShowEventNotes": "N", + "ShowSummary": "Y", + "EventEnablingCondition": "", + "CallBackURLAboutToStartEvent": "", + "CallBackURLAboutToSubmitEvent": "", + "CallBackURLSubmittedEvent": "" + }, + { + "CaseTypeID": "ET_Scotland", + "ID": "manageSupport", + "Name": "Manage Support", + "Description": "Manage Support", + "PreConditionState(s)": "*", + "PostConditionState": "*", + "SecurityClassification": "Public", + "ShowEventNotes": "N", + "ShowSummary": "Y", + "EventEnablingCondition": "", + "CallBackURLAboutToStartEvent": "", + "CallBackURLAboutToSubmitEvent": "", + "CallBackURLSubmittedEvent": "" + }, { "CaseTypeID": "ET_Scotland", "ID": "createCaseLink", diff --git a/ccd-definitions/jurisdictions/scotland/json/CaseEventToFields/CaseEventToFields-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/scotland/json/CaseEventToFields/CaseEventToFields-CaseFlagsCaseLinking.json index 1b37e051d3..653e4bf450 100644 --- a/ccd-definitions/jurisdictions/scotland/json/CaseEventToFields/CaseEventToFields-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/scotland/json/CaseEventToFields/CaseEventToFields-CaseFlagsCaseLinking.json @@ -8,6 +8,8 @@ "PageDisplayOrder": 1, "PageFieldDisplayOrder": 1, "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", "RetainHiddenValue": "Yes" }, { @@ -19,6 +21,8 @@ "PageDisplayOrder": 1, "PageFieldDisplayOrder": 7, "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", "RetainHiddenValue": "Yes" }, { @@ -30,6 +34,8 @@ "PageDisplayOrder": 1, "PageFieldDisplayOrder": 4, "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", "RetainHiddenValue": "Yes" }, { @@ -41,6 +47,60 @@ "PageDisplayOrder": 1, "PageFieldDisplayOrder": 4, "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "createFlag", + "CaseFieldID": "claimantExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 4, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageFlags", + "CaseFieldID": "claimantExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 4, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "requestSupport", + "CaseFieldID": "claimantExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 4, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageSupport", + "CaseFieldID": "claimantExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 4, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", "RetainHiddenValue": "Yes" }, { @@ -48,20 +108,44 @@ "CaseEventID": "createFlag", "CaseFieldID": "flagLauncher", "DisplayContext": "OPTIONAL", - "DisplayContextParameter": "#ARGUMENT(CREATE)", + "DisplayContextParameter": "#ARGUMENT(CREATE,VERSION2.1)", "PageID": 1, "PageDisplayOrder": 1, - "PageFieldDisplayOrder": 2 + "PageFieldDisplayOrder": 2, + "ShowSummaryChangeOption": "Y" }, { "CaseTypeID": "ET_Scotland", "CaseEventID": "manageFlags", "CaseFieldID": "flagLauncher", "DisplayContext": "OPTIONAL", - "DisplayContextParameter": "#ARGUMENT(UPDATE)", + "DisplayContextParameter": "#ARGUMENT(UPDATE,VERSION2.1)", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 6, + "ShowSummaryChangeOption": "Y" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "requestSupport", + "CaseFieldID": "flagLauncherExternal", + "DisplayContext": "OPTIONAL", + "DisplayContextParameter": "#ARGUMENT(CREATE,EXTERNAL)", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 2, + "ShowSummaryChangeOption": "Y" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageSupport", + "CaseFieldID": "flagLauncherExternal", + "DisplayContext": "OPTIONAL", + "DisplayContextParameter": "#ARGUMENT(UPDATE,EXTERNAL)", "PageID": 1, "PageDisplayOrder": 1, - "PageFieldDisplayOrder": 6 + "PageFieldDisplayOrder": 6, + "ShowSummaryChangeOption": "Y" }, { "CaseTypeID": "ET_Scotland", @@ -72,6 +156,8 @@ "PageDisplayOrder": 1, "PageFieldDisplayOrder": 5, "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", "RetainHiddenValue": "Yes" }, { @@ -83,6 +169,762 @@ "PageDisplayOrder": 1, "PageFieldDisplayOrder": 3, "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageFlags", + "CaseFieldID": "respondent1Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "createFlag", + "CaseFieldID": "respondent1Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageFlags", + "CaseFieldID": "respondent2Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "createFlag", + "CaseFieldID": "respondent2Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageFlags", + "CaseFieldID": "respondent3Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "createFlag", + "CaseFieldID": "respondent3Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageFlags", + "CaseFieldID": "respondent4Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "createFlag", + "CaseFieldID": "respondent4Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageFlags", + "CaseFieldID": "respondent5Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "createFlag", + "CaseFieldID": "respondent5Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageFlags", + "CaseFieldID": "respondent6Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "createFlag", + "CaseFieldID": "respondent6Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageFlags", + "CaseFieldID": "respondent7Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "createFlag", + "CaseFieldID": "respondent7Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageFlags", + "CaseFieldID": "respondent8Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "createFlag", + "CaseFieldID": "respondent8Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageFlags", + "CaseFieldID": "respondent9Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "createFlag", + "CaseFieldID": "respondent9Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageFlags", + "CaseFieldID": "respondentExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "createFlag", + "CaseFieldID": "respondentExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageFlags", + "CaseFieldID": "respondent1ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "createFlag", + "CaseFieldID": "respondent1ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageFlags", + "CaseFieldID": "respondent2ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "createFlag", + "CaseFieldID": "respondent2ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageFlags", + "CaseFieldID": "respondent3ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "createFlag", + "CaseFieldID": "respondent3ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageFlags", + "CaseFieldID": "respondent4ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "createFlag", + "CaseFieldID": "respondent4ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageFlags", + "CaseFieldID": "respondent5ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "createFlag", + "CaseFieldID": "respondent5ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageFlags", + "CaseFieldID": "respondent6ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "createFlag", + "CaseFieldID": "respondent6ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageFlags", + "CaseFieldID": "respondent7ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "createFlag", + "CaseFieldID": "respondent7ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageFlags", + "CaseFieldID": "respondent8ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "createFlag", + "CaseFieldID": "respondent8ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageFlags", + "CaseFieldID": "respondent9ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "createFlag", + "CaseFieldID": "respondent9ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageSupport", + "CaseFieldID": "respondentExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "requestSupport", + "CaseFieldID": "respondentExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageSupport", + "CaseFieldID": "respondent1ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "requestSupport", + "CaseFieldID": "respondent1ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageSupport", + "CaseFieldID": "respondent2ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "requestSupport", + "CaseFieldID": "respondent2ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageSupport", + "CaseFieldID": "respondent3ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "requestSupport", + "CaseFieldID": "respondent3ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageSupport", + "CaseFieldID": "respondent4ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "requestSupport", + "CaseFieldID": "respondent4ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageSupport", + "CaseFieldID": "respondent5ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "requestSupport", + "CaseFieldID": "respondent5ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageSupport", + "CaseFieldID": "respondent6ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "requestSupport", + "CaseFieldID": "respondent6ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageSupport", + "CaseFieldID": "respondent7ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "requestSupport", + "CaseFieldID": "respondent7ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageSupport", + "CaseFieldID": "respondent8ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "requestSupport", + "CaseFieldID": "respondent8ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageSupport", + "CaseFieldID": "respondent9ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "requestSupport", + "CaseFieldID": "respondent9ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", "RetainHiddenValue": "Yes" }, { @@ -131,4 +973,4 @@ "PageDisplayOrder": 1, "ShowSummaryChangeOption": "N" } -] \ No newline at end of file +] diff --git a/ccd-definitions/jurisdictions/scotland/json/CaseField/CaseField-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/scotland/json/CaseField/CaseField-CaseFlagsCaseLinking.json index bb9439cd88..68679450c8 100644 --- a/ccd-definitions/jurisdictions/scotland/json/CaseField/CaseField-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/scotland/json/CaseField/CaseField-CaseFlagsCaseLinking.json @@ -13,6 +13,13 @@ "FieldType": "Flags", "SecurityClassification": "Public" }, + { + "CaseTypeID": "ET_Scotland", + "ID": "claimantExternalFlags", + "Label": "Claimant External Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, { "CaseTypeID": "ET_Scotland", "ID": "flagLauncher", @@ -21,6 +28,13 @@ "SecurityClassification": "Public", "Searchable": "N" }, + { + "CaseTypeID": "ET_Scotland", + "ID": "flagLauncherExternal", + "Label": "Launch the external Flags screen", + "FieldType": "FlagLauncher", + "SecurityClassification": "Public" + }, { "CaseTypeID": "ET_Scotland", "ID": "respondentFlags", @@ -28,6 +42,139 @@ "FieldType": "Flags", "SecurityClassification": "Public" }, + { + "CaseTypeID": "ET_Scotland", + "ID": "respondent1Flags", + "Label": "Respondent 1 Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_Scotland", + "ID": "respondent2Flags", + "Label": "Respondent 2 Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_Scotland", + "ID": "respondent3Flags", + "Label": "Respondent 3 Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_Scotland", + "ID": "respondent4Flags", + "Label": "Respondent 4 Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_Scotland", + "ID": "respondent5Flags", + "Label": "Respondent 5 Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_Scotland", + "ID": "respondent6Flags", + "Label": "Respondent 6 Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_Scotland", + "ID": "respondent7Flags", + "Label": "Respondent 7 Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_Scotland", + "ID": "respondent8Flags", + "Label": "Respondent 8 Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_Scotland", + "ID": "respondent9Flags", + "Label": "Respondent 9 Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_Scotland", + "ID": "respondentExternalFlags", + "Label": "Respondent External Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_Scotland", + "ID": "respondent1ExternalFlags", + "Label": "Respondent 1 External Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_Scotland", + "ID": "respondent2ExternalFlags", + "Label": "Respondent 2 External Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_Scotland", + "ID": "respondent3ExternalFlags", + "Label": "Respondent 3 External Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_Scotland", + "ID": "respondent4ExternalFlags", + "Label": "Respondent 4 External Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_Scotland", + "ID": "respondent5ExternalFlags", + "Label": "Respondent 5 External Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_Scotland", + "ID": "respondent6ExternalFlags", + "Label": "Respondent 6 External Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_Scotland", + "ID": "respondent7ExternalFlags", + "Label": "Respondent 7 External Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_Scotland", + "ID": "respondent8ExternalFlags", + "Label": "Respondent 8 External Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_Scotland", + "ID": "respondent9ExternalFlags", + "Label": "Respondent 9 External Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, { "LiveFrom": "10/02/2023", "CaseTypeID": "ET_Scotland", diff --git a/ccd-definitions/jurisdictions/scotland/json/CaseTypeTab/CaseTypeTab-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/scotland/json/CaseTypeTab/CaseTypeTab-CaseFlagsCaseLinking.json index 0e0d9059b1..eb830993bf 100644 --- a/ccd-definitions/jurisdictions/scotland/json/CaseTypeTab/CaseTypeTab-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/scotland/json/CaseTypeTab/CaseTypeTab-CaseFlagsCaseLinking.json @@ -46,6 +46,96 @@ "TabLabel": "Case Flags", "TabFieldDisplayOrder": 2 }, + { + "CaseFieldID": "respondent1Flags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 3 + }, + { + "CaseFieldID": "respondent2Flags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 4 + }, + { + "CaseFieldID": "respondent3Flags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 5 + }, + { + "CaseFieldID": "respondent4Flags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 6 + }, + { + "CaseFieldID": "respondent5Flags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 7 + }, + { + "CaseFieldID": "respondent6Flags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 8 + }, + { + "CaseFieldID": "respondent7Flags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 9 + }, + { + "CaseFieldID": "respondent8Flags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 10 + }, + { + "CaseFieldID": "respondent9Flags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 11 + }, { "CaseFieldID": "caseFlags", "CaseTypeID": "ET_Scotland", @@ -54,7 +144,7 @@ "TabDisplayOrder": 69, "TabID": "caseFlags", "TabLabel": "Case Flags", - "TabFieldDisplayOrder": 3 + "TabFieldDisplayOrder": 12 }, { "CaseFieldID": "flagLauncher", @@ -63,7 +153,127 @@ "TabDisplayOrder": 69, "TabID": "caseFlags", "TabLabel": "Case Flags", - "TabFieldDisplayOrder": 4, - "DisplayContextParameter": "#ARGUMENT(READ)" + "TabFieldDisplayOrder": 13, + "DisplayContextParameter": "#ARGUMENT(READ,VERSION2.1)" + }, + { + "CaseFieldID": "claimantExternalFlags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 69, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 1 + }, + { + "CaseFieldID": "respondentExternalFlags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 2 + }, + { + "CaseFieldID": "respondent1ExternalFlags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 3 + }, + { + "CaseFieldID": "respondent2ExternalFlags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 4 + }, + { + "CaseFieldID": "respondent3ExternalFlags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 5 + }, + { + "CaseFieldID": "respondent4ExternalFlags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 6 + }, + { + "CaseFieldID": "respondent5ExternalFlags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 7 + }, + { + "CaseFieldID": "respondent6ExternalFlags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 8 + }, + { + "CaseFieldID": "respondent7ExternalFlags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 9 + }, + { + "CaseFieldID": "respondent8ExternalFlags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 10 + }, + { + "CaseFieldID": "respondent9ExternalFlags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 11 + }, + { + "CaseFieldID": "flagLauncherExternal", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "TabDisplayOrder": 69, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 12, + "DisplayContextParameter": "#ARGUMENT(READ,EXTERNAL)" } ] diff --git a/docs/cftlib.md b/docs/cftlib.md index 44c78d1614..6d4f88011d 100644 --- a/docs/cftlib.md +++ b/docs/cftlib.md @@ -212,4 +212,8 @@ export CFTLIB_HOST="http://host.docker.internal" # Use your WSL IP if host.docke export CAMUNDA_NEXUS_PASSWORD="" export CFTLIB_EXTRA_COMPOSE_FILES="wa-docker-compose.yml" export SERVICE_AUTH_PROVIDER_API_BASE_URL="http://localhost:8489" + +export CCD_MULTIPARTY_FIX_ENABLED=true +export CCD_MULTIPARTY_CASE_TYPES="*" +export CCD_MULTIPARTY_EVENTS="*" ``` diff --git a/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/CaseData.java b/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/CaseData.java index 52a7d6f3e7..cc6bbca6d3 100644 --- a/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/CaseData.java +++ b/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/CaseData.java @@ -1560,7 +1560,28 @@ public class CaseData extends Et1CaseData { // Case Flags private CaseFlagsType caseFlags; private CaseFlagsType claimantFlags; + private CaseFlagsType claimantExternalFlags; private CaseFlagsType respondentFlags; + private CaseFlagsType respondentExternalFlags; + private CaseFlagsType respondent1Flags; + private CaseFlagsType respondent1ExternalFlags; + private CaseFlagsType respondent2Flags; + private CaseFlagsType respondent2ExternalFlags; + private CaseFlagsType respondent3Flags; + private CaseFlagsType respondent3ExternalFlags; + private CaseFlagsType respondent4Flags; + private CaseFlagsType respondent4ExternalFlags; + private CaseFlagsType respondent5Flags; + private CaseFlagsType respondent5ExternalFlags; + private CaseFlagsType respondent6Flags; + private CaseFlagsType respondent6ExternalFlags; + private CaseFlagsType respondent7Flags; + private CaseFlagsType respondent7ExternalFlags; + private CaseFlagsType respondent8Flags; + private CaseFlagsType respondent8ExternalFlags; + private CaseFlagsType respondent9Flags; + private CaseFlagsType respondent9ExternalFlags; + //et-hearings-api @JsonProperty("autoListFlag") diff --git a/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/items/FlagDetailType.java b/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/items/FlagDetailType.java index e17383f082..12b3b29c1a 100644 --- a/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/items/FlagDetailType.java +++ b/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/items/FlagDetailType.java @@ -11,7 +11,7 @@ @AllArgsConstructor @NoArgsConstructor @JsonIgnoreProperties(ignoreUnknown = true) -@SuppressWarnings("checkstyle:MemberName") // needed for the welsh options +@SuppressWarnings("checkstyle:MemberName") // needed for the Welsh options public class FlagDetailType { private String name; private String name_cy; @@ -28,5 +28,6 @@ public class FlagDetailType { private String hearingRelevant; private String flagCode; private String status; + private String requestReason; private String availableExternally; } diff --git a/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/types/CaseFlagsType.java b/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/types/CaseFlagsType.java index 1db616f35b..f3db0f7a4b 100644 --- a/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/types/CaseFlagsType.java +++ b/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/types/CaseFlagsType.java @@ -19,6 +19,10 @@ public class CaseFlagsType { private String partyName; @JsonProperty("roleOnCase") private String roleOnCase; + @JsonProperty("groupId") + private String groupId; + @JsonProperty("visibility") + private String visibility; @JsonProperty("details") private ListTypeItem details; } diff --git a/src/cftlib/resources/compose/mocks/wiremock/__files/prd/party-flags.json b/src/cftlib/resources/compose/mocks/wiremock/__files/prd/party-flags.json index 99dad50155..19ed738471 100644 --- a/src/cftlib/resources/compose/mocks/wiremock/__files/prd/party-flags.json +++ b/src/cftlib/resources/compose/mocks/wiremock/__files/prd/party-flags.json @@ -9,6 +9,7 @@ "defaultStatus": "Active", "externallyAvailable": false, "flagCode": "CATGRY", + "nativeFlagCode": "PF0001", "childFlags": [ { "name": "Reasonable adjustment", @@ -17,6 +18,7 @@ "defaultStatus": "Active", "externallyAvailable": false, "flagCode": "CATGRY", + "nativeFlagCode": "RA0001", "childFlags": [ { "name": "I need documents in an alternative format", @@ -25,14 +27,16 @@ "defaultStatus": "Active", "externallyAvailable": false, "flagCode": "CATGRY", + "nativeFlagCode": "RA0002", "childFlags": [ { "name": "Documents in a specified colour", "hearingRelevant": true, - "flagComment": false, - "defaultStatus": "Active", + "flagComment": true, + "defaultStatus": "Requested", "externallyAvailable": true, "flagCode": "RA0010", + "nativeFlagCode": "RA0010", "childFlags": [], "isParent": false, "Path": [ @@ -45,9 +49,10 @@ "name": "Documents in easy read format", "hearingRelevant": true, "flagComment": false, - "defaultStatus": "Active", + "defaultStatus": "Requested", "externallyAvailable": true, "flagCode": "RA0011", + "nativeFlagCode": "RA0011", "childFlags": [], "isParent": false, "Path": [ @@ -60,9 +65,10 @@ "name": "Braille documents", "hearingRelevant": true, "flagComment": false, - "defaultStatus": "Active", + "defaultStatus": "Requested", "externallyAvailable": true, "flagCode": "RA0012", + "nativeFlagCode": "RA0012", "childFlags": [], "isParent": false, "Path": [ @@ -74,10 +80,11 @@ { "name": "Documents in large print", "hearingRelevant": true, - "flagComment": false, - "defaultStatus": "Active", + "flagComment": true, + "defaultStatus": "Requested", "externallyAvailable": true, "flagCode": "RA0013", + "nativeFlagCode": "RA0013", "childFlags": [], "isParent": false, "Path": [ @@ -90,9 +97,10 @@ "name": "Audio translation of documents", "hearingRelevant": false, "flagComment": false, - "defaultStatus": "Active", + "defaultStatus": "Requested", "externallyAvailable": true, "flagCode": "RA0014", + "nativeFlagCode": "RA0014", "childFlags": [], "isParent": false, "Path": [ @@ -103,11 +111,12 @@ }, { "name": "Documents read out to me", - "hearingRelevant": true, + "hearingRelevant": false, "flagComment": false, - "defaultStatus": "Active", + "defaultStatus": "Requested", "externallyAvailable": true, "flagCode": "RA0015", + "nativeFlagCode": "RA0015", "childFlags": [], "isParent": false, "Path": [ @@ -120,9 +129,10 @@ "name": "Information emailed to me", "hearingRelevant": false, "flagComment": false, - "defaultStatus": "Active", + "defaultStatus": "Requested", "externallyAvailable": true, "flagCode": "RA0016", + "nativeFlagCode": "RA0016", "childFlags": [], "isParent": false, "Path": [ @@ -135,9 +145,10 @@ "name": "Other", "hearingRelevant": true, "flagComment": true, - "defaultStatus": "Active", - "externallyAvailable": false, + "defaultStatus": "Requested", + "externallyAvailable": true, "flagCode": "OT0001", + "nativeFlagCode": "OT0001", "childFlags": [], "isParent": false, "Path": [ @@ -160,14 +171,16 @@ "defaultStatus": "Active", "externallyAvailable": false, "flagCode": "CATGRY", + "nativeFlagCode": "RA0003", "childFlags": [ { "name": "Guidance on how to complete forms", "hearingRelevant": false, "flagComment": false, - "defaultStatus": "Active", - "externallyAvailable": true, + "defaultStatus": "Requested", + "externallyAvailable": false, "flagCode": "RA0017", + "nativeFlagCode": "RA0017", "childFlags": [], "isParent": false, "Path": [ @@ -180,9 +193,10 @@ "name": "Support filling in forms", "hearingRelevant": false, "flagComment": false, - "defaultStatus": "Active", - "externallyAvailable": true, + "defaultStatus": "Requested", + "externallyAvailable": false, "flagCode": "RA0018", + "nativeFlagCode": "RA0018", "childFlags": [], "isParent": false, "Path": [ @@ -195,9 +209,10 @@ "name": "Other", "hearingRelevant": true, "flagComment": true, - "defaultStatus": "Active", - "externallyAvailable": false, + "defaultStatus": "Requested", + "externallyAvailable": true, "flagCode": "OT0001", + "nativeFlagCode": "OT0001", "childFlags": [], "isParent": false, "Path": [ @@ -220,14 +235,16 @@ "defaultStatus": "Active", "externallyAvailable": false, "flagCode": "CATGRY", + "nativeFlagCode": "RA0004", "childFlags": [ { "name": "Step free / wheelchair access", "hearingRelevant": true, "flagComment": false, - "defaultStatus": "Active", - "externallyAvailable": false, + "defaultStatus": "Requested", + "externallyAvailable": true, "flagCode": "RA0019", + "nativeFlagCode": "RA0019", "childFlags": [], "isParent": false, "Path": [ @@ -238,11 +255,12 @@ }, { "name": "Use of venue wheelchair", - "hearingRelevant": true, + "hearingRelevant": false, "flagComment": false, - "defaultStatus": "Active", + "defaultStatus": "Requested", "externallyAvailable": true, "flagCode": "RA0020", + "nativeFlagCode": "RA0020", "childFlags": [], "isParent": false, "Path": [ @@ -254,10 +272,11 @@ { "name": "Parking space close to the venue", "hearingRelevant": true, - "flagComment": false, + "flagComment": true, "defaultStatus": "Requested", "externallyAvailable": true, "flagCode": "RA0021", + "nativeFlagCode": "RA0021", "childFlags": [], "isParent": false, "Path": [ @@ -268,11 +287,12 @@ }, { "name": "Accessible toilet", - "hearingRelevant": true, + "hearingRelevant": false, "flagComment": false, - "defaultStatus": "Active", + "defaultStatus": "Requested", "externallyAvailable": true, "flagCode": "RA0022", + "nativeFlagCode": "RA0022", "childFlags": [], "isParent": false, "Path": [ @@ -283,11 +303,12 @@ }, { "name": "Help using a lift", - "hearingRelevant": true, + "hearingRelevant": false, "flagComment": false, - "defaultStatus": "Active", + "defaultStatus": "Requested", "externallyAvailable": true, "flagCode": "RA0023", + "nativeFlagCode": "RA0023", "childFlags": [], "isParent": false, "Path": [ @@ -301,8 +322,9 @@ "hearingRelevant": true, "flagComment": false, "defaultStatus": "Requested", - "externallyAvailable": true, + "externallyAvailable": false, "flagCode": "RA0024", + "nativeFlagCode": "RA0024", "childFlags": [], "isParent": false, "Path": [ @@ -315,9 +337,10 @@ "name": "Guiding in the building", "hearingRelevant": true, "flagComment": false, - "defaultStatus": "Active", + "defaultStatus": "Requested", "externallyAvailable": true, "flagCode": "RA0025", + "nativeFlagCode": "RA0025", "childFlags": [], "isParent": false, "Path": [ @@ -330,9 +353,10 @@ "name": "Other", "hearingRelevant": true, "flagComment": true, - "defaultStatus": "Active", - "externallyAvailable": false, + "defaultStatus": "Requested", + "externallyAvailable": true, "flagCode": "OT0001", + "nativeFlagCode": "OT0001", "childFlags": [], "isParent": false, "Path": [ @@ -355,14 +379,16 @@ "defaultStatus": "Active", "externallyAvailable": false, "flagCode": "CATGRY", + "nativeFlagCode": "RA0005", "childFlags": [ { "name": "Support worker or carer with me", "hearingRelevant": true, - "flagComment": false, + "flagComment": true, "defaultStatus": "Requested", "externallyAvailable": true, "flagCode": "RA0026", + "nativeFlagCode": "RA0026", "childFlags": [], "isParent": false, "Path": [ @@ -374,10 +400,11 @@ { "name": "Friend or family with me", "hearingRelevant": true, - "flagComment": false, + "flagComment": true, "defaultStatus": "Requested", "externallyAvailable": true, "flagCode": "RA0027", + "nativeFlagCode": "RA0027", "childFlags": [], "isParent": false, "Path": [ @@ -393,6 +420,7 @@ "defaultStatus": "Requested", "externallyAvailable": true, "flagCode": "RA0028", + "nativeFlagCode": "RA0028", "childFlags": [], "isParent": false, "Path": [ @@ -404,10 +432,11 @@ { "name": "Therapy animal", "hearingRelevant": true, - "flagComment": false, + "flagComment": true, "defaultStatus": "Requested", "externallyAvailable": true, "flagCode": "RA0029", + "nativeFlagCode": "RA0029", "childFlags": [], "isParent": false, "Path": [ @@ -420,9 +449,10 @@ "name": "Other", "hearingRelevant": true, "flagComment": true, - "defaultStatus": "Active", - "externallyAvailable": false, + "defaultStatus": "Requested", + "externallyAvailable": true, "flagCode": "OT0001", + "nativeFlagCode": "OT0001", "childFlags": [], "isParent": false, "Path": [ @@ -445,6 +475,7 @@ "defaultStatus": "Active", "externallyAvailable": false, "flagCode": "CATGRY", + "nativeFlagCode": "RA0006", "childFlags": [ { "name": "Appropriate lighting", @@ -453,6 +484,7 @@ "defaultStatus": "Requested", "externallyAvailable": true, "flagCode": "RA0030", + "nativeFlagCode": "RA0030", "childFlags": [], "isParent": false, "Path": [ @@ -468,6 +500,7 @@ "defaultStatus": "Requested", "externallyAvailable": true, "flagCode": "RA0031", + "nativeFlagCode": "RA0031", "childFlags": [], "isParent": false, "Path": [ @@ -478,11 +511,12 @@ }, { "name": "Space to be able to get up and move around", - "hearingRelevant": true, + "hearingRelevant": false, "flagComment": false, "defaultStatus": "Requested", "externallyAvailable": true, "flagCode": "RA0032", + "nativeFlagCode": "RA0032", "childFlags": [], "isParent": false, "Path": [ @@ -495,9 +529,10 @@ "name": "Private waiting area", "hearingRelevant": true, "flagComment": false, - "defaultStatus": "Active", - "externallyAvailable": false, + "defaultStatus": "Requested", + "externallyAvailable": true, "flagCode": "RA0033", + "nativeFlagCode": "RA0033", "childFlags": [], "isParent": false, "Path": [ @@ -510,9 +545,10 @@ "name": "Other", "hearingRelevant": true, "flagComment": true, - "defaultStatus": "Active", - "externallyAvailable": false, + "defaultStatus": "Requested", + "externallyAvailable": true, "flagCode": "OT0001", + "nativeFlagCode": "OT0001", "childFlags": [], "isParent": false, "Path": [ @@ -535,14 +571,16 @@ "defaultStatus": "Active", "externallyAvailable": false, "flagCode": "CATGRY", + "nativeFlagCode": "RA0007", "childFlags": [ { "name": "In person hearing", "hearingRelevant": true, "flagComment": false, - "defaultStatus": "Active", - "externallyAvailable": false, + "defaultStatus": "Requested", + "externallyAvailable": true, "flagCode": "RA0034", + "nativeFlagCode": "RA0034", "childFlags": [], "isParent": false, "Path": [ @@ -555,9 +593,10 @@ "name": "Video hearing", "hearingRelevant": true, "flagComment": false, - "defaultStatus": "Active", - "externallyAvailable": false, + "defaultStatus": "Requested", + "externallyAvailable": true, "flagCode": "RA0035", + "nativeFlagCode": "RA0035", "childFlags": [], "isParent": false, "Path": [ @@ -570,9 +609,10 @@ "name": "Phone hearing", "hearingRelevant": true, "flagComment": false, - "defaultStatus": "Active", - "externallyAvailable": false, + "defaultStatus": "Requested", + "externallyAvailable": true, "flagCode": "RA0036", + "nativeFlagCode": "RA0036", "childFlags": [], "isParent": false, "Path": [ @@ -585,9 +625,10 @@ "name": "Other", "hearingRelevant": true, "flagComment": true, - "defaultStatus": "Active", - "externallyAvailable": false, + "defaultStatus": "Requested", + "externallyAvailable": true, "flagCode": "OT0001", + "nativeFlagCode": "OT0001", "childFlags": [], "isParent": false, "Path": [ @@ -610,29 +651,32 @@ "defaultStatus": "Active", "externallyAvailable": false, "flagCode": "CATGRY", + "nativeFlagCode": "RA0008", "childFlags": [ { - "name": "I need an Hearing Enhancement System (Hearing/Induction Loop, Infrared Receiver)", + "name": "Hearing Enhancement System (Hearing/Induction Loop, Infrared Receiver)", "hearingRelevant": false, "flagComment": false, "defaultStatus": "Active", "externallyAvailable": false, "flagCode": "CATGRY", + "nativeFlagCode": "RA0009", "childFlags": [ { "name": "Hearing loop (hearing enhancement system)", "hearingRelevant": true, "flagComment": false, - "defaultStatus": "Active", - "externallyAvailable": false, + "defaultStatus": "Requested", + "externallyAvailable": true, "flagCode": "RA0043", + "nativeFlagCode": "RA0043", "childFlags": [], "isParent": false, "Path": [ "Party", "Reasonable adjustment", "I need help communicating and understanding", - "I need an Hearing Enhancement System (Hearing", + "Hearing Enhancement System (Hearing", "Induction Loop, Infrared Receiver)" ] }, @@ -640,16 +684,17 @@ "name": "Infrared receiver (hearing enhancement system)", "hearingRelevant": true, "flagComment": false, - "defaultStatus": "Active", - "externallyAvailable": false, + "defaultStatus": "Requested", + "externallyAvailable": true, "flagCode": "RA0044", + "nativeFlagCode": "RA0044", "childFlags": [], "isParent": false, "Path": [ "Party", "Reasonable adjustment", "I need help communicating and understanding", - "I need an Hearing Enhancement System (Hearing", + "Hearing Enhancement System (Hearing", "Induction Loop, Infrared Receiver)" ] }, @@ -657,16 +702,17 @@ "name": "Induction loop (hearing enhancement system)", "hearingRelevant": true, "flagComment": false, - "defaultStatus": "Active", - "externallyAvailable": false, + "defaultStatus": "Requested", + "externallyAvailable": true, "flagCode": "RA0045", + "nativeFlagCode": "RA0045", "childFlags": [], "isParent": false, "Path": [ "Party", "Reasonable adjustment", "I need help communicating and understanding", - "I need an Hearing Enhancement System (Hearing", + "Hearing Enhancement System (Hearing", "Induction Loop, Infrared Receiver)" ] }, @@ -674,16 +720,17 @@ "name": "Other", "hearingRelevant": true, "flagComment": true, - "defaultStatus": "Active", - "externallyAvailable": false, + "defaultStatus": "Requested", + "externallyAvailable": true, "flagCode": "OT0001", + "nativeFlagCode": "OT0001", "childFlags": [], "isParent": false, "Path": [ "Party", "Reasonable adjustment", "I need help communicating and understanding", - "I need an Hearing Enhancement System (Hearing", + "Hearing Enhancement System (Hearing", "Induction Loop, Infrared Receiver)" ] } @@ -697,11 +744,12 @@ }, { "name": "Extra time to think and explain myself", - "hearingRelevant": true, + "hearingRelevant": false, "flagComment": false, "defaultStatus": "Requested", "externallyAvailable": true, "flagCode": "RA0037", + "nativeFlagCode": "RA0037", "childFlags": [], "isParent": false, "Path": [ @@ -714,9 +762,10 @@ "name": "Intermediary", "hearingRelevant": true, "flagComment": false, - "defaultStatus": "Active", - "externallyAvailable": false, + "defaultStatus": "Requested", + "externallyAvailable": true, "flagCode": "RA0038", + "nativeFlagCode": "RA0038", "childFlags": [], "isParent": false, "Path": [ @@ -730,8 +779,9 @@ "hearingRelevant": true, "flagComment": false, "defaultStatus": "Requested", - "externallyAvailable": true, + "externallyAvailable": false, "flagCode": "RA0039", + "nativeFlagCode": "RA0039", "childFlags": [], "isParent": false, "Path": [ @@ -742,11 +792,12 @@ }, { "name": "Need to be close to who is speaking", - "hearingRelevant": true, + "hearingRelevant": false, "flagComment": false, "defaultStatus": "Requested", "externallyAvailable": true, "flagCode": "RA0040", + "nativeFlagCode": "RA0040", "childFlags": [], "isParent": false, "Path": [ @@ -759,9 +810,10 @@ "name": "Lip speaker", "hearingRelevant": true, "flagComment": false, - "defaultStatus": "Active", + "defaultStatus": "Requested", "externallyAvailable": false, "flagCode": "RA0041", + "nativeFlagCode": "RA0041", "childFlags": [], "isParent": false, "Path": [ @@ -774,58 +826,59 @@ "name": "Sign Language Interpreter", "hearingRelevant": true, "flagComment": false, - "defaultStatus": "Active", - "externallyAvailable": false, + "defaultStatus": "Requested", + "externallyAvailable": true, "flagCode": "RA0042", + "nativeFlagCode": "RA0042", "listOfValuesLength": 12, "listOfValues": [ + { + "key": "sign-sse", + "value": "Speech Supported English (SSE)" + }, + { + "key": "ils", + "value": "International Sign (IS)" + }, { "key": "ase", "value": "American Sign Language (ASL)" }, { - "key": "bfi", - "value": "British Sign Language (BSL)" + "key": "sign-ntr", + "value": "Notetaker" }, { - "key": "ils", - "value": "International Sign (IS)" + "key": "bfi", + "value": "British Sign Language (BSL)" }, { - "key": "sign-dfr", - "value": "Deaf Relay" + "key": "sign-mkn", + "value": "Makaton" }, { "key": "sign-dma", "value": "Deafblind manual alphabet" }, { - "key": "sign-hos", - "value": "Hands on signing" + "key": "sign-vfs", + "value": "Visual frame signing" }, { - "key": "sign-lps", - "value": "Lipspeaker" + "key": "sign-dfr", + "value": "Deaf Relay" }, { - "key": "sign-mkn", - "value": "Makaton" + "key": "sign-hos", + "value": "Hands on signing" }, { - "key": "sign-ntr", - "value": "Notetaker" + "key": "sign-lps", + "value": "Lipspeaker" }, { "key": "sign-pst", "value": "Palantypist / Speech to text" - }, - { - "key": "sign-sse", - "value": "Speech Supported English (SSE)" - }, - { - "key": "sign-vfs", - "value": "Visual frame signing" } ], "isParent": false, @@ -842,6 +895,7 @@ "defaultStatus": "Requested", "externallyAvailable": true, "flagCode": "RA0046", + "nativeFlagCode": "RA0046", "childFlags": [], "isParent": false, "Path": [ @@ -854,9 +908,10 @@ "name": "Explanation of the court or tribunal and who's in the room at the hearing", "hearingRelevant": true, "flagComment": false, - "defaultStatus": "Active", + "defaultStatus": "Requested", "externallyAvailable": true, "flagCode": "RA0047", + "nativeFlagCode": "RA0047", "childFlags": [], "isParent": false, "Path": [ @@ -869,9 +924,10 @@ "name": "Other", "hearingRelevant": true, "flagComment": true, - "defaultStatus": "Active", - "externallyAvailable": false, + "defaultStatus": "Requested", + "externallyAvailable": true, "flagCode": "OT0001", + "nativeFlagCode": "OT0001", "childFlags": [], "isParent": false, "Path": [ @@ -886,6 +942,21 @@ "Party", "Reasonable adjustment" ] + }, + { + "name": "Other", + "hearingRelevant": true, + "flagComment": true, + "defaultStatus": "Requested", + "externallyAvailable": true, + "flagCode": "OT0001", + "nativeFlagCode": "OT0001", + "childFlags": [], + "isParent": false, + "Path": [ + "Party", + "Reasonable adjustment" + ] } ], "isParent": true, @@ -893,97 +964,6 @@ "Party" ] }, - { - "name": "Vulnerable user", - "hearingRelevant": false, - "flagComment": false, - "defaultStatus": "Active", - "externallyAvailable": false, - "flagCode": "PF0002", - "childFlags": [], - "isParent": false, - "Path": [ - "Party" - ] - }, - { - "name": "Confidential party/address", - "hearingRelevant": false, - "flagComment": false, - "defaultStatus": "Active", - "externallyAvailable": false, - "flagCode": "PF0004", - "childFlags": [], - "isParent": false, - "Path": [ - "Party" - ] - }, - { - "name": "Unacceptable/disruptive customer behaviour", - "hearingRelevant": true, - "flagComment": false, - "defaultStatus": "Active", - "externallyAvailable": false, - "flagCode": "PF0007", - "childFlags": [], - "isParent": false, - "Path": [ - "Party" - ] - }, - { - "name": "Vexatious litigant", - "hearingRelevant": false, - "flagComment": false, - "defaultStatus": "Active", - "externallyAvailable": false, - "flagCode": "PF0008", - "childFlags": [], - "isParent": false, - "Path": [ - "Party" - ] - }, - { - "name": "Civil restraint order", - "hearingRelevant": true, - "flagComment": false, - "defaultStatus": "Active", - "externallyAvailable": false, - "flagCode": "PF0009", - "childFlags": [], - "isParent": false, - "Path": [ - "Party" - ] - }, - { - "name": "Banning order", - "hearingRelevant": true, - "flagComment": false, - "defaultStatus": "Active", - "externallyAvailable": false, - "flagCode": "PF0011", - "childFlags": [], - "isParent": false, - "Path": [ - "Party" - ] - }, - { - "name": "Audio/Video Evidence", - "hearingRelevant": true, - "flagComment": false, - "defaultStatus": "Active", - "externallyAvailable": false, - "flagCode": "PF0014", - "childFlags": [], - "isParent": false, - "Path": [ - "Party" - ] - }, { "name": "Language Interpreter", "hearingRelevant": true, @@ -991,771 +971,828 @@ "defaultStatus": "Active", "externallyAvailable": false, "flagCode": "PF0015", - "listOfValuesLength": 191, + "nativeFlagCode": "PF0015", + "listOfValuesLength": 205, "listOfValues": [ { - "key": "abr", - "value": "Brong" + "key": "rus", + "value": "Russian" }, { - "key": "ach", - "value": "Acholi" + "key": "mnk", + "value": "Mandinka" }, { - "key": "afr", - "value": "Afrikaans" - }, - { - "key": "aii", - "value": "Assyrian" + "key": "ara-ame", + "value": "Arabic Middle Eastern" }, { - "key": "aka", - "value": "Akan" + "key": "kur-kkr", + "value": "Kurdish kurmanji" }, { - "key": "amh", - "value": "Amharic" + "key": "ibb", + "value": "Ibibio" }, { - "key": "ara", - "value": "Arabic" + "key": "uzb", + "value": "Uzbek" }, { - "key": "ara-ame", - "value": "Arabic Middle Eastern" + "key": "mkd", + "value": "Macedonian" }, { - "key": "ara-ana", - "value": "Arabic North African" + "key": "ibo", + "value": "Igbo (Also Known As Ibo)" }, { - "key": "arq", - "value": "Algerian" + "key": "dyu", + "value": "Dioula" }, { - "key": "aze", - "value": "Azerbajani (aka Nth Azari)" + "key": "dua", + "value": "Douala" }, { - "key": "bal", - "value": "Baluchi" + "key": "men", + "value": "Mende" }, { - "key": "bam", - "value": "Bambara" + "key": "kur-kbr", + "value": "Kurdish Bardini" }, { - "key": "bas", - "value": "Bassa" + "key": "ron", + "value": "Romanian" }, { - "key": "bel", - "value": "Belorussian" + "key": "urd", + "value": "Urdu" }, { - "key": "bem", - "value": "Benba (Bemba)" + "key": "urh", + "value": "Urohobo" }, { - "key": "ben", - "value": "Bengali" + "key": "mal", + "value": "Malayalam" }, { - "key": "ben-bsy", - "value": "Bengali Sylheti" + "key": "run", + "value": "Kirundi" }, { - "key": "ber", - "value": "Berber" + "key": "rom", + "value": "Romany" }, { - "key": "bfz", - "value": "Pahari" + "key": "jpn", + "value": "Japanese" }, { - "key": "bih", - "value": "Bihari" + "key": "afr", + "value": "Afrikaans" }, { - "key": "bin", - "value": "Benin/Edo" + "key": "ita", + "value": "Italian" }, { - "key": "bjs", - "value": "Bajan (West Indian)" + "key": "abr", + "value": "Brong" }, { - "key": "bod", - "value": "Tibetan" + "key": "ach", + "value": "Acholi" }, { - "key": "btn", - "value": "Bhutanese" + "key": "iso", + "value": "Isoko" }, { - "key": "bul", - "value": "Bulgarian" + "key": "zul", + "value": "Zulu" }, { - "key": "byn", - "value": "Bilin" + "key": "mya", + "value": "Burmese" }, { - "key": "ceb", - "value": "Cebuano" + "key": "nde", + "value": "Ndebele" }, { - "key": "ces", - "value": "Czech" + "key": "efi", + "value": "Efik" }, { - "key": "cgg", - "value": "Rukiga" + "key": "ind", + "value": "Indonesian" }, { - "key": "che", - "value": "Chechen" + "key": "kur-fey", + "value": "Feyli" }, { - "key": "cmn", - "value": "Mandarin" + "key": "fra-faf", + "value": "French African" }, { - "key": "cpe", - "value": "Creole (English)" + "key": "amh", + "value": "Amharic" }, { - "key": "cpf", - "value": "Creole (French)" + "key": "zho-hok", + "value": "Hokkein" }, { - "key": "cpp", - "value": "Creole (Portuguese)" + "key": "msa", + "value": "Malay" }, { - "key": "crp", - "value": "Creole (Spanish)" + "key": "pus", + "value": "Pushtu (Also Known As Pashto)" }, { - "key": "ctg", - "value": "Chittagonain" + "key": "lit", + "value": "Lithuanian" }, { - "key": "cym", - "value": "Welsh" + "key": "hau", + "value": "Hausa" }, { - "key": "dan", - "value": "Danish" + "key": "mar", + "value": "Marathi" }, { - "key": "deu", - "value": "German" + "key": "hbs", + "value": "Serbo-Croatian" }, { - "key": "din", - "value": "Dinka" + "key": "lin", + "value": "Lingala" }, { - "key": "div", - "value": "Maldivian" + "key": "hac", + "value": "Gorani" }, { - "key": "don", - "value": "Toura" + "key": "bas", + "value": "Bassa" }, { - "key": "dua", - "value": "Douala" + "key": "heb", + "value": "Hebrew" }, { - "key": "dyu", - "value": "Dioula" + "key": "pol", + "value": "Polish" }, { - "key": "efi", - "value": "Efik" + "key": "cpp", + "value": "Creole (Portuguese)" }, { - "key": "ell", - "value": "Greek" + "key": "cpf", + "value": "Creole (French)" }, { "key": "est", "value": "Estonian" }, { - "key": "ewe", - "value": "Ewe" - }, - { - "key": "ewo", - "value": "Ewondo" + "key": "cpe", + "value": "Creole (English)" }, { - "key": "fas", - "value": "Farsi" + "key": "lav", + "value": "Latvian" }, { - "key": "fat", - "value": "Fanti" + "key": "pan-pji", + "value": "Punjabi Indian" }, { - "key": "fij", - "value": "Fijian" + "key": "phr", + "value": "Pahari-Potwari" }, { - "key": "fra", - "value": "French" + "key": "nor", + "value": "Norwegian" }, { - "key": "fra-faf", - "value": "French African" + "key": "cmn", + "value": "Mandarin" }, { - "key": "fra-far", - "value": "French Arabic" + "key": "fij", + "value": "Fijian" }, { - "key": "ful", - "value": "Fula" + "key": "hun", + "value": "Hungarian" }, { - "key": "gaa", - "value": "Ga" + "key": "ukr", + "value": "Ukrainian" }, { - "key": "gjk", - "value": "Kachi" + "key": "yue", + "value": "Cantonese" }, { - "key": "guj", - "value": "Gujarati" + "key": "jam", + "value": "Jamaican" }, { - "key": "hac", - "value": "Gorani" + "key": "zza", + "value": "Zaza" }, { - "key": "hak", - "value": "Hakka" + "key": "uig", + "value": "Uighur" }, { - "key": "hau", - "value": "Hausa" + "key": "din", + "value": "Dinka" }, { - "key": "hbs", - "value": "Serbo-Croatian" + "key": "vsa", + "value": "Visayan" }, { - "key": "heb", - "value": "Hebrew" + "key": "div", + "value": "Maldivian" }, { - "key": "her", - "value": "Herero" + "key": "hno", + "value": "Northern Hindko" }, { - "key": "hin", - "value": "Hindi" + "key": "deu", + "value": "German" }, { "key": "hnd", "value": "Hindko" }, { - "key": "hun", - "value": "Hungarian" + "key": "yor", + "value": "Yoruba" }, { - "key": "hye", - "value": "Armenian" + "key": "luo", + "value": "Luo" }, { - "key": "ibb", - "value": "Ibibio" - }, - { - "key": "ibo", - "value": "Igbo (Also Known As Ibo)" + "key": "lub", + "value": "Luba (Tshiluba)" }, { - "key": "ilo", - "value": "Ilocano" + "key": "nyo", + "value": "Runyoro" }, { - "key": "ind", - "value": "Indonesian" + "key": "lug", + "value": "Lugandan" }, { - "key": "iso", - "value": "Isoko" + "key": "ron-fmo", + "value": "Moldovan" }, { - "key": "ita", - "value": "Italian" + "key": "jav", + "value": "Javanese" }, { - "key": "jam", - "value": "Jamaican" + "key": "orm", + "value": "Oromo" }, { - "key": "jav", - "value": "Javanese" + "key": "kir", + "value": "Kyrgyz" }, { - "key": "jpn", - "value": "Japanese" + "key": "byn", + "value": "Bilin" }, { - "key": "kas", - "value": "Kashmiri" + "key": "khm", + "value": "Khmer" }, { - "key": "kat", - "value": "Georgian" + "key": "ewo", + "value": "Ewondo" }, { - "key": "kck", - "value": "Khalanga" + "key": "nyn", + "value": "Nyankole" }, { - "key": "kfr", - "value": "Kutchi" + "key": "aii", + "value": "Assyrian" }, { - "key": "khm", - "value": "Khmer" + "key": "syl", + "value": "Sylheti" }, { - "key": "kik", - "value": "Kikuyu" + "key": "gaa", + "value": "Ga" }, { "key": "kin", "value": "Kinyarwandan" }, { - "key": "kir", - "value": "Kyrgyz" + "key": "kik", + "value": "Kikuyu" }, { - "key": "knn", - "value": "Konkani" + "key": "btn", + "value": "Bhutanese" }, { - "key": "kon", - "value": "Kikongo" + "key": "swh", + "value": "Kiswahili" }, { - "key": "kor", - "value": "Korean" + "key": "kfr", + "value": "Kutchi" }, { - "key": "kri", - "value": "Krio (Sierra Leone)" + "key": "swe", + "value": "Swedish" }, { - "key": "krn", - "value": "Sarpo" + "key": "swa", + "value": "Swahili" }, { - "key": "kru", - "value": "Kru" + "key": "swa-skb", + "value": "Swahili Kibajuni" }, { - "key": "kur-kbr", - "value": "Kurdish Bardini" + "key": "kck", + "value": "Khalanga" }, { - "key": "kur-kkr", - "value": "Kurdish kurmanji" + "key": "sus", + "value": "Susu" }, { - "key": "kur-ksr", - "value": "Kurdish Sorani" + "key": "nzi", + "value": "Nzima" }, { - "key": "laj", - "value": "Lango" + "key": "scl", + "value": "Shina" }, { - "key": "lav", - "value": "Latvian" + "key": "kat", + "value": "Georgian" }, { - "key": "lin", - "value": "Lingala" + "key": "kas", + "value": "Kashmiri" }, { - "key": "lit", - "value": "Lithuanian" + "key": "spa", + "value": "Spanish" }, { - "key": "lub", - "value": "Luba (Tshiluba)" + "key": "sqi", + "value": "Albanian" }, { - "key": "lug", - "value": "Lugandan" + "key": "spv", + "value": "Kosli, Sambalpuri" }, { - "key": "luo", - "value": "Luo" + "key": "bod", + "value": "Tibetan" }, { - "key": "luo-lah", - "value": "Luo Acholi" + "key": "snd", + "value": "Sindhi" }, { - "key": "luo-lky", - "value": "Luo Kenyan" + "key": "sna", + "value": "Shona" }, { - "key": "luo-llg", - "value": "Luo Lango" + "key": "snk", + "value": "Soninke" }, { - "key": "mal", - "value": "Malayalam" + "key": "nld-nwf", + "value": "West Flemish" }, { - "key": "mar", - "value": "Marathi" + "key": "som", + "value": "Somali" }, { - "key": "men", - "value": "Mende" + "key": "ful", + "value": "Fula" }, { - "key": "min", - "value": "Mina" + "key": "swa-sbv", + "value": "Swahili Bravanese" }, { - "key": "mkd", - "value": "Macedonian" + "key": "bjs", + "value": "Bajan (West Indian)" }, { - "key": "mku", - "value": "Malinke" + "key": "fra", + "value": "French" }, { - "key": "mkw", - "value": "Monokutuba" + "key": "skt", + "value": "Sakata" }, { - "key": "mlt", - "value": "Maltese" + "key": "skr", + "value": "Saraiki (Seraiki)" }, { - "key": "mnk", - "value": "Mandinka" + "key": "slv", + "value": "Slovenian" }, { - "key": "mon", - "value": "Mongolian" + "key": "pat", + "value": "Patois" }, { - "key": "msa", - "value": "Malay" + "key": "sin", + "value": "Sinhalese" }, { - "key": "mya", - "value": "Burmese" + "key": "pag", + "value": "Pangasinan" }, { - "key": "nde", - "value": "Ndebele" + "key": "tig", + "value": "Tigre" }, { - "key": "nep", - "value": "Nepali" + "key": "pan", + "value": "Punjabi" }, { - "key": "nld", - "value": "Dutch" + "key": "tir", + "value": "Tigrinya" }, { - "key": "nld-nfl", - "value": "Flemish" + "key": "pam", + "value": "Pampangan" }, { - "key": "nld-nwf", - "value": "West Flemish" + "key": "tgl", + "value": "Tagalog" }, { - "key": "nor", - "value": "Norwegian" + "key": "cgg", + "value": "Rukiga" }, { - "key": "nya", - "value": "Chichewa" + "key": "glg", + "value": "Galician" }, { - "key": "nyo", - "value": "Runyoro" + "key": "teo", + "value": "Ateso" }, { - "key": "nzi", - "value": "Nzima" + "key": "bnt-kic", + "value": "Kichagga" }, { - "key": "orm", - "value": "Oromo" + "key": "tem", + "value": "Temne" }, { - "key": "pag", - "value": "Pangasinan" + "key": "tel", + "value": "Telugu" }, { - "key": "pam", - "value": "Pampangan" + "key": "ces", + "value": "Czech" }, { - "key": "pan", - "value": "Punjabi" + "key": "xog", + "value": "Lusoga" }, { - "key": "pan-pji", - "value": "Punjabi Indian" + "key": "ceb", + "value": "Cebuano" }, { - "key": "pan-pjp", - "value": "Punjabi Pakistani" + "key": "gjk", + "value": "Kachi" }, { - "key": "pat", - "value": "Patois" + "key": "krn", + "value": "Sarpo" }, { - "key": "phr", - "value": "Pothohari" + "key": "bam", + "value": "Bambara" }, { - "key": "pol", - "value": "Polish" + "key": "bal", + "value": "Baluchi" }, { - "key": "por", - "value": "Portuguese" + "key": "bfz", + "value": "Pahari" }, { - "key": "prs", - "value": "Dari" + "key": "nya", + "value": "Chichewa" }, { - "key": "pus", - "value": "Pushtu (Also Known As Pashto)" - }, + "key": "bin", + "value": "Benin/Edo" + }, + { + "key": "ber", + "value": "Berber" + }, + { + "key": "ben", + "value": "Bengali" + }, + { + "key": "bem", + "value": "Benba (Bemba)" + }, + { + "key": "kri", + "value": "Krio (Sierra Leone)" + }, + { + "key": "krx", + "value": "Karon" + }, + { + "key": "kru", + "value": "Kru" + }, + { + "key": "nep", + "value": "Nepali" + }, { "key": "rmm", "value": "Roma" }, { - "key": "rom", - "value": "Romany" + "key": "ara", + "value": "Arabic" }, { - "key": "ron", - "value": "Romanian" + "key": "ara-mag", + "value": "Maghreb" }, { - "key": "ron-fmo", - "value": "Moldovan" + "key": "luo-lky", + "value": "Luo Kenyan" }, { - "key": "run", - "value": "Kirundi" + "key": "arq", + "value": "Algerian" }, { - "key": "rus", - "value": "Russian" + "key": "kur-ksr", + "value": "Kurdish Sorani" }, { - "key": "scl", - "value": "Shina" + "key": "ewe", + "value": "Ewe" }, { - "key": "sgw", - "value": "Gurage" + "key": "nld", + "value": "Dutch" }, { - "key": "sin", - "value": "Sinhalese" + "key": "tam", + "value": "Tamil" }, { - "key": "skr", - "value": "Saraiki (Seraiki)" + "key": "tai", + "value": "Taiwanese" }, { - "key": "slk", - "value": "Slovak" + "key": "kor", + "value": "Korean" }, { - "key": "slv", - "value": "Slovenian" + "key": "nld-nfl", + "value": "Flemish" }, { - "key": "sna", - "value": "Shona" + "key": "luo-llg", + "value": "Luo Lango" }, { - "key": "snd", - "value": "Sindhi" + "key": "aka", + "value": "Akan" }, { - "key": "som", - "value": "Somali" + "key": "bih", + "value": "Bihari" }, { - "key": "spa", - "value": "Spanish" + "key": "sgw", + "value": "Gurage" }, { - "key": "sqi", - "value": "Albanian" + "key": "wol", + "value": "Wolof" }, { - "key": "sus", - "value": "Susu" + "key": "fat", + "value": "Fanti" }, { - "key": "swa", - "value": "Swahili" + "key": "mkw", + "value": "Monokutuba" }, { - "key": "swa-sbv", - "value": "Swahili Bravanese" + "key": "bel", + "value": "Belorussian" }, { - "key": "swa-skb", - "value": "Swahili Kibajuni" + "key": "ara-ana", + "value": "Arabic North African" }, { - "key": "swe", - "value": "Swedish" + "key": "mlt", + "value": "Maltese" }, { - "key": "syl", - "value": "Sylheti" + "key": "zag", + "value": "Zaghawa" }, { - "key": "tai", - "value": "Taiwanese" + "key": "mku", + "value": "Malinke" }, { - "key": "tam", - "value": "Tamil" + "key": "don", + "value": "Toura" }, { - "key": "tel", - "value": "Telugu" + "key": "mon", + "value": "Mongolian" }, { - "key": "tem", - "value": "Temne" + "key": "hye", + "value": "Armenian" }, { - "key": "teo", - "value": "Ateso" + "key": "min", + "value": "Mina" }, { - "key": "tgl", - "value": "Tagalog" + "key": "ish", + "value": "Esan" }, { - "key": "tha", - "value": "Thai" + "key": "myx", + "value": "Masaaba" }, { - "key": "tig", - "value": "Tigre" + "key": "ell", + "value": "Greek" }, { - "key": "tir", - "value": "Tigrinya" + "key": "ilo", + "value": "Ilocano" }, { - "key": "tsn", - "value": "Setswana" + "key": "ben-bsy", + "value": "Bengali Sylheti" + }, + { + "key": "vie", + "value": "Vietnamese" + }, + { + "key": "hak", + "value": "Hakka" + }, + { + "key": "prs", + "value": "Dari" + }, + { + "key": "luo-lah", + "value": "Luo Acholi" + }, + { + "key": "fra-far", + "value": "French Arabic" + }, + { + "key": "cym", + "value": "Welsh" }, { "key": "ttj", "value": "Rutoro" }, { - "key": "tuk", - "value": "Turkmen" + "key": "laj", + "value": "Lango" + }, + { + "key": "por", + "value": "Portuguese" + }, + { + "key": "tsn", + "value": "Setswana" }, { "key": "tur", "value": "Turkish" }, { - "key": "twi", - "value": "Twi" + "key": "guj", + "value": "Gujarati" }, { - "key": "uig", - "value": "Uighur" + "key": "ctg", + "value": "Chittagonain" }, { - "key": "ukr", - "value": "Ukrainian" + "key": "crp", + "value": "Creole (Spanish)" }, { - "key": "urd", - "value": "Urdu" + "key": "twi", + "value": "Twi" }, { - "key": "urh", - "value": "Urohobo" + "key": "tuk", + "value": "Turkmen" }, { - "key": "uzb", - "value": "Uzbek" + "key": "pan-pjp", + "value": "Punjabi Pakistani" }, { - "key": "vie", - "value": "Vietnamese" + "key": "her", + "value": "Herero" }, { - "key": "vsa", - "value": "Visayan" + "key": "hin", + "value": "Hindi" }, { - "key": "wol", - "value": "Wolof" + "key": "dan", + "value": "Danish" }, { - "key": "xho", - "value": "Xhosa" + "key": "slk", + "value": "Slovak" }, { - "key": "xog", - "value": "Lusoga" + "key": "che", + "value": "Chechen" }, { - "key": "yor", - "value": "Yoruba" + "key": "tha", + "value": "Thai" }, { - "key": "yue", - "value": "Cantonese" + "key": "aze", + "value": "Azerbajani (aka Nth Azari)" }, { - "key": "zag", - "value": "Zaghawa" + "key": "kon", + "value": "Kikongo" }, { - "key": "zul", - "value": "Zulu" + "key": "xho", + "value": "Xhosa" }, { - "key": "zza", - "value": "Zaza" + "key": "fas", + "value": "Farsi" + }, + { + "key": "bul", + "value": "Bulgarian" + }, + { + "key": "knn", + "value": "Konkani" } ], "isParent": false, @@ -1764,38 +1801,13 @@ ] }, { - "name": "Death of a Party", + "name": "Other", "hearingRelevant": true, - "flagComment": false, - "defaultStatus": "Active", - "externallyAvailable": false, - "flagCode": "PF0016", - "childFlags": [], - "isParent": false, - "Path": [ - "Party" - ] - }, - { - "name": "Litigation friend", - "hearingRelevant": true, - "flagComment": false, - "defaultStatus": "Active", - "externallyAvailable": false, - "flagCode": "PF0017", - "childFlags": [], - "isParent": false, - "Path": [ - "Party" - ] - }, - { - "name": "Lacking capacity", - "hearingRelevant": true, - "flagComment": false, - "defaultStatus": "Active", - "externallyAvailable": false, - "flagCode": "PF0018", + "flagComment": true, + "defaultStatus": "Requested", + "externallyAvailable": true, + "flagCode": "OT0001", + "nativeFlagCode": "OT0001", "childFlags": [], "isParent": false, "Path": [ diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsDataMigrationController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsDataMigrationController.java index f7e39a6af1..954aa55662 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsDataMigrationController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsDataMigrationController.java @@ -23,6 +23,9 @@ import static org.springframework.http.HttpStatus.FORBIDDEN; import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; import static uk.gov.hmcts.ethos.replacement.docmosis.helpers.CallbackRespHelper.getCallbackRespEntityErrors; +import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.CLAIMANT; +import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.INTERNAL; +import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.RESPONDENT1; @Slf4j @RequiredArgsConstructor @@ -56,6 +59,20 @@ public ResponseEntity addCaseFlagsData( CaseData caseData = ccdRequest.getCaseDetails().getCaseData(); caseFlagsService.setupCaseFlags(caseData); + + /* Add visibility and group ID fields for the claimant and the first respondent records + that were already migrated in Case Flag v1.0. */ + if (caseData.getClaimantFlags().getGroupId() == null) { + caseData.getClaimantFlags().setGroupId(CLAIMANT); + caseData.getClaimantFlags().setVisibility(INTERNAL); + } + + if (caseData.getRespondentFlags().getGroupId() == null) { + caseData.getRespondentFlags().setRoleOnCase(RESPONDENT1); + caseData.getRespondentFlags().setGroupId(RESPONDENT1); + caseData.getRespondentFlags().setVisibility(INTERNAL); + } + log.info("Migrating existing case: {} for claimant: {}, respondent: {},", ccdRequest.getCaseDetails().getCaseTypeId(), caseData.getClaimantFlags().getPartyName(), diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1ReppedController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1ReppedController.java index c13d9fb424..aa85131439 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1ReppedController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1ReppedController.java @@ -24,6 +24,7 @@ import uk.gov.hmcts.ethos.replacement.docmosis.constants.ET1ReppedConstants; import uk.gov.hmcts.ethos.replacement.docmosis.exceptions.GenericServiceException; import uk.gov.hmcts.ethos.replacement.docmosis.helpers.Et1ReppedHelper; +import uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService; import uk.gov.hmcts.ethos.replacement.docmosis.service.CaseManagementForCaseWorkerService; import uk.gov.hmcts.ethos.replacement.docmosis.service.Et1ReppedService; import uk.gov.hmcts.ethos.replacement.docmosis.service.Et1SubmissionService; @@ -52,6 +53,7 @@ public class Et1ReppedController { private final FeatureToggleService featureToggleService; private final Et1SubmissionService et1SubmissionService; private final NocRespondentRepresentativeService nocRespondentRepresentativeService; + private final CaseFlagsService caseFlagsService; /** * Callback to handle postcode validation for the ET1 Repped journey. @@ -519,6 +521,13 @@ public ResponseEntity submitClaim( Et1ReppedHelper.clearEt1ReppedCreationFields(caseData); caseData = nocRespondentRepresentativeService.prepopulateOrgPolicyAndNoc(caseData); + boolean caseFlagsToggle = featureToggleService.isCaseFlagsEnabled(); + log.info("Case flags feature flag is {}", caseFlagsToggle); + if (caseFlagsToggle && caseFlagsService.caseFlagsSetupRequired(caseData)) { + caseFlagsService.setupCaseFlags(caseData); + caseFlagsService.processNewlySetCaseFlags(caseData); + } + return getCallbackRespEntityNoErrors(caseData); } diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java index cf6d4360a2..ab096a094f 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java @@ -32,11 +32,87 @@ public class CaseFlagsService { private static final String GRANTED = "Granted"; + public static final String INTERNAL = "Internal"; + public static final String EXTERNAL = "External"; + public static final String CLAIMANT = "Claimant"; + public static final String RESPONDENT1 = "Respondent 1"; + public static final String RESPONDENT2 = "Respondent 2"; + public static final String RESPONDENT3 = "Respondent 3"; + public static final String RESPONDENT4 = "Respondent 4"; + public static final String RESPONDENT5 = "Respondent 5"; + public static final String RESPONDENT6 = "Respondent 6"; + public static final String RESPONDENT7 = "Respondent 7"; + public static final String RESPONDENT8 = "Respondent 8"; + public static final String RESPONDENT9 = "Respondent 9"; + public static final String RESPONDENT10 = "Respondent 10"; + public boolean caseFlagsSetupRequired(CaseData caseData) { - return caseData.getClaimantFlags() == null - || StringUtils.isEmpty(caseData.getClaimantFlags().getRoleOnCase()) - || caseData.getRespondentFlags() == null - || StringUtils.isEmpty(caseData.getRespondentFlags().getRoleOnCase()); + return (caseData.getCaseFlags() == null + || caseData.getClaimantFlags() == null + || StringUtils.isEmpty(caseData.getClaimantFlags().getRoleOnCase()) + || caseData.getClaimantExternalFlags() == null + || StringUtils.isEmpty(caseData.getClaimantExternalFlags().getRoleOnCase()) + || (!caseData.getRespondentCollection().isEmpty() + && (caseData.getRespondentFlags() == null + || StringUtils.isEmpty(caseData.getRespondentFlags().getRoleOnCase()))) + || (!caseData.getRespondentCollection().isEmpty() + && (caseData.getRespondentExternalFlags() == null + || StringUtils.isEmpty(caseData.getRespondentExternalFlags().getRoleOnCase()))) + || (caseData.getRespondentCollection().size() > 1 + && (caseData.getRespondent1Flags() == null + || StringUtils.isEmpty(caseData.getRespondent1Flags().getRoleOnCase()))) + || (caseData.getRespondentCollection().size() > 1 + && (caseData.getRespondent1ExternalFlags() == null + || StringUtils.isEmpty(caseData.getRespondent1ExternalFlags().getRoleOnCase()))) + || (caseData.getRespondentCollection().size() > 2 + && (caseData.getRespondent2Flags() == null + || StringUtils.isEmpty(caseData.getRespondent2Flags().getRoleOnCase()))) + || (caseData.getRespondentCollection().size() > 2 + && (caseData.getRespondent2ExternalFlags() == null + || StringUtils.isEmpty(caseData.getRespondent2ExternalFlags().getRoleOnCase()))) + || (caseData.getRespondentCollection().size() > 3 + && (caseData.getRespondent3Flags() == null + || StringUtils.isEmpty(caseData.getRespondent3Flags().getRoleOnCase()))) + || (caseData.getRespondentCollection().size() > 3 + && (caseData.getRespondent3ExternalFlags() == null + || StringUtils.isEmpty(caseData.getRespondent3ExternalFlags().getRoleOnCase()))) + || (caseData.getRespondentCollection().size() > 4 + && (caseData.getRespondent4Flags() == null + || StringUtils.isEmpty(caseData.getRespondent4Flags().getRoleOnCase()))) + || (caseData.getRespondentCollection().size() > 4 + && (caseData.getRespondent4ExternalFlags() == null + || StringUtils.isEmpty(caseData.getRespondent4ExternalFlags().getRoleOnCase()))) + || (caseData.getRespondentCollection().size() > 5 + && (caseData.getRespondent5Flags() == null + || StringUtils.isEmpty(caseData.getRespondent5Flags().getRoleOnCase()))) + || (caseData.getRespondentCollection().size() > 5 + && (caseData.getRespondent5ExternalFlags() == null + || StringUtils.isEmpty(caseData.getRespondent5ExternalFlags().getRoleOnCase()))) + || (caseData.getRespondentCollection().size() > 6 + && (caseData.getRespondent6Flags() == null + || StringUtils.isEmpty(caseData.getRespondent6Flags().getRoleOnCase()))) + || (caseData.getRespondentCollection().size() > 6 + && (caseData.getRespondent6ExternalFlags() == null + || StringUtils.isEmpty(caseData.getRespondent6ExternalFlags().getRoleOnCase()))) + || (caseData.getRespondentCollection().size() > 7 + && (caseData.getRespondent7Flags() == null + || StringUtils.isEmpty(caseData.getRespondent7Flags().getRoleOnCase()))) + || (caseData.getRespondentCollection().size() > 7 + && (caseData.getRespondent7ExternalFlags() == null + || StringUtils.isEmpty(caseData.getRespondent7ExternalFlags().getRoleOnCase()))) + || (caseData.getRespondentCollection().size() > 8 + && (caseData.getRespondent8Flags() == null + || StringUtils.isEmpty(caseData.getRespondent8Flags().getRoleOnCase()))) + || (caseData.getRespondentCollection().size() > 8 + && (caseData.getRespondent8ExternalFlags() == null + || StringUtils.isEmpty(caseData.getRespondent8ExternalFlags().getRoleOnCase()))) + || (caseData.getRespondentCollection().size() > 9 + && (caseData.getRespondent9Flags() == null + || StringUtils.isEmpty(caseData.getRespondent9Flags().getRoleOnCase()))) + || (caseData.getRespondentCollection().size() > 9 + && (caseData.getRespondent9ExternalFlags() == null + || StringUtils.isEmpty(caseData.getRespondent9ExternalFlags().getRoleOnCase()))) + ); } /** @@ -49,24 +125,320 @@ public void setupCaseFlags(CaseData caseData) { caseData.setCaseFlags(CaseFlagsType.builder().build()); } - if (caseData.getClaimantFlags() == null) { + if (caseData.getClaimantFlags() == null + || StringUtils.isEmpty(caseData.getClaimantFlags().getRoleOnCase())) { caseData.setClaimantFlags(CaseFlagsType.builder() .partyName(caseData.getClaimant()) - .roleOnCase("claimant") + .roleOnCase(CLAIMANT) + .groupId(CLAIMANT) + .visibility(INTERNAL) .build() ); } else if (!caseData.getClaimant().equals(caseData.getClaimantFlags().getPartyName())) { caseData.getClaimantFlags().setPartyName(caseData.getClaimant()); } - if (caseData.getRespondentFlags() == null) { - caseData.setRespondentFlags(CaseFlagsType.builder() - .partyName(caseData.getRespondent()) - .roleOnCase("respondent") + if (caseData.getClaimantExternalFlags() == null + || StringUtils.isEmpty(caseData.getClaimantExternalFlags().getRoleOnCase())) { + caseData.setClaimantExternalFlags(CaseFlagsType.builder() + .partyName(caseData.getClaimant()) + .roleOnCase(CLAIMANT) + .groupId(CLAIMANT) + .visibility(EXTERNAL) .build() ); - } else if (!caseData.getRespondent().equals(caseData.getRespondentFlags().getPartyName())) { - caseData.getRespondentFlags().setPartyName(caseData.getRespondent()); + } else if (!caseData.getClaimant().equals(caseData.getClaimantExternalFlags().getPartyName())) { + caseData.getClaimantExternalFlags().setPartyName(caseData.getClaimant()); + } + + if (!caseData.getRespondentCollection().isEmpty()) { + String respondent = caseData.getRespondentCollection().getFirst().getValue().getRespondentName(); + if (caseData.getRespondentFlags() == null + || StringUtils.isEmpty(caseData.getRespondentFlags().getRoleOnCase())) { + caseData.setRespondentFlags(CaseFlagsType.builder() + .partyName(respondent) + .roleOnCase(RESPONDENT1) + .groupId(RESPONDENT1) + .visibility(INTERNAL) + .build() + ); + } else if (!respondent.equals(caseData.getRespondentFlags().getPartyName())) { + caseData.getRespondentFlags().setPartyName(respondent); + } + + if (caseData.getRespondentExternalFlags() == null + || StringUtils.isEmpty(caseData.getRespondentExternalFlags().getRoleOnCase())) { + caseData.setRespondentExternalFlags(CaseFlagsType.builder() + .partyName(respondent) + .roleOnCase(RESPONDENT1) + .groupId(RESPONDENT1) + .visibility(EXTERNAL) + .build() + ); + } else if (!respondent.equals(caseData.getRespondentExternalFlags().getPartyName())) { + caseData.getRespondentExternalFlags().setPartyName(respondent); + } + } + + if (caseData.getRespondentCollection().size() > 1) { + String respondent = caseData.getRespondentCollection().get(1).getValue().getRespondentName(); + if (caseData.getRespondent1Flags() == null + || StringUtils.isEmpty(caseData.getRespondent1Flags().getRoleOnCase())) { + caseData.setRespondent1Flags(CaseFlagsType.builder() + .partyName(respondent) + .roleOnCase(RESPONDENT2) + .groupId(RESPONDENT2) + .visibility(INTERNAL) + .build() + ); + } else if (!respondent.equals(caseData.getRespondent1Flags().getPartyName())) { + caseData.getRespondent1Flags().setPartyName(respondent); + } + + if (caseData.getRespondent1ExternalFlags() == null + || StringUtils.isEmpty(caseData.getRespondent1ExternalFlags().getRoleOnCase())) { + caseData.setRespondent1ExternalFlags(CaseFlagsType.builder() + .partyName(respondent) + .roleOnCase(RESPONDENT2) + .groupId(RESPONDENT2) + .visibility(EXTERNAL) + .build() + ); + } else if (!respondent.equals(caseData.getRespondent1ExternalFlags().getPartyName())) { + caseData.getRespondent1ExternalFlags().setPartyName(respondent); + } + } + + if (caseData.getRespondentCollection().size() > 2) { + String respondent = caseData.getRespondentCollection().get(2).getValue().getRespondentName(); + if (caseData.getRespondent2Flags() == null + || StringUtils.isEmpty(caseData.getRespondent2Flags().getRoleOnCase())) { + caseData.setRespondent2Flags(CaseFlagsType.builder() + .partyName(respondent) + .roleOnCase(RESPONDENT3) + .groupId(RESPONDENT3) + .visibility(INTERNAL) + .build() + ); + } else if (!respondent.equals(caseData.getRespondent2Flags().getPartyName())) { + caseData.getRespondent2Flags().setPartyName(respondent); + } + + if (caseData.getRespondent2ExternalFlags() == null + || StringUtils.isEmpty(caseData.getRespondent2ExternalFlags().getRoleOnCase())) { + caseData.setRespondent2ExternalFlags(CaseFlagsType.builder() + .partyName(respondent) + .roleOnCase(RESPONDENT3) + .groupId(RESPONDENT3) + .visibility(EXTERNAL) + .build() + ); + } else if (!respondent.equals(caseData.getRespondent2ExternalFlags().getPartyName())) { + caseData.getRespondent2ExternalFlags().setPartyName(respondent); + } + } + + if (caseData.getRespondentCollection().size() > 3) { + String respondent = caseData.getRespondentCollection().get(3).getValue().getRespondentName(); + if (caseData.getRespondent3Flags() == null + || StringUtils.isEmpty(caseData.getRespondent3Flags().getRoleOnCase())) { + caseData.setRespondent3Flags(CaseFlagsType.builder() + .partyName(respondent) + .roleOnCase(RESPONDENT4) + .groupId(RESPONDENT4) + .visibility(INTERNAL) + .build() + ); + } else if (!respondent.equals(caseData.getRespondent3Flags().getPartyName())) { + caseData.getRespondent3Flags().setPartyName(respondent); + } + + if (caseData.getRespondent3ExternalFlags() == null + || StringUtils.isEmpty(caseData.getRespondent3ExternalFlags().getRoleOnCase())) { + caseData.setRespondent3ExternalFlags(CaseFlagsType.builder() + .partyName(respondent) + .roleOnCase(RESPONDENT4) + .groupId(RESPONDENT4) + .visibility(EXTERNAL) + .build() + ); + } else if (!respondent.equals(caseData.getRespondent3ExternalFlags().getPartyName())) { + caseData.getRespondent3ExternalFlags().setPartyName(respondent); + } + } + + if (caseData.getRespondentCollection().size() > 4) { + String respondent = caseData.getRespondentCollection().get(4).getValue().getRespondentName(); + if (caseData.getRespondent4Flags() == null + || StringUtils.isEmpty(caseData.getRespondent4Flags().getRoleOnCase())) { + caseData.setRespondent4Flags(CaseFlagsType.builder() + .partyName(respondent) + .roleOnCase(RESPONDENT5) + .groupId(RESPONDENT5) + .visibility(INTERNAL) + .build() + ); + } else if (!respondent.equals(caseData.getRespondent4Flags().getPartyName())) { + caseData.getRespondent4Flags().setPartyName(respondent); + } + + if (caseData.getRespondent4ExternalFlags() == null + || StringUtils.isEmpty(caseData.getRespondent4ExternalFlags().getRoleOnCase())) { + caseData.setRespondent4ExternalFlags(CaseFlagsType.builder() + .partyName(respondent) + .roleOnCase(RESPONDENT5) + .groupId(RESPONDENT5) + .visibility(EXTERNAL) + .build() + ); + } else if (!respondent.equals(caseData.getRespondent4ExternalFlags().getPartyName())) { + caseData.getRespondent4ExternalFlags().setPartyName(respondent); + } + } + + if (caseData.getRespondentCollection().size() > 5) { + String respondent = caseData.getRespondentCollection().get(5).getValue().getRespondentName(); + if (caseData.getRespondent5Flags() == null + || StringUtils.isEmpty(caseData.getRespondent5Flags().getRoleOnCase())) { + caseData.setRespondent5Flags(CaseFlagsType.builder() + .partyName(respondent) + .roleOnCase(RESPONDENT6) + .groupId(RESPONDENT6) + .visibility(INTERNAL) + .build() + ); + } else if (!respondent.equals(caseData.getRespondent5Flags().getPartyName())) { + caseData.getRespondent5Flags().setPartyName(respondent); + } + + if (caseData.getRespondent5ExternalFlags() == null + || StringUtils.isEmpty(caseData.getRespondent5ExternalFlags().getRoleOnCase())) { + caseData.setRespondent5ExternalFlags(CaseFlagsType.builder() + .partyName(respondent) + .roleOnCase(RESPONDENT6) + .groupId(RESPONDENT6) + .visibility(EXTERNAL) + .build() + ); + } else if (!respondent.equals(caseData.getRespondent5ExternalFlags().getPartyName())) { + caseData.getRespondent5ExternalFlags().setPartyName(respondent); + } + } + + if (caseData.getRespondentCollection().size() > 6) { + String respondent = caseData.getRespondentCollection().get(6).getValue().getRespondentName(); + if (caseData.getRespondent6Flags() == null + || StringUtils.isEmpty(caseData.getRespondent6Flags().getRoleOnCase())) { + caseData.setRespondent6Flags(CaseFlagsType.builder() + .partyName(respondent) + .roleOnCase(RESPONDENT7) + .groupId(RESPONDENT7) + .visibility(INTERNAL) + .build() + ); + } else if (!respondent.equals(caseData.getRespondent6Flags().getPartyName())) { + caseData.getRespondent6Flags().setPartyName(respondent); + } + + if (caseData.getRespondent6ExternalFlags() == null + || StringUtils.isEmpty(caseData.getRespondent6ExternalFlags().getRoleOnCase())) { + caseData.setRespondent6ExternalFlags(CaseFlagsType.builder() + .partyName(respondent) + .roleOnCase(RESPONDENT7) + .groupId(RESPONDENT7) + .visibility(EXTERNAL) + .build() + ); + } else if (!respondent.equals(caseData.getRespondent6ExternalFlags().getPartyName())) { + caseData.getRespondent6ExternalFlags().setPartyName(respondent); + } + } + + if (caseData.getRespondentCollection().size() > 7) { + String respondent = caseData.getRespondentCollection().get(7).getValue().getRespondentName(); + if (caseData.getRespondent7Flags() == null + || StringUtils.isEmpty(caseData.getRespondent7Flags().getRoleOnCase())) { + caseData.setRespondent7Flags(CaseFlagsType.builder() + .partyName(respondent) + .roleOnCase(RESPONDENT8) + .groupId(RESPONDENT8) + .visibility(INTERNAL) + .build() + ); + } else if (!respondent.equals(caseData.getRespondent7Flags().getPartyName())) { + caseData.getRespondent7Flags().setPartyName(respondent); + } + + if (caseData.getRespondent7ExternalFlags() == null + || StringUtils.isEmpty(caseData.getRespondent7ExternalFlags().getRoleOnCase())) { + caseData.setRespondent7ExternalFlags(CaseFlagsType.builder() + .partyName(respondent) + .roleOnCase(RESPONDENT8) + .groupId(RESPONDENT8) + .visibility(EXTERNAL) + .build() + ); + } else if (!respondent.equals(caseData.getRespondent7ExternalFlags().getPartyName())) { + caseData.getRespondent7ExternalFlags().setPartyName(respondent); + } + } + + if (caseData.getRespondentCollection().size() > 8) { + String respondent = caseData.getRespondentCollection().get(8).getValue().getRespondentName(); + if (caseData.getRespondent8Flags() == null + || StringUtils.isEmpty(caseData.getRespondent8Flags().getRoleOnCase())) { + caseData.setRespondent8Flags(CaseFlagsType.builder() + .partyName(respondent) + .roleOnCase(RESPONDENT9) + .groupId(RESPONDENT9) + .visibility(INTERNAL) + .build() + ); + } else if (!respondent.equals(caseData.getRespondent8Flags().getPartyName())) { + caseData.getRespondent8Flags().setPartyName(respondent); + } + + if (caseData.getRespondent8ExternalFlags() == null + || StringUtils.isEmpty(caseData.getRespondent8ExternalFlags().getRoleOnCase())) { + caseData.setRespondent8ExternalFlags(CaseFlagsType.builder() + .partyName(respondent) + .roleOnCase(RESPONDENT9) + .groupId(RESPONDENT9) + .visibility(EXTERNAL) + .build() + ); + } else if (!respondent.equals(caseData.getRespondent8ExternalFlags().getPartyName())) { + caseData.getRespondent8ExternalFlags().setPartyName(respondent); + } + } + + if (caseData.getRespondentCollection().size() > 9) { + String respondent = caseData.getRespondentCollection().get(9).getValue().getRespondentName(); + if (caseData.getRespondent9Flags() == null + || StringUtils.isEmpty(caseData.getRespondent9Flags().getRoleOnCase())) { + caseData.setRespondent9Flags(CaseFlagsType.builder() + .partyName(respondent) + .roleOnCase(RESPONDENT10) + .groupId(RESPONDENT10) + .visibility(INTERNAL) + .build() + ); + } else if (!respondent.equals(caseData.getRespondent9Flags().getPartyName())) { + caseData.getRespondent9Flags().setPartyName(respondent); + } + + if (caseData.getRespondent9ExternalFlags() == null + || StringUtils.isEmpty(caseData.getRespondent9ExternalFlags().getRoleOnCase())) { + caseData.setRespondent9ExternalFlags(CaseFlagsType.builder() + .partyName(respondent) + .roleOnCase(RESPONDENT10) + .groupId(RESPONDENT10) + .visibility(EXTERNAL) + .build() + ); + } else if (!respondent.equals(caseData.getRespondent9ExternalFlags().getPartyName())) { + caseData.getRespondent9ExternalFlags().setPartyName(respondent); + } } } @@ -78,7 +450,27 @@ public void setupCaseFlags(CaseData caseData) { public void rollbackCaseFlags(CaseData caseData) { caseData.setCaseFlags(null); caseData.setClaimantFlags(null); + caseData.setClaimantExternalFlags(null); caseData.setRespondentFlags(null); + caseData.setRespondentExternalFlags(null); + caseData.setRespondent1Flags(null); + caseData.setRespondent1ExternalFlags(null); + caseData.setRespondent2Flags(null); + caseData.setRespondent2ExternalFlags(null); + caseData.setRespondent3Flags(null); + caseData.setRespondent3ExternalFlags(null); + caseData.setRespondent4Flags(null); + caseData.setRespondent4ExternalFlags(null); + caseData.setRespondent5Flags(null); + caseData.setRespondent5ExternalFlags(null); + caseData.setRespondent6Flags(null); + caseData.setRespondent6ExternalFlags(null); + caseData.setRespondent7Flags(null); + caseData.setRespondent7ExternalFlags(null); + caseData.setRespondent8Flags(null); + caseData.setRespondent8ExternalFlags(null); + caseData.setRespondent9Flags(null); + caseData.setRespondent9ExternalFlags(null); } /** @@ -134,10 +526,41 @@ private boolean hasGrantedDecision(List list) { } private ListTypeItem getPartyCaseFlags(CaseData caseData) { - return ListTypeItem.concat( + ListTypeItem partyLevel = ListTypeItem.concat( caseData.getClaimantFlags().getDetails(), - caseData.getRespondentFlags().getDetails() + caseData.getClaimantExternalFlags().getDetails() ); + + partyLevel = appendDetailsIfPresent(partyLevel, caseData.getRespondentFlags()); + partyLevel = appendDetailsIfPresent(partyLevel, caseData.getRespondentExternalFlags()); + partyLevel = appendDetailsIfPresent(partyLevel, caseData.getRespondent1Flags()); + partyLevel = appendDetailsIfPresent(partyLevel, caseData.getRespondent1ExternalFlags()); + partyLevel = appendDetailsIfPresent(partyLevel, caseData.getRespondent2Flags()); + partyLevel = appendDetailsIfPresent(partyLevel, caseData.getRespondent2ExternalFlags()); + partyLevel = appendDetailsIfPresent(partyLevel, caseData.getRespondent3Flags()); + partyLevel = appendDetailsIfPresent(partyLevel, caseData.getRespondent3ExternalFlags()); + partyLevel = appendDetailsIfPresent(partyLevel, caseData.getRespondent4Flags()); + partyLevel = appendDetailsIfPresent(partyLevel, caseData.getRespondent4ExternalFlags()); + partyLevel = appendDetailsIfPresent(partyLevel, caseData.getRespondent5Flags()); + partyLevel = appendDetailsIfPresent(partyLevel, caseData.getRespondent5ExternalFlags()); + partyLevel = appendDetailsIfPresent(partyLevel, caseData.getRespondent6Flags()); + partyLevel = appendDetailsIfPresent(partyLevel, caseData.getRespondent6ExternalFlags()); + partyLevel = appendDetailsIfPresent(partyLevel, caseData.getRespondent7Flags()); + partyLevel = appendDetailsIfPresent(partyLevel, caseData.getRespondent7ExternalFlags()); + partyLevel = appendDetailsIfPresent(partyLevel, caseData.getRespondent8Flags()); + partyLevel = appendDetailsIfPresent(partyLevel, caseData.getRespondent8ExternalFlags()); + partyLevel = appendDetailsIfPresent(partyLevel, caseData.getRespondent9Flags()); + partyLevel = appendDetailsIfPresent(partyLevel, caseData.getRespondent9ExternalFlags()); + + return partyLevel; + } + + private ListTypeItem appendDetailsIfPresent( + ListTypeItem partyLevel, CaseFlagsType flags) { + if (flags != null && flags.getDetails() != null) { + return ListTypeItem.concat(partyLevel, flags.getDetails()); + } + return partyLevel; } @Nullable diff --git a/src/test/apiTest/java/uk/gov/hmcts/ethos/replacement/apitest/Et1ReppedControllerFunctionalTest.java b/src/test/apiTest/java/uk/gov/hmcts/ethos/replacement/apitest/Et1ReppedControllerFunctionalTest.java index 3431b1f361..19f8441aa8 100644 --- a/src/test/apiTest/java/uk/gov/hmcts/ethos/replacement/apitest/Et1ReppedControllerFunctionalTest.java +++ b/src/test/apiTest/java/uk/gov/hmcts/ethos/replacement/apitest/Et1ReppedControllerFunctionalTest.java @@ -15,6 +15,8 @@ import uk.gov.hmcts.et.common.model.ccd.CaseDetails; import uk.gov.hmcts.ethos.utils.CCDRequestBuilder; import java.io.IOException; +import java.net.URISyntaxException; + import static org.hamcrest.Matchers.notNullValue; @Slf4j @@ -46,13 +48,8 @@ public class Et1ReppedControllerFunctionalTest extends BaseFunctionalTest { private CCDRequest ccdRequest; @BeforeAll - void setUpEt1ReppedData() throws IOException { - // Create a real case in CCD - JSONObject caseJson = createSinglesCaseDataStore(); - - ObjectMapper mapper = new ObjectMapper().findAndRegisterModules(); - CaseDetails caseDetails = mapper.readValue(caseJson.toString(), CaseDetails.class); - CaseData caseData = caseDetails.getCaseData(); + void setUpEt1ReppedData() throws IOException, URISyntaxException { + CaseData caseData = generateCaseDetails("et1Repped.json").getCaseData(); caseData.setClaimantFirstName("John"); caseData.setClaimantLastName("Doe"); @@ -63,6 +60,11 @@ void setUpEt1ReppedData() throws IOException { address.setCountry("United Kingdom"); caseData.setRespondentAddress(address); + // Create a real case in CCD + JSONObject caseJson = createSinglesCaseDataStore(); + ObjectMapper mapper = new ObjectMapper().findAndRegisterModules(); + CaseDetails caseDetails = mapper.readValue(caseJson.toString(), CaseDetails.class); + ccdRequest = CCDRequestBuilder.builder() .withCaseData(caseData) .withCaseTypeId(caseDetails.getCaseTypeId()) diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsDataMigrationControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsDataMigrationControllerTest.java index e9024ea83e..1394f8bff6 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsDataMigrationControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsDataMigrationControllerTest.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -78,6 +79,44 @@ void shouldMigrateCaseFlags() throws Exception { verify(caseFlagsService).setupCaseFlags(any(CaseData.class)); } + @Test + void shouldAddCaseFlagGroupIdAndVisibilityForPreviouslyMigratedFlags() throws Exception { + when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); + + mvc.perform(post(CASE_FLAGS_DATA_MIGRATION) + .content(requestContent.toString()) + .header(AUTHORIZATION, AUTH_TOKEN) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.data.claimantFlags.groupId").value("Claimant")) + .andExpect(jsonPath("$.data.claimantFlags.visibility").value("Internal")) + .andExpect(jsonPath("$.data.respondentFlags.groupId").value("Respondent 1")) + .andExpect(jsonPath("$.data.respondentFlags.visibility").value("Internal")); + } + + @Test + void shouldNotOverwriteExistingCaseFlagGroupIdAndVisibility() throws Exception { + when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); + + ObjectNode caseData = (ObjectNode) requestContent.at("/case_details/case_data"); + ObjectNode claimantFlags = (ObjectNode) caseData.get("claimantFlags"); + claimantFlags.put("groupId", "existing-claimant-group"); + claimantFlags.put("visibility", "Internal"); + ObjectNode respondentFlags = (ObjectNode) caseData.get("respondentFlags"); + respondentFlags.put("groupId", "existing-respondent-group"); + respondentFlags.put("visibility", "Internal"); + + mvc.perform(post(CASE_FLAGS_DATA_MIGRATION) + .content(requestContent.toString()) + .header(AUTHORIZATION, AUTH_TOKEN) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.data.claimantFlags.groupId").value("existing-claimant-group")) + .andExpect(jsonPath("$.data.claimantFlags.visibility").value("Internal")) + .andExpect(jsonPath("$.data.respondentFlags.groupId").value("existing-respondent-group")) + .andExpect(jsonPath("$.data.respondentFlags.visibility").value("Internal")); + } + @Test void shouldMigrateCaseFlags_tokenFail() throws Exception { when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(false); diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1ReppedControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1ReppedControllerTest.java index d365d7029c..464da60ee6 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1ReppedControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1ReppedControllerTest.java @@ -925,6 +925,9 @@ void submitClaim() { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); + + verify(caseFlagsService, times(0)).setupCaseFlags(any()); + verify(caseFlagsService, times(0)).processNewlySetCaseFlags(any()); } @Test @@ -940,6 +943,51 @@ void submitClaim_toggleOn() { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); + + verify(caseFlagsService, times(0)).setupCaseFlags(any()); + verify(caseFlagsService, times(0)).processNewlySetCaseFlags(any()); + } + + @Test + @SneakyThrows + void submitClaim_caseFlagToggleOn() { + when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); + when(featureToggleService.isEt1DocGenEnabled()).thenReturn(true); + when(featureToggleService.isCaseFlagsEnabled()).thenReturn(true); + when(caseFlagsService.caseFlagsSetupRequired(any())).thenReturn(false); + + mockMvc.perform(post(SUBMIT_CLAIM) + .contentType(APPLICATION_JSON) + .header(HttpHeaders.AUTHORIZATION, AUTH_TOKEN) + .content(jsonMapper.toJson(ccdRequest2))) + .andExpect(status().isOk()) + .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) + .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) + .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); + + verify(caseFlagsService, times(0)).setupCaseFlags(any()); + verify(caseFlagsService, times(0)).processNewlySetCaseFlags(any()); + } + + @Test + @SneakyThrows + void submitClaim_caseFlagSetupToggleOn() { + when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); + when(featureToggleService.isEt1DocGenEnabled()).thenReturn(true); + when(featureToggleService.isCaseFlagsEnabled()).thenReturn(true); + when(caseFlagsService.caseFlagsSetupRequired(any())).thenReturn(true); + + mockMvc.perform(post(SUBMIT_CLAIM) + .contentType(APPLICATION_JSON) + .header(HttpHeaders.AUTHORIZATION, AUTH_TOKEN) + .content(jsonMapper.toJson(ccdRequest2))) + .andExpect(status().isOk()) + .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) + .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) + .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); + + verify(caseFlagsService, times(1)).setupCaseFlags(any()); + verify(caseFlagsService, times(1)).processNewlySetCaseFlags(any()); } @SneakyThrows diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java index f23b0d3930..58df7e6a26 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java @@ -3,32 +3,60 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import org.springframework.test.context.junit.jupiter.SpringExtension; import uk.gov.hmcts.et.common.model.ccd.CaseData; import uk.gov.hmcts.et.common.model.ccd.items.FlagDetailType; import uk.gov.hmcts.et.common.model.ccd.items.GenericTseApplicationType; import uk.gov.hmcts.et.common.model.ccd.items.GenericTseApplicationTypeItem; import uk.gov.hmcts.et.common.model.ccd.items.ListTypeItem; +import uk.gov.hmcts.et.common.model.ccd.items.RespondentSumTypeItem; import uk.gov.hmcts.et.common.model.ccd.items.TseAdminRecordDecisionTypeItem; import uk.gov.hmcts.et.common.model.ccd.types.CaseFlagsType; +import uk.gov.hmcts.et.common.model.ccd.types.RespondentSumType; import uk.gov.hmcts.et.common.model.ccd.types.RestrictedReportingType; import uk.gov.hmcts.et.common.model.ccd.types.TseAdminRecordDecisionType; import uk.gov.hmcts.ethos.utils.CaseDataBuilder; +import java.util.ArrayList; import java.util.List; +import java.util.function.BiConsumer; +import java.util.function.Function; +import java.util.stream.Stream; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.nullValue; +import static org.junit.jupiter.api.Assertions.assertAll; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.ACTIVE; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.DISRUPTIVE_CUSTOMER; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.INACTIVE; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.LANGUAGE_INTERPRETER; import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.SIGN_LANGUAGE_INTERPRETER; import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.VEXATIOUS_LITIGANT; import static uk.gov.hmcts.ecm.common.model.helper.Constants.NO; import static uk.gov.hmcts.ecm.common.model.helper.Constants.TSE_APP_RESTRICT_PUBLICITY; import static uk.gov.hmcts.ecm.common.model.helper.Constants.YES; +import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.CLAIMANT; +import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.EXTERNAL; +import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.INTERNAL; +import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.RESPONDENT1; +import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.RESPONDENT10; +import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.RESPONDENT2; +import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.RESPONDENT3; +import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.RESPONDENT4; +import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.RESPONDENT5; +import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.RESPONDENT6; +import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.RESPONDENT7; +import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.RESPONDENT8; +import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.RESPONDENT9; @ExtendWith(SpringExtension.class) class CaseFlagsServiceTest { @@ -43,30 +71,97 @@ void setUp() { caseData = CaseDataBuilder.builder().build(); caseData.setClaimant(CLAIMANT_NAME); caseData.setRespondent(RESPONDENT_NAME); + + caseData.setRespondentCollection(respondentCollection(10)); + } + + @Test + void caseFlagsSetupRequired_shouldBeFalseAfterAllRequiredCaseFlagsAreSetup() { + assertTrue(caseFlagsService.caseFlagsSetupRequired(caseData)); + + caseFlagsService.setupCaseFlags(caseData); + + assertFalse(caseFlagsService.caseFlagsSetupRequired(caseData)); } @Test - void caseFlagsSetupRequired() { + void caseFlagsSetupRequired_shouldBeTrueWhenCaseFlagsAreMissing() { + caseFlagsService.setupCaseFlags(caseData); + caseData.setCaseFlags(null); + + assertTrue(caseFlagsService.caseFlagsSetupRequired(caseData)); + } + + @ParameterizedTest(name = "{0}") + @MethodSource("allPartyFlagSlots") + void caseFlagsSetupRequired_shouldBeTrueWhenAnyRequiredPartyFlagIsMissing(FlagSlot slot) { + caseFlagsService.setupCaseFlags(caseData); + + slot.setter.accept(caseData, null); + + assertTrue(caseFlagsService.caseFlagsSetupRequired(caseData)); + } + + @ParameterizedTest(name = "{0}") + @MethodSource("allPartyFlagSlots") + void caseFlagsSetupRequired_shouldBeTrueWhenAnyRequiredPartyFlagRoleIsMissing(FlagSlot slot) { + caseFlagsService.setupCaseFlags(caseData); + slot.getter.apply(caseData).setRoleOnCase(""); + assertTrue(caseFlagsService.caseFlagsSetupRequired(caseData)); + } + + @Test + void caseFlagsSetupRequired_shouldNotRequireRespondentFlagsWhenThereAreNoRespondents() { + caseData.setRespondentCollection(new ArrayList<>()); + caseFlagsService.setupCaseFlags(caseData); + assertFalse(caseFlagsService.caseFlagsSetupRequired(caseData)); + assertNull(caseData.getRespondentFlags()); + assertNull(caseData.getRespondentExternalFlags()); } @Test - void setupCaseFlags_setsShellCaseFlags() { + void setupCaseFlags_setsShellCaseFlagsForClaimantAndEveryRespondent() { caseFlagsService.setupCaseFlags(caseData); CaseFlagsType caseFlags = caseData.getCaseFlags(); assertThat(caseFlags.getPartyName(), is(nullValue())); assertThat(caseFlags.getRoleOnCase(), is(nullValue())); - CaseFlagsType claimantFlags = caseData.getClaimantFlags(); - assertThat(claimantFlags.getPartyName(), is(CLAIMANT_NAME)); - assertThat(claimantFlags.getRoleOnCase(), is("claimant")); + allPartyFlagSlots().forEach(slot -> assertCaseFlag(slot, slot.getter.apply(caseData))); + } - CaseFlagsType respondentFlags = caseData.getRespondentFlags(); - assertThat(respondentFlags.getPartyName(), is(RESPONDENT_NAME)); - assertThat(respondentFlags.getRoleOnCase(), is("respondent")); + @Test + void setupCaseFlags_shouldOnlyCreateRespondentFlagsForExistingRespondents() { + caseData.setRespondentCollection(respondentCollection(3)); + + caseFlagsService.setupCaseFlags(caseData); + + respondentPartyFlagSlots().forEach(slot -> { + if (slot.respondentIndex < 3) { + assertNotNull(slot.getter.apply(caseData), slot + " should be populated"); + } else { + assertNull(slot.getter.apply(caseData), slot + " should not be populated"); + } + }); + } + + @ParameterizedTest(name = "{0}") + @MethodSource("allPartyFlagSlots") + void setupCaseFlags_shouldRecreatePartyFlagsWhenRoleIsMissing(FlagSlot slot) { + caseFlagsService.setupCaseFlags(caseData); + slot.setter.accept(caseData, CaseFlagsType.builder() + .partyName("Old name") + .roleOnCase("") + .groupId("old-group") + .visibility("old-visibility") + .build()); + + caseFlagsService.setupCaseFlags(caseData); + + assertCaseFlag(slot, slot.getter.apply(caseData)); } @Test @@ -77,6 +172,9 @@ void rollbackCaseFlags_shouldSetToNull() { assertThat(caseData.getCaseFlags(), is(nullValue())); assertThat(caseData.getClaimantFlags(), is(nullValue())); assertThat(caseData.getRespondentFlags(), is(nullValue())); + assertThat(caseData.getClaimantExternalFlags(), is(nullValue())); + assertThat(caseData.getRespondentExternalFlags(), is(nullValue())); + allPartyFlagSlots().forEach(slot -> assertNull(slot.getter.apply(caseData), slot + " should be cleared")); } @Test @@ -88,19 +186,32 @@ void setupCaseFlags_shouldUpdateClaimantFlagsWhenNameChanges() { caseFlagsService.setupCaseFlags(caseData); assertEquals(updatedClaimantName, caseData.getClaimantFlags().getPartyName()); - assertEquals("claimant", caseData.getClaimantFlags().getRoleOnCase()); + assertEquals(CLAIMANT, caseData.getClaimantFlags().getRoleOnCase()); + assertEquals(CLAIMANT, caseData.getClaimantFlags().getGroupId()); + assertEquals(INTERNAL, caseData.getClaimantFlags().getVisibility()); + + assertEquals(updatedClaimantName, caseData.getClaimantExternalFlags().getPartyName()); + assertEquals(CLAIMANT, caseData.getClaimantExternalFlags().getRoleOnCase()); + assertEquals(CLAIMANT, caseData.getClaimantExternalFlags().getGroupId()); + assertEquals(EXTERNAL, caseData.getClaimantExternalFlags().getVisibility()); } - @Test - void setupCaseFlags_shouldUpdateRespondentFlagsWhenNameChanges() { + @ParameterizedTest(name = "{0}") + @MethodSource("respondentPartyFlagSlots") + void setupCaseFlags_shouldUpdateRespondentFlagsWhenNameChanges(FlagSlot slot) { caseFlagsService.setupCaseFlags(caseData); - String updatedRespondentName = "Updated Respondent Name"; - caseData.setRespondent(updatedRespondentName); + String updatedRespondentName = "Updated " + slot; + caseData.getRespondentCollection() + .get(slot.respondentIndex) + .getValue() + .setRespondentName(updatedRespondentName); caseFlagsService.setupCaseFlags(caseData); - assertEquals(updatedRespondentName, caseData.getRespondentFlags().getPartyName()); - assertEquals("respondent", caseData.getRespondentFlags().getRoleOnCase()); + assertEquals(updatedRespondentName, slot.getter.apply(caseData).getPartyName()); + assertEquals(slot.roleOnCase, slot.getter.apply(caseData).getRoleOnCase()); + assertEquals(slot.roleOnCase, slot.getter.apply(caseData).getGroupId()); + assertEquals(slot.visibility, slot.getter.apply(caseData).getVisibility()); } @Test @@ -115,6 +226,8 @@ void processNewlySetCaseFlags_shouldSetInterpreterRequiredTrue() { .flagCode("RA00010") .build())) .build()); + caseData.setClaimantExternalFlags(CaseFlagsType.builder().build()); + caseFlagsService.processNewlySetCaseFlags(caseData); assertEquals(YES, caseData.getCaseInterpreterRequiredFlag()); @@ -132,11 +245,68 @@ void processNewlySetCaseFlags_shouldSetAdditionalSecurityFlagTrue() { .flagCode("CA00010") .build())) .build()); + caseData.setClaimantExternalFlags(CaseFlagsType.builder().build()); + + caseFlagsService.processNewlySetCaseFlags(caseData); + + assertEquals(YES, caseData.getCaseAdditionalSecurityFlag()); + } + + @ParameterizedTest(name = "{0}") + @MethodSource("allPartyFlagSlots") + void processNewlySetCaseFlags_shouldReadInterpreterFlagsFromAnyPartyFlagCollection(FlagSlot slot) { + caseFlagsService.setupCaseFlags(caseData); + slot.getter.apply(caseData).setDetails(ListTypeItem.from(activeFlag(SIGN_LANGUAGE_INTERPRETER))); + + caseFlagsService.processNewlySetCaseFlags(caseData); + + assertEquals(YES, caseData.getCaseInterpreterRequiredFlag()); + assertEquals(NO, caseData.getCaseAdditionalSecurityFlag()); + } + + @ParameterizedTest(name = "{0}") + @MethodSource("allPartyFlagSlots") + void processNewlySetCaseFlags_shouldReadSecurityFlagsFromAnyPartyFlagCollection(FlagSlot slot) { + caseFlagsService.setupCaseFlags(caseData); + slot.getter.apply(caseData).setDetails(ListTypeItem.from(activeFlag(VEXATIOUS_LITIGANT))); + + caseFlagsService.processNewlySetCaseFlags(caseData); + + assertEquals(NO, caseData.getCaseInterpreterRequiredFlag()); + assertEquals(YES, caseData.getCaseAdditionalSecurityFlag()); + } + + @Test + void processNewlySetCaseFlags_shouldSupportAlternativeInterpreterAndSecurityFlagNames() { + caseFlagsService.setupCaseFlags(caseData); + caseData.getClaimantExternalFlags().setDetails(ListTypeItem.from(activeFlag(LANGUAGE_INTERPRETER))); + caseData.getRespondent9ExternalFlags().setDetails(ListTypeItem.from(activeFlag(DISRUPTIVE_CUSTOMER))); + caseFlagsService.processNewlySetCaseFlags(caseData); + assertEquals(YES, caseData.getCaseInterpreterRequiredFlag()); assertEquals(YES, caseData.getCaseAdditionalSecurityFlag()); } + @Test + void processNewlySetCaseFlags_shouldSetFlagsToNoWhenMatchingFlagsAreInactiveOrAbsent() { + caseFlagsService.setupCaseFlags(caseData); + caseData.getClaimantFlags().setDetails(ListTypeItem.from(FlagDetailType.builder() + .name(SIGN_LANGUAGE_INTERPRETER) + .status(INACTIVE) + .build())); + caseData.getRespondentFlags().setDetails(ListTypeItem.from(FlagDetailType.builder() + .name(VEXATIOUS_LITIGANT) + .status(INACTIVE) + .build())); + caseData.getRespondentExternalFlags().setDetails(ListTypeItem.from(activeFlag("A different flag"))); + + caseFlagsService.processNewlySetCaseFlags(caseData); + + assertEquals(NO, caseData.getCaseInterpreterRequiredFlag()); + assertEquals(NO, caseData.getCaseAdditionalSecurityFlag()); + } + @Test void setPrivateHearingFlag_shouldBeTruthy_whenRestrictPublicityTseApplicationIsGranted() { List granted = List.of(TseAdminRecordDecisionTypeItem.builder() @@ -159,6 +329,29 @@ void setPrivateHearingFlag_shouldBeTruthy_whenRestrictPublicityTseApplicationIsG assertEquals(YES, caseData.getPrivateHearingRequiredFlag()); } + @Test + void setPrivateHearingFlag_shouldBeTruthy_whenRestrictPublicityTseApplicationDecisionStartsWithGranted() { + caseData.setGenericTseApplicationCollection(List.of(tseApplication( + TSE_APP_RESTRICT_PUBLICITY, + List.of(adminDecision("Granted - application approved")) + ))); + + caseFlagsService.setPrivateHearingFlag(caseData); + + assertEquals(YES, caseData.getPrivateHearingRequiredFlag()); + } + + @ParameterizedTest(name = "{0}") + @MethodSource("nonGrantedTseApplications") + void setPrivateHearingFlag_shouldBeFalsy_whenNoRestrictPublicityTseApplicationIsGranted( + String scenario, List applications) { + caseData.setGenericTseApplicationCollection(applications); + + caseFlagsService.setPrivateHearingFlag(caseData); + + assertEquals(NO, caseData.getPrivateHearingRequiredFlag(), scenario); + } + @Test void setPrivateHearingFlag_shouldBeFalsy_whenRestrictPublicityTseApplicationIsRejected() { List granted = List.of(TseAdminRecordDecisionTypeItem.builder() @@ -227,4 +420,155 @@ void setPrivateHearingFlag_shouldBeFalsy_whenIcListingPreliminaryHearingIsFalse( assertEquals(NO, caseData.getPrivateHearingRequiredFlag()); } + + private static Stream allPartyFlagSlots() { + return Stream.of( + slot("claimant internal flags", CaseData::getClaimantFlags, CaseData::setClaimantFlags, + CLAIMANT_NAME, CLAIMANT, INTERNAL, -1), + slot("claimant external flags", CaseData::getClaimantExternalFlags, + CaseData::setClaimantExternalFlags, CLAIMANT_NAME, CLAIMANT, EXTERNAL, -1), + slot("respondent 1 internal flags", CaseData::getRespondentFlags, CaseData::setRespondentFlags, + respondentName(0), RESPONDENT1, INTERNAL, 0), + slot("respondent 1 external flags", CaseData::getRespondentExternalFlags, + CaseData::setRespondentExternalFlags, respondentName(0), RESPONDENT1, EXTERNAL, 0), + slot("respondent 2 internal flags", CaseData::getRespondent1Flags, CaseData::setRespondent1Flags, + respondentName(1), RESPONDENT2, INTERNAL, 1), + slot("respondent 2 external flags", CaseData::getRespondent1ExternalFlags, + CaseData::setRespondent1ExternalFlags, respondentName(1), RESPONDENT2, EXTERNAL, 1), + slot("respondent 3 internal flags", CaseData::getRespondent2Flags, CaseData::setRespondent2Flags, + respondentName(2), RESPONDENT3, INTERNAL, 2), + slot("respondent 3 external flags", CaseData::getRespondent2ExternalFlags, + CaseData::setRespondent2ExternalFlags, respondentName(2), RESPONDENT3, EXTERNAL, 2), + slot("respondent 4 internal flags", CaseData::getRespondent3Flags, CaseData::setRespondent3Flags, + respondentName(3), RESPONDENT4, INTERNAL, 3), + slot("respondent 4 external flags", CaseData::getRespondent3ExternalFlags, + CaseData::setRespondent3ExternalFlags, respondentName(3), RESPONDENT4, EXTERNAL, 3), + slot("respondent 5 internal flags", CaseData::getRespondent4Flags, CaseData::setRespondent4Flags, + respondentName(4), RESPONDENT5, INTERNAL, 4), + slot("respondent 5 external flags", CaseData::getRespondent4ExternalFlags, + CaseData::setRespondent4ExternalFlags, respondentName(4), RESPONDENT5, EXTERNAL, 4), + slot("respondent 6 internal flags", CaseData::getRespondent5Flags, CaseData::setRespondent5Flags, + respondentName(5), RESPONDENT6, INTERNAL, 5), + slot("respondent 6 external flags", CaseData::getRespondent5ExternalFlags, + CaseData::setRespondent5ExternalFlags, respondentName(5), RESPONDENT6, EXTERNAL, 5), + slot("respondent 7 internal flags", CaseData::getRespondent6Flags, CaseData::setRespondent6Flags, + respondentName(6), RESPONDENT7, INTERNAL, 6), + slot("respondent 7 external flags", CaseData::getRespondent6ExternalFlags, + CaseData::setRespondent6ExternalFlags, respondentName(6), RESPONDENT7, EXTERNAL, 6), + slot("respondent 8 internal flags", CaseData::getRespondent7Flags, CaseData::setRespondent7Flags, + respondentName(7), RESPONDENT8, INTERNAL, 7), + slot("respondent 8 external flags", CaseData::getRespondent7ExternalFlags, + CaseData::setRespondent7ExternalFlags, respondentName(7), RESPONDENT8, EXTERNAL, 7), + slot("respondent 9 internal flags", CaseData::getRespondent8Flags, CaseData::setRespondent8Flags, + respondentName(8), RESPONDENT9, INTERNAL, 8), + slot("respondent 9 external flags", CaseData::getRespondent8ExternalFlags, + CaseData::setRespondent8ExternalFlags, respondentName(8), RESPONDENT9, EXTERNAL, 8), + slot("respondent 10 internal flags", CaseData::getRespondent9Flags, CaseData::setRespondent9Flags, + respondentName(9), RESPONDENT10, INTERNAL, 9), + slot("respondent 10 external flags", CaseData::getRespondent9ExternalFlags, + CaseData::setRespondent9ExternalFlags, respondentName(9), RESPONDENT10, EXTERNAL, 9) + ); + } + + private static Stream respondentPartyFlagSlots() { + return allPartyFlagSlots().filter(slot -> slot.respondentIndex >= 0); + } + + private static Stream nonGrantedTseApplications() { + return Stream.of( + Arguments.of("different TSE application type", + List.of(tseApplication("Another application", List.of(adminDecision("Granted"))))), + Arguments.of("missing admin decision", + List.of(tseApplication(TSE_APP_RESTRICT_PUBLICITY, null))), + Arguments.of("missing decision value", + List.of(tseApplication(TSE_APP_RESTRICT_PUBLICITY, List.of(adminDecision(null))))), + Arguments.of("refused restricted publicity decision", + List.of(tseApplication(TSE_APP_RESTRICT_PUBLICITY, List.of(adminDecision("Refused"))))) + ); + } + + private static FlagSlot slot(String name, Function getter, + BiConsumer setter, String partyName, + String roleOnCase, String visibility, int respondentIndex) { + return new FlagSlot(name, getter, setter, partyName, roleOnCase, visibility, respondentIndex); + } + + private static List respondentCollection(int numberOfRespondents) { + List respondentCollection = new ArrayList<>(); + for (int i = 0; i < numberOfRespondents; i++) { + RespondentSumTypeItem respondentSumTypeItem = new RespondentSumTypeItem(); + RespondentSumType respondentSumType = new RespondentSumType(); + respondentSumType.setRespondentName(respondentName(i)); + respondentSumTypeItem.setId(String.valueOf(i + 1)); + respondentSumTypeItem.setValue(respondentSumType); + respondentCollection.add(respondentSumTypeItem); + } + return respondentCollection; + } + + private static String respondentName(int index) { + return index == 0 ? RESPONDENT_NAME : RESPONDENT_NAME + " " + (index + 1); + } + + private static void assertCaseFlag(FlagSlot slot, CaseFlagsType actual) { + assertNotNull(actual, slot + " should be populated"); + assertAll(slot.toString(), + () -> assertEquals(slot.partyName, actual.getPartyName()), + () -> assertEquals(slot.roleOnCase, actual.getRoleOnCase()), + () -> assertEquals(slot.roleOnCase, actual.getGroupId()), + () -> assertEquals(slot.visibility, actual.getVisibility()) + ); + } + + private static FlagDetailType activeFlag(String name) { + return FlagDetailType.builder() + .name(name) + .status(ACTIVE) + .build(); + } + + private static GenericTseApplicationTypeItem tseApplication( + String type, List adminDecisions) { + return GenericTseApplicationTypeItem.builder() + .value(GenericTseApplicationType.builder() + .type(type) + .adminDecision(adminDecisions) + .build()) + .build(); + } + + private static TseAdminRecordDecisionTypeItem adminDecision(String decision) { + return TseAdminRecordDecisionTypeItem.builder() + .value(TseAdminRecordDecisionType.builder() + .decision(decision) + .build()) + .build(); + } + + private static final class FlagSlot { + private final String name; + private final Function getter; + private final BiConsumer setter; + private final String partyName; + private final String roleOnCase; + private final String visibility; + private final int respondentIndex; + + private FlagSlot(String name, Function getter, + BiConsumer setter, String partyName, + String roleOnCase, String visibility, int respondentIndex) { + this.name = name; + this.getter = getter; + this.setter = setter; + this.partyName = partyName; + this.roleOnCase = roleOnCase; + this.visibility = visibility; + this.respondentIndex = respondentIndex; + } + + @Override + public String toString() { + return name; + } + } } From 6f55bdebcbc08e42759da839d652273497f0a2f7 Mon Sep 17 00:00:00 2001 From: rajaram Date: Tue, 26 May 2026 16:42:27 +0100 Subject: [PATCH 002/100] Display case flags and support tabs to the respective users --- .../england-wales/data/ccd-template.xlsx | Bin 137857 -> 138812 bytes .../CaseTypeTab-CaseFlagsCaseLinking.json | 146 ++++++++-- ...RoleToAccessProfiles-RetainAndDispose.json | 6 +- .../RoleToAccessProfiles.json | 2 +- .../scotland/data/ccd-template.xlsx | Bin 110936 -> 111871 bytes .../CaseTypeTab-CaseFlagsCaseLinking.json | 146 ++++++++-- ...RoleToAccessProfiles-RetainAndDispose.json | 6 +- .../RoleToAccessProfiles.json | 2 +- .../replacement/docmosis/RolesConstants.java | 255 +++++++++--------- .../HighLevelDataSetupConfiguration.java | 2 + 10 files changed, 396 insertions(+), 169 deletions(-) diff --git a/ccd-definitions/jurisdictions/england-wales/data/ccd-template.xlsx b/ccd-definitions/jurisdictions/england-wales/data/ccd-template.xlsx index 18f32fb68291579e7ff3bbbc4c3292fb29f115bb..105adf4aa20d331686bea51b8f8ec07905af2bad 100644 GIT binary patch delta 121000 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 Rs2O_r0CMPS3{W=#`+q#Du{{6) literal 137857 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 KA? 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 diff --git a/ccd-definitions/jurisdictions/england-wales/json/CaseTypeTab/CaseTypeTab-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/england-wales/json/CaseTypeTab/CaseTypeTab-CaseFlagsCaseLinking.json index 049f94e17f..5ac6aeff0b 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/CaseTypeTab/CaseTypeTab-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/england-wales/json/CaseTypeTab/CaseTypeTab-CaseFlagsCaseLinking.json @@ -26,6 +26,27 @@ "TabFieldDisplayOrder": 3, "FieldShowCondition": "caseLinks=\"dummy\"" }, + { + "CaseFieldID": "flagLauncher", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "TabDisplayOrder": 69, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 13, + "UserRole": "caseworker-employment-caseflags", + "DisplayContextParameter": "#ARGUMENT(READ,VERSION2.1)" + }, + { + "CaseFieldID": "caseFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 69, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 12 + }, { "CaseFieldID": "claimantFlags", "CaseTypeID": "ET_EnglandWales", @@ -137,24 +158,125 @@ "TabFieldDisplayOrder": 11 }, { - "CaseFieldID": "caseFlags", + "CaseFieldID": "claimantExternalFlags", "CaseTypeID": "ET_EnglandWales", "Channel": "CaseWorker", - "FieldShowCondition": "flagLauncher = \"hidden\"", + "FieldShowCondition": "flagLauncher=\"hidden\"", "TabDisplayOrder": 69, "TabID": "caseFlags", "TabLabel": "Case Flags", - "TabFieldDisplayOrder": 12 + "TabFieldDisplayOrder": 1 }, { - "CaseFieldID": "flagLauncher", + "CaseFieldID": "respondentExternalFlags", "CaseTypeID": "ET_EnglandWales", "Channel": "CaseWorker", - "TabDisplayOrder": 69, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, "TabID": "caseFlags", "TabLabel": "Case Flags", - "TabFieldDisplayOrder": 13, - "DisplayContextParameter": "#ARGUMENT(READ,VERSION2.1)" + "TabFieldDisplayOrder": 2 + }, + { + "CaseFieldID": "respondent1ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 3 + }, + { + "CaseFieldID": "respondent2ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 4 + }, + { + "CaseFieldID": "respondent3ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 5 + }, + { + "CaseFieldID": "respondent4ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 6 + }, + { + "CaseFieldID": "respondent5ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 7 + }, + { + "CaseFieldID": "respondent6ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 8 + }, + { + "CaseFieldID": "respondent7ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 9 + }, + { + "CaseFieldID": "respondent8ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 10 + }, + { + "CaseFieldID": "respondent9ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 11 + }, + { + "CaseFieldID": "flagLauncherExternal", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "TabDisplayOrder": 69, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 12, + "UserRole": "caseworker-employment-support", + "DisplayContextParameter": "#ARGUMENT(READ,EXTERNAL)" }, { "CaseFieldID": "claimantExternalFlags", @@ -265,15 +387,5 @@ "TabID": "support", "TabLabel": "Support", "TabFieldDisplayOrder": 11 - }, - { - "CaseFieldID": "flagLauncherExternal", - "CaseTypeID": "ET_EnglandWales", - "Channel": "CaseWorker", - "TabDisplayOrder": 69, - "TabID": "support", - "TabLabel": "Support", - "TabFieldDisplayOrder": 12, - "DisplayContextParameter": "#ARGUMENT(READ,EXTERNAL)" } ] diff --git a/ccd-definitions/jurisdictions/england-wales/json/RoleToAccessProfiles/RoleToAccessProfiles-RetainAndDispose.json b/ccd-definitions/jurisdictions/england-wales/json/RoleToAccessProfiles/RoleToAccessProfiles-RetainAndDispose.json index 9c7af2e942..8ef639117c 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/RoleToAccessProfiles/RoleToAccessProfiles-RetainAndDispose.json +++ b/ccd-definitions/jurisdictions/england-wales/json/RoleToAccessProfiles/RoleToAccessProfiles-RetainAndDispose.json @@ -11,14 +11,14 @@ "CaseTypeID": "ET_EnglandWales", "RoleName": "idam:caseworker-employment-englandwales", "ReadOnly": "N", - "AccessProfiles": "TTL_profile,caseworker-employment-englandwales" + "AccessProfiles": "TTL_profile,caseworker-employment-englandwales,caseworker-employment-caseflags" }, { "LiveFrom": "01/01/2017", "CaseTypeID": "ET_EnglandWales", "RoleName": "idam:caseworker-employment-api", "ReadOnly": "N", - "AccessProfiles": "TTL_profile,caseworker-employment-api" + "AccessProfiles": "TTL_profile,caseworker-employment-api,caseworker-employment-caseflags" }, { "LiveFrom": "01/01/2017", @@ -32,6 +32,6 @@ "CaseTypeID": "ET_EnglandWales", "RoleName": "idam:caseworker-employment-legalrep-solicitor", "ReadOnly": "N", - "AccessProfiles": "TTL_profile,caseworker-employment-legalrep-solicitor" + "AccessProfiles": "TTL_profile,caseworker-employment-legalrep-solicitor,caseworker-employment-support" } ] diff --git a/ccd-definitions/jurisdictions/england-wales/json/RoleToAccessProfiles/RoleToAccessProfiles.json b/ccd-definitions/jurisdictions/england-wales/json/RoleToAccessProfiles/RoleToAccessProfiles.json index 8ac4ac784b..4ef68b601e 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/RoleToAccessProfiles/RoleToAccessProfiles.json +++ b/ccd-definitions/jurisdictions/england-wales/json/RoleToAccessProfiles/RoleToAccessProfiles.json @@ -11,7 +11,7 @@ "CaseTypeID": "ET_EnglandWales", "RoleName": "idam:caseworker-employment-etjudge-englandwales", "ReadOnly": "N", - "AccessProfiles": "caseworker-employment-etjudge-englandwales" + "AccessProfiles": "caseworker-employment-etjudge-englandwales,caseworker-employment-caseflags" }, { "LiveFrom": "01/01/2017", diff --git a/ccd-definitions/jurisdictions/scotland/data/ccd-template.xlsx b/ccd-definitions/jurisdictions/scotland/data/ccd-template.xlsx index 4727af2f4041bf1e7c310726c854a5d985f6395e..6ae7bf161cacddb8844e5aeb6196eccb9dfd503a 100644 GIT binary patch delta 97878 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%0Ac$+!vl8>qB_AX8-F`~^8+Q$kANij^3`T?fc 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 V1(t$XW+6wbz)aW#d1v$XzW^mp>5BjW diff --git a/ccd-definitions/jurisdictions/scotland/json/CaseTypeTab/CaseTypeTab-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/scotland/json/CaseTypeTab/CaseTypeTab-CaseFlagsCaseLinking.json index eb830993bf..6ba382ef87 100644 --- a/ccd-definitions/jurisdictions/scotland/json/CaseTypeTab/CaseTypeTab-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/scotland/json/CaseTypeTab/CaseTypeTab-CaseFlagsCaseLinking.json @@ -26,6 +26,27 @@ "TabFieldDisplayOrder": 3, "FieldShowCondition": "caseLinks=\"dummy\"" }, + { + "CaseFieldID": "flagLauncher", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "TabDisplayOrder": 69, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 13, + "UserRole": "caseworker-employment-caseflags", + "DisplayContextParameter": "#ARGUMENT(READ,VERSION2.1)" + }, + { + "CaseFieldID": "caseFlags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 69, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 12 + }, { "CaseFieldID": "claimantFlags", "CaseTypeID": "ET_Scotland", @@ -137,24 +158,125 @@ "TabFieldDisplayOrder": 11 }, { - "CaseFieldID": "caseFlags", + "CaseFieldID": "claimantExternalFlags", "CaseTypeID": "ET_Scotland", "Channel": "CaseWorker", - "FieldShowCondition": "flagLauncher = \"hidden\"", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", "TabDisplayOrder": 69, "TabID": "caseFlags", "TabLabel": "Case Flags", - "TabFieldDisplayOrder": 12 + "TabFieldDisplayOrder": 1 }, { - "CaseFieldID": "flagLauncher", + "CaseFieldID": "respondentExternalFlags", "CaseTypeID": "ET_Scotland", "Channel": "CaseWorker", - "TabDisplayOrder": 69, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, "TabID": "caseFlags", "TabLabel": "Case Flags", - "TabFieldDisplayOrder": 13, - "DisplayContextParameter": "#ARGUMENT(READ,VERSION2.1)" + "TabFieldDisplayOrder": 2 + }, + { + "CaseFieldID": "respondent1ExternalFlags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 3 + }, + { + "CaseFieldID": "respondent2ExternalFlags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 4 + }, + { + "CaseFieldID": "respondent3ExternalFlags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 5 + }, + { + "CaseFieldID": "respondent4ExternalFlags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 6 + }, + { + "CaseFieldID": "respondent5ExternalFlags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 7 + }, + { + "CaseFieldID": "respondent6ExternalFlags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 8 + }, + { + "CaseFieldID": "respondent7ExternalFlags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 9 + }, + { + "CaseFieldID": "respondent8ExternalFlags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 10 + }, + { + "CaseFieldID": "respondent9ExternalFlags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 11 + }, + { + "CaseFieldID": "flagLauncherExternal", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "TabDisplayOrder": 69, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 12, + "UserRole": "caseworker-employment-support", + "DisplayContextParameter": "#ARGUMENT(READ,EXTERNAL)" }, { "CaseFieldID": "claimantExternalFlags", @@ -265,15 +387,5 @@ "TabID": "support", "TabLabel": "Support", "TabFieldDisplayOrder": 11 - }, - { - "CaseFieldID": "flagLauncherExternal", - "CaseTypeID": "ET_Scotland", - "Channel": "CaseWorker", - "TabDisplayOrder": 69, - "TabID": "support", - "TabLabel": "Support", - "TabFieldDisplayOrder": 12, - "DisplayContextParameter": "#ARGUMENT(READ,EXTERNAL)" } ] diff --git a/ccd-definitions/jurisdictions/scotland/json/RoleToAccessProfiles/RoleToAccessProfiles-RetainAndDispose.json b/ccd-definitions/jurisdictions/scotland/json/RoleToAccessProfiles/RoleToAccessProfiles-RetainAndDispose.json index b4eae881e1..d870330ae2 100644 --- a/ccd-definitions/jurisdictions/scotland/json/RoleToAccessProfiles/RoleToAccessProfiles-RetainAndDispose.json +++ b/ccd-definitions/jurisdictions/scotland/json/RoleToAccessProfiles/RoleToAccessProfiles-RetainAndDispose.json @@ -11,14 +11,14 @@ "CaseTypeID": "ET_Scotland", "RoleName": "idam:caseworker-employment-scotland", "ReadOnly": "N", - "AccessProfiles": "TTL_profile,caseworker-employment-scotland" + "AccessProfiles": "TTL_profile,caseworker-employment-scotland,caseworker-employment-caseflags" }, { "LiveFrom": "01/01/2017", "CaseTypeID": "ET_Scotland", "RoleName": "idam:caseworker-employment-api", "ReadOnly": "N", - "AccessProfiles": "TTL_profile,caseworker-employment-api" + "AccessProfiles": "TTL_profile,caseworker-employment-api,caseworker-employment-caseflags" }, { "LiveFrom": "01/01/2017", @@ -32,6 +32,6 @@ "CaseTypeID": "ET_Scotland", "RoleName": "idam:caseworker-employment-legalrep-solicitor", "ReadOnly": "N", - "AccessProfiles": "TTL_profile,caseworker-employment-legalrep-solicitor" + "AccessProfiles": "TTL_profile,caseworker-employment-legalrep-solicitor,caseworker-employment-support" } ] \ No newline at end of file diff --git a/ccd-definitions/jurisdictions/scotland/json/RoleToAccessProfiles/RoleToAccessProfiles.json b/ccd-definitions/jurisdictions/scotland/json/RoleToAccessProfiles/RoleToAccessProfiles.json index 36f28e1315..267204c63e 100644 --- a/ccd-definitions/jurisdictions/scotland/json/RoleToAccessProfiles/RoleToAccessProfiles.json +++ b/ccd-definitions/jurisdictions/scotland/json/RoleToAccessProfiles/RoleToAccessProfiles.json @@ -11,7 +11,7 @@ "CaseTypeID": "ET_Scotland", "RoleName": "idam:caseworker-employment-etjudge-scotland", "ReadOnly": "N", - "AccessProfiles": "caseworker-employment-etjudge-scotland" + "AccessProfiles": "caseworker-employment-etjudge-scotland,caseworker-employment-caseflags" }, { "LiveFrom": "01/01/2017", diff --git a/src/cftlib/java/uk/gov/hmcts/ethos/replacement/docmosis/RolesConstants.java b/src/cftlib/java/uk/gov/hmcts/ethos/replacement/docmosis/RolesConstants.java index 881f56bed7..1a8c50822d 100644 --- a/src/cftlib/java/uk/gov/hmcts/ethos/replacement/docmosis/RolesConstants.java +++ b/src/cftlib/java/uk/gov/hmcts/ethos/replacement/docmosis/RolesConstants.java @@ -1,127 +1,128 @@ -package uk.gov.hmcts.ethos.replacement.docmosis; - -public final class RolesConstants { - public static final String CASEWORKER = "caseworker"; - public static final String CASEWORKER_ET_PCQEXTRACTOR = CASEWORKER.concat("-et-pcqextractor"); - public static final String CASEWORKER_CAA = CASEWORKER.concat("-caa"); - public static final String CASEWORKER_WA = CASEWORKER.concat("-wa"); - public static final String CASEWORKER_WA_TASK_OFFICER = CASEWORKER_WA.concat("-task-officer"); - public static final String CASEWORKER_EMPLOYMENT = CASEWORKER.concat("-employment"); - public static final String CASEWORKER_EMPLOYMENT_API = CASEWORKER_EMPLOYMENT.concat("-api"); - public static final String CASEWORKER_EMPLOYMENT_ENGLANDWALES = CASEWORKER_EMPLOYMENT.concat("-englandwales"); - public static final String CASEWORKER_EMPLOYMENT_SCOTLAND = CASEWORKER_EMPLOYMENT.concat("-scotland"); - public static final String CASEWORKER_EMPLOYMENT_ETJUDGE = CASEWORKER_EMPLOYMENT.concat("-etjudge"); - public static final String CASEWORKER_EMPLOYMENT_ETJUDGE_ENGLANDWALES = - CASEWORKER_EMPLOYMENT_ETJUDGE.concat("-englandwales"); - public static final String CASEWORKER_EMPLOYMENT_ETJUDGE_SCOTLAND = - CASEWORKER_EMPLOYMENT_ETJUDGE.concat("-scotland"); - public static final String CASEWORKER_EMPLOYMENT_LEGALREP_SOLICITOR = - CASEWORKER_EMPLOYMENT.concat("-legalrep-solicitor"); - public static final String CITIZEN = "citizen"; - public static final String CCD_IMPORT = "ccd-import"; - - public static final String ET_ACAS_API = "et-acas-api"; - - public static final String PUI_CASE_MANAGER = "pui-case-manager"; - public static final String PUI_FINANCE_MANAGER = "pui-finance-manager"; - public static final String PUI_ORGANISATION_MANAGER = "pui-organisation-manager"; - public static final String PUI_USER_MANAGER = "pui-user-manager"; - public static final String PUI_CAA = "pui-caa"; - public static final String MANAGE_USER = "manage-user"; - public static final String CASEWORKER_APPROVER = "caseworker-approver"; - public static final String PRD_AAC_SYSTEM = "prd-aac-system"; - public static final String PRD_ADMIN = "prd-admin"; - public static final String ACAS_API = "et-acas-api"; - public static final String GS_PROFILE = "GS_profile"; - public static final String TTL_PROFILE = "TTL_profile"; - public static final String RAS_VALIDATION = "caseworker-ras-validation"; - public static final String WA_TASK_CONFIGURATION = "caseworker-wa-task-configuration"; - - // Other roles that might be linked to WA - - public static final String CASE_ALLOCATOR = "case-allocator"; - public static final String CWD_USER = "cwd-user"; - public static final String CWD_ADMIN = "cwd-admin"; - public static final String CWD_SYSTEM_USER = "cwd-system-user"; - public static final String HEARING_CENTRE_ADMIN = "hearing-centre-admin"; - public static final String HEARING_CENTRE_TEAM_LEADER = "hearing-centre-team-leader"; - public static final String HEARING_MANAGER = "hearing-manager"; - public static final String HEARING_VIEWER = "hearing-viewer"; - public static final String HMCTS_ADMIN = "hmcts-admin"; - public static final String HMCTS_LEGAL_OPERATIONS = "hmcts-legal-operations"; - public static final String SENIOR_TRIBUNAL_CASEWORKER = "senior-tribunal-caseworker"; - public static final String SPECIFIC_ACCESS_APPROVER_ADMIN = "specific-access-approver-admin"; - public static final String SPECIFIC_ACCESS_APPROVER_LEGAL_OPS = "specific-access-approver-legal-ops"; - public static final String TASK_SUPERVISOR = "task-supervisor"; - public static final String TRIBUNAL_CASEWORKER = "tribunal-caseworker"; - public static final String EMPLOYMENT_TRIBUNAL_CASEWORKER = "employment-tribunal-caseworker"; - public static final String EMPLOYMENT_HEARING_CENTRE_ADMIN = "employment-hearing-centre-admin"; - public static final String EMPLOYMENT_SENIOR_TRIBUNAL_CASEWORKER = "employment-senior-tribunal-caseworker"; - public static final String EMPLOYMENT_HEARING_CENTRE_TEAM_LEADER = "employment-hearing-centre-team-leader"; - public static final String STAFF_ADMIN = "staff-admin"; - public static final String CTSC_TEAM_LEADER = "ctsc-team-leader"; - public static final String REGIONAL_CENTRE_TEAM_LEADER = "regional-centre-team-leader"; - - //Emails constants - public static final String JUDGE_EW_EMAIL = "judge.ew@hmcts.net"; - public static final String JUDGE_SC_EMAIL = "judge.sc@hmcts.net"; - public static final String LEGALREP_EMAIL = "legalrep@hmcts.net"; - public static final String CCD_DOCKER_DEFAULT_EMAIL = "ccd.docker.default@hmcts.net"; - public static final String ENGLANDWALES_EMAIL = "englandwales@hmcts.net"; - public static final String SCOTLAND_EMAIL = "scotland@hmcts.net"; - public static final String ADMIN_EMAIL = "admin@hmcts.net"; - public static final String SUPERUSER_EMAIL = "superuser@etorganisation1.com"; - public static final String SOLICITOR_1_EMAIL = "solicitor1@etorganisation1.com"; - public static final String CITIZEN_EMAIL = "citizen@gmail.com"; - public static final String RESPONDENT_EMAIL = "respondent@gmail.com"; - public static final String IDAM_SYSTEM_USER_EMAIL = "data.store.idam.system.user@gmail.com"; - public static final String MCA_SYSTEM_IDAM_ACC_EMAIL = "mca.system.idam.acc@gmail.com"; - public static final String MCA_NOC_APPROVER_EMAIL = "mca.noc.approver@gmail.com"; - public static final String ACAS_EMAIL = "et@acas.com"; - public static final String ET_SYSTEM_EMAIL = "et.service@hmcts.net"; - public static final String ROLE_ASSIGNMENT_ADMIN_EMAIL = "role.assignment.admin@gmail.com"; - public static final String ET_CASEADMIN_EMAIL = "et.caseadmin@hmcts.net"; - public static final String WA_SYSTEM_USER_EMAIL = "wa-system-user@fake.hmcts.net"; - - static final String[] ECM_CASEWORKER_ROLES = { - CASEWORKER_EMPLOYMENT.concat("-bristol"), CASEWORKER_EMPLOYMENT.concat("-leeds"), - CASEWORKER_EMPLOYMENT.concat("-londoncentral"), CASEWORKER_EMPLOYMENT.concat("-londoneast"), - CASEWORKER_EMPLOYMENT.concat("-londonsouth"), CASEWORKER_EMPLOYMENT.concat("-manchester"), - CASEWORKER_EMPLOYMENT.concat("-midlandseast"), CASEWORKER_EMPLOYMENT.concat("-midlandswest"), - CASEWORKER_EMPLOYMENT.concat("-newcastle"), CASEWORKER_EMPLOYMENT.concat("-wales"), - CASEWORKER_EMPLOYMENT.concat("-watford") - }; - static final String[] ECM_JUDGE_ROLES = { - CASEWORKER_EMPLOYMENT_ETJUDGE.concat("-bristol"), CASEWORKER_EMPLOYMENT_ETJUDGE.concat("-leeds"), - CASEWORKER_EMPLOYMENT_ETJUDGE.concat("-londoncentral"), CASEWORKER_EMPLOYMENT_ETJUDGE.concat("-londoneast"), - CASEWORKER_EMPLOYMENT_ETJUDGE.concat("-londonsouth"), CASEWORKER_EMPLOYMENT_ETJUDGE.concat("-manchester"), - CASEWORKER_EMPLOYMENT_ETJUDGE.concat("-midlandseast"), - CASEWORKER_EMPLOYMENT_ETJUDGE.concat("-midlandswest"), CASEWORKER_EMPLOYMENT_ETJUDGE.concat("-newcastle"), - CASEWORKER_EMPLOYMENT_ETJUDGE.concat("-wales"), CASEWORKER_EMPLOYMENT_ETJUDGE.concat("-watford") - }; - - //Paths to definition files - public static final String ENGLANGWALES_CONFIG_FILE = - "./ccd-definitions/jurisdictions/england-wales/xlsx/et-englandwales-ccd-config-cftlib.xlsx"; - public static final String SCOTLAND_CONFIG_FILE = - "./ccd-definitions/jurisdictions/scotland/xlsx/et-scotland-ccd-config-cftlib.xlsx"; - public static final String ADMIN_CONFIG_FILE = - "./ccd-definitions/jurisdictions/admin/xlsx/et-admin-ccd-config-cftlib.xlsx"; - - static final String[] CASEWORKER_ROLES = {CASEWORKER_ET_PCQEXTRACTOR, CASEWORKER_CAA, - CASEWORKER_EMPLOYMENT, CASEWORKER_EMPLOYMENT_API, CASEWORKER_EMPLOYMENT_ENGLANDWALES, - CASEWORKER_EMPLOYMENT_SCOTLAND, CASEWORKER_EMPLOYMENT_ETJUDGE, CASEWORKER_EMPLOYMENT_ETJUDGE_ENGLANDWALES, - CASEWORKER_EMPLOYMENT_ETJUDGE_SCOTLAND, CASEWORKER_EMPLOYMENT_LEGALREP_SOLICITOR, CITIZEN, ET_ACAS_API, - PUI_CASE_MANAGER, PUI_FINANCE_MANAGER, PUI_ORGANISATION_MANAGER, PUI_USER_MANAGER, PUI_CAA, MANAGE_USER, - CASEWORKER_APPROVER, PRD_AAC_SYSTEM, PRD_ADMIN, ACAS_API, GS_PROFILE, TTL_PROFILE, RAS_VALIDATION, - WA_TASK_CONFIGURATION, "caseworker-divorce-solicitor", CASEWORKER_WA, CASEWORKER_WA_TASK_OFFICER, - CASE_ALLOCATOR, CWD_USER, HEARING_CENTRE_ADMIN, HEARING_CENTRE_TEAM_LEADER, HEARING_MANAGER, - HEARING_VIEWER, HMCTS_ADMIN, HMCTS_LEGAL_OPERATIONS, SENIOR_TRIBUNAL_CASEWORKER, SPECIFIC_ACCESS_APPROVER_ADMIN, - SPECIFIC_ACCESS_APPROVER_LEGAL_OPS, TASK_SUPERVISOR, TRIBUNAL_CASEWORKER, EMPLOYMENT_TRIBUNAL_CASEWORKER, - EMPLOYMENT_HEARING_CENTRE_ADMIN, EMPLOYMENT_SENIOR_TRIBUNAL_CASEWORKER, - EMPLOYMENT_HEARING_CENTRE_TEAM_LEADER, CWD_ADMIN, CWD_SYSTEM_USER, CTSC_TEAM_LEADER, - REGIONAL_CENTRE_TEAM_LEADER, "allocated-admin-caseworker" }; - - private RolesConstants() { - } -} +package uk.gov.hmcts.ethos.replacement.docmosis; + +public final class RolesConstants { + public static final String CASEWORKER = "caseworker"; + public static final String CASEWORKER_ET_PCQEXTRACTOR = CASEWORKER.concat("-et-pcqextractor"); + public static final String CASEWORKER_CAA = CASEWORKER.concat("-caa"); + public static final String CASEWORKER_WA = CASEWORKER.concat("-wa"); + public static final String CASEWORKER_WA_TASK_OFFICER = CASEWORKER_WA.concat("-task-officer"); + public static final String CASEWORKER_EMPLOYMENT = CASEWORKER.concat("-employment"); + public static final String CASEWORKER_EMPLOYMENT_API = CASEWORKER_EMPLOYMENT.concat("-api"); + public static final String CASEWORKER_EMPLOYMENT_ENGLANDWALES = CASEWORKER_EMPLOYMENT.concat("-englandwales"); + public static final String CASEWORKER_EMPLOYMENT_SCOTLAND = CASEWORKER_EMPLOYMENT.concat("-scotland"); + public static final String CASEWORKER_EMPLOYMENT_ETJUDGE = CASEWORKER_EMPLOYMENT.concat("-etjudge"); + public static final String CASEWORKER_EMPLOYMENT_ETJUDGE_ENGLANDWALES = + CASEWORKER_EMPLOYMENT_ETJUDGE.concat("-englandwales"); + public static final String CASEWORKER_EMPLOYMENT_ETJUDGE_SCOTLAND = + CASEWORKER_EMPLOYMENT_ETJUDGE.concat("-scotland"); + public static final String CASEWORKER_EMPLOYMENT_LEGALREP_SOLICITOR = + CASEWORKER_EMPLOYMENT.concat("-legalrep-solicitor"); + public static final String CITIZEN = "citizen"; + public static final String CCD_IMPORT = "ccd-import"; + + public static final String ET_ACAS_API = "et-acas-api"; + + public static final String PUI_CASE_MANAGER = "pui-case-manager"; + public static final String PUI_FINANCE_MANAGER = "pui-finance-manager"; + public static final String PUI_ORGANISATION_MANAGER = "pui-organisation-manager"; + public static final String PUI_USER_MANAGER = "pui-user-manager"; + public static final String PUI_CAA = "pui-caa"; + public static final String MANAGE_USER = "manage-user"; + public static final String CASEWORKER_APPROVER = "caseworker-approver"; + public static final String PRD_AAC_SYSTEM = "prd-aac-system"; + public static final String PRD_ADMIN = "prd-admin"; + public static final String ACAS_API = "et-acas-api"; + public static final String GS_PROFILE = "GS_profile"; + public static final String TTL_PROFILE = "TTL_profile"; + public static final String RAS_VALIDATION = "caseworker-ras-validation"; + public static final String WA_TASK_CONFIGURATION = "caseworker-wa-task-configuration"; + + // Other roles that might be linked to WA + + public static final String CASE_ALLOCATOR = "case-allocator"; + public static final String CWD_USER = "cwd-user"; + public static final String CWD_ADMIN = "cwd-admin"; + public static final String CWD_SYSTEM_USER = "cwd-system-user"; + public static final String HEARING_CENTRE_ADMIN = "hearing-centre-admin"; + public static final String HEARING_CENTRE_TEAM_LEADER = "hearing-centre-team-leader"; + public static final String HEARING_MANAGER = "hearing-manager"; + public static final String HEARING_VIEWER = "hearing-viewer"; + public static final String HMCTS_ADMIN = "hmcts-admin"; + public static final String HMCTS_LEGAL_OPERATIONS = "hmcts-legal-operations"; + public static final String SENIOR_TRIBUNAL_CASEWORKER = "senior-tribunal-caseworker"; + public static final String SPECIFIC_ACCESS_APPROVER_ADMIN = "specific-access-approver-admin"; + public static final String SPECIFIC_ACCESS_APPROVER_LEGAL_OPS = "specific-access-approver-legal-ops"; + public static final String TASK_SUPERVISOR = "task-supervisor"; + public static final String TRIBUNAL_CASEWORKER = "tribunal-caseworker"; + public static final String EMPLOYMENT_TRIBUNAL_CASEWORKER = "employment-tribunal-caseworker"; + public static final String EMPLOYMENT_HEARING_CENTRE_ADMIN = "employment-hearing-centre-admin"; + public static final String EMPLOYMENT_SENIOR_TRIBUNAL_CASEWORKER = "employment-senior-tribunal-caseworker"; + public static final String EMPLOYMENT_HEARING_CENTRE_TEAM_LEADER = "employment-hearing-centre-team-leader"; + public static final String STAFF_ADMIN = "staff-admin"; + public static final String CTSC_TEAM_LEADER = "ctsc-team-leader"; + public static final String REGIONAL_CENTRE_TEAM_LEADER = "regional-centre-team-leader"; + + //Emails constants + public static final String JUDGE_EW_EMAIL = "judge.ew@hmcts.net"; + public static final String JUDGE_SC_EMAIL = "judge.sc@hmcts.net"; + public static final String LEGALREP_EMAIL = "legalrep@hmcts.net"; + public static final String CCD_DOCKER_DEFAULT_EMAIL = "ccd.docker.default@hmcts.net"; + public static final String ENGLANDWALES_EMAIL = "englandwales@hmcts.net"; + public static final String SCOTLAND_EMAIL = "scotland@hmcts.net"; + public static final String ADMIN_EMAIL = "admin@hmcts.net"; + public static final String SUPERUSER_EMAIL = "superuser@etorganisation1.com"; + public static final String SOLICITOR_1_EMAIL = "solicitor1@etorganisation1.com"; + public static final String CITIZEN_EMAIL = "citizen@gmail.com"; + public static final String RESPONDENT_EMAIL = "respondent@gmail.com"; + public static final String IDAM_SYSTEM_USER_EMAIL = "data.store.idam.system.user@gmail.com"; + public static final String MCA_SYSTEM_IDAM_ACC_EMAIL = "mca.system.idam.acc@gmail.com"; + public static final String MCA_NOC_APPROVER_EMAIL = "mca.noc.approver@gmail.com"; + public static final String ACAS_EMAIL = "et@acas.com"; + public static final String ET_SYSTEM_EMAIL = "et.service@hmcts.net"; + public static final String ROLE_ASSIGNMENT_ADMIN_EMAIL = "role.assignment.admin@gmail.com"; + public static final String ET_CASEADMIN_EMAIL = "et.caseadmin@hmcts.net"; + public static final String WA_SYSTEM_USER_EMAIL = "wa-system-user@fake.hmcts.net"; + + static final String[] ECM_CASEWORKER_ROLES = { + CASEWORKER_EMPLOYMENT.concat("-bristol"), CASEWORKER_EMPLOYMENT.concat("-leeds"), + CASEWORKER_EMPLOYMENT.concat("-londoncentral"), CASEWORKER_EMPLOYMENT.concat("-londoneast"), + CASEWORKER_EMPLOYMENT.concat("-londonsouth"), CASEWORKER_EMPLOYMENT.concat("-manchester"), + CASEWORKER_EMPLOYMENT.concat("-midlandseast"), CASEWORKER_EMPLOYMENT.concat("-midlandswest"), + CASEWORKER_EMPLOYMENT.concat("-newcastle"), CASEWORKER_EMPLOYMENT.concat("-wales"), + CASEWORKER_EMPLOYMENT.concat("-watford") + }; + static final String[] ECM_JUDGE_ROLES = { + CASEWORKER_EMPLOYMENT_ETJUDGE.concat("-bristol"), CASEWORKER_EMPLOYMENT_ETJUDGE.concat("-leeds"), + CASEWORKER_EMPLOYMENT_ETJUDGE.concat("-londoncentral"), CASEWORKER_EMPLOYMENT_ETJUDGE.concat("-londoneast"), + CASEWORKER_EMPLOYMENT_ETJUDGE.concat("-londonsouth"), CASEWORKER_EMPLOYMENT_ETJUDGE.concat("-manchester"), + CASEWORKER_EMPLOYMENT_ETJUDGE.concat("-midlandseast"), + CASEWORKER_EMPLOYMENT_ETJUDGE.concat("-midlandswest"), CASEWORKER_EMPLOYMENT_ETJUDGE.concat("-newcastle"), + CASEWORKER_EMPLOYMENT_ETJUDGE.concat("-wales"), CASEWORKER_EMPLOYMENT_ETJUDGE.concat("-watford") + }; + + //Paths to definition files + public static final String ENGLANGWALES_CONFIG_FILE = + "./ccd-definitions/jurisdictions/england-wales/xlsx/et-englandwales-ccd-config-cftlib.xlsx"; + public static final String SCOTLAND_CONFIG_FILE = + "./ccd-definitions/jurisdictions/scotland/xlsx/et-scotland-ccd-config-cftlib.xlsx"; + public static final String ADMIN_CONFIG_FILE = + "./ccd-definitions/jurisdictions/admin/xlsx/et-admin-ccd-config-cftlib.xlsx"; + + static final String[] CASEWORKER_ROLES = {CASEWORKER_ET_PCQEXTRACTOR, CASEWORKER_CAA, + CASEWORKER_EMPLOYMENT, CASEWORKER_EMPLOYMENT_API, CASEWORKER_EMPLOYMENT_ENGLANDWALES, + CASEWORKER_EMPLOYMENT_SCOTLAND, CASEWORKER_EMPLOYMENT_ETJUDGE, CASEWORKER_EMPLOYMENT_ETJUDGE_ENGLANDWALES, + CASEWORKER_EMPLOYMENT_ETJUDGE_SCOTLAND, CASEWORKER_EMPLOYMENT_LEGALREP_SOLICITOR, CITIZEN, ET_ACAS_API, + PUI_CASE_MANAGER, PUI_FINANCE_MANAGER, PUI_ORGANISATION_MANAGER, PUI_USER_MANAGER, PUI_CAA, MANAGE_USER, + CASEWORKER_APPROVER, PRD_AAC_SYSTEM, PRD_ADMIN, ACAS_API, GS_PROFILE, TTL_PROFILE, RAS_VALIDATION, + WA_TASK_CONFIGURATION, "caseworker-divorce-solicitor", CASEWORKER_WA, CASEWORKER_WA_TASK_OFFICER, + CASE_ALLOCATOR, CWD_USER, HEARING_CENTRE_ADMIN, HEARING_CENTRE_TEAM_LEADER, HEARING_MANAGER, + HEARING_VIEWER, HMCTS_ADMIN, HMCTS_LEGAL_OPERATIONS, SENIOR_TRIBUNAL_CASEWORKER, SPECIFIC_ACCESS_APPROVER_ADMIN, + SPECIFIC_ACCESS_APPROVER_LEGAL_OPS, TASK_SUPERVISOR, TRIBUNAL_CASEWORKER, EMPLOYMENT_TRIBUNAL_CASEWORKER, + EMPLOYMENT_HEARING_CENTRE_ADMIN, EMPLOYMENT_SENIOR_TRIBUNAL_CASEWORKER, + EMPLOYMENT_HEARING_CENTRE_TEAM_LEADER, CWD_ADMIN, CWD_SYSTEM_USER, CTSC_TEAM_LEADER, + REGIONAL_CENTRE_TEAM_LEADER, "allocated-admin-caseworker", "caseworker-employment-caseflags", + "caseworker-employment-support" }; + + private RolesConstants() { + } +} diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/config/HighLevelDataSetupConfiguration.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/config/HighLevelDataSetupConfiguration.java index 394a0f04ef..0eb220df80 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/config/HighLevelDataSetupConfiguration.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/config/HighLevelDataSetupConfiguration.java @@ -39,6 +39,8 @@ public class HighLevelDataSetupConfiguration extends DataLoaderToDefinitionStore new CcdRoleConfig("caseworker-approver", PUBLIC), new CcdRoleConfig("caseworker-caa", PUBLIC), new CcdRoleConfig("caseworker-et-pcqextractor", PUBLIC), + new CcdRoleConfig("caseworker-employment-caseflags", PUBLIC), + new CcdRoleConfig("caseworker-employment-support", PUBLIC), }; public HighLevelDataSetupConfiguration(CcdEnvironment dataSetupEnvironment) { From 457a15f3abef356c4a444dedc9d7619bf34ad95e Mon Sep 17 00:00:00 2001 From: rajaram Date: Mon, 15 Jun 2026 14:23:28 +0100 Subject: [PATCH 003/100] Case flags feature added for representatives --- ...isationCaseField-CaseFlagsCaseLinking.json | 462 ++++++++++ ...aseEventToFields-CaseFlagsCaseLinking.json | 858 ++++++++++++++++++ .../CaseField-CaseFlagsCaseLinking.json | 154 ++++ .../CaseTypeTab-CaseFlagsCaseLinking.json | 330 +++++++ ...isationCaseField-CaseFlagsCaseLinking.json | 462 ++++++++++ ...aseEventToFields-CaseFlagsCaseLinking.json | 858 ++++++++++++++++++ .../CaseField-CaseFlagsCaseLinking.json | 154 ++++ .../CaseTypeTab-CaseFlagsCaseLinking.json | 330 +++++++ .../hmcts/et/common/model/ccd/CaseData.java | 23 +- .../__files/prd/accountIdByEmailResponse.json | 4 + .../mappings/prd/accountIdByEmailRequest.json | 18 + ...AmendClaimantRepresentativeController.java | 15 +- .../CaseActionsForCaseWorkerController.java | 14 +- .../controllers/NoticeOfChangeController.java | 9 + .../docmosis/service/CaseFlagsService.java | 694 +++++--------- ...epresentativeControllerFunctionalTest.java | 76 +- ...ForCaseWorkerControllerFunctionalTest.java | 76 +- ...oticeOfChangeControllerFunctionalTest.java | 20 + ...dClaimantRepresentativeControllerTest.java | 44 +- ...aseActionsForCaseWorkerControllerTest.java | 66 ++ .../NoticeOfChangeControllerTest.java | 36 +- .../service/CaseFlagsServiceTest.java | 221 ++++- 22 files changed, 4460 insertions(+), 464 deletions(-) create mode 100644 src/cftlib/resources/compose/mocks/wiremock/__files/prd/accountIdByEmailResponse.json create mode 100644 src/cftlib/resources/compose/mocks/wiremock/mappings/prd/accountIdByEmailRequest.json diff --git a/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json index 43c1ac2988..98e9f71331 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json @@ -233,6 +233,204 @@ "UserRole": "caseworker-employment-englandwales", "CRUD": "CRU" }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "claimantRepresentativeFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "claimantRepresentativeFlags", + "UserRole": "caseworker-employment-etjudge-englandwales", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "claimantRepresentativeFlags", + "UserRole": "caseworker-employment-englandwales", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representativeFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representativeFlags", + "UserRole": "caseworker-employment-etjudge-englandwales", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representativeFlags", + "UserRole": "caseworker-employment-englandwales", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative1Flags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative1Flags", + "UserRole": "caseworker-employment-etjudge-englandwales", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative1Flags", + "UserRole": "caseworker-employment-englandwales", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative2Flags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative2Flags", + "UserRole": "caseworker-employment-etjudge-englandwales", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative2Flags", + "UserRole": "caseworker-employment-englandwales", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative3Flags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative3Flags", + "UserRole": "caseworker-employment-etjudge-englandwales", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative3Flags", + "UserRole": "caseworker-employment-englandwales", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative4Flags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative4Flags", + "UserRole": "caseworker-employment-etjudge-englandwales", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative4Flags", + "UserRole": "caseworker-employment-englandwales", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative5Flags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative5Flags", + "UserRole": "caseworker-employment-etjudge-englandwales", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative5Flags", + "UserRole": "caseworker-employment-englandwales", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative6Flags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative6Flags", + "UserRole": "caseworker-employment-etjudge-englandwales", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative6Flags", + "UserRole": "caseworker-employment-englandwales", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative7Flags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative7Flags", + "UserRole": "caseworker-employment-etjudge-englandwales", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative7Flags", + "UserRole": "caseworker-employment-englandwales", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative8Flags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative8Flags", + "UserRole": "caseworker-employment-etjudge-englandwales", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative8Flags", + "UserRole": "caseworker-employment-englandwales", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative9Flags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative9Flags", + "UserRole": "caseworker-employment-etjudge-englandwales", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative9Flags", + "UserRole": "caseworker-employment-englandwales", + "CRUD": "CRU" + }, { "CaseTypeId": "ET_EnglandWales", "CaseFieldID": "flagLauncherExternal", @@ -520,5 +718,269 @@ "CaseFieldID": "respondent9ExternalFlags", "UserRole": "caseworker-employment-api", "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "claimantRepresentativeExternalFlags", + "UserRole": "[CLAIMANTSOLICITOR]", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representativeExternalFlags", + "UserRole": "[SOLICITORA]", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative1ExternalFlags", + "UserRole": "[SOLICITORB]", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative2ExternalFlags", + "UserRole": "[SOLICITORC]", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative3ExternalFlags", + "UserRole": "[SOLICITORD]", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative4ExternalFlags", + "UserRole": "[SOLICITORE]", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative5ExternalFlags", + "UserRole": "[SOLICITORF]", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative6ExternalFlags", + "UserRole": "[SOLICITORG]", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative7ExternalFlags", + "UserRole": "[SOLICITORH]", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative8ExternalFlags", + "UserRole": "[SOLICITORI]", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative9ExternalFlags", + "UserRole": "[SOLICITORJ]", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "claimantRepresentativeExternalFlags", + "UserRole": "caseworker-employment-englandwales", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representativeExternalFlags", + "UserRole": "caseworker-employment-englandwales", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative1ExternalFlags", + "UserRole": "caseworker-employment-englandwales", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative2ExternalFlags", + "UserRole": "caseworker-employment-englandwales", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative3ExternalFlags", + "UserRole": "caseworker-employment-englandwales", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative4ExternalFlags", + "UserRole": "caseworker-employment-englandwales", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative5ExternalFlags", + "UserRole": "caseworker-employment-englandwales", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative6ExternalFlags", + "UserRole": "caseworker-employment-englandwales", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative7ExternalFlags", + "UserRole": "caseworker-employment-englandwales", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative8ExternalFlags", + "UserRole": "caseworker-employment-englandwales", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative9ExternalFlags", + "UserRole": "caseworker-employment-englandwales", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "claimantRepresentativeExternalFlags", + "UserRole": "caseworker-employment-etjudge-englandwales", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representativeExternalFlags", + "UserRole": "caseworker-employment-etjudge-englandwales", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative1ExternalFlags", + "UserRole": "caseworker-employment-etjudge-englandwales", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative2ExternalFlags", + "UserRole": "caseworker-employment-etjudge-englandwales", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative3ExternalFlags", + "UserRole": "caseworker-employment-etjudge-englandwales", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative4ExternalFlags", + "UserRole": "caseworker-employment-etjudge-englandwales", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative5ExternalFlags", + "UserRole": "caseworker-employment-etjudge-englandwales", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative6ExternalFlags", + "UserRole": "caseworker-employment-etjudge-englandwales", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative7ExternalFlags", + "UserRole": "caseworker-employment-etjudge-englandwales", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative8ExternalFlags", + "UserRole": "caseworker-employment-etjudge-englandwales", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative9ExternalFlags", + "UserRole": "caseworker-employment-etjudge-englandwales", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "claimantRepresentativeExternalFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representativeExternalFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative1ExternalFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative2ExternalFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative3ExternalFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative4ExternalFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative5ExternalFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative6ExternalFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative7ExternalFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative8ExternalFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "representative9ExternalFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" } ] diff --git a/ccd-definitions/jurisdictions/england-wales/json/CaseEventToFields/CaseEventToFields-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/england-wales/json/CaseEventToFields/CaseEventToFields-CaseFlagsCaseLinking.json index 8a894048b3..689bc51c66 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/CaseEventToFields/CaseEventToFields-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/england-wales/json/CaseEventToFields/CaseEventToFields-CaseFlagsCaseLinking.json @@ -103,6 +103,84 @@ "ShowSummary": "Y", "RetainHiddenValue": "Yes" }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "createFlag", + "CaseFieldID": "claimantRepresentativeFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 4, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageFlags", + "CaseFieldID": "claimantRepresentativeFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 4, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "createFlag", + "CaseFieldID": "claimantRepresentativeExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 4, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageFlags", + "CaseFieldID": "claimantRepresentativeExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 4, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "requestSupport", + "CaseFieldID": "claimantRepresentativeExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 4, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageSupport", + "CaseFieldID": "claimantRepresentativeExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 4, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, { "CaseTypeID": "ET_EnglandWales", "CaseEventID": "createFlag", @@ -927,6 +1005,786 @@ "ShowSummary": "Y", "RetainHiddenValue": "Yes" }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageFlags", + "CaseFieldID": "representativeFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "createFlag", + "CaseFieldID": "representativeFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageFlags", + "CaseFieldID": "representative1Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "createFlag", + "CaseFieldID": "representative1Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageFlags", + "CaseFieldID": "representative2Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "createFlag", + "CaseFieldID": "representative2Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageFlags", + "CaseFieldID": "representative3Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "createFlag", + "CaseFieldID": "representative3Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageFlags", + "CaseFieldID": "representative4Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "createFlag", + "CaseFieldID": "representative4Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageFlags", + "CaseFieldID": "representative5Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "createFlag", + "CaseFieldID": "representative5Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageFlags", + "CaseFieldID": "representative6Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "createFlag", + "CaseFieldID": "representative6Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageFlags", + "CaseFieldID": "representative7Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "createFlag", + "CaseFieldID": "representative7Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageFlags", + "CaseFieldID": "representative8Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "createFlag", + "CaseFieldID": "representative8Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageFlags", + "CaseFieldID": "representative9Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "createFlag", + "CaseFieldID": "representative9Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageFlags", + "CaseFieldID": "representativeExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "createFlag", + "CaseFieldID": "representativeExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageFlags", + "CaseFieldID": "representative1ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "createFlag", + "CaseFieldID": "representative1ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageFlags", + "CaseFieldID": "representative2ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "createFlag", + "CaseFieldID": "representative2ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageFlags", + "CaseFieldID": "representative3ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "createFlag", + "CaseFieldID": "representative3ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageFlags", + "CaseFieldID": "representative4ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "createFlag", + "CaseFieldID": "representative4ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageFlags", + "CaseFieldID": "representative5ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "createFlag", + "CaseFieldID": "representative5ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageFlags", + "CaseFieldID": "representative6ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "createFlag", + "CaseFieldID": "representative6ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageFlags", + "CaseFieldID": "representative7ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "createFlag", + "CaseFieldID": "representative7ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageFlags", + "CaseFieldID": "representative8ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "createFlag", + "CaseFieldID": "representative8ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageFlags", + "CaseFieldID": "representative9ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "createFlag", + "CaseFieldID": "representative9ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageSupport", + "CaseFieldID": "representativeExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "requestSupport", + "CaseFieldID": "representativeExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageSupport", + "CaseFieldID": "representative1ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "requestSupport", + "CaseFieldID": "representative1ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageSupport", + "CaseFieldID": "representative2ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "requestSupport", + "CaseFieldID": "representative2ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageSupport", + "CaseFieldID": "representative3ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "requestSupport", + "CaseFieldID": "representative3ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageSupport", + "CaseFieldID": "representative4ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "requestSupport", + "CaseFieldID": "representative4ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageSupport", + "CaseFieldID": "representative5ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "requestSupport", + "CaseFieldID": "representative5ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageSupport", + "CaseFieldID": "representative6ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "requestSupport", + "CaseFieldID": "representative6ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageSupport", + "CaseFieldID": "representative7ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "requestSupport", + "CaseFieldID": "representative7ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageSupport", + "CaseFieldID": "representative8ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "requestSupport", + "CaseFieldID": "representative8ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageSupport", + "CaseFieldID": "representative9ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "requestSupport", + "CaseFieldID": "representative9ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, { "CaseTypeID": "ET_EnglandWales", "CaseEventID": "createCaseLink", diff --git a/ccd-definitions/jurisdictions/england-wales/json/CaseField/CaseField-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/england-wales/json/CaseField/CaseField-CaseFlagsCaseLinking.json index e7eb30f721..58c6240020 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/CaseField/CaseField-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/england-wales/json/CaseField/CaseField-CaseFlagsCaseLinking.json @@ -20,6 +20,20 @@ "FieldType": "Flags", "SecurityClassification": "Public" }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "claimantRepresentativeFlags", + "Label": "Claimant Representative Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "claimantRepresentativeExternalFlags", + "Label": "Claimant Representative External Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, { "CaseTypeID": "ET_EnglandWales", "ID": "flagLauncher", @@ -174,6 +188,146 @@ "FieldType": "Flags", "SecurityClassification": "Public" }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "representativeFlags", + "Label": "Representative Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "representative1Flags", + "Label": "Representative 1 Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "representative2Flags", + "Label": "Representative 2 Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "representative3Flags", + "Label": "Representative 3 Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "representative4Flags", + "Label": "Representative 4 Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "representative5Flags", + "Label": "Representative 5 Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "representative6Flags", + "Label": "Representative 6 Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "representative7Flags", + "Label": "Representative 7 Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "representative8Flags", + "Label": "Representative 8 Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "representative9Flags", + "Label": "Representative 9 Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "representativeExternalFlags", + "Label": "Representative External Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "representative1ExternalFlags", + "Label": "Representative 1 External Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "representative2ExternalFlags", + "Label": "Representative 2 External Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "representative3ExternalFlags", + "Label": "Representative 3 External Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "representative4ExternalFlags", + "Label": "Representative 4 External Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "representative5ExternalFlags", + "Label": "Representative 5 External Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "representative6ExternalFlags", + "Label": "Representative 6 External Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "representative7ExternalFlags", + "Label": "Representative 7 External Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "representative8ExternalFlags", + "Label": "Representative 8 External Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "representative9ExternalFlags", + "Label": "Representative 9 External Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, { "LiveFrom": "03/11/2022", "CaseTypeID": "ET_EnglandWales", diff --git a/ccd-definitions/jurisdictions/england-wales/json/CaseTypeTab/CaseTypeTab-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/england-wales/json/CaseTypeTab/CaseTypeTab-CaseFlagsCaseLinking.json index 5ac6aeff0b..ddebf94923 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/CaseTypeTab/CaseTypeTab-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/england-wales/json/CaseTypeTab/CaseTypeTab-CaseFlagsCaseLinking.json @@ -57,6 +57,16 @@ "TabLabel": "Case Flags", "TabFieldDisplayOrder": 1 }, + { + "CaseFieldID": "claimantRepresentativeFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 69, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 1 + }, { "CaseFieldID": "respondentFlags", "CaseTypeID": "ET_EnglandWales", @@ -157,6 +167,106 @@ "TabLabel": "Case Flags", "TabFieldDisplayOrder": 11 }, + { + "CaseFieldID": "representativeFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 2 + }, + { + "CaseFieldID": "representative1Flags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 3 + }, + { + "CaseFieldID": "representative2Flags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 4 + }, + { + "CaseFieldID": "representative3Flags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 5 + }, + { + "CaseFieldID": "representative4Flags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 6 + }, + { + "CaseFieldID": "representative5Flags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 7 + }, + { + "CaseFieldID": "representative6Flags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 8 + }, + { + "CaseFieldID": "representative7Flags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 9 + }, + { + "CaseFieldID": "representative8Flags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 10 + }, + { + "CaseFieldID": "representative9Flags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 11 + }, { "CaseFieldID": "claimantExternalFlags", "CaseTypeID": "ET_EnglandWales", @@ -167,6 +277,16 @@ "TabLabel": "Case Flags", "TabFieldDisplayOrder": 1 }, + { + "CaseFieldID": "claimantRepresentativeExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 69, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 1 + }, { "CaseFieldID": "respondentExternalFlags", "CaseTypeID": "ET_EnglandWales", @@ -267,6 +387,106 @@ "TabLabel": "Case Flags", "TabFieldDisplayOrder": 11 }, + { + "CaseFieldID": "representativeExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 2 + }, + { + "CaseFieldID": "representative1ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 3 + }, + { + "CaseFieldID": "representative2ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 4 + }, + { + "CaseFieldID": "representative3ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 5 + }, + { + "CaseFieldID": "representative4ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 6 + }, + { + "CaseFieldID": "representative5ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 7 + }, + { + "CaseFieldID": "representative6ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 8 + }, + { + "CaseFieldID": "representative7ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 9 + }, + { + "CaseFieldID": "representative8ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 10 + }, + { + "CaseFieldID": "representative9ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 11 + }, { "CaseFieldID": "flagLauncherExternal", "CaseTypeID": "ET_EnglandWales", @@ -288,6 +508,16 @@ "TabLabel": "Support", "TabFieldDisplayOrder": 1 }, + { + "CaseFieldID": "claimantRepresentativeExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 69, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 1 + }, { "CaseFieldID": "respondentExternalFlags", "CaseTypeID": "ET_EnglandWales", @@ -387,5 +617,105 @@ "TabID": "support", "TabLabel": "Support", "TabFieldDisplayOrder": 11 + }, + { + "CaseFieldID": "representativeExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 2 + }, + { + "CaseFieldID": "representative1ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 3 + }, + { + "CaseFieldID": "representative2ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 4 + }, + { + "CaseFieldID": "representative3ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 5 + }, + { + "CaseFieldID": "representative4ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 6 + }, + { + "CaseFieldID": "representative5ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 7 + }, + { + "CaseFieldID": "representative6ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 8 + }, + { + "CaseFieldID": "representative7ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 9 + }, + { + "CaseFieldID": "representative8ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 10 + }, + { + "CaseFieldID": "representative9ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 11 } ] diff --git a/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json index efda93b72a..522ea17fb3 100644 --- a/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json @@ -233,6 +233,204 @@ "UserRole": "caseworker-employment-scotland", "CRUD": "CRU" }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "claimantRepresentativeFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "claimantRepresentativeFlags", + "UserRole": "caseworker-employment-etjudge-scotland", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "claimantRepresentativeFlags", + "UserRole": "caseworker-employment-scotland", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representativeFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representativeFlags", + "UserRole": "caseworker-employment-etjudge-scotland", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representativeFlags", + "UserRole": "caseworker-employment-scotland", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative1Flags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative1Flags", + "UserRole": "caseworker-employment-etjudge-scotland", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative1Flags", + "UserRole": "caseworker-employment-scotland", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative2Flags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative2Flags", + "UserRole": "caseworker-employment-etjudge-scotland", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative2Flags", + "UserRole": "caseworker-employment-scotland", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative3Flags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative3Flags", + "UserRole": "caseworker-employment-etjudge-scotland", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative3Flags", + "UserRole": "caseworker-employment-scotland", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative4Flags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative4Flags", + "UserRole": "caseworker-employment-etjudge-scotland", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative4Flags", + "UserRole": "caseworker-employment-scotland", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative5Flags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative5Flags", + "UserRole": "caseworker-employment-etjudge-scotland", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative5Flags", + "UserRole": "caseworker-employment-scotland", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative6Flags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative6Flags", + "UserRole": "caseworker-employment-etjudge-scotland", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative6Flags", + "UserRole": "caseworker-employment-scotland", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative7Flags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative7Flags", + "UserRole": "caseworker-employment-etjudge-scotland", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative7Flags", + "UserRole": "caseworker-employment-scotland", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative8Flags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative8Flags", + "UserRole": "caseworker-employment-etjudge-scotland", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative8Flags", + "UserRole": "caseworker-employment-scotland", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative9Flags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative9Flags", + "UserRole": "caseworker-employment-etjudge-scotland", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative9Flags", + "UserRole": "caseworker-employment-scotland", + "CRUD": "CRU" + }, { "CaseTypeId": "ET_Scotland", "CaseFieldID": "flagLauncherExternal", @@ -305,6 +503,72 @@ "UserRole": "[SOLICITORJ]", "CRUD": "CRU" }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "claimantRepresentativeExternalFlags", + "UserRole": "[CLAIMANTSOLICITOR]", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representativeExternalFlags", + "UserRole": "[SOLICITORA]", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative1ExternalFlags", + "UserRole": "[SOLICITORB]", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative2ExternalFlags", + "UserRole": "[SOLICITORC]", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative3ExternalFlags", + "UserRole": "[SOLICITORD]", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative4ExternalFlags", + "UserRole": "[SOLICITORE]", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative5ExternalFlags", + "UserRole": "[SOLICITORF]", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative6ExternalFlags", + "UserRole": "[SOLICITORG]", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative7ExternalFlags", + "UserRole": "[SOLICITORH]", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative8ExternalFlags", + "UserRole": "[SOLICITORI]", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative9ExternalFlags", + "UserRole": "[SOLICITORJ]", + "CRUD": "CRU" + }, { "CaseTypeId": "ET_Scotland", "CaseFieldID": "flagLauncherExternal", @@ -377,6 +641,72 @@ "UserRole": "caseworker-employment-scotland", "CRUD": "CRU" }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "claimantRepresentativeExternalFlags", + "UserRole": "caseworker-employment-scotland", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representativeExternalFlags", + "UserRole": "caseworker-employment-scotland", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative1ExternalFlags", + "UserRole": "caseworker-employment-scotland", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative2ExternalFlags", + "UserRole": "caseworker-employment-scotland", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative3ExternalFlags", + "UserRole": "caseworker-employment-scotland", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative4ExternalFlags", + "UserRole": "caseworker-employment-scotland", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative5ExternalFlags", + "UserRole": "caseworker-employment-scotland", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative6ExternalFlags", + "UserRole": "caseworker-employment-scotland", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative7ExternalFlags", + "UserRole": "caseworker-employment-scotland", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative8ExternalFlags", + "UserRole": "caseworker-employment-scotland", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative9ExternalFlags", + "UserRole": "caseworker-employment-scotland", + "CRUD": "CRU" + }, { "CaseTypeId": "ET_Scotland", "CaseFieldID": "flagLauncherExternal", @@ -449,6 +779,72 @@ "UserRole": "caseworker-employment-etjudge-scotland", "CRUD": "R" }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "claimantRepresentativeExternalFlags", + "UserRole": "caseworker-employment-etjudge-scotland", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representativeExternalFlags", + "UserRole": "caseworker-employment-etjudge-scotland", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative1ExternalFlags", + "UserRole": "caseworker-employment-etjudge-scotland", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative2ExternalFlags", + "UserRole": "caseworker-employment-etjudge-scotland", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative3ExternalFlags", + "UserRole": "caseworker-employment-etjudge-scotland", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative4ExternalFlags", + "UserRole": "caseworker-employment-etjudge-scotland", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative5ExternalFlags", + "UserRole": "caseworker-employment-etjudge-scotland", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative6ExternalFlags", + "UserRole": "caseworker-employment-etjudge-scotland", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative7ExternalFlags", + "UserRole": "caseworker-employment-etjudge-scotland", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative8ExternalFlags", + "UserRole": "caseworker-employment-etjudge-scotland", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative9ExternalFlags", + "UserRole": "caseworker-employment-etjudge-scotland", + "CRUD": "R" + }, { "CaseTypeId": "ET_Scotland", "CaseFieldID": "flagLauncherExternal", @@ -520,5 +916,71 @@ "CaseFieldID": "respondent9ExternalFlags", "UserRole": "caseworker-employment-api", "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "claimantRepresentativeExternalFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representativeExternalFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative1ExternalFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative2ExternalFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative3ExternalFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative4ExternalFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative5ExternalFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative6ExternalFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative7ExternalFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative8ExternalFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "representative9ExternalFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" } ] diff --git a/ccd-definitions/jurisdictions/scotland/json/CaseEventToFields/CaseEventToFields-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/scotland/json/CaseEventToFields/CaseEventToFields-CaseFlagsCaseLinking.json index 653e4bf450..bd9a4b553d 100644 --- a/ccd-definitions/jurisdictions/scotland/json/CaseEventToFields/CaseEventToFields-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/scotland/json/CaseEventToFields/CaseEventToFields-CaseFlagsCaseLinking.json @@ -103,6 +103,84 @@ "ShowSummary": "Y", "RetainHiddenValue": "Yes" }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "createFlag", + "CaseFieldID": "claimantRepresentativeFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 4, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageFlags", + "CaseFieldID": "claimantRepresentativeFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 4, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "createFlag", + "CaseFieldID": "claimantRepresentativeExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 4, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageFlags", + "CaseFieldID": "claimantRepresentativeExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 4, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "requestSupport", + "CaseFieldID": "claimantRepresentativeExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 4, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageSupport", + "CaseFieldID": "claimantRepresentativeExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 4, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, { "CaseTypeID": "ET_Scotland", "CaseEventID": "createFlag", @@ -927,6 +1005,786 @@ "ShowSummary": "Y", "RetainHiddenValue": "Yes" }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageFlags", + "CaseFieldID": "representativeFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "createFlag", + "CaseFieldID": "representativeFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageFlags", + "CaseFieldID": "representative1Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "createFlag", + "CaseFieldID": "representative1Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageFlags", + "CaseFieldID": "representative2Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "createFlag", + "CaseFieldID": "representative2Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageFlags", + "CaseFieldID": "representative3Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "createFlag", + "CaseFieldID": "representative3Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageFlags", + "CaseFieldID": "representative4Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "createFlag", + "CaseFieldID": "representative4Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageFlags", + "CaseFieldID": "representative5Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "createFlag", + "CaseFieldID": "representative5Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageFlags", + "CaseFieldID": "representative6Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "createFlag", + "CaseFieldID": "representative6Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageFlags", + "CaseFieldID": "representative7Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "createFlag", + "CaseFieldID": "representative7Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageFlags", + "CaseFieldID": "representative8Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "createFlag", + "CaseFieldID": "representative8Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageFlags", + "CaseFieldID": "representative9Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "createFlag", + "CaseFieldID": "representative9Flags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageFlags", + "CaseFieldID": "representativeExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "createFlag", + "CaseFieldID": "representativeExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageFlags", + "CaseFieldID": "representative1ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "createFlag", + "CaseFieldID": "representative1ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageFlags", + "CaseFieldID": "representative2ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "createFlag", + "CaseFieldID": "representative2ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageFlags", + "CaseFieldID": "representative3ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "createFlag", + "CaseFieldID": "representative3ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageFlags", + "CaseFieldID": "representative4ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "createFlag", + "CaseFieldID": "representative4ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageFlags", + "CaseFieldID": "representative5ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "createFlag", + "CaseFieldID": "representative5ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageFlags", + "CaseFieldID": "representative6ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "createFlag", + "CaseFieldID": "representative6ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageFlags", + "CaseFieldID": "representative7ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "createFlag", + "CaseFieldID": "representative7ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageFlags", + "CaseFieldID": "representative8ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "createFlag", + "CaseFieldID": "representative8ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageFlags", + "CaseFieldID": "representative9ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "createFlag", + "CaseFieldID": "representative9ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageSupport", + "CaseFieldID": "representativeExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "requestSupport", + "CaseFieldID": "representativeExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageSupport", + "CaseFieldID": "representative1ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "requestSupport", + "CaseFieldID": "representative1ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageSupport", + "CaseFieldID": "representative2ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "requestSupport", + "CaseFieldID": "representative2ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageSupport", + "CaseFieldID": "representative3ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "requestSupport", + "CaseFieldID": "representative3ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageSupport", + "CaseFieldID": "representative4ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "requestSupport", + "CaseFieldID": "representative4ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageSupport", + "CaseFieldID": "representative5ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "requestSupport", + "CaseFieldID": "representative5ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageSupport", + "CaseFieldID": "representative6ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "requestSupport", + "CaseFieldID": "representative6ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageSupport", + "CaseFieldID": "representative7ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "requestSupport", + "CaseFieldID": "representative7ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageSupport", + "CaseFieldID": "representative8ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "requestSupport", + "CaseFieldID": "representative8ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageSupport", + "CaseFieldID": "representative9ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 5, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "requestSupport", + "CaseFieldID": "representative9ExternalFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 3, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "Y", + "ShowSummary": "Y", + "RetainHiddenValue": "Yes" + }, { "CaseTypeID": "ET_Scotland", "CaseEventID": "createCaseLink", diff --git a/ccd-definitions/jurisdictions/scotland/json/CaseField/CaseField-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/scotland/json/CaseField/CaseField-CaseFlagsCaseLinking.json index 68679450c8..dfb21555fb 100644 --- a/ccd-definitions/jurisdictions/scotland/json/CaseField/CaseField-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/scotland/json/CaseField/CaseField-CaseFlagsCaseLinking.json @@ -20,6 +20,20 @@ "FieldType": "Flags", "SecurityClassification": "Public" }, + { + "CaseTypeID": "ET_Scotland", + "ID": "claimantRepresentativeFlags", + "Label": "Claimant Representative Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_Scotland", + "ID": "claimantRepresentativeExternalFlags", + "Label": "Claimant Representative External Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, { "CaseTypeID": "ET_Scotland", "ID": "flagLauncher", @@ -175,6 +189,146 @@ "FieldType": "Flags", "SecurityClassification": "Public" }, + { + "CaseTypeID": "ET_Scotland", + "ID": "representativeFlags", + "Label": "Representative Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_Scotland", + "ID": "representative1Flags", + "Label": "Representative 1 Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_Scotland", + "ID": "representative2Flags", + "Label": "Representative 2 Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_Scotland", + "ID": "representative3Flags", + "Label": "Representative 3 Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_Scotland", + "ID": "representative4Flags", + "Label": "Representative 4 Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_Scotland", + "ID": "representative5Flags", + "Label": "Representative 5 Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_Scotland", + "ID": "representative6Flags", + "Label": "Representative 6 Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_Scotland", + "ID": "representative7Flags", + "Label": "Representative 7 Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_Scotland", + "ID": "representative8Flags", + "Label": "Representative 8 Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_Scotland", + "ID": "representative9Flags", + "Label": "Representative 9 Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_Scotland", + "ID": "representativeExternalFlags", + "Label": "Representative External Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_Scotland", + "ID": "representative1ExternalFlags", + "Label": "Representative 1 External Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_Scotland", + "ID": "representative2ExternalFlags", + "Label": "Representative 2 External Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_Scotland", + "ID": "representative3ExternalFlags", + "Label": "Representative 3 External Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_Scotland", + "ID": "representative4ExternalFlags", + "Label": "Representative 4 External Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_Scotland", + "ID": "representative5ExternalFlags", + "Label": "Representative 5 External Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_Scotland", + "ID": "representative6ExternalFlags", + "Label": "Representative 6 External Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_Scotland", + "ID": "representative7ExternalFlags", + "Label": "Representative 7 External Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_Scotland", + "ID": "representative8ExternalFlags", + "Label": "Representative 8 External Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, + { + "CaseTypeID": "ET_Scotland", + "ID": "representative9ExternalFlags", + "Label": "Representative 9 External Flags", + "FieldType": "Flags", + "SecurityClassification": "Public" + }, { "LiveFrom": "10/02/2023", "CaseTypeID": "ET_Scotland", diff --git a/ccd-definitions/jurisdictions/scotland/json/CaseTypeTab/CaseTypeTab-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/scotland/json/CaseTypeTab/CaseTypeTab-CaseFlagsCaseLinking.json index 6ba382ef87..39139b33a1 100644 --- a/ccd-definitions/jurisdictions/scotland/json/CaseTypeTab/CaseTypeTab-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/scotland/json/CaseTypeTab/CaseTypeTab-CaseFlagsCaseLinking.json @@ -57,6 +57,16 @@ "TabLabel": "Case Flags", "TabFieldDisplayOrder": 1 }, + { + "CaseFieldID": "claimantRepresentativeFlags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 69, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 1 + }, { "CaseFieldID": "respondentFlags", "CaseTypeID": "ET_Scotland", @@ -157,6 +167,106 @@ "TabLabel": "Case Flags", "TabFieldDisplayOrder": 11 }, + { + "CaseFieldID": "representativeFlags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 2 + }, + { + "CaseFieldID": "representative1Flags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 3 + }, + { + "CaseFieldID": "representative2Flags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 4 + }, + { + "CaseFieldID": "representative3Flags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 5 + }, + { + "CaseFieldID": "representative4Flags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 6 + }, + { + "CaseFieldID": "representative5Flags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 7 + }, + { + "CaseFieldID": "representative6Flags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 8 + }, + { + "CaseFieldID": "representative7Flags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 9 + }, + { + "CaseFieldID": "representative8Flags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 10 + }, + { + "CaseFieldID": "representative9Flags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncher=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 11 + }, { "CaseFieldID": "claimantExternalFlags", "CaseTypeID": "ET_Scotland", @@ -167,6 +277,16 @@ "TabLabel": "Case Flags", "TabFieldDisplayOrder": 1 }, + { + "CaseFieldID": "claimantRepresentativeExternalFlags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 69, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 1 + }, { "CaseFieldID": "respondentExternalFlags", "CaseTypeID": "ET_Scotland", @@ -267,6 +387,106 @@ "TabLabel": "Case Flags", "TabFieldDisplayOrder": 11 }, + { + "CaseFieldID": "representativeExternalFlags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 2 + }, + { + "CaseFieldID": "representative1ExternalFlags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 3 + }, + { + "CaseFieldID": "representative2ExternalFlags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 4 + }, + { + "CaseFieldID": "representative3ExternalFlags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 5 + }, + { + "CaseFieldID": "representative4ExternalFlags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 6 + }, + { + "CaseFieldID": "representative5ExternalFlags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 7 + }, + { + "CaseFieldID": "representative6ExternalFlags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 8 + }, + { + "CaseFieldID": "representative7ExternalFlags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 9 + }, + { + "CaseFieldID": "representative8ExternalFlags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 10 + }, + { + "CaseFieldID": "representative9ExternalFlags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "caseFlags", + "TabLabel": "Case Flags", + "TabFieldDisplayOrder": 11 + }, { "CaseFieldID": "flagLauncherExternal", "CaseTypeID": "ET_Scotland", @@ -288,6 +508,16 @@ "TabLabel": "Support", "TabFieldDisplayOrder": 1 }, + { + "CaseFieldID": "claimantRepresentativeExternalFlags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 69, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 1 + }, { "CaseFieldID": "respondentExternalFlags", "CaseTypeID": "ET_Scotland", @@ -387,5 +617,105 @@ "TabID": "support", "TabLabel": "Support", "TabFieldDisplayOrder": 11 + }, + { + "CaseFieldID": "representativeExternalFlags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 2 + }, + { + "CaseFieldID": "representative1ExternalFlags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 3 + }, + { + "CaseFieldID": "representative2ExternalFlags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 4 + }, + { + "CaseFieldID": "representative3ExternalFlags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 5 + }, + { + "CaseFieldID": "representative4ExternalFlags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 6 + }, + { + "CaseFieldID": "representative5ExternalFlags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 7 + }, + { + "CaseFieldID": "representative6ExternalFlags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 8 + }, + { + "CaseFieldID": "representative7ExternalFlags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 9 + }, + { + "CaseFieldID": "representative8ExternalFlags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 10 + }, + { + "CaseFieldID": "representative9ExternalFlags", + "CaseTypeID": "ET_Scotland", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 11 } ] diff --git a/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/CaseData.java b/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/CaseData.java index cc6bbca6d3..81eabc6c81 100644 --- a/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/CaseData.java +++ b/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/CaseData.java @@ -1581,7 +1581,28 @@ public class CaseData extends Et1CaseData { private CaseFlagsType respondent8ExternalFlags; private CaseFlagsType respondent9Flags; private CaseFlagsType respondent9ExternalFlags; - + private CaseFlagsType claimantRepresentativeFlags; + private CaseFlagsType claimantRepresentativeExternalFlags; + private CaseFlagsType representativeFlags; + private CaseFlagsType representativeExternalFlags; + private CaseFlagsType representative1Flags; + private CaseFlagsType representative1ExternalFlags; + private CaseFlagsType representative2Flags; + private CaseFlagsType representative2ExternalFlags; + private CaseFlagsType representative3Flags; + private CaseFlagsType representative3ExternalFlags; + private CaseFlagsType representative4Flags; + private CaseFlagsType representative4ExternalFlags; + private CaseFlagsType representative5Flags; + private CaseFlagsType representative5ExternalFlags; + private CaseFlagsType representative6Flags; + private CaseFlagsType representative6ExternalFlags; + private CaseFlagsType representative7Flags; + private CaseFlagsType representative7ExternalFlags; + private CaseFlagsType representative8Flags; + private CaseFlagsType representative8ExternalFlags; + private CaseFlagsType representative9Flags; + private CaseFlagsType representative9ExternalFlags; //et-hearings-api @JsonProperty("autoListFlag") diff --git a/src/cftlib/resources/compose/mocks/wiremock/__files/prd/accountIdByEmailResponse.json b/src/cftlib/resources/compose/mocks/wiremock/__files/prd/accountIdByEmailResponse.json new file mode 100644 index 0000000000..fdd40175d0 --- /dev/null +++ b/src/cftlib/resources/compose/mocks/wiremock/__files/prd/accountIdByEmailResponse.json @@ -0,0 +1,4 @@ +{ + "idamStatus": "ACTIVE", + "userIdentifier": "112b0bdd-5e58-32f1-8c51-6e71f5f90bc5" +} diff --git a/src/cftlib/resources/compose/mocks/wiremock/mappings/prd/accountIdByEmailRequest.json b/src/cftlib/resources/compose/mocks/wiremock/mappings/prd/accountIdByEmailRequest.json new file mode 100644 index 0000000000..85030a622d --- /dev/null +++ b/src/cftlib/resources/compose/mocks/wiremock/mappings/prd/accountIdByEmailRequest.json @@ -0,0 +1,18 @@ +{ + "request": { + "method": "GET", + "urlPath": "/refdata/external/v1/organisations/users/accountId", + "queryParameters": { + "email": { + "matches": "solicitor1@etorganisation1.com" + } + } + }, + "response": { + "status": 200, + "headers": { + "Content-Type": "application/json" + }, + "bodyFileName": "prd/accountIdByEmailResponse.json" + } +} diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeController.java index fba00acf37..f938f449fe 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeController.java @@ -20,10 +20,13 @@ import uk.gov.hmcts.et.common.model.ccd.CaseData; import uk.gov.hmcts.ethos.replacement.docmosis.exceptions.CcdInputOutputException; import uk.gov.hmcts.ethos.replacement.docmosis.service.AddAmendClaimantRepresentativeService; +import uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService; +import uk.gov.hmcts.ethos.replacement.docmosis.service.FeatureToggleService; import uk.gov.hmcts.ethos.replacement.docmosis.service.NocClaimantRepresentativeService; import uk.gov.hmcts.ethos.replacement.docmosis.service.UserIdamService; import java.io.IOException; + import static org.springframework.util.MimeTypeUtils.APPLICATION_JSON_VALUE; import static uk.gov.hmcts.ethos.replacement.docmosis.helpers.CallbackRespHelper.getCallbackRespEntityNoErrors; @@ -39,6 +42,8 @@ public class AddAmendClaimantRepresentativeController { private final AddAmendClaimantRepresentativeService addAmendClaimantRepresentativeService; private final NocClaimantRepresentativeService nocClaimantRepresentativeService; private final UserIdamService userIdamService; + private final FeatureToggleService featureToggleService; + private final CaseFlagsService caseFlagsService; /** * AboutToSubmit for addAmendClaimantRepresentative. Sets the claimant rep's id. @@ -72,16 +77,24 @@ public ResponseEntity aboutToSubmit( @ApiResponse(responseCode = "400", description = "Bad Request"), @ApiResponse(responseCode = "500", description = "Internal Server Error") }) - public void amendClaimantRepSubmitted( + public ResponseEntity amendClaimantRepSubmitted( @RequestBody CallbackRequest callbackRequest, @RequestHeader(HttpHeaders.AUTHORIZATION) String userToken) { log.info("AMEND CLAIMANT REPRESENTATIVE SUBMITTED ---> " + LOG_MESSAGE + "{}", callbackRequest.getCaseDetails().getCaseId()); + CaseData caseData = callbackRequest.getCaseDetails().getCaseData(); + try { nocClaimantRepresentativeService.updateClaimantRepAccess(callbackRequest); + + if (featureToggleService.isCaseFlagsEnabled()) { + caseFlagsService.setupCaseFlags(caseData); + } } catch (IOException e) { throw new CcdInputOutputException("Failed to update claimant representatives access", e); } + + return getCallbackRespEntityNoErrors(caseData); } } diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java index c4d1c77069..b99499a7ae 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java @@ -447,7 +447,10 @@ public ResponseEntity amendClaimantDetails( caseManagementForCaseWorkerService.setPublicCaseName(caseData); } - caseFlagsService.setupCaseFlags(caseData); + if (featureToggleService.isCaseFlagsEnabled()) { + caseFlagsService.setupCaseFlags(caseData); + } + caseManagementForCaseWorkerService.setNextListedDate(caseData); removeSpacesFromPartyNames(caseData); return getCallbackRespEntityNoErrors(caseData); @@ -500,7 +503,10 @@ public ResponseEntity amendRespondentDetails( caseManagementForCaseWorkerService.setPublicCaseName(caseData); } - caseFlagsService.setupCaseFlags(caseData); + if (featureToggleService.isCaseFlagsEnabled()) { + caseFlagsService.setupCaseFlags(caseData); + } + caseManagementForCaseWorkerService.updateWorkAllocationField(errors, caseData); removeSpacesFromPartyNames(caseData); @@ -536,6 +542,10 @@ public ResponseEntity amendRespondentRepresentative( if (featureToggleService.isHmcEnabled()) { nocRespondentRepresentativeService.updateNonMyHmctsOrgIds(caseData.getRepCollection()); } + + if (featureToggleService.isCaseFlagsEnabled()) { + caseFlagsService.setupCaseFlags(caseData); + } } log.info(EVENT_FIELDS_VALIDATION + errors); diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/NoticeOfChangeController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/NoticeOfChangeController.java index 748cab27b7..0aa741d8da 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/NoticeOfChangeController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/NoticeOfChangeController.java @@ -17,7 +17,9 @@ import uk.gov.hmcts.et.common.model.ccd.CallbackRequest; import uk.gov.hmcts.et.common.model.ccd.CaseData; import uk.gov.hmcts.et.common.model.ccd.CaseDetails; +import uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService; import uk.gov.hmcts.ethos.replacement.docmosis.service.CcdCaseAssignment; +import uk.gov.hmcts.ethos.replacement.docmosis.service.FeatureToggleService; import uk.gov.hmcts.ethos.replacement.docmosis.service.NocNotificationService; import uk.gov.hmcts.ethos.replacement.docmosis.service.NocRepresentativeService; import uk.gov.hmcts.ethos.replacement.docmosis.service.UserIdamService; @@ -38,6 +40,8 @@ public class NoticeOfChangeController { private final NocRepresentativeService noCRepresentativeService; private final CcdCaseAssignment ccdCaseAssignment; private final UserIdamService userIdamService; + private final FeatureToggleService featureToggleService; + private final CaseFlagsService caseFlagsService; private static final String INVALID_TOKEN = "Invalid Token {}"; private static final String APPLY_NOC_DECISION = "applyNocDecision"; @@ -53,6 +57,11 @@ public ResponseEntity handleAboutToSubmit( CaseData caseData = noCRepresentativeService .updateRepresentation(callbackRequest.getCaseDetails(), userToken); + + if (featureToggleService.isCaseFlagsEnabled()) { + caseFlagsService.setupCaseFlags(caseData); + } + callbackRequest.getCaseDetails().setCaseData(caseData); return ResponseEntity.ok(ccdCaseAssignment.applyNoc(callbackRequest, userToken)); } diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java index ab096a094f..1624a01aea 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java @@ -16,6 +16,8 @@ import java.util.Arrays; import java.util.List; import java.util.Objects; +import java.util.function.BiConsumer; +import java.util.function.Function; import javax.annotation.Nullable; import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.ACTIVE; @@ -31,92 +33,125 @@ @Service public class CaseFlagsService { private static final String GRANTED = "Granted"; - - public static final String INTERNAL = "Internal"; - public static final String EXTERNAL = "External"; - public static final String CLAIMANT = "Claimant"; - public static final String RESPONDENT1 = "Respondent 1"; - public static final String RESPONDENT2 = "Respondent 2"; - public static final String RESPONDENT3 = "Respondent 3"; - public static final String RESPONDENT4 = "Respondent 4"; - public static final String RESPONDENT5 = "Respondent 5"; - public static final String RESPONDENT6 = "Respondent 6"; - public static final String RESPONDENT7 = "Respondent 7"; - public static final String RESPONDENT8 = "Respondent 8"; - public static final String RESPONDENT9 = "Respondent 9"; - public static final String RESPONDENT10 = "Respondent 10"; + private static final int NOT_INDEXED = -1; + + public static final String INTERNAL = "Internal"; + public static final String EXTERNAL = "External"; + public static final String CLAIMANT = "Claimant"; + public static final String RESPONDENT1 = "Respondent 1"; + public static final String RESPONDENT2 = "Respondent 2"; + public static final String RESPONDENT3 = "Respondent 3"; + public static final String RESPONDENT4 = "Respondent 4"; + public static final String RESPONDENT5 = "Respondent 5"; + public static final String RESPONDENT6 = "Respondent 6"; + public static final String RESPONDENT7 = "Respondent 7"; + public static final String RESPONDENT8 = "Respondent 8"; + public static final String RESPONDENT9 = "Respondent 9"; + public static final String RESPONDENT10 = "Respondent 10"; + public static final String CLAIMANT_REPRESENTATIVE = "Claimant Representative"; + public static final String REPRESENTATIVE1 = "Representative 1"; + public static final String REPRESENTATIVE2 = "Representative 2"; + public static final String REPRESENTATIVE3 = "Representative 3"; + public static final String REPRESENTATIVE4 = "Representative 4"; + public static final String REPRESENTATIVE5 = "Representative 5"; + public static final String REPRESENTATIVE6 = "Representative 6"; + public static final String REPRESENTATIVE7 = "Representative 7"; + public static final String REPRESENTATIVE8 = "Representative 8"; + public static final String REPRESENTATIVE9 = "Representative 9"; + public static final String REPRESENTATIVE10 = "Representative 10"; + + private static final List PARTY_FLAGS = List.of( + claimantFlag(CaseData::getClaimantFlags, CaseData::setClaimantFlags, INTERNAL), + claimantFlag(CaseData::getClaimantExternalFlags, CaseData::setClaimantExternalFlags, EXTERNAL), + + respondentFlag(CaseData::getRespondentFlags, CaseData::setRespondentFlags, RESPONDENT1, INTERNAL, 0), + respondentFlag(CaseData::getRespondentExternalFlags, CaseData::setRespondentExternalFlags, + RESPONDENT1, EXTERNAL, 0), + respondentFlag(CaseData::getRespondent1Flags, CaseData::setRespondent1Flags, RESPONDENT2, INTERNAL, 1), + respondentFlag(CaseData::getRespondent1ExternalFlags, CaseData::setRespondent1ExternalFlags, + RESPONDENT2, EXTERNAL, 1), + respondentFlag(CaseData::getRespondent2Flags, CaseData::setRespondent2Flags, RESPONDENT3, INTERNAL, 2), + respondentFlag(CaseData::getRespondent2ExternalFlags, CaseData::setRespondent2ExternalFlags, + RESPONDENT3, EXTERNAL, 2), + respondentFlag(CaseData::getRespondent3Flags, CaseData::setRespondent3Flags, RESPONDENT4, INTERNAL, 3), + respondentFlag(CaseData::getRespondent3ExternalFlags, CaseData::setRespondent3ExternalFlags, + RESPONDENT4, EXTERNAL, 3), + respondentFlag(CaseData::getRespondent4Flags, CaseData::setRespondent4Flags, RESPONDENT5, INTERNAL, 4), + respondentFlag(CaseData::getRespondent4ExternalFlags, CaseData::setRespondent4ExternalFlags, + RESPONDENT5, EXTERNAL, 4), + respondentFlag(CaseData::getRespondent5Flags, CaseData::setRespondent5Flags, RESPONDENT6, INTERNAL, 5), + respondentFlag(CaseData::getRespondent5ExternalFlags, CaseData::setRespondent5ExternalFlags, + RESPONDENT6, EXTERNAL, 5), + respondentFlag(CaseData::getRespondent6Flags, CaseData::setRespondent6Flags, RESPONDENT7, INTERNAL, 6), + respondentFlag(CaseData::getRespondent6ExternalFlags, CaseData::setRespondent6ExternalFlags, + RESPONDENT7, EXTERNAL, 6), + respondentFlag(CaseData::getRespondent7Flags, CaseData::setRespondent7Flags, RESPONDENT8, INTERNAL, 7), + respondentFlag(CaseData::getRespondent7ExternalFlags, CaseData::setRespondent7ExternalFlags, + RESPONDENT8, EXTERNAL, 7), + respondentFlag(CaseData::getRespondent8Flags, CaseData::setRespondent8Flags, RESPONDENT9, INTERNAL, 8), + respondentFlag(CaseData::getRespondent8ExternalFlags, CaseData::setRespondent8ExternalFlags, + RESPONDENT9, EXTERNAL, 8), + respondentFlag(CaseData::getRespondent9Flags, CaseData::setRespondent9Flags, RESPONDENT10, + INTERNAL, 9), + respondentFlag(CaseData::getRespondent9ExternalFlags, CaseData::setRespondent9ExternalFlags, + RESPONDENT10, EXTERNAL, 9), + + claimantRepresentativeFlag(CaseData::getClaimantRepresentativeFlags, + CaseData::setClaimantRepresentativeFlags, INTERNAL), + claimantRepresentativeFlag(CaseData::getClaimantRepresentativeExternalFlags, + CaseData::setClaimantRepresentativeExternalFlags, EXTERNAL), + + representativeFlag(CaseData::getRepresentativeFlags, CaseData::setRepresentativeFlags, + REPRESENTATIVE1, INTERNAL, 0), + representativeFlag(CaseData::getRepresentativeExternalFlags, CaseData::setRepresentativeExternalFlags, + REPRESENTATIVE1, EXTERNAL, 0), + representativeFlag(CaseData::getRepresentative1Flags, CaseData::setRepresentative1Flags, + REPRESENTATIVE2, INTERNAL, 1), + representativeFlag(CaseData::getRepresentative1ExternalFlags, CaseData::setRepresentative1ExternalFlags, + REPRESENTATIVE2, EXTERNAL, 1), + representativeFlag(CaseData::getRepresentative2Flags, CaseData::setRepresentative2Flags, + REPRESENTATIVE3, INTERNAL, 2), + representativeFlag(CaseData::getRepresentative2ExternalFlags, CaseData::setRepresentative2ExternalFlags, + REPRESENTATIVE3, EXTERNAL, 2), + representativeFlag(CaseData::getRepresentative3Flags, CaseData::setRepresentative3Flags, + REPRESENTATIVE4, INTERNAL, 3), + representativeFlag(CaseData::getRepresentative3ExternalFlags, CaseData::setRepresentative3ExternalFlags, + REPRESENTATIVE4, EXTERNAL, 3), + representativeFlag(CaseData::getRepresentative4Flags, CaseData::setRepresentative4Flags, + REPRESENTATIVE5, INTERNAL, 4), + representativeFlag(CaseData::getRepresentative4ExternalFlags, CaseData::setRepresentative4ExternalFlags, + REPRESENTATIVE5, EXTERNAL, 4), + representativeFlag(CaseData::getRepresentative5Flags, CaseData::setRepresentative5Flags, + REPRESENTATIVE6, INTERNAL, 5), + representativeFlag(CaseData::getRepresentative5ExternalFlags, CaseData::setRepresentative5ExternalFlags, + REPRESENTATIVE6, EXTERNAL, 5), + representativeFlag(CaseData::getRepresentative6Flags, CaseData::setRepresentative6Flags, + REPRESENTATIVE7, INTERNAL, 6), + representativeFlag(CaseData::getRepresentative6ExternalFlags, CaseData::setRepresentative6ExternalFlags, + REPRESENTATIVE7, EXTERNAL, 6), + representativeFlag(CaseData::getRepresentative7Flags, CaseData::setRepresentative7Flags, + REPRESENTATIVE8, INTERNAL, 7), + representativeFlag(CaseData::getRepresentative7ExternalFlags, CaseData::setRepresentative7ExternalFlags, + REPRESENTATIVE8, EXTERNAL, 7), + representativeFlag(CaseData::getRepresentative8Flags, CaseData::setRepresentative8Flags, + REPRESENTATIVE9, INTERNAL, 8), + representativeFlag(CaseData::getRepresentative8ExternalFlags, CaseData::setRepresentative8ExternalFlags, + REPRESENTATIVE9, EXTERNAL, 8), + representativeFlag(CaseData::getRepresentative9Flags, CaseData::setRepresentative9Flags, + REPRESENTATIVE10, INTERNAL, 9), + representativeFlag(CaseData::getRepresentative9ExternalFlags, CaseData::setRepresentative9ExternalFlags, + REPRESENTATIVE10, EXTERNAL, 9) + ); public boolean caseFlagsSetupRequired(CaseData caseData) { - return (caseData.getCaseFlags() == null - || caseData.getClaimantFlags() == null - || StringUtils.isEmpty(caseData.getClaimantFlags().getRoleOnCase()) - || caseData.getClaimantExternalFlags() == null - || StringUtils.isEmpty(caseData.getClaimantExternalFlags().getRoleOnCase()) - || (!caseData.getRespondentCollection().isEmpty() - && (caseData.getRespondentFlags() == null - || StringUtils.isEmpty(caseData.getRespondentFlags().getRoleOnCase()))) - || (!caseData.getRespondentCollection().isEmpty() - && (caseData.getRespondentExternalFlags() == null - || StringUtils.isEmpty(caseData.getRespondentExternalFlags().getRoleOnCase()))) - || (caseData.getRespondentCollection().size() > 1 - && (caseData.getRespondent1Flags() == null - || StringUtils.isEmpty(caseData.getRespondent1Flags().getRoleOnCase()))) - || (caseData.getRespondentCollection().size() > 1 - && (caseData.getRespondent1ExternalFlags() == null - || StringUtils.isEmpty(caseData.getRespondent1ExternalFlags().getRoleOnCase()))) - || (caseData.getRespondentCollection().size() > 2 - && (caseData.getRespondent2Flags() == null - || StringUtils.isEmpty(caseData.getRespondent2Flags().getRoleOnCase()))) - || (caseData.getRespondentCollection().size() > 2 - && (caseData.getRespondent2ExternalFlags() == null - || StringUtils.isEmpty(caseData.getRespondent2ExternalFlags().getRoleOnCase()))) - || (caseData.getRespondentCollection().size() > 3 - && (caseData.getRespondent3Flags() == null - || StringUtils.isEmpty(caseData.getRespondent3Flags().getRoleOnCase()))) - || (caseData.getRespondentCollection().size() > 3 - && (caseData.getRespondent3ExternalFlags() == null - || StringUtils.isEmpty(caseData.getRespondent3ExternalFlags().getRoleOnCase()))) - || (caseData.getRespondentCollection().size() > 4 - && (caseData.getRespondent4Flags() == null - || StringUtils.isEmpty(caseData.getRespondent4Flags().getRoleOnCase()))) - || (caseData.getRespondentCollection().size() > 4 - && (caseData.getRespondent4ExternalFlags() == null - || StringUtils.isEmpty(caseData.getRespondent4ExternalFlags().getRoleOnCase()))) - || (caseData.getRespondentCollection().size() > 5 - && (caseData.getRespondent5Flags() == null - || StringUtils.isEmpty(caseData.getRespondent5Flags().getRoleOnCase()))) - || (caseData.getRespondentCollection().size() > 5 - && (caseData.getRespondent5ExternalFlags() == null - || StringUtils.isEmpty(caseData.getRespondent5ExternalFlags().getRoleOnCase()))) - || (caseData.getRespondentCollection().size() > 6 - && (caseData.getRespondent6Flags() == null - || StringUtils.isEmpty(caseData.getRespondent6Flags().getRoleOnCase()))) - || (caseData.getRespondentCollection().size() > 6 - && (caseData.getRespondent6ExternalFlags() == null - || StringUtils.isEmpty(caseData.getRespondent6ExternalFlags().getRoleOnCase()))) - || (caseData.getRespondentCollection().size() > 7 - && (caseData.getRespondent7Flags() == null - || StringUtils.isEmpty(caseData.getRespondent7Flags().getRoleOnCase()))) - || (caseData.getRespondentCollection().size() > 7 - && (caseData.getRespondent7ExternalFlags() == null - || StringUtils.isEmpty(caseData.getRespondent7ExternalFlags().getRoleOnCase()))) - || (caseData.getRespondentCollection().size() > 8 - && (caseData.getRespondent8Flags() == null - || StringUtils.isEmpty(caseData.getRespondent8Flags().getRoleOnCase()))) - || (caseData.getRespondentCollection().size() > 8 - && (caseData.getRespondent8ExternalFlags() == null - || StringUtils.isEmpty(caseData.getRespondent8ExternalFlags().getRoleOnCase()))) - || (caseData.getRespondentCollection().size() > 9 - && (caseData.getRespondent9Flags() == null - || StringUtils.isEmpty(caseData.getRespondent9Flags().getRoleOnCase()))) - || (caseData.getRespondentCollection().size() > 9 - && (caseData.getRespondent9ExternalFlags() == null - || StringUtils.isEmpty(caseData.getRespondent9ExternalFlags().getRoleOnCase()))) - ); + return caseData.getCaseFlags() == null + || PARTY_FLAGS.stream() + .filter(flag -> isRequired(caseData, flag)) + .anyMatch(flag -> isMissingRole(caseData, flag)); } /** - * Setup case flags for Claimant, Respondent and Case level. + * Setup case flags for Claimant, Respondent, Representative and Case level. * * @param caseData Data about the current case */ @@ -125,352 +160,19 @@ public void setupCaseFlags(CaseData caseData) { caseData.setCaseFlags(CaseFlagsType.builder().build()); } - if (caseData.getClaimantFlags() == null - || StringUtils.isEmpty(caseData.getClaimantFlags().getRoleOnCase())) { - caseData.setClaimantFlags(CaseFlagsType.builder() - .partyName(caseData.getClaimant()) - .roleOnCase(CLAIMANT) - .groupId(CLAIMANT) - .visibility(INTERNAL) - .build() - ); - } else if (!caseData.getClaimant().equals(caseData.getClaimantFlags().getPartyName())) { - caseData.getClaimantFlags().setPartyName(caseData.getClaimant()); - } - - if (caseData.getClaimantExternalFlags() == null - || StringUtils.isEmpty(caseData.getClaimantExternalFlags().getRoleOnCase())) { - caseData.setClaimantExternalFlags(CaseFlagsType.builder() - .partyName(caseData.getClaimant()) - .roleOnCase(CLAIMANT) - .groupId(CLAIMANT) - .visibility(EXTERNAL) - .build() - ); - } else if (!caseData.getClaimant().equals(caseData.getClaimantExternalFlags().getPartyName())) { - caseData.getClaimantExternalFlags().setPartyName(caseData.getClaimant()); - } - - if (!caseData.getRespondentCollection().isEmpty()) { - String respondent = caseData.getRespondentCollection().getFirst().getValue().getRespondentName(); - if (caseData.getRespondentFlags() == null - || StringUtils.isEmpty(caseData.getRespondentFlags().getRoleOnCase())) { - caseData.setRespondentFlags(CaseFlagsType.builder() - .partyName(respondent) - .roleOnCase(RESPONDENT1) - .groupId(RESPONDENT1) - .visibility(INTERNAL) - .build() - ); - } else if (!respondent.equals(caseData.getRespondentFlags().getPartyName())) { - caseData.getRespondentFlags().setPartyName(respondent); - } - - if (caseData.getRespondentExternalFlags() == null - || StringUtils.isEmpty(caseData.getRespondentExternalFlags().getRoleOnCase())) { - caseData.setRespondentExternalFlags(CaseFlagsType.builder() - .partyName(respondent) - .roleOnCase(RESPONDENT1) - .groupId(RESPONDENT1) - .visibility(EXTERNAL) - .build() - ); - } else if (!respondent.equals(caseData.getRespondentExternalFlags().getPartyName())) { - caseData.getRespondentExternalFlags().setPartyName(respondent); - } - } - - if (caseData.getRespondentCollection().size() > 1) { - String respondent = caseData.getRespondentCollection().get(1).getValue().getRespondentName(); - if (caseData.getRespondent1Flags() == null - || StringUtils.isEmpty(caseData.getRespondent1Flags().getRoleOnCase())) { - caseData.setRespondent1Flags(CaseFlagsType.builder() - .partyName(respondent) - .roleOnCase(RESPONDENT2) - .groupId(RESPONDENT2) - .visibility(INTERNAL) - .build() - ); - } else if (!respondent.equals(caseData.getRespondent1Flags().getPartyName())) { - caseData.getRespondent1Flags().setPartyName(respondent); - } - - if (caseData.getRespondent1ExternalFlags() == null - || StringUtils.isEmpty(caseData.getRespondent1ExternalFlags().getRoleOnCase())) { - caseData.setRespondent1ExternalFlags(CaseFlagsType.builder() - .partyName(respondent) - .roleOnCase(RESPONDENT2) - .groupId(RESPONDENT2) - .visibility(EXTERNAL) - .build() - ); - } else if (!respondent.equals(caseData.getRespondent1ExternalFlags().getPartyName())) { - caseData.getRespondent1ExternalFlags().setPartyName(respondent); - } - } - - if (caseData.getRespondentCollection().size() > 2) { - String respondent = caseData.getRespondentCollection().get(2).getValue().getRespondentName(); - if (caseData.getRespondent2Flags() == null - || StringUtils.isEmpty(caseData.getRespondent2Flags().getRoleOnCase())) { - caseData.setRespondent2Flags(CaseFlagsType.builder() - .partyName(respondent) - .roleOnCase(RESPONDENT3) - .groupId(RESPONDENT3) - .visibility(INTERNAL) - .build() - ); - } else if (!respondent.equals(caseData.getRespondent2Flags().getPartyName())) { - caseData.getRespondent2Flags().setPartyName(respondent); - } - - if (caseData.getRespondent2ExternalFlags() == null - || StringUtils.isEmpty(caseData.getRespondent2ExternalFlags().getRoleOnCase())) { - caseData.setRespondent2ExternalFlags(CaseFlagsType.builder() - .partyName(respondent) - .roleOnCase(RESPONDENT3) - .groupId(RESPONDENT3) - .visibility(EXTERNAL) - .build() - ); - } else if (!respondent.equals(caseData.getRespondent2ExternalFlags().getPartyName())) { - caseData.getRespondent2ExternalFlags().setPartyName(respondent); - } - } - - if (caseData.getRespondentCollection().size() > 3) { - String respondent = caseData.getRespondentCollection().get(3).getValue().getRespondentName(); - if (caseData.getRespondent3Flags() == null - || StringUtils.isEmpty(caseData.getRespondent3Flags().getRoleOnCase())) { - caseData.setRespondent3Flags(CaseFlagsType.builder() - .partyName(respondent) - .roleOnCase(RESPONDENT4) - .groupId(RESPONDENT4) - .visibility(INTERNAL) - .build() - ); - } else if (!respondent.equals(caseData.getRespondent3Flags().getPartyName())) { - caseData.getRespondent3Flags().setPartyName(respondent); - } - - if (caseData.getRespondent3ExternalFlags() == null - || StringUtils.isEmpty(caseData.getRespondent3ExternalFlags().getRoleOnCase())) { - caseData.setRespondent3ExternalFlags(CaseFlagsType.builder() - .partyName(respondent) - .roleOnCase(RESPONDENT4) - .groupId(RESPONDENT4) - .visibility(EXTERNAL) - .build() - ); - } else if (!respondent.equals(caseData.getRespondent3ExternalFlags().getPartyName())) { - caseData.getRespondent3ExternalFlags().setPartyName(respondent); - } - } - - if (caseData.getRespondentCollection().size() > 4) { - String respondent = caseData.getRespondentCollection().get(4).getValue().getRespondentName(); - if (caseData.getRespondent4Flags() == null - || StringUtils.isEmpty(caseData.getRespondent4Flags().getRoleOnCase())) { - caseData.setRespondent4Flags(CaseFlagsType.builder() - .partyName(respondent) - .roleOnCase(RESPONDENT5) - .groupId(RESPONDENT5) - .visibility(INTERNAL) - .build() - ); - } else if (!respondent.equals(caseData.getRespondent4Flags().getPartyName())) { - caseData.getRespondent4Flags().setPartyName(respondent); - } - - if (caseData.getRespondent4ExternalFlags() == null - || StringUtils.isEmpty(caseData.getRespondent4ExternalFlags().getRoleOnCase())) { - caseData.setRespondent4ExternalFlags(CaseFlagsType.builder() - .partyName(respondent) - .roleOnCase(RESPONDENT5) - .groupId(RESPONDENT5) - .visibility(EXTERNAL) - .build() - ); - } else if (!respondent.equals(caseData.getRespondent4ExternalFlags().getPartyName())) { - caseData.getRespondent4ExternalFlags().setPartyName(respondent); - } - } - - if (caseData.getRespondentCollection().size() > 5) { - String respondent = caseData.getRespondentCollection().get(5).getValue().getRespondentName(); - if (caseData.getRespondent5Flags() == null - || StringUtils.isEmpty(caseData.getRespondent5Flags().getRoleOnCase())) { - caseData.setRespondent5Flags(CaseFlagsType.builder() - .partyName(respondent) - .roleOnCase(RESPONDENT6) - .groupId(RESPONDENT6) - .visibility(INTERNAL) - .build() - ); - } else if (!respondent.equals(caseData.getRespondent5Flags().getPartyName())) { - caseData.getRespondent5Flags().setPartyName(respondent); - } - - if (caseData.getRespondent5ExternalFlags() == null - || StringUtils.isEmpty(caseData.getRespondent5ExternalFlags().getRoleOnCase())) { - caseData.setRespondent5ExternalFlags(CaseFlagsType.builder() - .partyName(respondent) - .roleOnCase(RESPONDENT6) - .groupId(RESPONDENT6) - .visibility(EXTERNAL) - .build() - ); - } else if (!respondent.equals(caseData.getRespondent5ExternalFlags().getPartyName())) { - caseData.getRespondent5ExternalFlags().setPartyName(respondent); - } - } - - if (caseData.getRespondentCollection().size() > 6) { - String respondent = caseData.getRespondentCollection().get(6).getValue().getRespondentName(); - if (caseData.getRespondent6Flags() == null - || StringUtils.isEmpty(caseData.getRespondent6Flags().getRoleOnCase())) { - caseData.setRespondent6Flags(CaseFlagsType.builder() - .partyName(respondent) - .roleOnCase(RESPONDENT7) - .groupId(RESPONDENT7) - .visibility(INTERNAL) - .build() - ); - } else if (!respondent.equals(caseData.getRespondent6Flags().getPartyName())) { - caseData.getRespondent6Flags().setPartyName(respondent); - } - - if (caseData.getRespondent6ExternalFlags() == null - || StringUtils.isEmpty(caseData.getRespondent6ExternalFlags().getRoleOnCase())) { - caseData.setRespondent6ExternalFlags(CaseFlagsType.builder() - .partyName(respondent) - .roleOnCase(RESPONDENT7) - .groupId(RESPONDENT7) - .visibility(EXTERNAL) - .build() - ); - } else if (!respondent.equals(caseData.getRespondent6ExternalFlags().getPartyName())) { - caseData.getRespondent6ExternalFlags().setPartyName(respondent); - } - } - - if (caseData.getRespondentCollection().size() > 7) { - String respondent = caseData.getRespondentCollection().get(7).getValue().getRespondentName(); - if (caseData.getRespondent7Flags() == null - || StringUtils.isEmpty(caseData.getRespondent7Flags().getRoleOnCase())) { - caseData.setRespondent7Flags(CaseFlagsType.builder() - .partyName(respondent) - .roleOnCase(RESPONDENT8) - .groupId(RESPONDENT8) - .visibility(INTERNAL) - .build() - ); - } else if (!respondent.equals(caseData.getRespondent7Flags().getPartyName())) { - caseData.getRespondent7Flags().setPartyName(respondent); - } - - if (caseData.getRespondent7ExternalFlags() == null - || StringUtils.isEmpty(caseData.getRespondent7ExternalFlags().getRoleOnCase())) { - caseData.setRespondent7ExternalFlags(CaseFlagsType.builder() - .partyName(respondent) - .roleOnCase(RESPONDENT8) - .groupId(RESPONDENT8) - .visibility(EXTERNAL) - .build() - ); - } else if (!respondent.equals(caseData.getRespondent7ExternalFlags().getPartyName())) { - caseData.getRespondent7ExternalFlags().setPartyName(respondent); - } - } - - if (caseData.getRespondentCollection().size() > 8) { - String respondent = caseData.getRespondentCollection().get(8).getValue().getRespondentName(); - if (caseData.getRespondent8Flags() == null - || StringUtils.isEmpty(caseData.getRespondent8Flags().getRoleOnCase())) { - caseData.setRespondent8Flags(CaseFlagsType.builder() - .partyName(respondent) - .roleOnCase(RESPONDENT9) - .groupId(RESPONDENT9) - .visibility(INTERNAL) - .build() - ); - } else if (!respondent.equals(caseData.getRespondent8Flags().getPartyName())) { - caseData.getRespondent8Flags().setPartyName(respondent); - } - - if (caseData.getRespondent8ExternalFlags() == null - || StringUtils.isEmpty(caseData.getRespondent8ExternalFlags().getRoleOnCase())) { - caseData.setRespondent8ExternalFlags(CaseFlagsType.builder() - .partyName(respondent) - .roleOnCase(RESPONDENT9) - .groupId(RESPONDENT9) - .visibility(EXTERNAL) - .build() - ); - } else if (!respondent.equals(caseData.getRespondent8ExternalFlags().getPartyName())) { - caseData.getRespondent8ExternalFlags().setPartyName(respondent); - } - } - - if (caseData.getRespondentCollection().size() > 9) { - String respondent = caseData.getRespondentCollection().get(9).getValue().getRespondentName(); - if (caseData.getRespondent9Flags() == null - || StringUtils.isEmpty(caseData.getRespondent9Flags().getRoleOnCase())) { - caseData.setRespondent9Flags(CaseFlagsType.builder() - .partyName(respondent) - .roleOnCase(RESPONDENT10) - .groupId(RESPONDENT10) - .visibility(INTERNAL) - .build() - ); - } else if (!respondent.equals(caseData.getRespondent9Flags().getPartyName())) { - caseData.getRespondent9Flags().setPartyName(respondent); - } - - if (caseData.getRespondent9ExternalFlags() == null - || StringUtils.isEmpty(caseData.getRespondent9ExternalFlags().getRoleOnCase())) { - caseData.setRespondent9ExternalFlags(CaseFlagsType.builder() - .partyName(respondent) - .roleOnCase(RESPONDENT10) - .groupId(RESPONDENT10) - .visibility(EXTERNAL) - .build() - ); - } else if (!respondent.equals(caseData.getRespondent9ExternalFlags().getPartyName())) { - caseData.getRespondent9ExternalFlags().setPartyName(respondent); - } - } + PARTY_FLAGS.stream() + .filter(flag -> hasParty(caseData, flag)) + .forEach(flag -> setupPartyFlag(caseData, flag)); } /** - * Sets case flags for Claimant, Respondent and Case level to null. + * Sets case flags for Claimant, Respondent, Representative and Case level to null. * * @param caseData Data about the current case */ public void rollbackCaseFlags(CaseData caseData) { caseData.setCaseFlags(null); - caseData.setClaimantFlags(null); - caseData.setClaimantExternalFlags(null); - caseData.setRespondentFlags(null); - caseData.setRespondentExternalFlags(null); - caseData.setRespondent1Flags(null); - caseData.setRespondent1ExternalFlags(null); - caseData.setRespondent2Flags(null); - caseData.setRespondent2ExternalFlags(null); - caseData.setRespondent3Flags(null); - caseData.setRespondent3ExternalFlags(null); - caseData.setRespondent4Flags(null); - caseData.setRespondent4ExternalFlags(null); - caseData.setRespondent5Flags(null); - caseData.setRespondent5ExternalFlags(null); - caseData.setRespondent6Flags(null); - caseData.setRespondent6ExternalFlags(null); - caseData.setRespondent7Flags(null); - caseData.setRespondent7ExternalFlags(null); - caseData.setRespondent8Flags(null); - caseData.setRespondent8ExternalFlags(null); - caseData.setRespondent9Flags(null); - caseData.setRespondent9ExternalFlags(null); + PARTY_FLAGS.forEach(flag -> flag.clear(caseData)); } /** @@ -500,6 +202,104 @@ public void setPrivateHearingFlag(CaseData caseData) { caseData.setPrivateHearingRequiredFlag(shouldBePrivate ? YES : NO); } + private static PartyFlag claimantFlag( + Function getter, + BiConsumer setter, + String visibility) { + return new PartyFlag(getter, setter, PartyType.CLAIMANT, CLAIMANT, visibility, NOT_INDEXED); + } + + private static PartyFlag respondentFlag( + Function getter, + BiConsumer setter, + String roleOnCase, + String visibility, + int index) { + return new PartyFlag(getter, setter, PartyType.RESPONDENT, roleOnCase, visibility, index); + } + + private static PartyFlag claimantRepresentativeFlag( + Function getter, + BiConsumer setter, + String visibility) { + return new PartyFlag(getter, setter, PartyType.CLAIMANT_REPRESENTATIVE, CLAIMANT_REPRESENTATIVE, + visibility, NOT_INDEXED); + } + + private static PartyFlag representativeFlag( + Function getter, + BiConsumer setter, + String roleOnCase, + String visibility, + int index) { + return new PartyFlag(getter, setter, PartyType.RESPONDENT_REPRESENTATIVE, roleOnCase, visibility, index); + } + + private static boolean isRequired(CaseData caseData, PartyFlag flag) { + return switch (flag.partyType()) { + case CLAIMANT, CLAIMANT_REPRESENTATIVE -> true; + case RESPONDENT -> respondentCount(caseData) > flag.index(); + case RESPONDENT_REPRESENTATIVE -> representativeCount(caseData) > flag.index(); + }; + } + + private static boolean hasParty(CaseData caseData, PartyFlag flag) { + return switch (flag.partyType()) { + case CLAIMANT -> true; + case RESPONDENT -> respondentCount(caseData) > flag.index(); + case CLAIMANT_REPRESENTATIVE -> caseData.getRepresentativeClaimantType() != null; + case RESPONDENT_REPRESENTATIVE -> representativeCount(caseData) > flag.index(); + }; + } + + private static boolean isMissingRole(CaseData caseData, PartyFlag flag) { + CaseFlagsType flags = flag.get(caseData); + return flags == null || StringUtils.isEmpty(flags.getRoleOnCase()); + } + + private static void setupPartyFlag(CaseData caseData, PartyFlag flag) { + String partyName = getPartyName(caseData, flag); + CaseFlagsType existingFlag = flag.get(caseData); + + if (existingFlag == null || StringUtils.isEmpty(existingFlag.getRoleOnCase())) { + flag.set(caseData, createShellFlag(partyName, flag.roleOnCase(), flag.visibility())); + } else if (!Objects.equals(partyName, existingFlag.getPartyName())) { + existingFlag.setPartyName(partyName); + } + } + + private static CaseFlagsType createShellFlag(String partyName, String roleOnCase, String visibility) { + return CaseFlagsType.builder() + .partyName(partyName) + .roleOnCase(roleOnCase) + .groupId(roleOnCase) + .visibility(visibility) + .build(); + } + + private static String getPartyName(CaseData caseData, PartyFlag flag) { + return switch (flag.partyType()) { + case CLAIMANT -> caseData.getClaimant(); + case RESPONDENT -> caseData.getRespondentCollection() + .get(flag.index()) + .getValue() + .getRespondentName(); + case CLAIMANT_REPRESENTATIVE -> caseData.getRepresentativeClaimantType().getNameOfRepresentative(); + case RESPONDENT_REPRESENTATIVE -> caseData.getRepCollection() + .get(flag.index()) + .getValue() + .getNameOfRepresentative(); + }; + } + + private static int respondentCount(CaseData caseData) { + return caseData.getRespondentCollection() == null ? 0 : caseData.getRespondentCollection().size(); + } + + private static int representativeCount(CaseData caseData) { + return caseData.getRepCollection() == null ? 0 : caseData.getRepCollection().size(); + } + private boolean isFlaggedForRestrictedReporting(CaseData caseData) { RestrictedReportingType restricted = caseData.getRestrictedReporting(); return restricted != null && (YES.equals(restricted.getRule503b()) || YES.equals(restricted.getImposed())); @@ -526,31 +326,11 @@ private boolean hasGrantedDecision(List list) { } private ListTypeItem getPartyCaseFlags(CaseData caseData) { - ListTypeItem partyLevel = ListTypeItem.concat( - caseData.getClaimantFlags().getDetails(), - caseData.getClaimantExternalFlags().getDetails() - ); + ListTypeItem partyLevel = new ListTypeItem<>(); - partyLevel = appendDetailsIfPresent(partyLevel, caseData.getRespondentFlags()); - partyLevel = appendDetailsIfPresent(partyLevel, caseData.getRespondentExternalFlags()); - partyLevel = appendDetailsIfPresent(partyLevel, caseData.getRespondent1Flags()); - partyLevel = appendDetailsIfPresent(partyLevel, caseData.getRespondent1ExternalFlags()); - partyLevel = appendDetailsIfPresent(partyLevel, caseData.getRespondent2Flags()); - partyLevel = appendDetailsIfPresent(partyLevel, caseData.getRespondent2ExternalFlags()); - partyLevel = appendDetailsIfPresent(partyLevel, caseData.getRespondent3Flags()); - partyLevel = appendDetailsIfPresent(partyLevel, caseData.getRespondent3ExternalFlags()); - partyLevel = appendDetailsIfPresent(partyLevel, caseData.getRespondent4Flags()); - partyLevel = appendDetailsIfPresent(partyLevel, caseData.getRespondent4ExternalFlags()); - partyLevel = appendDetailsIfPresent(partyLevel, caseData.getRespondent5Flags()); - partyLevel = appendDetailsIfPresent(partyLevel, caseData.getRespondent5ExternalFlags()); - partyLevel = appendDetailsIfPresent(partyLevel, caseData.getRespondent6Flags()); - partyLevel = appendDetailsIfPresent(partyLevel, caseData.getRespondent6ExternalFlags()); - partyLevel = appendDetailsIfPresent(partyLevel, caseData.getRespondent7Flags()); - partyLevel = appendDetailsIfPresent(partyLevel, caseData.getRespondent7ExternalFlags()); - partyLevel = appendDetailsIfPresent(partyLevel, caseData.getRespondent8Flags()); - partyLevel = appendDetailsIfPresent(partyLevel, caseData.getRespondent8ExternalFlags()); - partyLevel = appendDetailsIfPresent(partyLevel, caseData.getRespondent9Flags()); - partyLevel = appendDetailsIfPresent(partyLevel, caseData.getRespondent9ExternalFlags()); + for (PartyFlag flag : PARTY_FLAGS) { + partyLevel = appendDetailsIfPresent(partyLevel, flag.get(caseData)); + } return partyLevel; } @@ -578,4 +358,32 @@ private boolean areAnyFlagsActive(ListTypeItem flags, String...n .filter(Objects::nonNull) .anyMatch(o -> ACTIVE.equals(o.getStatus())); } + + private enum PartyType { + CLAIMANT, + RESPONDENT, + CLAIMANT_REPRESENTATIVE, + RESPONDENT_REPRESENTATIVE + } + + private record PartyFlag( + Function getter, + BiConsumer setter, + PartyType partyType, + String roleOnCase, + String visibility, + int index) { + + private CaseFlagsType get(CaseData caseData) { + return getter.apply(caseData); + } + + private void set(CaseData caseData, CaseFlagsType flags) { + setter.accept(caseData, flags); + } + + private void clear(CaseData caseData) { + setter.accept(caseData, null); + } + } } diff --git a/src/test/apiTest/java/uk/gov/hmcts/ethos/replacement/apitest/AddAmendClaimantRepresentativeControllerFunctionalTest.java b/src/test/apiTest/java/uk/gov/hmcts/ethos/replacement/apitest/AddAmendClaimantRepresentativeControllerFunctionalTest.java index 0f895acfc7..9c5604680d 100644 --- a/src/test/apiTest/java/uk/gov/hmcts/ethos/replacement/apitest/AddAmendClaimantRepresentativeControllerFunctionalTest.java +++ b/src/test/apiTest/java/uk/gov/hmcts/ethos/replacement/apitest/AddAmendClaimantRepresentativeControllerFunctionalTest.java @@ -5,22 +5,59 @@ import io.restassured.http.Header; import lombok.extern.slf4j.Slf4j; import org.apache.http.HttpStatus; +import org.json.JSONObject; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import uk.gov.hmcts.et.common.model.ccd.CCDRequest; +import uk.gov.hmcts.et.common.model.ccd.CallbackRequest; +import uk.gov.hmcts.et.common.model.ccd.CaseData; +import uk.gov.hmcts.et.common.model.ccd.CaseDetails; +import uk.gov.hmcts.et.common.model.ccd.types.Organisation; +import uk.gov.hmcts.et.common.model.ccd.types.RepresentedTypeC; import uk.gov.hmcts.ethos.utils.CCDRequestBuilder; import uk.gov.hmcts.ethos.utils.CaseDataBuilder; +import java.io.IOException; +import java.util.ArrayList; + +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.nullValue; +import static uk.gov.hmcts.ecm.common.model.helper.Constants.EMPLOYMENT; +import static uk.gov.hmcts.ecm.common.model.helper.Constants.SCOTLAND_CASE_TYPE_ID; + @Slf4j public class AddAmendClaimantRepresentativeControllerFunctionalTest extends BaseFunctionalTest { private static final String ABOUT_TO_SUBMIT_URL = "/addAmendClaimantRepresentative/aboutToSubmit"; + private static final String SUBMITTED_URL = "/addAmendClaimantRepresentative/amendClaimantRepSubmitted"; private CCDRequest ccdRequest; + private CallbackRequest callbackRequest; @BeforeAll - public void setUpCaseData() { + public void setUpCaseData() throws IOException { ccdRequest = CCDRequestBuilder.builder() .withCaseData(CaseDataBuilder.builder().build()) .build(); + final JSONObject createdCase = createSinglesCaseDataStore(); + + CaseData caseDataBefore = CaseDataBuilder.builder() + .withEthosCaseReference("1234") + .withClaimant("claimant") + .build(); + CaseData caseDataAfter = CaseDataBuilder.builder() + .withEthosCaseReference("1234") + .withClaimant("claimant") + .build(); + caseDataBefore.setRespondentCollection(new ArrayList<>()); + caseDataAfter.setRespondentCollection(new ArrayList<>()); + caseDataAfter.setRepresentativeClaimantType(createClaimantRepresentative()); + + CaseDetails caseDetailsBefore = createCaseDetails(String.valueOf(createdCase.getLong("id")), caseDataBefore); + CaseDetails caseDetails = createCaseDetails(String.valueOf(createdCase.getLong("id")), caseDataAfter); + + callbackRequest = CallbackRequest.builder() + .caseDetails(caseDetails) + .caseDetailsBefore(caseDetailsBefore) + .build(); } @Test @@ -36,4 +73,41 @@ void aboutToSubmitSuccessResponse() { .log() .all(true); } + + @Test + void submittedSuccessResponse() { + RestAssured.given() + .spec(spec) + .contentType(ContentType.JSON) + .header(new Header(AUTHORIZATION, userToken)) + .body(callbackRequest) + .post(SUBMITTED_URL) + .then() + .statusCode(HttpStatus.SC_OK) + .body("data", notNullValue()) + .body("errors", nullValue()) + .body("warnings", nullValue()) + .log() + .all(true); + } + + private CaseDetails createCaseDetails(String caseId, CaseData caseData) { + CaseDetails caseDetails = new CaseDetails(); + caseDetails.setCaseId(caseId); + caseDetails.setCaseTypeId(SCOTLAND_CASE_TYPE_ID); + caseDetails.setJurisdiction(EMPLOYMENT); + caseDetails.setCaseData(caseData); + + return caseDetails; + } + + private RepresentedTypeC createClaimantRepresentative() { + RepresentedTypeC claimantRepresentative = new RepresentedTypeC(); + claimantRepresentative.setMyHmctsOrganisation(Organisation.builder() + .organisationID("ORG1") + .organisationName("ET Org 1") + .build()); + + return claimantRepresentative; + } } diff --git a/src/test/apiTest/java/uk/gov/hmcts/ethos/replacement/apitest/CaseActionsForCaseWorkerControllerFunctionalTest.java b/src/test/apiTest/java/uk/gov/hmcts/ethos/replacement/apitest/CaseActionsForCaseWorkerControllerFunctionalTest.java index 0e9fadf309..8e72258dc8 100644 --- a/src/test/apiTest/java/uk/gov/hmcts/ethos/replacement/apitest/CaseActionsForCaseWorkerControllerFunctionalTest.java +++ b/src/test/apiTest/java/uk/gov/hmcts/ethos/replacement/apitest/CaseActionsForCaseWorkerControllerFunctionalTest.java @@ -7,29 +7,45 @@ import org.apache.http.HttpStatus; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import uk.gov.hmcts.et.common.model.bulk.types.DynamicFixedListType; +import uk.gov.hmcts.et.common.model.bulk.types.DynamicValueType; import uk.gov.hmcts.et.common.model.ccd.CCDRequest; import uk.gov.hmcts.et.common.model.ccd.CaseData; +import uk.gov.hmcts.et.common.model.ccd.items.RepresentedTypeRItem; +import uk.gov.hmcts.et.common.model.ccd.types.RepresentedTypeR; import uk.gov.hmcts.ethos.utils.CCDRequestBuilder; import uk.gov.hmcts.ethos.utils.CaseDataBuilder; +import java.util.List; + +import static uk.gov.hmcts.ecm.common.model.helper.Constants.NO; +import static uk.gov.hmcts.ecm.common.model.helper.Constants.SCOTLAND_CASE_TYPE_ID; import static uk.gov.hmcts.ecm.common.model.helper.Constants.YES; @Slf4j public class CaseActionsForCaseWorkerControllerFunctionalTest extends BaseFunctionalTest { private static final String RESTRICTED_CASES_URL = "/restrictedCases"; + private static final String AMEND_CLAIMANT_DETAILS_URL = "/amendClaimantDetails"; + private static final String AMEND_RESPONDENT_DETAILS_URL = "/amendRespondentDetails"; + private static final String AMEND_RESPONDENT_REPRESENTATIVE_URL = "/amendRespondentRepresentative"; + private static final String RESPONDENT_NAME = "Respondent Ltd"; private CCDRequest ccdRequest; @BeforeAll public void setUpCaseData() { CaseData caseData = CaseDataBuilder.builder() .withEthosCaseReference("6000001/2023") + .withClaimant("claimant") + .withRespondent(RESPONDENT_NAME, NO, null, false) .build(); caseData.setIcListingPreliminaryHearing(YES); + caseData.setRepCollection(List.of(createRespondentRepresentative())); ccdRequest = CCDRequestBuilder.builder() .withCaseData(caseData) .withCaseId("1694206942069420") + .withCaseTypeId(SCOTLAND_CASE_TYPE_ID) .build(); } @@ -46,4 +62,62 @@ void restrictedCases() { .log() .all(true); } -} \ No newline at end of file + + @Test + void amendClaimantDetails() { + RestAssured.given() + .spec(spec) + .contentType(ContentType.JSON) + .header(new Header(AUTHORIZATION, userToken)) + .body(ccdRequest) + .post(AMEND_CLAIMANT_DETAILS_URL) + .then() + .statusCode(HttpStatus.SC_OK) + .log() + .all(true); + } + + @Test + void amendRespondentDetails() { + RestAssured.given() + .spec(spec) + .contentType(ContentType.JSON) + .header(new Header(AUTHORIZATION, userToken)) + .body(ccdRequest) + .post(AMEND_RESPONDENT_DETAILS_URL) + .then() + .statusCode(HttpStatus.SC_OK) + .log() + .all(true); + } + + @Test + void amendRespondentRepresentative() { + RestAssured.given() + .spec(spec) + .contentType(ContentType.JSON) + .header(new Header(AUTHORIZATION, userToken)) + .body(ccdRequest) + .post(AMEND_RESPONDENT_REPRESENTATIVE_URL) + .then() + .statusCode(HttpStatus.SC_OK) + .log() + .all(true); + } + + private RepresentedTypeRItem createRespondentRepresentative() { + RepresentedTypeR representative = RepresentedTypeR.builder() + .respRepName(RESPONDENT_NAME) + .nameOfRepresentative("Respondent Rep") + .representativeEmailAddress("rep@example.com") + .myHmctsYesNo(NO) + .dynamicRespRepName(DynamicFixedListType.of( + DynamicValueType.create("R: " + RESPONDENT_NAME, RESPONDENT_NAME))) + .build(); + + RepresentedTypeRItem item = new RepresentedTypeRItem(); + item.setValue(representative); + + return item; + } +} diff --git a/src/test/apiTest/java/uk/gov/hmcts/ethos/replacement/apitest/NoticeOfChangeControllerFunctionalTest.java b/src/test/apiTest/java/uk/gov/hmcts/ethos/replacement/apitest/NoticeOfChangeControllerFunctionalTest.java index 567bd5cdd0..fc4b555b90 100644 --- a/src/test/apiTest/java/uk/gov/hmcts/ethos/replacement/apitest/NoticeOfChangeControllerFunctionalTest.java +++ b/src/test/apiTest/java/uk/gov/hmcts/ethos/replacement/apitest/NoticeOfChangeControllerFunctionalTest.java @@ -9,6 +9,7 @@ import uk.gov.hmcts.et.common.model.bulk.types.DynamicFixedListType; import uk.gov.hmcts.et.common.model.bulk.types.DynamicValueType; import uk.gov.hmcts.et.common.model.ccd.CCDRequest; +import uk.gov.hmcts.et.common.model.ccd.CallbackRequest; import uk.gov.hmcts.et.common.model.ccd.CaseData; import uk.gov.hmcts.et.common.model.ccd.items.RespondentSumTypeItem; import uk.gov.hmcts.et.common.model.ccd.types.ChangeOrganisationRequest; @@ -27,6 +28,7 @@ public class NoticeOfChangeControllerFunctionalTest extends BaseFunctionalTest { private static final String AUTHORIZATION = "Authorization"; + private static final String ABOUT_TO_SUBMIT_URL = "/noc-decision/about-to-submit"; private static final String SUBMITTED_URL = "/noc-decision/submitted"; private static final String SOLICITORA = "[SOLICITORA]"; @@ -36,6 +38,7 @@ public class NoticeOfChangeControllerFunctionalTest extends BaseFunctionalTest { private static final String ET_ORG_2 = "ET Org 2"; private CCDRequest ccdRequest; + private CallbackRequest callbackRequest; @BeforeAll public void setUpCaseData() throws IOException { @@ -76,6 +79,23 @@ public void setUpCaseData() throws IOException { .withCaseId(String.valueOf(caseId)) .build(); + callbackRequest = CallbackRequest.builder() + .caseDetails(ccdRequest.getCaseDetails()) + .build(); + } + + @Test + void nocAboutToSubmitSuccessResponse() { + RestAssured.given() + .spec(spec) + .contentType(ContentType.JSON) + .header(new Header(AUTHORIZATION, userToken)) + .body(callbackRequest) + .post(ABOUT_TO_SUBMIT_URL) + .then() + .statusCode(HttpStatus.SC_OK) + .log() + .all(true); } @Test diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeControllerTest.java index 73e28a0812..314ce028d5 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeControllerTest.java @@ -9,10 +9,12 @@ import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.web.servlet.MockMvc; -import uk.gov.hmcts.ecm.common.idam.models.UserDetails; import uk.gov.hmcts.et.common.model.ccd.CCDRequest; +import uk.gov.hmcts.et.common.model.ccd.CallbackRequest; import uk.gov.hmcts.et.common.model.ccd.CaseDetails; import uk.gov.hmcts.ethos.replacement.docmosis.service.AddAmendClaimantRepresentativeService; +import uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService; +import uk.gov.hmcts.ethos.replacement.docmosis.service.FeatureToggleService; import uk.gov.hmcts.ethos.replacement.docmosis.service.NocClaimantRepresentativeService; import uk.gov.hmcts.ethos.replacement.docmosis.service.ScheduledTaskRunner; import uk.gov.hmcts.ethos.replacement.docmosis.service.UserIdamService; @@ -49,6 +51,10 @@ class AddAmendClaimantRepresentativeControllerTest { private NocClaimantRepresentativeService nocClaimantRepresentativeService; @MockitoBean private UserIdamService userIdamService; + @MockitoBean + private FeatureToggleService featureToggleService; + @MockitoBean + private CaseFlagsService caseFlagsService; @Autowired private MockMvc mockMvc; @@ -56,17 +62,23 @@ class AddAmendClaimantRepresentativeControllerTest { private JsonMapper jsonMapper; private CCDRequest ccdRequest; + private CallbackRequest callbackRequest; @BeforeEach void setUp() { CaseDetails caseDetails = CaseDataBuilder.builder() .buildAsCaseDetails(ENGLANDWALES_CASE_TYPE_ID); + caseDetails.setCaseId("1234"); caseDetails.getCaseData().setEthosCaseReference("1234"); ccdRequest = CCDRequestBuilder.builder() .withCaseData(caseDetails.getCaseData()) .build(); + callbackRequest = CallbackRequest.builder() + .caseDetails(caseDetails) + .caseDetailsBefore(caseDetails) + .build(); } @Test @@ -88,16 +100,36 @@ void testAboutToSubmitSetsClaimantRepresentativeId() throws Exception { @Test void testAmendClaimantRepSubmitted() throws Exception { when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); - UserDetails userDetails = new UserDetails(); - userDetails.setEmail("test@test.com"); - when(userIdamService.getUserDetails(any())).thenReturn(userDetails); mockMvc.perform(post(SUBMITTED_URL) - .content(jsonMapper.toJson(ccdRequest)) + .content(jsonMapper.toJson(callbackRequest)) .header("Authorization", AUTH_TOKEN) .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()); + .andExpect(status().isOk()) + .andExpect(jsonPath("$.data", notNullValue())) + .andExpect(jsonPath("$.errors", nullValue())) + .andExpect(jsonPath("$.warnings", nullValue())); + + verify(nocClaimantRepresentativeService, times(1)) + .updateClaimantRepAccess(any()); + verify(caseFlagsService, times(0)).setupCaseFlags(any()); + } + + @Test + void testAmendClaimantRepSubmittedSetsUpCaseFlagsWhenEnabled() throws Exception { + when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); + when(featureToggleService.isCaseFlagsEnabled()).thenReturn(true); + + mockMvc.perform(post(SUBMITTED_URL) + .content(jsonMapper.toJson(callbackRequest)) + .header("Authorization", AUTH_TOKEN) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.data", notNullValue())) + .andExpect(jsonPath("$.errors", nullValue())) + .andExpect(jsonPath("$.warnings", nullValue())); verify(nocClaimantRepresentativeService, times(1)) .updateClaimantRepAccess(any()); + verify(caseFlagsService, times(1)).setupCaseFlags(any()); } } diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java index d9c0d2d6e7..0f8b291a01 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java @@ -436,6 +436,26 @@ void amendClaimantDetails() { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); + + verify(caseFlagsService, times(0)).setupCaseFlags(any(CaseData.class)); + } + + @Test + @SneakyThrows + void amendClaimantDetailsSetsUpCaseFlagsWhenEnabled() { + when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); + when(featureToggleService.isCaseFlagsEnabled()).thenReturn(true); + + mvc.perform(post(AMEND_CLAIMANT_DETAILS_URL) + .content(requestContent2.toString()) + .header(AUTHORIZATION, AUTH_TOKEN) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) + .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) + .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); + + verify(caseFlagsService, times(1)).setupCaseFlags(any(CaseData.class)); } @Test @@ -453,6 +473,29 @@ void amendRespondentDetails() { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, notNullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); + + verify(caseFlagsService, times(0)).setupCaseFlags(any(CaseData.class)); + } + + @Test + @SneakyThrows + void amendRespondentDetailsSetsUpCaseFlagsWhenEnabled() { + when(caseManagementForCaseWorkerService.struckOutRespondents(any(CCDRequest.class))) + .thenReturn(submitEvent.getCaseData()); + when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); + when(featureToggleService.isCaseFlagsEnabled()).thenReturn(true); + doNothing().when(nocRespondentHelper).amendRespondentNameRepresentativeNames(any(CaseData.class)); + + mvc.perform(post(AMEND_RESPONDENT_DETAILS_URL) + .content(requestContent2.toString()) + .header(AUTHORIZATION, AUTH_TOKEN) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) + .andExpect(jsonPath(JsonMapper.ERRORS, notNullValue())) + .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); + + verify(caseFlagsService, times(1)).setupCaseFlags(any(CaseData.class)); } @Test @@ -558,6 +601,29 @@ void amendRespondentRepresentative() { .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); verify(nocRespondentRepresentativeService, times(1)).updateNonMyHmctsOrgIds(anyList()); + verify(caseFlagsService, times(0)).setupCaseFlags(any(CaseData.class)); + } + + @Test + @SneakyThrows + void amendRespondentRepresentativeSetsUpCaseFlagsWhenEnabled() { + when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); + when(featureToggleService.isCaseFlagsEnabled()).thenReturn(true); + when(nocRespondentRepresentativeService.prepopulateOrgPolicyAndNoc(any(CaseData.class))) + .thenReturn(ccdRequest.getCaseDetails().getCaseData()); + when(nocRespondentRepresentativeService.prepopulateOrgAddress(any(CaseData.class), anyString())) + .thenReturn(ccdRequest.getCaseDetails().getCaseData()); + + mvc.perform(post(AMEND_RESPONDENT_REPRESENTATIVE_URL) + .content(requestContent.toString()) + .header(AUTHORIZATION, AUTH_TOKEN) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) + .andExpect(jsonPath(JsonMapper.ERRORS, notNullValue())) + .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); + + verify(caseFlagsService, times(1)).setupCaseFlags(any(CaseData.class)); } @Test diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/NoticeOfChangeControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/NoticeOfChangeControllerTest.java index cc5234ff19..e21c933c0d 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/NoticeOfChangeControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/NoticeOfChangeControllerTest.java @@ -17,7 +17,9 @@ import uk.gov.hmcts.et.common.model.ccd.CCDCallbackResponse; import uk.gov.hmcts.et.common.model.ccd.CallbackRequest; import uk.gov.hmcts.et.common.model.ccd.CaseData; +import uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService; import uk.gov.hmcts.ethos.replacement.docmosis.service.CcdCaseAssignment; +import uk.gov.hmcts.ethos.replacement.docmosis.service.FeatureToggleService; import uk.gov.hmcts.ethos.replacement.docmosis.service.NocClaimantRepresentativeService; import uk.gov.hmcts.ethos.replacement.docmosis.service.NocNotificationService; import uk.gov.hmcts.ethos.replacement.docmosis.service.NocRepresentativeService; @@ -35,6 +37,8 @@ import static org.hamcrest.Matchers.nullValue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; @@ -66,6 +70,10 @@ class NoticeOfChangeControllerTest { @MockitoBean private UserIdamService userIdamService; + @MockitoBean + private FeatureToggleService featureToggleService; + @MockitoBean + private CaseFlagsService caseFlagsService; @Autowired private WebApplicationContext applicationContext; @@ -94,8 +102,7 @@ void setUp() throws URISyntaxException, IOException { @Test void handleAboutToSubmit_RespondentRep() throws Exception { when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); - when(nocRespondentRepresentativeService - .updateRespondentRepresentation(any())).thenReturn(caseData); + when(nocRepresentativeService.updateRepresentation(any(), any())).thenReturn(caseData); when(ccdCaseAssignment.applyNoc(any(), any())).thenReturn(CCDCallbackResponse.builder() .data(caseData) .build()); @@ -108,6 +115,29 @@ void handleAboutToSubmit_RespondentRep() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); + + verify(caseFlagsService, times(0)).setupCaseFlags(any(CaseData.class)); + } + + @Test + void handleAboutToSubmitSetsUpCaseFlagsWhenEnabled() throws Exception { + when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); + when(featureToggleService.isCaseFlagsEnabled()).thenReturn(true); + when(nocRepresentativeService.updateRepresentation(any(), any())).thenReturn(caseData); + when(ccdCaseAssignment.applyNoc(any(), any())).thenReturn(CCDCallbackResponse.builder() + .data(caseData) + .build()); + + mvc.perform(post(ABOUT_TO_SUBMIT_URL) + .content(requestContent.toString()) + .header(AUTHORIZATION, AUTH_TOKEN) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) + .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) + .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); + + verify(caseFlagsService, times(1)).setupCaseFlags(any(CaseData.class)); } @Test @@ -124,4 +154,4 @@ void nocSubmitted() throws Exception { .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); } -} \ No newline at end of file +} diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java index 58df7e6a26..cc5344e1f5 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java @@ -12,9 +12,12 @@ import uk.gov.hmcts.et.common.model.ccd.items.GenericTseApplicationType; import uk.gov.hmcts.et.common.model.ccd.items.GenericTseApplicationTypeItem; import uk.gov.hmcts.et.common.model.ccd.items.ListTypeItem; +import uk.gov.hmcts.et.common.model.ccd.items.RepresentedTypeRItem; import uk.gov.hmcts.et.common.model.ccd.items.RespondentSumTypeItem; import uk.gov.hmcts.et.common.model.ccd.items.TseAdminRecordDecisionTypeItem; import uk.gov.hmcts.et.common.model.ccd.types.CaseFlagsType; +import uk.gov.hmcts.et.common.model.ccd.types.RepresentedTypeC; +import uk.gov.hmcts.et.common.model.ccd.types.RepresentedTypeR; import uk.gov.hmcts.et.common.model.ccd.types.RespondentSumType; import uk.gov.hmcts.et.common.model.ccd.types.RestrictedReportingType; import uk.gov.hmcts.et.common.model.ccd.types.TseAdminRecordDecisionType; @@ -45,8 +48,19 @@ import static uk.gov.hmcts.ecm.common.model.helper.Constants.TSE_APP_RESTRICT_PUBLICITY; import static uk.gov.hmcts.ecm.common.model.helper.Constants.YES; import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.CLAIMANT; +import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.CLAIMANT_REPRESENTATIVE; import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.EXTERNAL; import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.INTERNAL; +import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.REPRESENTATIVE1; +import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.REPRESENTATIVE10; +import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.REPRESENTATIVE2; +import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.REPRESENTATIVE3; +import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.REPRESENTATIVE4; +import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.REPRESENTATIVE5; +import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.REPRESENTATIVE6; +import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.REPRESENTATIVE7; +import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.REPRESENTATIVE8; +import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.REPRESENTATIVE9; import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.RESPONDENT1; import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.RESPONDENT10; import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.RESPONDENT2; @@ -61,6 +75,8 @@ @ExtendWith(SpringExtension.class) class CaseFlagsServiceTest { public static final String CLAIMANT_NAME = "Claimant Name"; + public static final String CLAIMANT_REPRESENTATIVE_NAME = "Claimant Representative Name"; + public static final String REPRESENTATIVE_NAME = "Representative Name"; public static final String RESPONDENT_NAME = "Respondent Name"; private CaseFlagsService caseFlagsService; private CaseData caseData; @@ -73,6 +89,10 @@ void setUp() { caseData.setRespondent(RESPONDENT_NAME); caseData.setRespondentCollection(respondentCollection(10)); + caseData.setRepresentativeClaimantType(RepresentedTypeC.builder() + .nameOfRepresentative(CLAIMANT_REPRESENTATIVE_NAME) + .build()); + caseData.setRepCollection(representativeCollection(10)); } @Test @@ -123,7 +143,40 @@ void caseFlagsSetupRequired_shouldNotRequireRespondentFlagsWhenThereAreNoRespond } @Test - void setupCaseFlags_setsShellCaseFlagsForClaimantAndEveryRespondent() { + void caseFlagsSetupRequired_shouldNotRequireRespondentFlagsWhenRespondentCollectionIsNull() { + caseData.setRespondentCollection(null); + + caseFlagsService.setupCaseFlags(caseData); + + assertFalse(caseFlagsService.caseFlagsSetupRequired(caseData)); + respondentPartyFlagSlots() + .forEach(slot -> assertNull(slot.getter.apply(caseData), slot + " should not be populated")); + } + + @Test + void caseFlagsSetupRequired_shouldNotRequireRespondentRepresentativeFlagsWhenThereAreNoRepresentatives() { + caseData.setRepCollection(null); + + caseFlagsService.setupCaseFlags(caseData); + + assertFalse(caseFlagsService.caseFlagsSetupRequired(caseData)); + respondentRepresentativePartyFlagSlots() + .forEach(slot -> assertNull(slot.getter.apply(caseData), slot + " should not be populated")); + } + + @Test + void caseFlagsSetupRequired_shouldRequireClaimantRepresentativeFlagsEvenWhenClaimantRepresentativeIsAbsent() { + caseData.setRepresentativeClaimantType(null); + + caseFlagsService.setupCaseFlags(caseData); + + assertTrue(caseFlagsService.caseFlagsSetupRequired(caseData)); + assertNull(caseData.getClaimantRepresentativeFlags()); + assertNull(caseData.getClaimantRepresentativeExternalFlags()); + } + + @Test + void setupCaseFlags_setsShellCaseFlagsForClaimantRespondentAndRepresentativeParties() { caseFlagsService.setupCaseFlags(caseData); CaseFlagsType caseFlags = caseData.getCaseFlags(); @@ -148,6 +201,31 @@ void setupCaseFlags_shouldOnlyCreateRespondentFlagsForExistingRespondents() { }); } + @Test + void setupCaseFlags_shouldOnlyCreateRespondentRepresentativeFlagsForExistingRepresentatives() { + caseData.setRepCollection(representativeCollection(3)); + + caseFlagsService.setupCaseFlags(caseData); + + respondentRepresentativePartyFlagSlots().forEach(slot -> { + if (slot.representativeIndex < 3) { + assertNotNull(slot.getter.apply(caseData), slot + " should be populated"); + } else { + assertNull(slot.getter.apply(caseData), slot + " should not be populated"); + } + }); + } + + @Test + void setupCaseFlags_shouldNotCreateClaimantRepresentativeFlagsWhenClaimantRepresentativeIsAbsent() { + caseData.setRepresentativeClaimantType(null); + + caseFlagsService.setupCaseFlags(caseData); + + assertNull(caseData.getClaimantRepresentativeFlags()); + assertNull(caseData.getClaimantRepresentativeExternalFlags()); + } + @ParameterizedTest(name = "{0}") @MethodSource("allPartyFlagSlots") void setupCaseFlags_shouldRecreatePartyFlagsWhenRoleIsMissing(FlagSlot slot) { @@ -214,6 +292,43 @@ void setupCaseFlags_shouldUpdateRespondentFlagsWhenNameChanges(FlagSlot slot) { assertEquals(slot.visibility, slot.getter.apply(caseData).getVisibility()); } + @Test + void setupCaseFlags_shouldUpdateClaimantRepresentativeFlagsWhenNameChanges() { + caseFlagsService.setupCaseFlags(caseData); + String updatedRepresentativeName = "Updated Claimant Representative Name"; + caseData.getRepresentativeClaimantType().setNameOfRepresentative(updatedRepresentativeName); + + caseFlagsService.setupCaseFlags(caseData); + + assertEquals(updatedRepresentativeName, caseData.getClaimantRepresentativeFlags().getPartyName()); + assertEquals(CLAIMANT_REPRESENTATIVE, caseData.getClaimantRepresentativeFlags().getRoleOnCase()); + assertEquals(CLAIMANT_REPRESENTATIVE, caseData.getClaimantRepresentativeFlags().getGroupId()); + assertEquals(INTERNAL, caseData.getClaimantRepresentativeFlags().getVisibility()); + + assertEquals(updatedRepresentativeName, caseData.getClaimantRepresentativeExternalFlags().getPartyName()); + assertEquals(CLAIMANT_REPRESENTATIVE, caseData.getClaimantRepresentativeExternalFlags().getRoleOnCase()); + assertEquals(CLAIMANT_REPRESENTATIVE, caseData.getClaimantRepresentativeExternalFlags().getGroupId()); + assertEquals(EXTERNAL, caseData.getClaimantRepresentativeExternalFlags().getVisibility()); + } + + @ParameterizedTest(name = "{0}") + @MethodSource("respondentRepresentativePartyFlagSlots") + void setupCaseFlags_shouldUpdateRespondentRepresentativeFlagsWhenNameChanges(FlagSlot slot) { + caseFlagsService.setupCaseFlags(caseData); + String updatedRepresentativeName = "Updated " + slot; + caseData.getRepCollection() + .get(slot.representativeIndex) + .getValue() + .setNameOfRepresentative(updatedRepresentativeName); + + caseFlagsService.setupCaseFlags(caseData); + + assertEquals(updatedRepresentativeName, slot.getter.apply(caseData).getPartyName()); + assertEquals(slot.roleOnCase, slot.getter.apply(caseData).getRoleOnCase()); + assertEquals(slot.roleOnCase, slot.getter.apply(caseData).getGroupId()); + assertEquals(slot.visibility, slot.getter.apply(caseData).getVisibility()); + } + @Test void processNewlySetCaseFlags_shouldSetInterpreterRequiredTrue() { caseData.setRespondentFlags(CaseFlagsType.builder().build()); @@ -279,8 +394,9 @@ void processNewlySetCaseFlags_shouldReadSecurityFlagsFromAnyPartyFlagCollection( @Test void processNewlySetCaseFlags_shouldSupportAlternativeInterpreterAndSecurityFlagNames() { caseFlagsService.setupCaseFlags(caseData); - caseData.getClaimantExternalFlags().setDetails(ListTypeItem.from(activeFlag(LANGUAGE_INTERPRETER))); - caseData.getRespondent9ExternalFlags().setDetails(ListTypeItem.from(activeFlag(DISRUPTIVE_CUSTOMER))); + caseData.getClaimantRepresentativeExternalFlags() + .setDetails(ListTypeItem.from(activeFlag(LANGUAGE_INTERPRETER))); + caseData.getRepresentative9ExternalFlags().setDetails(ListTypeItem.from(activeFlag(DISRUPTIVE_CUSTOMER))); caseFlagsService.processNewlySetCaseFlags(caseData); @@ -307,6 +423,14 @@ void processNewlySetCaseFlags_shouldSetFlagsToNoWhenMatchingFlagsAreInactiveOrAb assertEquals(NO, caseData.getCaseAdditionalSecurityFlag()); } + @Test + void processNewlySetCaseFlags_shouldSetFlagsToNoWhenPartyFlagCollectionsAreMissing() { + caseFlagsService.processNewlySetCaseFlags(caseData); + + assertEquals(NO, caseData.getCaseInterpreterRequiredFlag()); + assertEquals(NO, caseData.getCaseAdditionalSecurityFlag()); + } + @Test void setPrivateHearingFlag_shouldBeTruthy_whenRestrictPublicityTseApplicationIsGranted() { List granted = List.of(TseAdminRecordDecisionTypeItem.builder() @@ -427,6 +551,12 @@ private static Stream allPartyFlagSlots() { CLAIMANT_NAME, CLAIMANT, INTERNAL, -1), slot("claimant external flags", CaseData::getClaimantExternalFlags, CaseData::setClaimantExternalFlags, CLAIMANT_NAME, CLAIMANT, EXTERNAL, -1), + slot("claimant representative internal flags", CaseData::getClaimantRepresentativeFlags, + CaseData::setClaimantRepresentativeFlags, CLAIMANT_REPRESENTATIVE_NAME, + CLAIMANT_REPRESENTATIVE, INTERNAL, -1), + slot("claimant representative external flags", CaseData::getClaimantRepresentativeExternalFlags, + CaseData::setClaimantRepresentativeExternalFlags, CLAIMANT_REPRESENTATIVE_NAME, + CLAIMANT_REPRESENTATIVE, EXTERNAL, -1), slot("respondent 1 internal flags", CaseData::getRespondentFlags, CaseData::setRespondentFlags, respondentName(0), RESPONDENT1, INTERNAL, 0), slot("respondent 1 external flags", CaseData::getRespondentExternalFlags, @@ -466,7 +596,56 @@ private static Stream allPartyFlagSlots() { slot("respondent 10 internal flags", CaseData::getRespondent9Flags, CaseData::setRespondent9Flags, respondentName(9), RESPONDENT10, INTERNAL, 9), slot("respondent 10 external flags", CaseData::getRespondent9ExternalFlags, - CaseData::setRespondent9ExternalFlags, respondentName(9), RESPONDENT10, EXTERNAL, 9) + CaseData::setRespondent9ExternalFlags, respondentName(9), RESPONDENT10, EXTERNAL, 9), + representativeSlot("representative 1 internal flags", CaseData::getRepresentativeFlags, + CaseData::setRepresentativeFlags, representativeName(0), REPRESENTATIVE1, INTERNAL, 0), + representativeSlot("representative 1 external flags", CaseData::getRepresentativeExternalFlags, + CaseData::setRepresentativeExternalFlags, representativeName(0), REPRESENTATIVE1, EXTERNAL, 0), + representativeSlot("representative 2 internal flags", CaseData::getRepresentative1Flags, + CaseData::setRepresentative1Flags, representativeName(1), REPRESENTATIVE2, INTERNAL, 1), + representativeSlot("representative 2 external flags", CaseData::getRepresentative1ExternalFlags, + CaseData::setRepresentative1ExternalFlags, representativeName(1), REPRESENTATIVE2, + EXTERNAL, 1), + representativeSlot("representative 3 internal flags", CaseData::getRepresentative2Flags, + CaseData::setRepresentative2Flags, representativeName(2), REPRESENTATIVE3, INTERNAL, 2), + representativeSlot("representative 3 external flags", CaseData::getRepresentative2ExternalFlags, + CaseData::setRepresentative2ExternalFlags, representativeName(2), REPRESENTATIVE3, + EXTERNAL, 2), + representativeSlot("representative 4 internal flags", CaseData::getRepresentative3Flags, + CaseData::setRepresentative3Flags, representativeName(3), REPRESENTATIVE4, INTERNAL, 3), + representativeSlot("representative 4 external flags", CaseData::getRepresentative3ExternalFlags, + CaseData::setRepresentative3ExternalFlags, representativeName(3), REPRESENTATIVE4, + EXTERNAL, 3), + representativeSlot("representative 5 internal flags", CaseData::getRepresentative4Flags, + CaseData::setRepresentative4Flags, representativeName(4), REPRESENTATIVE5, INTERNAL, 4), + representativeSlot("representative 5 external flags", CaseData::getRepresentative4ExternalFlags, + CaseData::setRepresentative4ExternalFlags, representativeName(4), REPRESENTATIVE5, + EXTERNAL, 4), + representativeSlot("representative 6 internal flags", CaseData::getRepresentative5Flags, + CaseData::setRepresentative5Flags, representativeName(5), REPRESENTATIVE6, INTERNAL, 5), + representativeSlot("representative 6 external flags", CaseData::getRepresentative5ExternalFlags, + CaseData::setRepresentative5ExternalFlags, representativeName(5), REPRESENTATIVE6, + EXTERNAL, 5), + representativeSlot("representative 7 internal flags", CaseData::getRepresentative6Flags, + CaseData::setRepresentative6Flags, representativeName(6), REPRESENTATIVE7, INTERNAL, 6), + representativeSlot("representative 7 external flags", CaseData::getRepresentative6ExternalFlags, + CaseData::setRepresentative6ExternalFlags, representativeName(6), REPRESENTATIVE7, + EXTERNAL, 6), + representativeSlot("representative 8 internal flags", CaseData::getRepresentative7Flags, + CaseData::setRepresentative7Flags, representativeName(7), REPRESENTATIVE8, INTERNAL, 7), + representativeSlot("representative 8 external flags", CaseData::getRepresentative7ExternalFlags, + CaseData::setRepresentative7ExternalFlags, representativeName(7), REPRESENTATIVE8, + EXTERNAL, 7), + representativeSlot("representative 9 internal flags", CaseData::getRepresentative8Flags, + CaseData::setRepresentative8Flags, representativeName(8), REPRESENTATIVE9, INTERNAL, 8), + representativeSlot("representative 9 external flags", CaseData::getRepresentative8ExternalFlags, + CaseData::setRepresentative8ExternalFlags, representativeName(8), REPRESENTATIVE9, + EXTERNAL, 8), + representativeSlot("representative 10 internal flags", CaseData::getRepresentative9Flags, + CaseData::setRepresentative9Flags, representativeName(9), REPRESENTATIVE10, INTERNAL, 9), + representativeSlot("representative 10 external flags", CaseData::getRepresentative9ExternalFlags, + CaseData::setRepresentative9ExternalFlags, representativeName(9), REPRESENTATIVE10, + EXTERNAL, 9) ); } @@ -474,6 +653,10 @@ private static Stream respondentPartyFlagSlots() { return allPartyFlagSlots().filter(slot -> slot.respondentIndex >= 0); } + private static Stream respondentRepresentativePartyFlagSlots() { + return allPartyFlagSlots().filter(slot -> slot.representativeIndex >= 0); + } + private static Stream nonGrantedTseApplications() { return Stream.of( Arguments.of("different TSE application type", @@ -490,7 +673,13 @@ private static Stream nonGrantedTseApplications() { private static FlagSlot slot(String name, Function getter, BiConsumer setter, String partyName, String roleOnCase, String visibility, int respondentIndex) { - return new FlagSlot(name, getter, setter, partyName, roleOnCase, visibility, respondentIndex); + return new FlagSlot(name, getter, setter, partyName, roleOnCase, visibility, respondentIndex, -1); + } + + private static FlagSlot representativeSlot(String name, Function getter, + BiConsumer setter, String partyName, + String roleOnCase, String visibility, int representativeIndex) { + return new FlagSlot(name, getter, setter, partyName, roleOnCase, visibility, -1, representativeIndex); } private static List respondentCollection(int numberOfRespondents) { @@ -506,10 +695,28 @@ private static List respondentCollection(int numberOfResp return respondentCollection; } + private static List representativeCollection(int numberOfRepresentatives) { + List representativeCollection = new ArrayList<>(); + for (int i = 0; i < numberOfRepresentatives; i++) { + RepresentedTypeR representative = RepresentedTypeR.builder() + .nameOfRepresentative(representativeName(i)) + .build(); + RepresentedTypeRItem representativeItem = new RepresentedTypeRItem(); + representativeItem.setId(String.valueOf(i + 1)); + representativeItem.setValue(representative); + representativeCollection.add(representativeItem); + } + return representativeCollection; + } + private static String respondentName(int index) { return index == 0 ? RESPONDENT_NAME : RESPONDENT_NAME + " " + (index + 1); } + private static String representativeName(int index) { + return index == 0 ? REPRESENTATIVE_NAME : REPRESENTATIVE_NAME + " " + (index + 1); + } + private static void assertCaseFlag(FlagSlot slot, CaseFlagsType actual) { assertNotNull(actual, slot + " should be populated"); assertAll(slot.toString(), @@ -553,10 +760,11 @@ private static final class FlagSlot { private final String roleOnCase; private final String visibility; private final int respondentIndex; + private final int representativeIndex; private FlagSlot(String name, Function getter, BiConsumer setter, String partyName, - String roleOnCase, String visibility, int respondentIndex) { + String roleOnCase, String visibility, int respondentIndex, int representativeIndex) { this.name = name; this.getter = getter; this.setter = setter; @@ -564,6 +772,7 @@ private FlagSlot(String name, Function getter, this.roleOnCase = roleOnCase; this.visibility = visibility; this.respondentIndex = respondentIndex; + this.representativeIndex = representativeIndex; } @Override From 3cadaf3be27dc628be5157ece56dfa6e547f01d3 Mon Sep 17 00:00:00 2001 From: rajaram Date: Tue, 16 Jun 2026 09:36:43 +0100 Subject: [PATCH 004/100] Show both Case flags and Support tabs to Admin users --- .../RoleToAccessProfiles-RetainAndDispose.json | 2 +- .../RoleToAccessProfiles-RetainAndDispose.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ccd-definitions/jurisdictions/england-wales/json/RoleToAccessProfiles/RoleToAccessProfiles-RetainAndDispose.json b/ccd-definitions/jurisdictions/england-wales/json/RoleToAccessProfiles/RoleToAccessProfiles-RetainAndDispose.json index 8ef639117c..da2f18fed4 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/RoleToAccessProfiles/RoleToAccessProfiles-RetainAndDispose.json +++ b/ccd-definitions/jurisdictions/england-wales/json/RoleToAccessProfiles/RoleToAccessProfiles-RetainAndDispose.json @@ -18,7 +18,7 @@ "CaseTypeID": "ET_EnglandWales", "RoleName": "idam:caseworker-employment-api", "ReadOnly": "N", - "AccessProfiles": "TTL_profile,caseworker-employment-api,caseworker-employment-caseflags" + "AccessProfiles": "TTL_profile,caseworker-employment-api,caseworker-employment-caseflags,caseworker-employment-support" }, { "LiveFrom": "01/01/2017", diff --git a/ccd-definitions/jurisdictions/scotland/json/RoleToAccessProfiles/RoleToAccessProfiles-RetainAndDispose.json b/ccd-definitions/jurisdictions/scotland/json/RoleToAccessProfiles/RoleToAccessProfiles-RetainAndDispose.json index d870330ae2..390b9f8289 100644 --- a/ccd-definitions/jurisdictions/scotland/json/RoleToAccessProfiles/RoleToAccessProfiles-RetainAndDispose.json +++ b/ccd-definitions/jurisdictions/scotland/json/RoleToAccessProfiles/RoleToAccessProfiles-RetainAndDispose.json @@ -18,7 +18,7 @@ "CaseTypeID": "ET_Scotland", "RoleName": "idam:caseworker-employment-api", "ReadOnly": "N", - "AccessProfiles": "TTL_profile,caseworker-employment-api,caseworker-employment-caseflags" + "AccessProfiles": "TTL_profile,caseworker-employment-api,caseworker-employment-caseflags,caseworker-employment-support" }, { "LiveFrom": "01/01/2017", From 362015c7c370c8836014e4a573c6ad52bd6c05d2 Mon Sep 17 00:00:00 2001 From: rajaram Date: Tue, 16 Jun 2026 12:09:34 +0100 Subject: [PATCH 005/100] CVE suppression added --- config/owasp/suppressions.xml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/config/owasp/suppressions.xml b/config/owasp/suppressions.xml index 9c84186bf4..c6579d50a2 100644 --- a/config/owasp/suppressions.xml +++ b/config/owasp/suppressions.xml @@ -16,6 +16,33 @@ ^pkg:maven/org\.hibernate\.validator/hibernate\-validator@.*$ CVE-2025-15104 + + CVE-2026-46340 + CVE-2026-48043 + CVE-2026-50009 + CVE-2026-47691 + CVE-2026-50020 + CVE-2026-50560 + CVE-2026-41003 + CVE-2026-44892 + CVE-2026-44893 + CVE-2026-48059 + CVE-2026-44894 + CVE-2026-44250 + CVE-2026-47244 + CVE-2026-44890 + CVE-2026-50010 + CVE-2026-50011 + CVE-2026-45416 + CVE-2026-40988 + CVE-2026-48748 + CVE-2026-44249 + CVE-2026-45536 + CVE-2026-48006 + CVE-2026-45673 + CVE-2026-45674 + CVE-2026-41694 + Date: Tue, 16 Jun 2026 16:27:31 +0100 Subject: [PATCH 006/100] Addressed review comments --- .../model/helper/CaseFlagConstants.java | 28 ++++++++++ .../CaseFlagsDataMigrationController.java | 6 +-- .../docmosis/service/CaseFlagsService.java | 53 +++++++++---------- ...dClaimantRepresentativeControllerTest.java | 10 ++-- .../CaseFlagsDataMigrationControllerTest.java | 19 ++++--- .../service/CaseFlagsServiceTest.java | 48 ++++++++--------- 6 files changed, 101 insertions(+), 63 deletions(-) diff --git a/et-shared/src/main/java/uk/gov/hmcts/ecm/common/model/helper/CaseFlagConstants.java b/et-shared/src/main/java/uk/gov/hmcts/ecm/common/model/helper/CaseFlagConstants.java index dff02df6e4..eb25963166 100644 --- a/et-shared/src/main/java/uk/gov/hmcts/ecm/common/model/helper/CaseFlagConstants.java +++ b/et-shared/src/main/java/uk/gov/hmcts/ecm/common/model/helper/CaseFlagConstants.java @@ -8,6 +8,34 @@ public class CaseFlagConstants { public static final String VEXATIOUS_LITIGANT = "Vexatious litigant"; public static final String DISRUPTIVE_CUSTOMER = "Unacceptable/disruptive customer behaviour"; + public static final String GRANTED = "Granted"; + public static final int NOT_INDEXED = -1; + + public static final String INTERNAL = "Internal"; + public static final String EXTERNAL = "External"; + public static final String CLAIMANT = "Claimant"; + public static final String RESPONDENT1 = "Respondent 1"; + public static final String RESPONDENT2 = "Respondent 2"; + public static final String RESPONDENT3 = "Respondent 3"; + public static final String RESPONDENT4 = "Respondent 4"; + public static final String RESPONDENT5 = "Respondent 5"; + public static final String RESPONDENT6 = "Respondent 6"; + public static final String RESPONDENT7 = "Respondent 7"; + public static final String RESPONDENT8 = "Respondent 8"; + public static final String RESPONDENT9 = "Respondent 9"; + public static final String RESPONDENT10 = "Respondent 10"; + public static final String CLAIMANT_REPRESENTATIVE = "Claimant Representative"; + public static final String REPRESENTATIVE1 = "Representative 1"; + public static final String REPRESENTATIVE2 = "Representative 2"; + public static final String REPRESENTATIVE3 = "Representative 3"; + public static final String REPRESENTATIVE4 = "Representative 4"; + public static final String REPRESENTATIVE5 = "Representative 5"; + public static final String REPRESENTATIVE6 = "Representative 6"; + public static final String REPRESENTATIVE7 = "Representative 7"; + public static final String REPRESENTATIVE8 = "Representative 8"; + public static final String REPRESENTATIVE9 = "Representative 9"; + public static final String REPRESENTATIVE10 = "Representative 10"; + private CaseFlagConstants() { // Class only provides constant values } diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsDataMigrationController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsDataMigrationController.java index 954aa55662..6fe4b8baa3 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsDataMigrationController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsDataMigrationController.java @@ -22,10 +22,10 @@ import static org.springframework.http.HttpStatus.FORBIDDEN; import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.CLAIMANT; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.INTERNAL; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.RESPONDENT1; import static uk.gov.hmcts.ethos.replacement.docmosis.helpers.CallbackRespHelper.getCallbackRespEntityErrors; -import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.CLAIMANT; -import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.INTERNAL; -import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.RESPONDENT1; @Slf4j @RequiredArgsConstructor diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java index 1624a01aea..be4d5458be 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java @@ -21,8 +21,34 @@ import javax.annotation.Nullable; import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.ACTIVE; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.CLAIMANT; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.CLAIMANT_REPRESENTATIVE; import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.DISRUPTIVE_CUSTOMER; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.EXTERNAL; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.GRANTED; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.INTERNAL; import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.LANGUAGE_INTERPRETER; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.NOT_INDEXED; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.REPRESENTATIVE1; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.REPRESENTATIVE10; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.REPRESENTATIVE2; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.REPRESENTATIVE3; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.REPRESENTATIVE4; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.REPRESENTATIVE5; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.REPRESENTATIVE6; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.REPRESENTATIVE7; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.REPRESENTATIVE8; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.REPRESENTATIVE9; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.RESPONDENT1; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.RESPONDENT10; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.RESPONDENT2; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.RESPONDENT3; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.RESPONDENT4; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.RESPONDENT5; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.RESPONDENT6; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.RESPONDENT7; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.RESPONDENT8; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.RESPONDENT9; import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.SIGN_LANGUAGE_INTERPRETER; import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.VEXATIOUS_LITIGANT; import static uk.gov.hmcts.ecm.common.model.helper.Constants.NO; @@ -32,33 +58,6 @@ @Slf4j @Service public class CaseFlagsService { - private static final String GRANTED = "Granted"; - private static final int NOT_INDEXED = -1; - - public static final String INTERNAL = "Internal"; - public static final String EXTERNAL = "External"; - public static final String CLAIMANT = "Claimant"; - public static final String RESPONDENT1 = "Respondent 1"; - public static final String RESPONDENT2 = "Respondent 2"; - public static final String RESPONDENT3 = "Respondent 3"; - public static final String RESPONDENT4 = "Respondent 4"; - public static final String RESPONDENT5 = "Respondent 5"; - public static final String RESPONDENT6 = "Respondent 6"; - public static final String RESPONDENT7 = "Respondent 7"; - public static final String RESPONDENT8 = "Respondent 8"; - public static final String RESPONDENT9 = "Respondent 9"; - public static final String RESPONDENT10 = "Respondent 10"; - public static final String CLAIMANT_REPRESENTATIVE = "Claimant Representative"; - public static final String REPRESENTATIVE1 = "Representative 1"; - public static final String REPRESENTATIVE2 = "Representative 2"; - public static final String REPRESENTATIVE3 = "Representative 3"; - public static final String REPRESENTATIVE4 = "Representative 4"; - public static final String REPRESENTATIVE5 = "Representative 5"; - public static final String REPRESENTATIVE6 = "Representative 6"; - public static final String REPRESENTATIVE7 = "Representative 7"; - public static final String REPRESENTATIVE8 = "Representative 8"; - public static final String REPRESENTATIVE9 = "Representative 9"; - public static final String REPRESENTATIVE10 = "Representative 10"; private static final List PARTY_FLAGS = List.of( claimantFlag(CaseData::getClaimantFlags, CaseData::setClaimantFlags, INTERNAL), diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeControllerTest.java index 314ce028d5..255ed098e3 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeControllerTest.java @@ -1,5 +1,6 @@ package uk.gov.hmcts.ethos.replacement.docmosis.controllers; +import lombok.SneakyThrows; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -82,7 +83,8 @@ void setUp() { } @Test - void testAboutToSubmitSetsClaimantRepresentativeId() throws Exception { + @SneakyThrows + void testAboutToSubmitSetsClaimantRepresentativeId() { when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); mockMvc.perform(post(ABOUT_TO_SUBMIT_URL) .content(jsonMapper.toJson(ccdRequest)) @@ -98,7 +100,8 @@ void testAboutToSubmitSetsClaimantRepresentativeId() throws Exception { } @Test - void testAmendClaimantRepSubmitted() throws Exception { + @SneakyThrows + void testAmendClaimantRepSubmitted() { when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); mockMvc.perform(post(SUBMITTED_URL) .content(jsonMapper.toJson(callbackRequest)) @@ -115,7 +118,8 @@ void testAmendClaimantRepSubmitted() throws Exception { } @Test - void testAmendClaimantRepSubmittedSetsUpCaseFlagsWhenEnabled() throws Exception { + @SneakyThrows + void testAmendClaimantRepSubmittedSetsUpCaseFlagsWhenEnabled() { when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); when(featureToggleService.isCaseFlagsEnabled()).thenReturn(true); diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsDataMigrationControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsDataMigrationControllerTest.java index 1394f8bff6..4909f38170 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsDataMigrationControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsDataMigrationControllerTest.java @@ -3,6 +3,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; +import lombok.SneakyThrows; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -65,7 +66,8 @@ void setUp() throws URISyntaxException, IOException { } @Test - void shouldMigrateCaseFlags() throws Exception { + @SneakyThrows + void shouldMigrateCaseFlags() { when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); mvc.perform(post(CASE_FLAGS_DATA_MIGRATION) .content(requestContent.toString()) @@ -80,7 +82,8 @@ void shouldMigrateCaseFlags() throws Exception { } @Test - void shouldAddCaseFlagGroupIdAndVisibilityForPreviouslyMigratedFlags() throws Exception { + @SneakyThrows + void shouldAddCaseFlagGroupIdAndVisibilityForPreviouslyMigratedFlags() { when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); mvc.perform(post(CASE_FLAGS_DATA_MIGRATION) @@ -95,7 +98,8 @@ void shouldAddCaseFlagGroupIdAndVisibilityForPreviouslyMigratedFlags() throws Ex } @Test - void shouldNotOverwriteExistingCaseFlagGroupIdAndVisibility() throws Exception { + @SneakyThrows + void shouldNotOverwriteExistingCaseFlagGroupIdAndVisibility() { when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); ObjectNode caseData = (ObjectNode) requestContent.at("/case_details/case_data"); @@ -118,7 +122,8 @@ void shouldNotOverwriteExistingCaseFlagGroupIdAndVisibility() throws Exception { } @Test - void shouldMigrateCaseFlags_tokenFail() throws Exception { + @SneakyThrows + void shouldMigrateCaseFlags_tokenFail() { when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(false); mvc.perform(post(CASE_FLAGS_DATA_MIGRATION) .content(requestContent.toString()) @@ -128,7 +133,8 @@ void shouldMigrateCaseFlags_tokenFail() throws Exception { } @Test - void shouldRollbackCaseFlags() throws Exception { + @SneakyThrows + void shouldRollbackCaseFlags() { when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); mvc.perform(post(CASE_FLAGS_DATA_ROLLBACK) .content(requestContent.toString()) @@ -141,7 +147,8 @@ void shouldRollbackCaseFlags() throws Exception { } @Test - void shouldRollbackCaseFlags_tokenFail() throws Exception { + @SneakyThrows + void shouldRollbackCaseFlags_tokenFail() { when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(false); mvc.perform(post(CASE_FLAGS_DATA_ROLLBACK) .content(requestContent.toString()) diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java index cc5344e1f5..fdfebc7ecc 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java @@ -39,38 +39,38 @@ import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.ACTIVE; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.CLAIMANT; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.CLAIMANT_REPRESENTATIVE; import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.DISRUPTIVE_CUSTOMER; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.EXTERNAL; import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.INACTIVE; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.INTERNAL; import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.LANGUAGE_INTERPRETER; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.REPRESENTATIVE1; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.REPRESENTATIVE10; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.REPRESENTATIVE2; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.REPRESENTATIVE3; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.REPRESENTATIVE4; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.REPRESENTATIVE5; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.REPRESENTATIVE6; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.REPRESENTATIVE7; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.REPRESENTATIVE8; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.REPRESENTATIVE9; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.RESPONDENT1; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.RESPONDENT10; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.RESPONDENT2; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.RESPONDENT3; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.RESPONDENT4; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.RESPONDENT5; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.RESPONDENT6; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.RESPONDENT7; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.RESPONDENT8; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.RESPONDENT9; import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.SIGN_LANGUAGE_INTERPRETER; import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.VEXATIOUS_LITIGANT; import static uk.gov.hmcts.ecm.common.model.helper.Constants.NO; import static uk.gov.hmcts.ecm.common.model.helper.Constants.TSE_APP_RESTRICT_PUBLICITY; import static uk.gov.hmcts.ecm.common.model.helper.Constants.YES; -import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.CLAIMANT; -import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.CLAIMANT_REPRESENTATIVE; -import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.EXTERNAL; -import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.INTERNAL; -import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.REPRESENTATIVE1; -import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.REPRESENTATIVE10; -import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.REPRESENTATIVE2; -import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.REPRESENTATIVE3; -import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.REPRESENTATIVE4; -import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.REPRESENTATIVE5; -import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.REPRESENTATIVE6; -import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.REPRESENTATIVE7; -import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.REPRESENTATIVE8; -import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.REPRESENTATIVE9; -import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.RESPONDENT1; -import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.RESPONDENT10; -import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.RESPONDENT2; -import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.RESPONDENT3; -import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.RESPONDENT4; -import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.RESPONDENT5; -import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.RESPONDENT6; -import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.RESPONDENT7; -import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.RESPONDENT8; -import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService.RESPONDENT9; @ExtendWith(SpringExtension.class) class CaseFlagsServiceTest { From f979bd997f006bbdffdf804f4bf9f22b074db0ea Mon Sep 17 00:00:00 2001 From: Mehmet Tahir Dede <105645217+JustMehmet@users.noreply.github.com> Date: Tue, 16 Jun 2026 17:36:11 +0100 Subject: [PATCH 007/100] Remove multiple CVEs from suppressions.xml --- config/owasp/suppressions.xml | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/config/owasp/suppressions.xml b/config/owasp/suppressions.xml index c6579d50a2..9c84186bf4 100644 --- a/config/owasp/suppressions.xml +++ b/config/owasp/suppressions.xml @@ -16,33 +16,6 @@ ^pkg:maven/org\.hibernate\.validator/hibernate\-validator@.*$ CVE-2025-15104 - - CVE-2026-46340 - CVE-2026-48043 - CVE-2026-50009 - CVE-2026-47691 - CVE-2026-50020 - CVE-2026-50560 - CVE-2026-41003 - CVE-2026-44892 - CVE-2026-44893 - CVE-2026-48059 - CVE-2026-44894 - CVE-2026-44250 - CVE-2026-47244 - CVE-2026-44890 - CVE-2026-50010 - CVE-2026-50011 - CVE-2026-45416 - CVE-2026-40988 - CVE-2026-48748 - CVE-2026-44249 - CVE-2026-45536 - CVE-2026-48006 - CVE-2026-45673 - CVE-2026-45674 - CVE-2026-41694 - Date: Wed, 17 Jun 2026 15:51:39 +0100 Subject: [PATCH 008/100] Addressed review comments --- .../hmcts/et/common/model/ccd/CaseData.java | 51 +-- .../common/model/ccd/types/AllPartyFlags.java | 62 +++ .../CaseFlagsDataMigrationController.java | 21 +- .../docmosis/service/CaseFlagsService.java | 169 +++++---- .../CaseFlagsDataMigrationControllerTest.java | 10 +- .../service/CaseFlagsServiceTest.java | 353 ++++++++++-------- 6 files changed, 399 insertions(+), 267 deletions(-) create mode 100644 et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/types/AllPartyFlags.java diff --git a/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/CaseData.java b/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/CaseData.java index 81eabc6c81..157ab88135 100644 --- a/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/CaseData.java +++ b/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/CaseData.java @@ -3,6 +3,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonUnwrapped; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; @@ -26,7 +27,7 @@ import uk.gov.hmcts.et.common.model.ccd.items.VettingJurCodesTypeItem; import uk.gov.hmcts.et.common.model.ccd.types.AddressLabelsAttributesType; import uk.gov.hmcts.et.common.model.ccd.types.AddressLabelsSelectionType; -import uk.gov.hmcts.et.common.model.ccd.types.CaseFlagsType; +import uk.gov.hmcts.et.common.model.ccd.types.AllPartyFlags; import uk.gov.hmcts.et.common.model.ccd.types.CaseLink; import uk.gov.hmcts.et.common.model.ccd.types.CaseNote; import uk.gov.hmcts.et.common.model.ccd.types.CasePreAcceptType; @@ -1557,52 +1558,8 @@ public class CaseData extends Et1CaseData { @JsonProperty("appealDocumentCollection") private List appealDocumentCollection; - // Case Flags - private CaseFlagsType caseFlags; - private CaseFlagsType claimantFlags; - private CaseFlagsType claimantExternalFlags; - private CaseFlagsType respondentFlags; - private CaseFlagsType respondentExternalFlags; - private CaseFlagsType respondent1Flags; - private CaseFlagsType respondent1ExternalFlags; - private CaseFlagsType respondent2Flags; - private CaseFlagsType respondent2ExternalFlags; - private CaseFlagsType respondent3Flags; - private CaseFlagsType respondent3ExternalFlags; - private CaseFlagsType respondent4Flags; - private CaseFlagsType respondent4ExternalFlags; - private CaseFlagsType respondent5Flags; - private CaseFlagsType respondent5ExternalFlags; - private CaseFlagsType respondent6Flags; - private CaseFlagsType respondent6ExternalFlags; - private CaseFlagsType respondent7Flags; - private CaseFlagsType respondent7ExternalFlags; - private CaseFlagsType respondent8Flags; - private CaseFlagsType respondent8ExternalFlags; - private CaseFlagsType respondent9Flags; - private CaseFlagsType respondent9ExternalFlags; - private CaseFlagsType claimantRepresentativeFlags; - private CaseFlagsType claimantRepresentativeExternalFlags; - private CaseFlagsType representativeFlags; - private CaseFlagsType representativeExternalFlags; - private CaseFlagsType representative1Flags; - private CaseFlagsType representative1ExternalFlags; - private CaseFlagsType representative2Flags; - private CaseFlagsType representative2ExternalFlags; - private CaseFlagsType representative3Flags; - private CaseFlagsType representative3ExternalFlags; - private CaseFlagsType representative4Flags; - private CaseFlagsType representative4ExternalFlags; - private CaseFlagsType representative5Flags; - private CaseFlagsType representative5ExternalFlags; - private CaseFlagsType representative6Flags; - private CaseFlagsType representative6ExternalFlags; - private CaseFlagsType representative7Flags; - private CaseFlagsType representative7ExternalFlags; - private CaseFlagsType representative8Flags; - private CaseFlagsType representative8ExternalFlags; - private CaseFlagsType representative9Flags; - private CaseFlagsType representative9ExternalFlags; + @JsonUnwrapped + private AllPartyFlags allPartyFlags; //et-hearings-api @JsonProperty("autoListFlag") diff --git a/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/types/AllPartyFlags.java b/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/types/AllPartyFlags.java new file mode 100644 index 0000000000..3a391bafe3 --- /dev/null +++ b/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/types/AllPartyFlags.java @@ -0,0 +1,62 @@ +package uk.gov.hmcts.et.common.model.ccd.types; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.extern.jackson.Jacksonized; + +@Data +@Builder(toBuilder = true) +@AllArgsConstructor +@NoArgsConstructor +@Jacksonized +@JsonIgnoreProperties(ignoreUnknown = true) +public class AllPartyFlags { + private CaseFlagsType caseFlags; + private CaseFlagsType claimantFlags; + private CaseFlagsType claimantExternalFlags; + private CaseFlagsType respondentFlags; + private CaseFlagsType respondentExternalFlags; + private CaseFlagsType respondent1Flags; + private CaseFlagsType respondent1ExternalFlags; + private CaseFlagsType respondent2Flags; + private CaseFlagsType respondent2ExternalFlags; + private CaseFlagsType respondent3Flags; + private CaseFlagsType respondent3ExternalFlags; + private CaseFlagsType respondent4Flags; + private CaseFlagsType respondent4ExternalFlags; + private CaseFlagsType respondent5Flags; + private CaseFlagsType respondent5ExternalFlags; + private CaseFlagsType respondent6Flags; + private CaseFlagsType respondent6ExternalFlags; + private CaseFlagsType respondent7Flags; + private CaseFlagsType respondent7ExternalFlags; + private CaseFlagsType respondent8Flags; + private CaseFlagsType respondent8ExternalFlags; + private CaseFlagsType respondent9Flags; + private CaseFlagsType respondent9ExternalFlags; + private CaseFlagsType claimantRepresentativeFlags; + private CaseFlagsType claimantRepresentativeExternalFlags; + private CaseFlagsType representativeFlags; + private CaseFlagsType representativeExternalFlags; + private CaseFlagsType representative1Flags; + private CaseFlagsType representative1ExternalFlags; + private CaseFlagsType representative2Flags; + private CaseFlagsType representative2ExternalFlags; + private CaseFlagsType representative3Flags; + private CaseFlagsType representative3ExternalFlags; + private CaseFlagsType representative4Flags; + private CaseFlagsType representative4ExternalFlags; + private CaseFlagsType representative5Flags; + private CaseFlagsType representative5ExternalFlags; + private CaseFlagsType representative6Flags; + private CaseFlagsType representative6ExternalFlags; + private CaseFlagsType representative7Flags; + private CaseFlagsType representative7ExternalFlags; + private CaseFlagsType representative8Flags; + private CaseFlagsType representative8ExternalFlags; + private CaseFlagsType representative9Flags; + private CaseFlagsType representative9ExternalFlags; +} diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsDataMigrationController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsDataMigrationController.java index 6fe4b8baa3..cfc593dd6c 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsDataMigrationController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsDataMigrationController.java @@ -15,6 +15,7 @@ import uk.gov.hmcts.et.common.model.ccd.CCDCallbackResponse; import uk.gov.hmcts.et.common.model.ccd.CCDRequest; import uk.gov.hmcts.et.common.model.ccd.CaseData; +import uk.gov.hmcts.et.common.model.ccd.types.CaseFlagsType; import uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService; import uk.gov.hmcts.ethos.replacement.docmosis.service.VerifyTokenService; @@ -59,24 +60,26 @@ public ResponseEntity addCaseFlagsData( CaseData caseData = ccdRequest.getCaseDetails().getCaseData(); caseFlagsService.setupCaseFlags(caseData); + CaseFlagsType claimantFlags = caseData.getAllPartyFlags().getClaimantFlags(); + CaseFlagsType respondentFlags = caseData.getAllPartyFlags().getRespondentFlags(); /* Add visibility and group ID fields for the claimant and the first respondent records that were already migrated in Case Flag v1.0. */ - if (caseData.getClaimantFlags().getGroupId() == null) { - caseData.getClaimantFlags().setGroupId(CLAIMANT); - caseData.getClaimantFlags().setVisibility(INTERNAL); + if (claimantFlags.getGroupId() == null) { + claimantFlags.setGroupId(CLAIMANT); + claimantFlags.setVisibility(INTERNAL); } - if (caseData.getRespondentFlags().getGroupId() == null) { - caseData.getRespondentFlags().setRoleOnCase(RESPONDENT1); - caseData.getRespondentFlags().setGroupId(RESPONDENT1); - caseData.getRespondentFlags().setVisibility(INTERNAL); + if (respondentFlags.getGroupId() == null) { + respondentFlags.setRoleOnCase(RESPONDENT1); + respondentFlags.setGroupId(RESPONDENT1); + respondentFlags.setVisibility(INTERNAL); } log.info("Migrating existing case: {} for claimant: {}, respondent: {},", ccdRequest.getCaseDetails().getCaseTypeId(), - caseData.getClaimantFlags().getPartyName(), - caseData.getRespondentFlags().getPartyName()); + claimantFlags.getPartyName(), + respondentFlags.getPartyName()); return getCallbackRespEntityErrors(List.of(), caseData); } diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java index be4d5458be..95c78ea599 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java @@ -10,6 +10,7 @@ import uk.gov.hmcts.et.common.model.ccd.items.GenericTypeItem; import uk.gov.hmcts.et.common.model.ccd.items.ListTypeItem; import uk.gov.hmcts.et.common.model.ccd.items.TseAdminRecordDecisionTypeItem; +import uk.gov.hmcts.et.common.model.ccd.types.AllPartyFlags; import uk.gov.hmcts.et.common.model.ccd.types.CaseFlagsType; import uk.gov.hmcts.et.common.model.ccd.types.RestrictedReportingType; @@ -60,90 +61,109 @@ public class CaseFlagsService { private static final List PARTY_FLAGS = List.of( - claimantFlag(CaseData::getClaimantFlags, CaseData::setClaimantFlags, INTERNAL), - claimantFlag(CaseData::getClaimantExternalFlags, CaseData::setClaimantExternalFlags, EXTERNAL), + claimantFlag(AllPartyFlags::getClaimantFlags, AllPartyFlags::setClaimantFlags, INTERNAL), + claimantFlag(AllPartyFlags::getClaimantExternalFlags, AllPartyFlags::setClaimantExternalFlags, EXTERNAL), - respondentFlag(CaseData::getRespondentFlags, CaseData::setRespondentFlags, RESPONDENT1, INTERNAL, 0), - respondentFlag(CaseData::getRespondentExternalFlags, CaseData::setRespondentExternalFlags, + respondentFlag(AllPartyFlags::getRespondentFlags, AllPartyFlags::setRespondentFlags, + RESPONDENT1, INTERNAL, 0), + respondentFlag(AllPartyFlags::getRespondentExternalFlags, AllPartyFlags::setRespondentExternalFlags, RESPONDENT1, EXTERNAL, 0), - respondentFlag(CaseData::getRespondent1Flags, CaseData::setRespondent1Flags, RESPONDENT2, INTERNAL, 1), - respondentFlag(CaseData::getRespondent1ExternalFlags, CaseData::setRespondent1ExternalFlags, + respondentFlag(AllPartyFlags::getRespondent1Flags, AllPartyFlags::setRespondent1Flags, + RESPONDENT2, INTERNAL, 1), + respondentFlag(AllPartyFlags::getRespondent1ExternalFlags, AllPartyFlags::setRespondent1ExternalFlags, RESPONDENT2, EXTERNAL, 1), - respondentFlag(CaseData::getRespondent2Flags, CaseData::setRespondent2Flags, RESPONDENT3, INTERNAL, 2), - respondentFlag(CaseData::getRespondent2ExternalFlags, CaseData::setRespondent2ExternalFlags, + respondentFlag(AllPartyFlags::getRespondent2Flags, AllPartyFlags::setRespondent2Flags, + RESPONDENT3, INTERNAL, 2), + respondentFlag(AllPartyFlags::getRespondent2ExternalFlags, AllPartyFlags::setRespondent2ExternalFlags, RESPONDENT3, EXTERNAL, 2), - respondentFlag(CaseData::getRespondent3Flags, CaseData::setRespondent3Flags, RESPONDENT4, INTERNAL, 3), - respondentFlag(CaseData::getRespondent3ExternalFlags, CaseData::setRespondent3ExternalFlags, + respondentFlag(AllPartyFlags::getRespondent3Flags, AllPartyFlags::setRespondent3Flags, + RESPONDENT4, INTERNAL, 3), + respondentFlag(AllPartyFlags::getRespondent3ExternalFlags, AllPartyFlags::setRespondent3ExternalFlags, RESPONDENT4, EXTERNAL, 3), - respondentFlag(CaseData::getRespondent4Flags, CaseData::setRespondent4Flags, RESPONDENT5, INTERNAL, 4), - respondentFlag(CaseData::getRespondent4ExternalFlags, CaseData::setRespondent4ExternalFlags, + respondentFlag(AllPartyFlags::getRespondent4Flags, AllPartyFlags::setRespondent4Flags, + RESPONDENT5, INTERNAL, 4), + respondentFlag(AllPartyFlags::getRespondent4ExternalFlags, AllPartyFlags::setRespondent4ExternalFlags, RESPONDENT5, EXTERNAL, 4), - respondentFlag(CaseData::getRespondent5Flags, CaseData::setRespondent5Flags, RESPONDENT6, INTERNAL, 5), - respondentFlag(CaseData::getRespondent5ExternalFlags, CaseData::setRespondent5ExternalFlags, + respondentFlag(AllPartyFlags::getRespondent5Flags, AllPartyFlags::setRespondent5Flags, + RESPONDENT6, INTERNAL, 5), + respondentFlag(AllPartyFlags::getRespondent5ExternalFlags, AllPartyFlags::setRespondent5ExternalFlags, RESPONDENT6, EXTERNAL, 5), - respondentFlag(CaseData::getRespondent6Flags, CaseData::setRespondent6Flags, RESPONDENT7, INTERNAL, 6), - respondentFlag(CaseData::getRespondent6ExternalFlags, CaseData::setRespondent6ExternalFlags, + respondentFlag(AllPartyFlags::getRespondent6Flags, AllPartyFlags::setRespondent6Flags, + RESPONDENT7, INTERNAL, 6), + respondentFlag(AllPartyFlags::getRespondent6ExternalFlags, AllPartyFlags::setRespondent6ExternalFlags, RESPONDENT7, EXTERNAL, 6), - respondentFlag(CaseData::getRespondent7Flags, CaseData::setRespondent7Flags, RESPONDENT8, INTERNAL, 7), - respondentFlag(CaseData::getRespondent7ExternalFlags, CaseData::setRespondent7ExternalFlags, + respondentFlag(AllPartyFlags::getRespondent7Flags, AllPartyFlags::setRespondent7Flags, + RESPONDENT8, INTERNAL, 7), + respondentFlag(AllPartyFlags::getRespondent7ExternalFlags, AllPartyFlags::setRespondent7ExternalFlags, RESPONDENT8, EXTERNAL, 7), - respondentFlag(CaseData::getRespondent8Flags, CaseData::setRespondent8Flags, RESPONDENT9, INTERNAL, 8), - respondentFlag(CaseData::getRespondent8ExternalFlags, CaseData::setRespondent8ExternalFlags, + respondentFlag(AllPartyFlags::getRespondent8Flags, AllPartyFlags::setRespondent8Flags, + RESPONDENT9, INTERNAL, 8), + respondentFlag(AllPartyFlags::getRespondent8ExternalFlags, AllPartyFlags::setRespondent8ExternalFlags, RESPONDENT9, EXTERNAL, 8), - respondentFlag(CaseData::getRespondent9Flags, CaseData::setRespondent9Flags, RESPONDENT10, + respondentFlag(AllPartyFlags::getRespondent9Flags, AllPartyFlags::setRespondent9Flags, RESPONDENT10, INTERNAL, 9), - respondentFlag(CaseData::getRespondent9ExternalFlags, CaseData::setRespondent9ExternalFlags, + respondentFlag(AllPartyFlags::getRespondent9ExternalFlags, AllPartyFlags::setRespondent9ExternalFlags, RESPONDENT10, EXTERNAL, 9), - claimantRepresentativeFlag(CaseData::getClaimantRepresentativeFlags, - CaseData::setClaimantRepresentativeFlags, INTERNAL), - claimantRepresentativeFlag(CaseData::getClaimantRepresentativeExternalFlags, - CaseData::setClaimantRepresentativeExternalFlags, EXTERNAL), + claimantRepresentativeFlag(AllPartyFlags::getClaimantRepresentativeFlags, + AllPartyFlags::setClaimantRepresentativeFlags, INTERNAL), + claimantRepresentativeFlag(AllPartyFlags::getClaimantRepresentativeExternalFlags, + AllPartyFlags::setClaimantRepresentativeExternalFlags, EXTERNAL), - representativeFlag(CaseData::getRepresentativeFlags, CaseData::setRepresentativeFlags, + representativeFlag(AllPartyFlags::getRepresentativeFlags, AllPartyFlags::setRepresentativeFlags, REPRESENTATIVE1, INTERNAL, 0), - representativeFlag(CaseData::getRepresentativeExternalFlags, CaseData::setRepresentativeExternalFlags, + representativeFlag(AllPartyFlags::getRepresentativeExternalFlags, + AllPartyFlags::setRepresentativeExternalFlags, REPRESENTATIVE1, EXTERNAL, 0), - representativeFlag(CaseData::getRepresentative1Flags, CaseData::setRepresentative1Flags, + representativeFlag(AllPartyFlags::getRepresentative1Flags, AllPartyFlags::setRepresentative1Flags, REPRESENTATIVE2, INTERNAL, 1), - representativeFlag(CaseData::getRepresentative1ExternalFlags, CaseData::setRepresentative1ExternalFlags, + representativeFlag(AllPartyFlags::getRepresentative1ExternalFlags, + AllPartyFlags::setRepresentative1ExternalFlags, REPRESENTATIVE2, EXTERNAL, 1), - representativeFlag(CaseData::getRepresentative2Flags, CaseData::setRepresentative2Flags, + representativeFlag(AllPartyFlags::getRepresentative2Flags, AllPartyFlags::setRepresentative2Flags, REPRESENTATIVE3, INTERNAL, 2), - representativeFlag(CaseData::getRepresentative2ExternalFlags, CaseData::setRepresentative2ExternalFlags, + representativeFlag(AllPartyFlags::getRepresentative2ExternalFlags, + AllPartyFlags::setRepresentative2ExternalFlags, REPRESENTATIVE3, EXTERNAL, 2), - representativeFlag(CaseData::getRepresentative3Flags, CaseData::setRepresentative3Flags, + representativeFlag(AllPartyFlags::getRepresentative3Flags, AllPartyFlags::setRepresentative3Flags, REPRESENTATIVE4, INTERNAL, 3), - representativeFlag(CaseData::getRepresentative3ExternalFlags, CaseData::setRepresentative3ExternalFlags, + representativeFlag(AllPartyFlags::getRepresentative3ExternalFlags, + AllPartyFlags::setRepresentative3ExternalFlags, REPRESENTATIVE4, EXTERNAL, 3), - representativeFlag(CaseData::getRepresentative4Flags, CaseData::setRepresentative4Flags, + representativeFlag(AllPartyFlags::getRepresentative4Flags, AllPartyFlags::setRepresentative4Flags, REPRESENTATIVE5, INTERNAL, 4), - representativeFlag(CaseData::getRepresentative4ExternalFlags, CaseData::setRepresentative4ExternalFlags, + representativeFlag(AllPartyFlags::getRepresentative4ExternalFlags, + AllPartyFlags::setRepresentative4ExternalFlags, REPRESENTATIVE5, EXTERNAL, 4), - representativeFlag(CaseData::getRepresentative5Flags, CaseData::setRepresentative5Flags, + representativeFlag(AllPartyFlags::getRepresentative5Flags, AllPartyFlags::setRepresentative5Flags, REPRESENTATIVE6, INTERNAL, 5), - representativeFlag(CaseData::getRepresentative5ExternalFlags, CaseData::setRepresentative5ExternalFlags, + representativeFlag(AllPartyFlags::getRepresentative5ExternalFlags, + AllPartyFlags::setRepresentative5ExternalFlags, REPRESENTATIVE6, EXTERNAL, 5), - representativeFlag(CaseData::getRepresentative6Flags, CaseData::setRepresentative6Flags, + representativeFlag(AllPartyFlags::getRepresentative6Flags, AllPartyFlags::setRepresentative6Flags, REPRESENTATIVE7, INTERNAL, 6), - representativeFlag(CaseData::getRepresentative6ExternalFlags, CaseData::setRepresentative6ExternalFlags, + representativeFlag(AllPartyFlags::getRepresentative6ExternalFlags, + AllPartyFlags::setRepresentative6ExternalFlags, REPRESENTATIVE7, EXTERNAL, 6), - representativeFlag(CaseData::getRepresentative7Flags, CaseData::setRepresentative7Flags, + representativeFlag(AllPartyFlags::getRepresentative7Flags, AllPartyFlags::setRepresentative7Flags, REPRESENTATIVE8, INTERNAL, 7), - representativeFlag(CaseData::getRepresentative7ExternalFlags, CaseData::setRepresentative7ExternalFlags, + representativeFlag(AllPartyFlags::getRepresentative7ExternalFlags, + AllPartyFlags::setRepresentative7ExternalFlags, REPRESENTATIVE8, EXTERNAL, 7), - representativeFlag(CaseData::getRepresentative8Flags, CaseData::setRepresentative8Flags, + representativeFlag(AllPartyFlags::getRepresentative8Flags, AllPartyFlags::setRepresentative8Flags, REPRESENTATIVE9, INTERNAL, 8), - representativeFlag(CaseData::getRepresentative8ExternalFlags, CaseData::setRepresentative8ExternalFlags, + representativeFlag(AllPartyFlags::getRepresentative8ExternalFlags, + AllPartyFlags::setRepresentative8ExternalFlags, REPRESENTATIVE9, EXTERNAL, 8), - representativeFlag(CaseData::getRepresentative9Flags, CaseData::setRepresentative9Flags, + representativeFlag(AllPartyFlags::getRepresentative9Flags, AllPartyFlags::setRepresentative9Flags, REPRESENTATIVE10, INTERNAL, 9), - representativeFlag(CaseData::getRepresentative9ExternalFlags, CaseData::setRepresentative9ExternalFlags, + representativeFlag(AllPartyFlags::getRepresentative9ExternalFlags, + AllPartyFlags::setRepresentative9ExternalFlags, REPRESENTATIVE10, EXTERNAL, 9) ); public boolean caseFlagsSetupRequired(CaseData caseData) { - return caseData.getCaseFlags() == null + return getCaseFlags(caseData) == null || PARTY_FLAGS.stream() .filter(flag -> isRequired(caseData, flag)) .anyMatch(flag -> isMissingRole(caseData, flag)); @@ -155,8 +175,8 @@ public boolean caseFlagsSetupRequired(CaseData caseData) { * @param caseData Data about the current case */ public void setupCaseFlags(CaseData caseData) { - if (caseData.getCaseFlags() == null) { - caseData.setCaseFlags(CaseFlagsType.builder().build()); + if (getCaseFlags(caseData) == null) { + setCaseFlags(caseData, CaseFlagsType.builder().build()); } PARTY_FLAGS.stream() @@ -170,7 +190,7 @@ public void setupCaseFlags(CaseData caseData) { * @param caseData Data about the current case */ public void rollbackCaseFlags(CaseData caseData) { - caseData.setCaseFlags(null); + setCaseFlags(caseData, null); PARTY_FLAGS.forEach(flag -> flag.clear(caseData)); } @@ -202,15 +222,15 @@ public void setPrivateHearingFlag(CaseData caseData) { } private static PartyFlag claimantFlag( - Function getter, - BiConsumer setter, + Function getter, + BiConsumer setter, String visibility) { return new PartyFlag(getter, setter, PartyType.CLAIMANT, CLAIMANT, visibility, NOT_INDEXED); } private static PartyFlag respondentFlag( - Function getter, - BiConsumer setter, + Function getter, + BiConsumer setter, String roleOnCase, String visibility, int index) { @@ -218,22 +238,41 @@ private static PartyFlag respondentFlag( } private static PartyFlag claimantRepresentativeFlag( - Function getter, - BiConsumer setter, + Function getter, + BiConsumer setter, String visibility) { return new PartyFlag(getter, setter, PartyType.CLAIMANT_REPRESENTATIVE, CLAIMANT_REPRESENTATIVE, visibility, NOT_INDEXED); } private static PartyFlag representativeFlag( - Function getter, - BiConsumer setter, + Function getter, + BiConsumer setter, String roleOnCase, String visibility, int index) { return new PartyFlag(getter, setter, PartyType.RESPONDENT_REPRESENTATIVE, roleOnCase, visibility, index); } + private static CaseFlagsType getCaseFlags(CaseData caseData) { + AllPartyFlags allPartyFlags = caseData.getAllPartyFlags(); + return allPartyFlags == null ? null : allPartyFlags.getCaseFlags(); + } + + private static void setCaseFlags(CaseData caseData, CaseFlagsType caseFlags) { + if (caseFlags == null && caseData.getAllPartyFlags() == null) { + return; + } + getOrCreateAllPartyFlags(caseData).setCaseFlags(caseFlags); + } + + private static AllPartyFlags getOrCreateAllPartyFlags(CaseData caseData) { + if (caseData.getAllPartyFlags() == null) { + caseData.setAllPartyFlags(new AllPartyFlags()); + } + return caseData.getAllPartyFlags(); + } + private static boolean isRequired(CaseData caseData, PartyFlag flag) { return switch (flag.partyType()) { case CLAIMANT, CLAIMANT_REPRESENTATIVE -> true; @@ -366,23 +405,27 @@ private enum PartyType { } private record PartyFlag( - Function getter, - BiConsumer setter, + Function getter, + BiConsumer setter, PartyType partyType, String roleOnCase, String visibility, int index) { private CaseFlagsType get(CaseData caseData) { - return getter.apply(caseData); + AllPartyFlags allPartyFlags = caseData.getAllPartyFlags(); + return allPartyFlags == null ? null : getter.apply(allPartyFlags); } private void set(CaseData caseData, CaseFlagsType flags) { - setter.accept(caseData, flags); + setter.accept(getOrCreateAllPartyFlags(caseData), flags); } private void clear(CaseData caseData) { - setter.accept(caseData, null); + AllPartyFlags allPartyFlags = caseData.getAllPartyFlags(); + if (allPartyFlags != null) { + setter.accept(allPartyFlags, null); + } } } } diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsDataMigrationControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsDataMigrationControllerTest.java index 4909f38170..a12ca4a399 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsDataMigrationControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsDataMigrationControllerTest.java @@ -7,6 +7,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.ArgumentCaptor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.http.MediaType; @@ -29,6 +30,7 @@ import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -78,7 +80,11 @@ void shouldMigrateCaseFlags() { .andExpect(jsonPath(JsonMapper.ERRORS, notNullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(caseFlagsService).setupCaseFlags(any(CaseData.class)); + ArgumentCaptor caseDataCaptor = ArgumentCaptor.forClass(CaseData.class); + verify(caseFlagsService).setupCaseFlags(caseDataCaptor.capture()); + assertNotNull(caseDataCaptor.getValue().getAllPartyFlags()); + assertNotNull(caseDataCaptor.getValue().getAllPartyFlags().getClaimantFlags()); + assertNotNull(caseDataCaptor.getValue().getAllPartyFlags().getRespondentFlags()); } @Test @@ -144,6 +150,8 @@ void shouldRollbackCaseFlags() { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, notNullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); + + verify(caseFlagsService).rollbackCaseFlags(any(CaseData.class)); } @Test diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java index fdfebc7ecc..1343481254 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java @@ -15,6 +15,7 @@ import uk.gov.hmcts.et.common.model.ccd.items.RepresentedTypeRItem; import uk.gov.hmcts.et.common.model.ccd.items.RespondentSumTypeItem; import uk.gov.hmcts.et.common.model.ccd.items.TseAdminRecordDecisionTypeItem; +import uk.gov.hmcts.et.common.model.ccd.types.AllPartyFlags; import uk.gov.hmcts.et.common.model.ccd.types.CaseFlagsType; import uk.gov.hmcts.et.common.model.ccd.types.RepresentedTypeC; import uk.gov.hmcts.et.common.model.ccd.types.RepresentedTypeR; @@ -25,6 +26,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.function.BiConsumer; import java.util.function.Function; import java.util.stream.Stream; @@ -107,7 +109,7 @@ void caseFlagsSetupRequired_shouldBeFalseAfterAllRequiredCaseFlagsAreSetup() { @Test void caseFlagsSetupRequired_shouldBeTrueWhenCaseFlagsAreMissing() { caseFlagsService.setupCaseFlags(caseData); - caseData.setCaseFlags(null); + allPartyFlags(caseData).setCaseFlags(null); assertTrue(caseFlagsService.caseFlagsSetupRequired(caseData)); } @@ -117,7 +119,7 @@ void caseFlagsSetupRequired_shouldBeTrueWhenCaseFlagsAreMissing() { void caseFlagsSetupRequired_shouldBeTrueWhenAnyRequiredPartyFlagIsMissing(FlagSlot slot) { caseFlagsService.setupCaseFlags(caseData); - slot.setter.accept(caseData, null); + slot.set(caseData, null); assertTrue(caseFlagsService.caseFlagsSetupRequired(caseData)); } @@ -126,7 +128,7 @@ void caseFlagsSetupRequired_shouldBeTrueWhenAnyRequiredPartyFlagIsMissing(FlagSl @MethodSource("allPartyFlagSlots") void caseFlagsSetupRequired_shouldBeTrueWhenAnyRequiredPartyFlagRoleIsMissing(FlagSlot slot) { caseFlagsService.setupCaseFlags(caseData); - slot.getter.apply(caseData).setRoleOnCase(""); + Objects.requireNonNull(slot.get(caseData)).setRoleOnCase(""); assertTrue(caseFlagsService.caseFlagsSetupRequired(caseData)); } @@ -138,8 +140,8 @@ void caseFlagsSetupRequired_shouldNotRequireRespondentFlagsWhenThereAreNoRespond caseFlagsService.setupCaseFlags(caseData); assertFalse(caseFlagsService.caseFlagsSetupRequired(caseData)); - assertNull(caseData.getRespondentFlags()); - assertNull(caseData.getRespondentExternalFlags()); + assertNull(allPartyFlags(caseData).getRespondentFlags()); + assertNull(allPartyFlags(caseData).getRespondentExternalFlags()); } @Test @@ -150,7 +152,7 @@ void caseFlagsSetupRequired_shouldNotRequireRespondentFlagsWhenRespondentCollect assertFalse(caseFlagsService.caseFlagsSetupRequired(caseData)); respondentPartyFlagSlots() - .forEach(slot -> assertNull(slot.getter.apply(caseData), slot + " should not be populated")); + .forEach(slot -> assertNull(slot.get(caseData), slot + " should not be populated")); } @Test @@ -161,7 +163,7 @@ void caseFlagsSetupRequired_shouldNotRequireRespondentRepresentativeFlagsWhenThe assertFalse(caseFlagsService.caseFlagsSetupRequired(caseData)); respondentRepresentativePartyFlagSlots() - .forEach(slot -> assertNull(slot.getter.apply(caseData), slot + " should not be populated")); + .forEach(slot -> assertNull(slot.get(caseData), slot + " should not be populated")); } @Test @@ -171,19 +173,31 @@ void caseFlagsSetupRequired_shouldRequireClaimantRepresentativeFlagsEvenWhenClai caseFlagsService.setupCaseFlags(caseData); assertTrue(caseFlagsService.caseFlagsSetupRequired(caseData)); - assertNull(caseData.getClaimantRepresentativeFlags()); - assertNull(caseData.getClaimantRepresentativeExternalFlags()); + assertNull(allPartyFlags(caseData).getClaimantRepresentativeFlags()); + assertNull(allPartyFlags(caseData).getClaimantRepresentativeExternalFlags()); } @Test void setupCaseFlags_setsShellCaseFlagsForClaimantRespondentAndRepresentativeParties() { caseFlagsService.setupCaseFlags(caseData); - CaseFlagsType caseFlags = caseData.getCaseFlags(); + CaseFlagsType caseFlags = allPartyFlags(caseData).getCaseFlags(); assertThat(caseFlags.getPartyName(), is(nullValue())); assertThat(caseFlags.getRoleOnCase(), is(nullValue())); - allPartyFlagSlots().forEach(slot -> assertCaseFlag(slot, slot.getter.apply(caseData))); + allPartyFlagSlots().forEach(slot -> assertCaseFlag(slot, slot.get(caseData))); + } + + @Test + void setupCaseFlags_shouldCreateAllPartyFlagsHolderWhenAbsent() { + assertNull(caseData.getAllPartyFlags()); + + caseFlagsService.setupCaseFlags(caseData); + + assertNotNull(caseData.getAllPartyFlags()); + assertNotNull(allPartyFlags(caseData).getCaseFlags()); + assertNotNull(allPartyFlags(caseData).getClaimantFlags()); + assertNotNull(allPartyFlags(caseData).getClaimantExternalFlags()); } @Test @@ -194,9 +208,9 @@ void setupCaseFlags_shouldOnlyCreateRespondentFlagsForExistingRespondents() { respondentPartyFlagSlots().forEach(slot -> { if (slot.respondentIndex < 3) { - assertNotNull(slot.getter.apply(caseData), slot + " should be populated"); + assertNotNull(slot.get(caseData), slot + " should be populated"); } else { - assertNull(slot.getter.apply(caseData), slot + " should not be populated"); + assertNull(slot.get(caseData), slot + " should not be populated"); } }); } @@ -209,9 +223,9 @@ void setupCaseFlags_shouldOnlyCreateRespondentRepresentativeFlagsForExistingRepr respondentRepresentativePartyFlagSlots().forEach(slot -> { if (slot.representativeIndex < 3) { - assertNotNull(slot.getter.apply(caseData), slot + " should be populated"); + assertNotNull(slot.get(caseData), slot + " should be populated"); } else { - assertNull(slot.getter.apply(caseData), slot + " should not be populated"); + assertNull(slot.get(caseData), slot + " should not be populated"); } }); } @@ -222,15 +236,15 @@ void setupCaseFlags_shouldNotCreateClaimantRepresentativeFlagsWhenClaimantRepres caseFlagsService.setupCaseFlags(caseData); - assertNull(caseData.getClaimantRepresentativeFlags()); - assertNull(caseData.getClaimantRepresentativeExternalFlags()); + assertNull(allPartyFlags(caseData).getClaimantRepresentativeFlags()); + assertNull(allPartyFlags(caseData).getClaimantRepresentativeExternalFlags()); } @ParameterizedTest(name = "{0}") @MethodSource("allPartyFlagSlots") void setupCaseFlags_shouldRecreatePartyFlagsWhenRoleIsMissing(FlagSlot slot) { caseFlagsService.setupCaseFlags(caseData); - slot.setter.accept(caseData, CaseFlagsType.builder() + slot.set(caseData, CaseFlagsType.builder() .partyName("Old name") .roleOnCase("") .groupId("old-group") @@ -239,7 +253,7 @@ void setupCaseFlags_shouldRecreatePartyFlagsWhenRoleIsMissing(FlagSlot slot) { caseFlagsService.setupCaseFlags(caseData); - assertCaseFlag(slot, slot.getter.apply(caseData)); + assertCaseFlag(slot, slot.get(caseData)); } @Test @@ -247,12 +261,19 @@ void rollbackCaseFlags_shouldSetToNull() { caseFlagsService.setupCaseFlags(caseData); caseFlagsService.rollbackCaseFlags(caseData); - assertThat(caseData.getCaseFlags(), is(nullValue())); - assertThat(caseData.getClaimantFlags(), is(nullValue())); - assertThat(caseData.getRespondentFlags(), is(nullValue())); - assertThat(caseData.getClaimantExternalFlags(), is(nullValue())); - assertThat(caseData.getRespondentExternalFlags(), is(nullValue())); - allPartyFlagSlots().forEach(slot -> assertNull(slot.getter.apply(caseData), slot + " should be cleared")); + assertThat(allPartyFlags(caseData).getCaseFlags(), is(nullValue())); + assertThat(allPartyFlags(caseData).getClaimantFlags(), is(nullValue())); + assertThat(allPartyFlags(caseData).getRespondentFlags(), is(nullValue())); + assertThat(allPartyFlags(caseData).getClaimantExternalFlags(), is(nullValue())); + assertThat(allPartyFlags(caseData).getRespondentExternalFlags(), is(nullValue())); + allPartyFlagSlots().forEach(slot -> assertNull(slot.get(caseData), slot + " should be cleared")); + } + + @Test + void rollbackCaseFlags_shouldNotCreateAllPartyFlagsWhenAbsent() { + caseFlagsService.rollbackCaseFlags(caseData); + + assertNull(caseData.getAllPartyFlags()); } @Test @@ -263,15 +284,17 @@ void setupCaseFlags_shouldUpdateClaimantFlagsWhenNameChanges() { caseFlagsService.setupCaseFlags(caseData); - assertEquals(updatedClaimantName, caseData.getClaimantFlags().getPartyName()); - assertEquals(CLAIMANT, caseData.getClaimantFlags().getRoleOnCase()); - assertEquals(CLAIMANT, caseData.getClaimantFlags().getGroupId()); - assertEquals(INTERNAL, caseData.getClaimantFlags().getVisibility()); + CaseFlagsType claimantFlags = allPartyFlags(caseData).getClaimantFlags(); + assertEquals(updatedClaimantName, claimantFlags.getPartyName()); + assertEquals(CLAIMANT, claimantFlags.getRoleOnCase()); + assertEquals(CLAIMANT, claimantFlags.getGroupId()); + assertEquals(INTERNAL, claimantFlags.getVisibility()); - assertEquals(updatedClaimantName, caseData.getClaimantExternalFlags().getPartyName()); - assertEquals(CLAIMANT, caseData.getClaimantExternalFlags().getRoleOnCase()); - assertEquals(CLAIMANT, caseData.getClaimantExternalFlags().getGroupId()); - assertEquals(EXTERNAL, caseData.getClaimantExternalFlags().getVisibility()); + CaseFlagsType claimantExternalFlags = allPartyFlags(caseData).getClaimantExternalFlags(); + assertEquals(updatedClaimantName, claimantExternalFlags.getPartyName()); + assertEquals(CLAIMANT, claimantExternalFlags.getRoleOnCase()); + assertEquals(CLAIMANT, claimantExternalFlags.getGroupId()); + assertEquals(EXTERNAL, claimantExternalFlags.getVisibility()); } @ParameterizedTest(name = "{0}") @@ -286,10 +309,10 @@ void setupCaseFlags_shouldUpdateRespondentFlagsWhenNameChanges(FlagSlot slot) { caseFlagsService.setupCaseFlags(caseData); - assertEquals(updatedRespondentName, slot.getter.apply(caseData).getPartyName()); - assertEquals(slot.roleOnCase, slot.getter.apply(caseData).getRoleOnCase()); - assertEquals(slot.roleOnCase, slot.getter.apply(caseData).getGroupId()); - assertEquals(slot.visibility, slot.getter.apply(caseData).getVisibility()); + assertEquals(updatedRespondentName, Objects.requireNonNull(slot.get(caseData)).getPartyName()); + assertEquals(slot.roleOnCase, Objects.requireNonNull(slot.get(caseData)).getRoleOnCase()); + assertEquals(slot.roleOnCase, Objects.requireNonNull(slot.get(caseData)).getGroupId()); + assertEquals(slot.visibility, Objects.requireNonNull(slot.get(caseData)).getVisibility()); } @Test @@ -300,15 +323,18 @@ void setupCaseFlags_shouldUpdateClaimantRepresentativeFlagsWhenNameChanges() { caseFlagsService.setupCaseFlags(caseData); - assertEquals(updatedRepresentativeName, caseData.getClaimantRepresentativeFlags().getPartyName()); - assertEquals(CLAIMANT_REPRESENTATIVE, caseData.getClaimantRepresentativeFlags().getRoleOnCase()); - assertEquals(CLAIMANT_REPRESENTATIVE, caseData.getClaimantRepresentativeFlags().getGroupId()); - assertEquals(INTERNAL, caseData.getClaimantRepresentativeFlags().getVisibility()); + CaseFlagsType claimantRepresentativeFlags = allPartyFlags(caseData).getClaimantRepresentativeFlags(); + assertEquals(updatedRepresentativeName, claimantRepresentativeFlags.getPartyName()); + assertEquals(CLAIMANT_REPRESENTATIVE, claimantRepresentativeFlags.getRoleOnCase()); + assertEquals(CLAIMANT_REPRESENTATIVE, claimantRepresentativeFlags.getGroupId()); + assertEquals(INTERNAL, claimantRepresentativeFlags.getVisibility()); - assertEquals(updatedRepresentativeName, caseData.getClaimantRepresentativeExternalFlags().getPartyName()); - assertEquals(CLAIMANT_REPRESENTATIVE, caseData.getClaimantRepresentativeExternalFlags().getRoleOnCase()); - assertEquals(CLAIMANT_REPRESENTATIVE, caseData.getClaimantRepresentativeExternalFlags().getGroupId()); - assertEquals(EXTERNAL, caseData.getClaimantRepresentativeExternalFlags().getVisibility()); + CaseFlagsType claimantRepresentativeExternalFlags = + allPartyFlags(caseData).getClaimantRepresentativeExternalFlags(); + assertEquals(updatedRepresentativeName, claimantRepresentativeExternalFlags.getPartyName()); + assertEquals(CLAIMANT_REPRESENTATIVE, claimantRepresentativeExternalFlags.getRoleOnCase()); + assertEquals(CLAIMANT_REPRESENTATIVE, claimantRepresentativeExternalFlags.getGroupId()); + assertEquals(EXTERNAL, claimantRepresentativeExternalFlags.getVisibility()); } @ParameterizedTest(name = "{0}") @@ -323,16 +349,16 @@ void setupCaseFlags_shouldUpdateRespondentRepresentativeFlagsWhenNameChanges(Fla caseFlagsService.setupCaseFlags(caseData); - assertEquals(updatedRepresentativeName, slot.getter.apply(caseData).getPartyName()); - assertEquals(slot.roleOnCase, slot.getter.apply(caseData).getRoleOnCase()); - assertEquals(slot.roleOnCase, slot.getter.apply(caseData).getGroupId()); - assertEquals(slot.visibility, slot.getter.apply(caseData).getVisibility()); + assertEquals(updatedRepresentativeName, Objects.requireNonNull(slot.get(caseData)).getPartyName()); + assertEquals(slot.roleOnCase, Objects.requireNonNull(slot.get(caseData)).getRoleOnCase()); + assertEquals(slot.roleOnCase, Objects.requireNonNull(slot.get(caseData)).getGroupId()); + assertEquals(slot.visibility, Objects.requireNonNull(slot.get(caseData)).getVisibility()); } @Test void processNewlySetCaseFlags_shouldSetInterpreterRequiredTrue() { - caseData.setRespondentFlags(CaseFlagsType.builder().build()); - caseData.setClaimantFlags(CaseFlagsType.builder() + getOrCreateAllPartyFlags(caseData).setRespondentFlags(CaseFlagsType.builder().build()); + getOrCreateAllPartyFlags(caseData).setClaimantFlags(CaseFlagsType.builder() .details( ListTypeItem.from( FlagDetailType.builder() @@ -341,7 +367,7 @@ void processNewlySetCaseFlags_shouldSetInterpreterRequiredTrue() { .flagCode("RA00010") .build())) .build()); - caseData.setClaimantExternalFlags(CaseFlagsType.builder().build()); + getOrCreateAllPartyFlags(caseData).setClaimantExternalFlags(CaseFlagsType.builder().build()); caseFlagsService.processNewlySetCaseFlags(caseData); @@ -350,8 +376,8 @@ void processNewlySetCaseFlags_shouldSetInterpreterRequiredTrue() { @Test void processNewlySetCaseFlags_shouldSetAdditionalSecurityFlagTrue() { - caseData.setRespondentFlags(CaseFlagsType.builder().build()); - caseData.setClaimantFlags(CaseFlagsType.builder() + getOrCreateAllPartyFlags(caseData).setRespondentFlags(CaseFlagsType.builder().build()); + getOrCreateAllPartyFlags(caseData).setClaimantFlags(CaseFlagsType.builder() .details( ListTypeItem.from( FlagDetailType.builder() @@ -360,7 +386,7 @@ void processNewlySetCaseFlags_shouldSetAdditionalSecurityFlagTrue() { .flagCode("CA00010") .build())) .build()); - caseData.setClaimantExternalFlags(CaseFlagsType.builder().build()); + getOrCreateAllPartyFlags(caseData).setClaimantExternalFlags(CaseFlagsType.builder().build()); caseFlagsService.processNewlySetCaseFlags(caseData); @@ -371,7 +397,7 @@ void processNewlySetCaseFlags_shouldSetAdditionalSecurityFlagTrue() { @MethodSource("allPartyFlagSlots") void processNewlySetCaseFlags_shouldReadInterpreterFlagsFromAnyPartyFlagCollection(FlagSlot slot) { caseFlagsService.setupCaseFlags(caseData); - slot.getter.apply(caseData).setDetails(ListTypeItem.from(activeFlag(SIGN_LANGUAGE_INTERPRETER))); + Objects.requireNonNull(slot.get(caseData)).setDetails(ListTypeItem.from(activeFlag(SIGN_LANGUAGE_INTERPRETER))); caseFlagsService.processNewlySetCaseFlags(caseData); @@ -383,7 +409,7 @@ void processNewlySetCaseFlags_shouldReadInterpreterFlagsFromAnyPartyFlagCollecti @MethodSource("allPartyFlagSlots") void processNewlySetCaseFlags_shouldReadSecurityFlagsFromAnyPartyFlagCollection(FlagSlot slot) { caseFlagsService.setupCaseFlags(caseData); - slot.getter.apply(caseData).setDetails(ListTypeItem.from(activeFlag(VEXATIOUS_LITIGANT))); + Objects.requireNonNull(slot.get(caseData)).setDetails(ListTypeItem.from(activeFlag(VEXATIOUS_LITIGANT))); caseFlagsService.processNewlySetCaseFlags(caseData); @@ -394,9 +420,10 @@ void processNewlySetCaseFlags_shouldReadSecurityFlagsFromAnyPartyFlagCollection( @Test void processNewlySetCaseFlags_shouldSupportAlternativeInterpreterAndSecurityFlagNames() { caseFlagsService.setupCaseFlags(caseData); - caseData.getClaimantRepresentativeExternalFlags() + allPartyFlags(caseData).getClaimantRepresentativeExternalFlags() .setDetails(ListTypeItem.from(activeFlag(LANGUAGE_INTERPRETER))); - caseData.getRepresentative9ExternalFlags().setDetails(ListTypeItem.from(activeFlag(DISRUPTIVE_CUSTOMER))); + allPartyFlags(caseData).getRepresentative9ExternalFlags() + .setDetails(ListTypeItem.from(activeFlag(DISRUPTIVE_CUSTOMER))); caseFlagsService.processNewlySetCaseFlags(caseData); @@ -407,15 +434,16 @@ void processNewlySetCaseFlags_shouldSupportAlternativeInterpreterAndSecurityFlag @Test void processNewlySetCaseFlags_shouldSetFlagsToNoWhenMatchingFlagsAreInactiveOrAbsent() { caseFlagsService.setupCaseFlags(caseData); - caseData.getClaimantFlags().setDetails(ListTypeItem.from(FlagDetailType.builder() + allPartyFlags(caseData).getClaimantFlags().setDetails(ListTypeItem.from(FlagDetailType.builder() .name(SIGN_LANGUAGE_INTERPRETER) .status(INACTIVE) .build())); - caseData.getRespondentFlags().setDetails(ListTypeItem.from(FlagDetailType.builder() + allPartyFlags(caseData).getRespondentFlags().setDetails(ListTypeItem.from(FlagDetailType.builder() .name(VEXATIOUS_LITIGANT) .status(INACTIVE) .build())); - caseData.getRespondentExternalFlags().setDetails(ListTypeItem.from(activeFlag("A different flag"))); + allPartyFlags(caseData).getRespondentExternalFlags() + .setDetails(ListTypeItem.from(activeFlag("A different flag"))); caseFlagsService.processNewlySetCaseFlags(caseData); @@ -547,104 +575,115 @@ void setPrivateHearingFlag_shouldBeFalsy_whenIcListingPreliminaryHearingIsFalse( private static Stream allPartyFlagSlots() { return Stream.of( - slot("claimant internal flags", CaseData::getClaimantFlags, CaseData::setClaimantFlags, + slot("claimant internal flags", AllPartyFlags::getClaimantFlags, AllPartyFlags::setClaimantFlags, CLAIMANT_NAME, CLAIMANT, INTERNAL, -1), - slot("claimant external flags", CaseData::getClaimantExternalFlags, - CaseData::setClaimantExternalFlags, CLAIMANT_NAME, CLAIMANT, EXTERNAL, -1), - slot("claimant representative internal flags", CaseData::getClaimantRepresentativeFlags, - CaseData::setClaimantRepresentativeFlags, CLAIMANT_REPRESENTATIVE_NAME, + slot("claimant external flags", AllPartyFlags::getClaimantExternalFlags, + AllPartyFlags::setClaimantExternalFlags, CLAIMANT_NAME, CLAIMANT, EXTERNAL, -1), + slot("claimant representative internal flags", AllPartyFlags::getClaimantRepresentativeFlags, + AllPartyFlags::setClaimantRepresentativeFlags, CLAIMANT_REPRESENTATIVE_NAME, CLAIMANT_REPRESENTATIVE, INTERNAL, -1), - slot("claimant representative external flags", CaseData::getClaimantRepresentativeExternalFlags, - CaseData::setClaimantRepresentativeExternalFlags, CLAIMANT_REPRESENTATIVE_NAME, + slot("claimant representative external flags", AllPartyFlags::getClaimantRepresentativeExternalFlags, + AllPartyFlags::setClaimantRepresentativeExternalFlags, CLAIMANT_REPRESENTATIVE_NAME, CLAIMANT_REPRESENTATIVE, EXTERNAL, -1), - slot("respondent 1 internal flags", CaseData::getRespondentFlags, CaseData::setRespondentFlags, + slot("respondent 1 internal flags", AllPartyFlags::getRespondentFlags, + AllPartyFlags::setRespondentFlags, respondentName(0), RESPONDENT1, INTERNAL, 0), - slot("respondent 1 external flags", CaseData::getRespondentExternalFlags, - CaseData::setRespondentExternalFlags, respondentName(0), RESPONDENT1, EXTERNAL, 0), - slot("respondent 2 internal flags", CaseData::getRespondent1Flags, CaseData::setRespondent1Flags, + slot("respondent 1 external flags", AllPartyFlags::getRespondentExternalFlags, + AllPartyFlags::setRespondentExternalFlags, respondentName(0), RESPONDENT1, EXTERNAL, 0), + slot("respondent 2 internal flags", AllPartyFlags::getRespondent1Flags, + AllPartyFlags::setRespondent1Flags, respondentName(1), RESPONDENT2, INTERNAL, 1), - slot("respondent 2 external flags", CaseData::getRespondent1ExternalFlags, - CaseData::setRespondent1ExternalFlags, respondentName(1), RESPONDENT2, EXTERNAL, 1), - slot("respondent 3 internal flags", CaseData::getRespondent2Flags, CaseData::setRespondent2Flags, + slot("respondent 2 external flags", AllPartyFlags::getRespondent1ExternalFlags, + AllPartyFlags::setRespondent1ExternalFlags, respondentName(1), RESPONDENT2, EXTERNAL, 1), + slot("respondent 3 internal flags", AllPartyFlags::getRespondent2Flags, + AllPartyFlags::setRespondent2Flags, respondentName(2), RESPONDENT3, INTERNAL, 2), - slot("respondent 3 external flags", CaseData::getRespondent2ExternalFlags, - CaseData::setRespondent2ExternalFlags, respondentName(2), RESPONDENT3, EXTERNAL, 2), - slot("respondent 4 internal flags", CaseData::getRespondent3Flags, CaseData::setRespondent3Flags, + slot("respondent 3 external flags", AllPartyFlags::getRespondent2ExternalFlags, + AllPartyFlags::setRespondent2ExternalFlags, respondentName(2), RESPONDENT3, EXTERNAL, 2), + slot("respondent 4 internal flags", AllPartyFlags::getRespondent3Flags, + AllPartyFlags::setRespondent3Flags, respondentName(3), RESPONDENT4, INTERNAL, 3), - slot("respondent 4 external flags", CaseData::getRespondent3ExternalFlags, - CaseData::setRespondent3ExternalFlags, respondentName(3), RESPONDENT4, EXTERNAL, 3), - slot("respondent 5 internal flags", CaseData::getRespondent4Flags, CaseData::setRespondent4Flags, + slot("respondent 4 external flags", AllPartyFlags::getRespondent3ExternalFlags, + AllPartyFlags::setRespondent3ExternalFlags, respondentName(3), RESPONDENT4, EXTERNAL, 3), + slot("respondent 5 internal flags", AllPartyFlags::getRespondent4Flags, + AllPartyFlags::setRespondent4Flags, respondentName(4), RESPONDENT5, INTERNAL, 4), - slot("respondent 5 external flags", CaseData::getRespondent4ExternalFlags, - CaseData::setRespondent4ExternalFlags, respondentName(4), RESPONDENT5, EXTERNAL, 4), - slot("respondent 6 internal flags", CaseData::getRespondent5Flags, CaseData::setRespondent5Flags, + slot("respondent 5 external flags", AllPartyFlags::getRespondent4ExternalFlags, + AllPartyFlags::setRespondent4ExternalFlags, respondentName(4), RESPONDENT5, EXTERNAL, 4), + slot("respondent 6 internal flags", AllPartyFlags::getRespondent5Flags, + AllPartyFlags::setRespondent5Flags, respondentName(5), RESPONDENT6, INTERNAL, 5), - slot("respondent 6 external flags", CaseData::getRespondent5ExternalFlags, - CaseData::setRespondent5ExternalFlags, respondentName(5), RESPONDENT6, EXTERNAL, 5), - slot("respondent 7 internal flags", CaseData::getRespondent6Flags, CaseData::setRespondent6Flags, + slot("respondent 6 external flags", AllPartyFlags::getRespondent5ExternalFlags, + AllPartyFlags::setRespondent5ExternalFlags, respondentName(5), RESPONDENT6, EXTERNAL, 5), + slot("respondent 7 internal flags", AllPartyFlags::getRespondent6Flags, + AllPartyFlags::setRespondent6Flags, respondentName(6), RESPONDENT7, INTERNAL, 6), - slot("respondent 7 external flags", CaseData::getRespondent6ExternalFlags, - CaseData::setRespondent6ExternalFlags, respondentName(6), RESPONDENT7, EXTERNAL, 6), - slot("respondent 8 internal flags", CaseData::getRespondent7Flags, CaseData::setRespondent7Flags, + slot("respondent 7 external flags", AllPartyFlags::getRespondent6ExternalFlags, + AllPartyFlags::setRespondent6ExternalFlags, respondentName(6), RESPONDENT7, EXTERNAL, 6), + slot("respondent 8 internal flags", AllPartyFlags::getRespondent7Flags, + AllPartyFlags::setRespondent7Flags, respondentName(7), RESPONDENT8, INTERNAL, 7), - slot("respondent 8 external flags", CaseData::getRespondent7ExternalFlags, - CaseData::setRespondent7ExternalFlags, respondentName(7), RESPONDENT8, EXTERNAL, 7), - slot("respondent 9 internal flags", CaseData::getRespondent8Flags, CaseData::setRespondent8Flags, + slot("respondent 8 external flags", AllPartyFlags::getRespondent7ExternalFlags, + AllPartyFlags::setRespondent7ExternalFlags, respondentName(7), RESPONDENT8, EXTERNAL, 7), + slot("respondent 9 internal flags", AllPartyFlags::getRespondent8Flags, + AllPartyFlags::setRespondent8Flags, respondentName(8), RESPONDENT9, INTERNAL, 8), - slot("respondent 9 external flags", CaseData::getRespondent8ExternalFlags, - CaseData::setRespondent8ExternalFlags, respondentName(8), RESPONDENT9, EXTERNAL, 8), - slot("respondent 10 internal flags", CaseData::getRespondent9Flags, CaseData::setRespondent9Flags, + slot("respondent 9 external flags", AllPartyFlags::getRespondent8ExternalFlags, + AllPartyFlags::setRespondent8ExternalFlags, respondentName(8), RESPONDENT9, EXTERNAL, 8), + slot("respondent 10 internal flags", AllPartyFlags::getRespondent9Flags, + AllPartyFlags::setRespondent9Flags, respondentName(9), RESPONDENT10, INTERNAL, 9), - slot("respondent 10 external flags", CaseData::getRespondent9ExternalFlags, - CaseData::setRespondent9ExternalFlags, respondentName(9), RESPONDENT10, EXTERNAL, 9), - representativeSlot("representative 1 internal flags", CaseData::getRepresentativeFlags, - CaseData::setRepresentativeFlags, representativeName(0), REPRESENTATIVE1, INTERNAL, 0), - representativeSlot("representative 1 external flags", CaseData::getRepresentativeExternalFlags, - CaseData::setRepresentativeExternalFlags, representativeName(0), REPRESENTATIVE1, EXTERNAL, 0), - representativeSlot("representative 2 internal flags", CaseData::getRepresentative1Flags, - CaseData::setRepresentative1Flags, representativeName(1), REPRESENTATIVE2, INTERNAL, 1), - representativeSlot("representative 2 external flags", CaseData::getRepresentative1ExternalFlags, - CaseData::setRepresentative1ExternalFlags, representativeName(1), REPRESENTATIVE2, + slot("respondent 10 external flags", AllPartyFlags::getRespondent9ExternalFlags, + AllPartyFlags::setRespondent9ExternalFlags, respondentName(9), RESPONDENT10, EXTERNAL, 9), + representativeSlot("representative 1 internal flags", AllPartyFlags::getRepresentativeFlags, + AllPartyFlags::setRepresentativeFlags, representativeName(0), REPRESENTATIVE1, INTERNAL, 0), + representativeSlot("representative 1 external flags", AllPartyFlags::getRepresentativeExternalFlags, + AllPartyFlags::setRepresentativeExternalFlags, representativeName(0), REPRESENTATIVE1, + EXTERNAL, 0), + representativeSlot("representative 2 internal flags", AllPartyFlags::getRepresentative1Flags, + AllPartyFlags::setRepresentative1Flags, representativeName(1), REPRESENTATIVE2, INTERNAL, 1), + representativeSlot("representative 2 external flags", AllPartyFlags::getRepresentative1ExternalFlags, + AllPartyFlags::setRepresentative1ExternalFlags, representativeName(1), REPRESENTATIVE2, EXTERNAL, 1), - representativeSlot("representative 3 internal flags", CaseData::getRepresentative2Flags, - CaseData::setRepresentative2Flags, representativeName(2), REPRESENTATIVE3, INTERNAL, 2), - representativeSlot("representative 3 external flags", CaseData::getRepresentative2ExternalFlags, - CaseData::setRepresentative2ExternalFlags, representativeName(2), REPRESENTATIVE3, + representativeSlot("representative 3 internal flags", AllPartyFlags::getRepresentative2Flags, + AllPartyFlags::setRepresentative2Flags, representativeName(2), REPRESENTATIVE3, INTERNAL, 2), + representativeSlot("representative 3 external flags", AllPartyFlags::getRepresentative2ExternalFlags, + AllPartyFlags::setRepresentative2ExternalFlags, representativeName(2), REPRESENTATIVE3, EXTERNAL, 2), - representativeSlot("representative 4 internal flags", CaseData::getRepresentative3Flags, - CaseData::setRepresentative3Flags, representativeName(3), REPRESENTATIVE4, INTERNAL, 3), - representativeSlot("representative 4 external flags", CaseData::getRepresentative3ExternalFlags, - CaseData::setRepresentative3ExternalFlags, representativeName(3), REPRESENTATIVE4, + representativeSlot("representative 4 internal flags", AllPartyFlags::getRepresentative3Flags, + AllPartyFlags::setRepresentative3Flags, representativeName(3), REPRESENTATIVE4, INTERNAL, 3), + representativeSlot("representative 4 external flags", AllPartyFlags::getRepresentative3ExternalFlags, + AllPartyFlags::setRepresentative3ExternalFlags, representativeName(3), REPRESENTATIVE4, EXTERNAL, 3), - representativeSlot("representative 5 internal flags", CaseData::getRepresentative4Flags, - CaseData::setRepresentative4Flags, representativeName(4), REPRESENTATIVE5, INTERNAL, 4), - representativeSlot("representative 5 external flags", CaseData::getRepresentative4ExternalFlags, - CaseData::setRepresentative4ExternalFlags, representativeName(4), REPRESENTATIVE5, + representativeSlot("representative 5 internal flags", AllPartyFlags::getRepresentative4Flags, + AllPartyFlags::setRepresentative4Flags, representativeName(4), REPRESENTATIVE5, INTERNAL, 4), + representativeSlot("representative 5 external flags", AllPartyFlags::getRepresentative4ExternalFlags, + AllPartyFlags::setRepresentative4ExternalFlags, representativeName(4), REPRESENTATIVE5, EXTERNAL, 4), - representativeSlot("representative 6 internal flags", CaseData::getRepresentative5Flags, - CaseData::setRepresentative5Flags, representativeName(5), REPRESENTATIVE6, INTERNAL, 5), - representativeSlot("representative 6 external flags", CaseData::getRepresentative5ExternalFlags, - CaseData::setRepresentative5ExternalFlags, representativeName(5), REPRESENTATIVE6, + representativeSlot("representative 6 internal flags", AllPartyFlags::getRepresentative5Flags, + AllPartyFlags::setRepresentative5Flags, representativeName(5), REPRESENTATIVE6, INTERNAL, 5), + representativeSlot("representative 6 external flags", AllPartyFlags::getRepresentative5ExternalFlags, + AllPartyFlags::setRepresentative5ExternalFlags, representativeName(5), REPRESENTATIVE6, EXTERNAL, 5), - representativeSlot("representative 7 internal flags", CaseData::getRepresentative6Flags, - CaseData::setRepresentative6Flags, representativeName(6), REPRESENTATIVE7, INTERNAL, 6), - representativeSlot("representative 7 external flags", CaseData::getRepresentative6ExternalFlags, - CaseData::setRepresentative6ExternalFlags, representativeName(6), REPRESENTATIVE7, + representativeSlot("representative 7 internal flags", AllPartyFlags::getRepresentative6Flags, + AllPartyFlags::setRepresentative6Flags, representativeName(6), REPRESENTATIVE7, INTERNAL, 6), + representativeSlot("representative 7 external flags", AllPartyFlags::getRepresentative6ExternalFlags, + AllPartyFlags::setRepresentative6ExternalFlags, representativeName(6), REPRESENTATIVE7, EXTERNAL, 6), - representativeSlot("representative 8 internal flags", CaseData::getRepresentative7Flags, - CaseData::setRepresentative7Flags, representativeName(7), REPRESENTATIVE8, INTERNAL, 7), - representativeSlot("representative 8 external flags", CaseData::getRepresentative7ExternalFlags, - CaseData::setRepresentative7ExternalFlags, representativeName(7), REPRESENTATIVE8, + representativeSlot("representative 8 internal flags", AllPartyFlags::getRepresentative7Flags, + AllPartyFlags::setRepresentative7Flags, representativeName(7), REPRESENTATIVE8, INTERNAL, 7), + representativeSlot("representative 8 external flags", AllPartyFlags::getRepresentative7ExternalFlags, + AllPartyFlags::setRepresentative7ExternalFlags, representativeName(7), REPRESENTATIVE8, EXTERNAL, 7), - representativeSlot("representative 9 internal flags", CaseData::getRepresentative8Flags, - CaseData::setRepresentative8Flags, representativeName(8), REPRESENTATIVE9, INTERNAL, 8), - representativeSlot("representative 9 external flags", CaseData::getRepresentative8ExternalFlags, - CaseData::setRepresentative8ExternalFlags, representativeName(8), REPRESENTATIVE9, + representativeSlot("representative 9 internal flags", AllPartyFlags::getRepresentative8Flags, + AllPartyFlags::setRepresentative8Flags, representativeName(8), REPRESENTATIVE9, INTERNAL, 8), + representativeSlot("representative 9 external flags", AllPartyFlags::getRepresentative8ExternalFlags, + AllPartyFlags::setRepresentative8ExternalFlags, representativeName(8), REPRESENTATIVE9, EXTERNAL, 8), - representativeSlot("representative 10 internal flags", CaseData::getRepresentative9Flags, - CaseData::setRepresentative9Flags, representativeName(9), REPRESENTATIVE10, INTERNAL, 9), - representativeSlot("representative 10 external flags", CaseData::getRepresentative9ExternalFlags, - CaseData::setRepresentative9ExternalFlags, representativeName(9), REPRESENTATIVE10, + representativeSlot("representative 10 internal flags", AllPartyFlags::getRepresentative9Flags, + AllPartyFlags::setRepresentative9Flags, representativeName(9), REPRESENTATIVE10, INTERNAL, 9), + representativeSlot("representative 10 external flags", AllPartyFlags::getRepresentative9ExternalFlags, + AllPartyFlags::setRepresentative9ExternalFlags, representativeName(9), REPRESENTATIVE10, EXTERNAL, 9) ); } @@ -670,14 +709,14 @@ private static Stream nonGrantedTseApplications() { ); } - private static FlagSlot slot(String name, Function getter, - BiConsumer setter, String partyName, + private static FlagSlot slot(String name, Function getter, + BiConsumer setter, String partyName, String roleOnCase, String visibility, int respondentIndex) { return new FlagSlot(name, getter, setter, partyName, roleOnCase, visibility, respondentIndex, -1); } - private static FlagSlot representativeSlot(String name, Function getter, - BiConsumer setter, String partyName, + private static FlagSlot representativeSlot(String name, Function getter, + BiConsumer setter, String partyName, String roleOnCase, String visibility, int representativeIndex) { return new FlagSlot(name, getter, setter, partyName, roleOnCase, visibility, -1, representativeIndex); } @@ -717,6 +756,17 @@ private static String representativeName(int index) { return index == 0 ? REPRESENTATIVE_NAME : REPRESENTATIVE_NAME + " " + (index + 1); } + private static AllPartyFlags allPartyFlags(CaseData caseData) { + return caseData.getAllPartyFlags(); + } + + private static AllPartyFlags getOrCreateAllPartyFlags(CaseData caseData) { + if (caseData.getAllPartyFlags() == null) { + caseData.setAllPartyFlags(new AllPartyFlags()); + } + return caseData.getAllPartyFlags(); + } + private static void assertCaseFlag(FlagSlot slot, CaseFlagsType actual) { assertNotNull(actual, slot + " should be populated"); assertAll(slot.toString(), @@ -754,16 +804,16 @@ private static TseAdminRecordDecisionTypeItem adminDecision(String decision) { private static final class FlagSlot { private final String name; - private final Function getter; - private final BiConsumer setter; + private final Function getter; + private final BiConsumer setter; private final String partyName; private final String roleOnCase; private final String visibility; private final int respondentIndex; private final int representativeIndex; - private FlagSlot(String name, Function getter, - BiConsumer setter, String partyName, + private FlagSlot(String name, Function getter, + BiConsumer setter, String partyName, String roleOnCase, String visibility, int respondentIndex, int representativeIndex) { this.name = name; this.getter = getter; @@ -775,6 +825,15 @@ private FlagSlot(String name, Function getter, this.representativeIndex = representativeIndex; } + private CaseFlagsType get(CaseData caseData) { + AllPartyFlags allPartyFlags = caseData.getAllPartyFlags(); + return allPartyFlags == null ? null : getter.apply(allPartyFlags); + } + + private void set(CaseData caseData, CaseFlagsType flags) { + setter.accept(getOrCreateAllPartyFlags(caseData), flags); + } + @Override public String toString() { return name; From 466cfa7b089869a9e20f73e6c4d42d6580a7d31f Mon Sep 17 00:00:00 2001 From: rajaram Date: Fri, 19 Jun 2026 11:20:38 +0100 Subject: [PATCH 009/100] Fixed all the test failures --- .../docmosis/CallbackBindingSetupTest.java | 4 ++ .../AllocateHearingControllerTest.java | 34 +++++++------ .../BundlesRespondentControllerTest.java | 7 +-- .../controllers/CaseAccessControllerTest.java | 3 +- .../controllers/CaseNotesControllerTest.java | 9 ++-- .../CaseTransferControllerTest.java | 21 ++++---- .../controllers/Et1ReppedControllerTest.java | 8 ++- .../Et1SubmissionControllerTest.java | 5 +- .../Et3ResponseControllerTest.java | 4 +- .../HearingDetailsControllerTest.java | 17 ++++--- .../ListHearingControllerTest.java | 15 +++--- .../admin/TseAdmReplyControllerTest.java | 39 ++++++++------- .../admin/TseAdminControllerTest.java | 49 ++++++++++--------- ...aimantTellSomethingElseControllerTest.java | 18 ++++--- ...ondentTellSomethingElseControllerTest.java | 10 ++-- .../PseRespondToTribunalControllerTest.java | 18 ++++--- .../PseRespondentViewControllerTest.java | 7 +-- 17 files changed, 147 insertions(+), 121 deletions(-) diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/CallbackBindingSetupTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/CallbackBindingSetupTest.java index a66d05e5e3..343846a806 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/CallbackBindingSetupTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/CallbackBindingSetupTest.java @@ -5,6 +5,7 @@ import org.junit.jupiter.api.Test; import org.mockito.Answers; import org.mockito.Mockito; +import org.junit.jupiter.api.Assumptions; import org.springframework.beans.factory.ListableBeanFactory; import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; import org.springframework.core.annotation.AnnotatedElementUtils; @@ -53,6 +54,9 @@ private static Map loadCaseTypeDefinitions() Map definitions = new LinkedHashMap<>(); Class caseTypeDefinitionClass = Class.forName("uk.gov.hmcts.ccd.domain.model.definition.CaseTypeDefinition"); + Assumptions.assumeTrue(Files.isDirectory(DEFINITION_SNAPSHOTS_ROOT), + "CCD definition snapshots are generated by cftlib tasks and are not present"); + try (Stream paths = Files.walk(DEFINITION_SNAPSHOTS_ROOT)) { for (Path path : paths .filter(Files::isRegularFile) diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AllocateHearingControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AllocateHearingControllerTest.java index efb598a279..f3a358bcfd 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AllocateHearingControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AllocateHearingControllerTest.java @@ -9,6 +9,7 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.web.servlet.MockMvc; import uk.gov.hmcts.et.common.model.ccd.CCDRequest; +import uk.gov.hmcts.et.common.model.ccd.CaseData; import uk.gov.hmcts.ethos.replacement.docmosis.service.CaseManagementForCaseWorkerService; import uk.gov.hmcts.ethos.replacement.docmosis.service.VerifyTokenService; import uk.gov.hmcts.ethos.replacement.docmosis.service.hearings.allocatehearing.AllocateHearingService; @@ -18,6 +19,7 @@ import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -67,7 +69,7 @@ void testInitialiseHearingDynamicList() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(allocateHearingService, times(1)).initialiseAllocateHearing(ccdRequest.getCaseDetails().getCaseData()); + verify(allocateHearingService, times(1)).initialiseAllocateHearing(any(CaseData.class)); } @Test @@ -84,7 +86,7 @@ void testInitialiseHearingDynamicListInvalidToken() throws Exception { .content(jsonMapper.toJson(ccdRequest))) .andExpect(status().isForbidden()); - verify(allocateHearingService, never()).initialiseAllocateHearing(ccdRequest.getCaseDetails().getCaseData()); + verify(allocateHearingService, never()).initialiseAllocateHearing(any(CaseData.class)); } @Test @@ -104,7 +106,7 @@ void testHandleListingSelected() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(allocateHearingService, times(1)).handleListingSelected(ccdRequest.getCaseDetails().getCaseData()); + verify(allocateHearingService, times(1)).handleListingSelected(any(CaseData.class)); } @Test @@ -121,7 +123,7 @@ void testHandleListingSelectedInvalidToken() throws Exception { .content(jsonMapper.toJson(ccdRequest))) .andExpect(status().isForbidden()); - verify(allocateHearingService, never()).handleListingSelected(ccdRequest.getCaseDetails().getCaseData()); + verify(allocateHearingService, never()).handleListingSelected(any(CaseData.class)); } @Test @@ -137,7 +139,7 @@ void testHandleListingSelectedInvalidCaseTypeId() throws Exception { .header("Authorization", token) .content(jsonMapper.toJson(ccdRequest))) .andExpect(status().isBadRequest()); - verify(allocateHearingService, never()).handleListingSelected(ccdRequest.getCaseDetails().getCaseData()); + verify(allocateHearingService, never()).handleListingSelected(any(CaseData.class)); } @Test @@ -157,8 +159,8 @@ void testPopulateRoomsEnglandWales() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(allocateHearingService, times(1)).populateRooms(ccdRequest.getCaseDetails().getCaseData()); - verify(scotlandAllocateHearingService, never()).populateRooms(ccdRequest.getCaseDetails().getCaseData()); + verify(allocateHearingService, times(1)).populateRooms(any(CaseData.class)); + verify(scotlandAllocateHearingService, never()).populateRooms(any(CaseData.class)); } @Test @@ -178,8 +180,8 @@ void testPopulateRoomsScotland() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(scotlandAllocateHearingService, times(1)).populateRooms(ccdRequest.getCaseDetails().getCaseData()); - verify(allocateHearingService, never()).populateRooms(ccdRequest.getCaseDetails().getCaseData()); + verify(scotlandAllocateHearingService, times(1)).populateRooms(any(CaseData.class)); + verify(allocateHearingService, never()).populateRooms(any(CaseData.class)); } @Test @@ -196,7 +198,7 @@ void testPopulateRoomsInvalidToken() throws Exception { .content(jsonMapper.toJson(ccdRequest))) .andExpect(status().isForbidden()); - verify(allocateHearingService, never()).populateRooms(ccdRequest.getCaseDetails().getCaseData()); + verify(allocateHearingService, never()).populateRooms(any(CaseData.class)); } @Test @@ -216,8 +218,8 @@ void testAboutToSubmit_EnglandWales() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(allocateHearingService, times(1)).updateSelectedHearing(ccdRequest.getCaseDetails().getCaseData()); - verify(allocateHearingService, times(1)).updateCase(ccdRequest.getCaseDetails().getCaseData()); + verify(allocateHearingService, times(1)).updateSelectedHearing(any(CaseData.class)); + verify(allocateHearingService, times(1)).updateCase(any(CaseData.class)); } @Test @@ -237,8 +239,8 @@ void testAboutToSubmit_Scotland() throws Exception { .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(allocateHearingService, times(1)).updateSelectedHearing(ccdRequest.getCaseDetails().getCaseData()); - verify(scotlandAllocateHearingService, times(1)).updateCase(ccdRequest.getCaseDetails().getCaseData()); + verify(allocateHearingService, times(1)).updateSelectedHearing(any(CaseData.class)); + verify(scotlandAllocateHearingService, times(1)).updateCase(any(CaseData.class)); } @Test @@ -255,7 +257,7 @@ void testAboutToSubmitInvalidToken() throws Exception { .content(jsonMapper.toJson(ccdRequest))) .andExpect(status().isForbidden()); - verify(allocateHearingService, never()).updateSelectedHearing(ccdRequest.getCaseDetails().getCaseData()); - verify(allocateHearingService, never()).updateCase(ccdRequest.getCaseDetails().getCaseData()); + verify(allocateHearingService, never()).updateSelectedHearing(any(CaseData.class)); + verify(allocateHearingService, never()).updateCase(any(CaseData.class)); } } diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/BundlesRespondentControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/BundlesRespondentControllerTest.java index 4ca371bb8b..712bb481e3 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/BundlesRespondentControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/BundlesRespondentControllerTest.java @@ -11,6 +11,7 @@ import org.springframework.test.web.servlet.MockMvc; import org.webjars.NotFoundException; import uk.gov.hmcts.et.common.model.ccd.CCDRequest; +import uk.gov.hmcts.et.common.model.ccd.CaseData; import uk.gov.hmcts.ethos.replacement.docmosis.service.BundlesRespondentService; import uk.gov.hmcts.ethos.replacement.docmosis.service.FeatureToggleService; import uk.gov.hmcts.ethos.replacement.docmosis.service.SendNotificationService; @@ -116,7 +117,7 @@ void aboutToSubmit_tokenOk() throws Exception { .andExpect(jsonPath("$.data", notNullValue())) .andExpect(jsonPath("$.errors", nullValue())) .andExpect(jsonPath("$.warnings", nullValue())); - verify(bundlesRespondentService).clearInputData(ccdRequest.getCaseDetails().getCaseData()); + verify(bundlesRespondentService).clearInputData(any(CaseData.class)); } @Test @@ -127,7 +128,7 @@ void aboutToSubmit_tokenFail() throws Exception { .header("Authorization", AUTH_TOKEN) .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isForbidden()); - verify(bundlesRespondentService, never()).clearInputData(ccdRequest.getCaseDetails().getCaseData()); + verify(bundlesRespondentService, never()).clearInputData(any(CaseData.class)); } @Test @@ -137,7 +138,7 @@ void aboutToSubmit_badRequest() throws Exception { .header("Authorization", AUTH_TOKEN) .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isBadRequest()); - verify(bundlesRespondentService, never()).clearInputData(ccdRequest.getCaseDetails().getCaseData()); + verify(bundlesRespondentService, never()).clearInputData(any(CaseData.class)); } @Test diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseAccessControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseAccessControllerTest.java index f133e2ba7a..0e878cf5ef 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseAccessControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseAccessControllerTest.java @@ -16,6 +16,7 @@ import org.springframework.web.context.WebApplicationContext; import uk.gov.hmcts.et.common.model.ccd.CCDRequest; import uk.gov.hmcts.et.common.model.ccd.CaseData; +import uk.gov.hmcts.et.common.model.ccd.CaseDetails; import uk.gov.hmcts.ethos.replacement.docmosis.DocmosisApplication; import uk.gov.hmcts.ethos.replacement.docmosis.service.CaseAccessService; import uk.gov.hmcts.ethos.replacement.docmosis.service.VerifyTokenService; @@ -88,7 +89,7 @@ void assignClaimantTransferredCaseAccess_success() throws Exception { @Test void assignClaimantTransferredCaseAccess_error() throws Exception { ccdRequest.getCaseDetails().getCaseData().setLinkedCaseCT(null); - doCallRealMethod().when(caseAccessService).assignExistingCaseRoles(ccdRequest.getCaseDetails()); + doCallRealMethod().when(caseAccessService).assignExistingCaseRoles(any(CaseDetails.class)); mockMvc.perform(post(CLAIMANT_TRANSFERRED_CASE_URL) .contentType(APPLICATION_JSON) diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseNotesControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseNotesControllerTest.java index 6b57d5cf66..65d259bd0a 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseNotesControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseNotesControllerTest.java @@ -32,6 +32,7 @@ import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doCallRealMethod; import static org.mockito.Mockito.when; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; @@ -124,7 +125,7 @@ void aboutToSubmitSingles_ok() throws Exception { @Test void manageCaseNote_aboutToStart_noNotes() throws Exception { when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); - doCallRealMethod().when(caseNotesService).populateCaseNoteList(ccdRequest.getCaseDetails().getCaseData()); + doCallRealMethod().when(caseNotesService).populateCaseNoteList(any(CaseData.class)); ccdRequest.getCaseDetails().getCaseData().setCaseNotesCollection(null); mockMvc.perform(post(SINGLES_MANAGE_ABOUT_TO_START_URL) .content(jsonMapper.toJson(ccdRequest)) @@ -139,7 +140,7 @@ void manageCaseNote_aboutToStart_noNotes() throws Exception { @Test void manageCaseNote_aboutToStart() throws Exception { when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); - doCallRealMethod().when(caseNotesService).populateCaseNoteList(ccdRequest.getCaseDetails().getCaseData()); + doCallRealMethod().when(caseNotesService).populateCaseNoteList(any(CaseData.class)); GenericTypeItem caseNoteItem = createCaseNoteItem(); ccdRequest.getCaseDetails().getCaseData().setCaseNotesCollection(List.of(caseNoteItem, caseNoteItem)); mockMvc.perform(post(SINGLES_MANAGE_ABOUT_TO_START_URL) @@ -154,7 +155,7 @@ void manageCaseNote_aboutToStart() throws Exception { @Test void manageCaseNote_midEvent() throws Exception { when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); - doCallRealMethod().when(caseNotesService).populateEditCaseNote(ccdRequest.getCaseDetails().getCaseData()); + doCallRealMethod().when(caseNotesService).populateEditCaseNote(any(CaseData.class)); GenericTypeItem caseNoteItem = createCaseNoteItem(); ccdRequest.getCaseDetails().getCaseData().setCaseNotesCollection(List.of(caseNoteItem)); ccdRequest.getCaseDetails().getCaseData().setEditOrDeleteCaseNote("Edit"); @@ -171,7 +172,7 @@ void manageCaseNote_midEvent() throws Exception { @Test void manageCaseNote_aboutToSubmit() throws Exception { when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); - doCallRealMethod().when(caseNotesService).submitCaseNoteUpdate(ccdRequest.getCaseDetails().getCaseData()); + doCallRealMethod().when(caseNotesService).submitCaseNoteUpdate(any(CaseData.class)); GenericTypeItem caseNoteItem = createCaseNoteItem(); ccdRequest.getCaseDetails().getCaseData().setCaseNotesCollection(List.of(caseNoteItem)); ccdRequest.getCaseDetails().getCaseData().setEditOrDeleteCaseNote("Delete"); diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseTransferControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseTransferControllerTest.java index c33b6dcf03..ff02191e6e 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseTransferControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseTransferControllerTest.java @@ -42,6 +42,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.mock; @@ -180,7 +181,7 @@ void testTransferSameCountry() throws Exception { .andExpect(jsonPath(JsonMapper.ERRORS, hasSize(0))) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(caseTransferSameCountryService, times(1)).transferCase(ccdRequest.getCaseDetails(), AUTH_TOKEN); + verify(caseTransferSameCountryService, times(1)).transferCase(any(CaseDetails.class), eq(AUTH_TOKEN)); } @Test @@ -205,7 +206,7 @@ void testTransferSameCountryForbidden() throws Exception { .content(jsonMapper.toJson(ccdRequest))) .andExpect(status().isForbidden()); - verify(caseTransferSameCountryService, never()).transferCase(ccdRequest.getCaseDetails(), AUTH_TOKEN); + verify(caseTransferSameCountryService, never()).transferCase(any(CaseDetails.class), eq(AUTH_TOKEN)); } @Test @@ -222,7 +223,7 @@ void testTransferSameCountryEccLinkedCase() throws Exception { .andExpect(jsonPath(JsonMapper.ERRORS, hasSize(0))) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(caseTransferSameCountryService, times(1)).updateEccLinkedCase(ccdRequest.getCaseDetails(), AUTH_TOKEN); + verify(caseTransferSameCountryService, times(1)).updateEccLinkedCase(any(CaseDetails.class), eq(AUTH_TOKEN)); } @Test @@ -244,10 +245,10 @@ void testTransferSameCountryEccLinkedCaseForbidden() throws Exception { mockMvc.perform(post(CASE_TRANSFER_SAME_COUNTRY_ECC_LINKED_CASE_URL) .header("Authorization", AUTH_TOKEN) .contentType(MediaType.APPLICATION_JSON) - .content(jsonMapper.toJson(ccdRequest))) + .content(jsonMapper.toJson(ccdRequest))) .andExpect(status().isForbidden()); - verify(caseTransferSameCountryService, never()).updateEccLinkedCase(ccdRequest.getCaseDetails(), AUTH_TOKEN); + verify(caseTransferSameCountryService, never()).updateEccLinkedCase(any(CaseDetails.class), eq(AUTH_TOKEN)); } @Test @@ -264,7 +265,7 @@ void testTransferDifferentCountry() throws Exception { .andExpect(jsonPath(JsonMapper.ERRORS, hasSize(0))) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(caseTransferDifferentCountryService, times(1)).transferCase(ccdRequest.getCaseDetails(), AUTH_TOKEN); + verify(caseTransferDifferentCountryService, times(1)).transferCase(any(CaseDetails.class), eq(AUTH_TOKEN)); } @Test @@ -286,10 +287,10 @@ void testTransferDifferentCountryForbidden() throws Exception { mockMvc.perform(post(CASE_TRANSFER_DIFFERENT_COUNTRY_URL) .header("Authorization", AUTH_TOKEN) .contentType(MediaType.APPLICATION_JSON) - .content(jsonMapper.toJson(ccdRequest))) + .content(jsonMapper.toJson(ccdRequest))) .andExpect(status().isForbidden()); - verify(caseTransferDifferentCountryService, never()).transferCase(ccdRequest.getCaseDetails(), AUTH_TOKEN); + verify(caseTransferDifferentCountryService, never()).transferCase(any(CaseDetails.class), eq(AUTH_TOKEN)); } @Test @@ -397,7 +398,7 @@ void testTransferSameCountryAddsCaseMgtLocationCode() throws Exception { .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); verify(caseManagementLocationService, times(1)) - .setCaseManagementLocationCode(ccdRequest.getCaseDetails().getCaseData()); + .setCaseManagementLocationCode(any(CaseData.class)); } @Test @@ -415,7 +416,7 @@ void testTransferDifferentCountryUpdatesCaseMgtLocation() throws Exception { .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); verify(caseManagementLocationService, times(1)) - .setCaseManagementLocationCode(ccdRequest.getCaseDetails().getCaseData()); + .setCaseManagementLocationCode(any(CaseData.class)); } diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1ReppedControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1ReppedControllerTest.java index 464da60ee6..f8cf542510 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1ReppedControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1ReppedControllerTest.java @@ -1188,8 +1188,7 @@ void theMidEventAmendClaimantRepresentativeContact_ThrowsException() { StringUtils.EMPTY, "Et1ReppedService", "checkCaseData")).when(et1ReppedService) - .setMyHmctsOrganisationAddress(AUTH_TOKEN, - ccdRequestWithClaimantRepresentative.getCaseDetails().getCaseData()); + .setMyHmctsOrganisationAddress(anyString(), any(CaseData.class)); mockMvc.perform(post(MID_EVENT_AMEND_CLAIMANT_REPRESENTATIVE_CONTACT) .contentType(APPLICATION_JSON) .header(HttpHeaders.AUTHORIZATION, AUTH_TOKEN) @@ -1228,8 +1227,7 @@ void theAboutToSubmitAmendClaimantRepresentativeContact_ThrowsException() { StringUtils.EMPTY, "Et3ResponseService", "setRespondentRepresentsContactDetails")).when(et1ReppedService) - .setClaimantRepresentativeValues(AUTH_TOKEN, - ccdRequestWithClaimantRepresentative.getCaseDetails().getCaseData()); + .setClaimantRepresentativeValues(anyString(), any(CaseData.class)); mockMvc.perform(post(ABOUT_TO_SUBMIT_AMEND_CLAIMANT_REPRESENTATIVE_CONTACT) .contentType(APPLICATION_JSON) .header(HttpHeaders.AUTHORIZATION, AUTH_TOKEN) @@ -1240,4 +1238,4 @@ void theAboutToSubmitAmendClaimantRepresentativeContact_ThrowsException() { .andExpect(jsonPath("$.errors[0]", is(ERROR_CASE_DATA_NOT_FOUND))) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); } -} \ No newline at end of file +} diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1SubmissionControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1SubmissionControllerTest.java index 8bdc6c2c08..1839c67cbb 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1SubmissionControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1SubmissionControllerTest.java @@ -11,6 +11,7 @@ import org.springframework.test.web.servlet.MockMvc; import uk.gov.hmcts.et.common.model.ccd.CCDRequest; import uk.gov.hmcts.et.common.model.ccd.CaseData; +import uk.gov.hmcts.et.common.model.ccd.CaseDetails; import uk.gov.hmcts.ethos.replacement.docmosis.service.CaseManagementForCaseWorkerService; import uk.gov.hmcts.ethos.replacement.docmosis.service.Et1SubmissionService; import uk.gov.hmcts.ethos.replacement.docmosis.utils.JsonMapper; @@ -76,9 +77,9 @@ void addServiceId_success() throws Exception { .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); verify(caseManagementForCaseWorkerService, times(1)) - .setHmctsServiceIdSupplementary(ccdRequest.getCaseDetails()); + .setHmctsServiceIdSupplementary(any(CaseDetails.class)); verify(et1SubmissionService, times(1)) - .sendEt1ConfirmationClaimant(ccdRequest.getCaseDetails(), AUTH_TOKEN); + .sendEt1ConfirmationClaimant(any(CaseDetails.class), eq(AUTH_TOKEN)); } @Test diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et3ResponseControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et3ResponseControllerTest.java index c37a3cac82..96c0bcea34 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et3ResponseControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et3ResponseControllerTest.java @@ -480,8 +480,8 @@ void downloadDraftAboutToSubmit_tokenOk() throws Exception { documentInfo.setMarkUp("Document"); documentInfo.setDescription("Document.pdf"); ccdRequest.setEventId("draftEt3"); - when(et3ResponseService.generateEt3ResponseDocument(ccdRequest.getCaseDetails().getCaseData(), AUTH_TOKEN, - ENGLANDWALES_CASE_TYPE_ID, "draftEt3")).thenReturn(documentInfo); + when(et3ResponseService.generateEt3ResponseDocument(any(CaseData.class), anyString(), + anyString(), anyString())).thenReturn(documentInfo); when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); mvc.perform(post(DOWNLOAD_DRAFT_ABOUT_TO_SUBMIT) .content(jsonMapper.toJson(ccdRequest)) diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/HearingDetailsControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/HearingDetailsControllerTest.java index fefa4ae8f4..9f4a7aae39 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/HearingDetailsControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/HearingDetailsControllerTest.java @@ -9,6 +9,8 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.web.servlet.MockMvc; import uk.gov.hmcts.et.common.model.ccd.CCDRequest; +import uk.gov.hmcts.et.common.model.ccd.CaseData; +import uk.gov.hmcts.et.common.model.ccd.CaseDetails; import uk.gov.hmcts.ethos.replacement.docmosis.service.CaseManagementForCaseWorkerService; import uk.gov.hmcts.ethos.replacement.docmosis.service.VerifyTokenService; import uk.gov.hmcts.ethos.replacement.docmosis.service.hearings.hearingdetails.HearingDetailsService; @@ -18,6 +20,7 @@ import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -59,7 +62,7 @@ void testInitialiseHearingDynamicList() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(hearingDetailsService, times(1)).initialiseHearingDetails(ccdRequest.getCaseDetails().getCaseData()); + verify(hearingDetailsService, times(1)).initialiseHearingDetails(any(CaseData.class)); } @Test @@ -74,7 +77,7 @@ void testInitialiseHearingDynamicListInvalidToken() throws Exception { .content(jsonMapper.toJson(ccdRequest))) .andExpect(status().isForbidden()); - verify(hearingDetailsService, never()).initialiseHearingDetails(ccdRequest.getCaseDetails().getCaseData()); + verify(hearingDetailsService, never()).initialiseHearingDetails(any(CaseData.class)); } @Test @@ -92,7 +95,7 @@ void testHandleListingSelected() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(hearingDetailsService, times(1)).handleListingSelected(ccdRequest.getCaseDetails().getCaseData()); + verify(hearingDetailsService, times(1)).handleListingSelected(any(CaseData.class)); } @Test @@ -107,7 +110,7 @@ void testHandleListingSelectedInvalidToken() throws Exception { .content(jsonMapper.toJson(ccdRequest))) .andExpect(status().isForbidden()); - verify(hearingDetailsService, never()).handleListingSelected(ccdRequest.getCaseDetails().getCaseData()); + verify(hearingDetailsService, never()).handleListingSelected(any(CaseData.class)); } @Test @@ -139,7 +142,7 @@ void testhearingMidEventValidationInvalidToken() throws Exception { .content(jsonMapper.toJson(ccdRequest))) .andExpect(status().isForbidden()); - verify(hearingDetailsService, never()).handleListingSelected(ccdRequest.getCaseDetails().getCaseData()); + verify(hearingDetailsService, never()).handleListingSelected(any(CaseData.class)); } @Test @@ -157,7 +160,7 @@ void testAboutToSubmit() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(hearingDetailsService, times(1)).updateCase(ccdRequest.getCaseDetails()); + verify(hearingDetailsService, times(1)).updateCase(any(CaseDetails.class)); } @Test @@ -172,6 +175,6 @@ void testAboutToSubmitInvalidToken() throws Exception { .content(jsonMapper.toJson(ccdRequest))) .andExpect(status().isForbidden()); - verify(hearingDetailsService, never()).updateCase(ccdRequest.getCaseDetails()); + verify(hearingDetailsService, never()).updateCase(any(CaseDetails.class)); } } diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/ListHearingControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/ListHearingControllerTest.java index 9ed61600e3..b3928b2263 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/ListHearingControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/ListHearingControllerTest.java @@ -9,6 +9,7 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.web.servlet.MockMvc; import uk.gov.hmcts.et.common.model.ccd.CCDRequest; +import uk.gov.hmcts.et.common.model.ccd.CaseData; import uk.gov.hmcts.ethos.replacement.docmosis.service.hearings.allocatehearing.ScotlandVenueSelectionService; import uk.gov.hmcts.ethos.replacement.docmosis.service.hearings.allocatehearing.VenueSelectionService; import uk.gov.hmcts.ethos.replacement.docmosis.utils.JsonMapper; @@ -16,6 +17,7 @@ import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -59,8 +61,8 @@ void testInitialiseHearingEnglandWales() throws Exception { .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(venueSelectionService, times(1)).initHearingCollection(ccdRequest.getCaseDetails().getCaseData()); - verify(scotlandVenueSelectionService, never()).initHearingCollection(ccdRequest.getCaseDetails().getCaseData()); + verify(venueSelectionService, times(1)).initHearingCollection(any(CaseData.class)); + verify(scotlandVenueSelectionService, never()).initHearingCollection(any(CaseData.class)); } @Test @@ -79,9 +81,8 @@ void testInitialiseHearingScotland() throws Exception { .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(scotlandVenueSelectionService, times(1)).initHearingCollection( - ccdRequest.getCaseDetails().getCaseData()); - verify(venueSelectionService, never()).initHearingCollection(ccdRequest.getCaseDetails().getCaseData()); + verify(scotlandVenueSelectionService, times(1)).initHearingCollection(any(CaseData.class)); + verify(venueSelectionService, never()).initHearingCollection(any(CaseData.class)); } @Test @@ -97,7 +98,7 @@ void testInitialiseHearingInvalidToken() throws Exception { .andExpect(status().isForbidden()); - verify(venueSelectionService, never()).initHearingCollection(ccdRequest.getCaseDetails().getCaseData()); - verify(scotlandVenueSelectionService, never()).initHearingCollection(ccdRequest.getCaseDetails().getCaseData()); + verify(venueSelectionService, never()).initHearingCollection(any(CaseData.class)); + verify(scotlandVenueSelectionService, never()).initHearingCollection(any(CaseData.class)); } } diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/admin/TseAdmReplyControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/admin/TseAdmReplyControllerTest.java index 63a49f4b1a..c9a4b26b1b 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/admin/TseAdmReplyControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/admin/TseAdmReplyControllerTest.java @@ -10,6 +10,7 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.web.servlet.MockMvc; import uk.gov.hmcts.et.common.model.ccd.CCDRequest; +import uk.gov.hmcts.et.common.model.ccd.CaseData; import uk.gov.hmcts.et.common.model.ccd.CaseDetails; import uk.gov.hmcts.ethos.replacement.docmosis.controllers.BaseControllerTest; import uk.gov.hmcts.ethos.replacement.docmosis.service.applications.admin.TseAdmReplyService; @@ -22,6 +23,8 @@ import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -77,8 +80,8 @@ void midDetailsTable_tokenOk() throws Exception { .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); verify(tseAdmReplyService).initialTseAdmReplyTableMarkUp( - ccdRequest.getCaseDetails().getCaseData(), - AUTH_TOKEN); + any(CaseData.class), + eq(AUTH_TOKEN)); } @Test @@ -90,8 +93,8 @@ void midDetailsTable_tokenFail() throws Exception { .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isForbidden()); verify(tseAdmReplyService, never()).initialTseAdmReplyTableMarkUp( - ccdRequest.getCaseDetails().getCaseData(), - AUTH_TOKEN); + any(CaseData.class), + eq(AUTH_TOKEN)); } @Test @@ -102,8 +105,8 @@ void midDetailsTable_badRequest() throws Exception { .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isBadRequest()); verify(tseAdmReplyService, never()).initialTseAdmReplyTableMarkUp( - ccdRequest.getCaseDetails().getCaseData(), - AUTH_TOKEN); + any(CaseData.class), + eq(AUTH_TOKEN)); } @Test @@ -118,7 +121,7 @@ void midValidateInput_tokenOk() throws Exception { .andExpect(jsonPath(JsonMapper.ERRORS, notNullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); verify(tseAdmReplyService).validateInput( - ccdRequest.getCaseDetails().getCaseData()); + any(CaseData.class)); } @Test @@ -130,7 +133,7 @@ void midValidateInput_tokenFail() throws Exception { .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isForbidden()); verify(tseAdmReplyService, never()).validateInput( - ccdRequest.getCaseDetails().getCaseData()); + any(CaseData.class)); } @Test @@ -141,7 +144,7 @@ void midValidateInput_badRequest() throws Exception { .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isBadRequest()); verify(tseAdmReplyService, never()).validateInput( - ccdRequest.getCaseDetails().getCaseData()); + any(CaseData.class)); } @Test @@ -156,11 +159,11 @@ void aboutToSubmit_tokenOk() throws Exception { .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); verify(tseAdmReplyService).saveTseAdmReplyDataFromCaseData( - ccdRequest.getCaseDetails().getCaseData()); + any(CaseData.class)); verify(tseAdmReplyService).sendNotifyEmailsToClaimant( - ccdRequest.getCaseDetails().getCaseId(), ccdRequest.getCaseDetails().getCaseData(), AUTH_TOKEN); + eq(ccdRequest.getCaseDetails().getCaseId()), any(CaseData.class), eq(AUTH_TOKEN)); verify(tseAdmReplyService).clearTseAdmReplyDataFromCaseData( - ccdRequest.getCaseDetails().getCaseData()); + any(CaseData.class)); } @Test @@ -172,11 +175,11 @@ void aboutToSubmit_tokenFail() throws Exception { .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isForbidden()); verify(tseAdmReplyService, never()).saveTseAdmReplyDataFromCaseData( - ccdRequest.getCaseDetails().getCaseData()); + any(CaseData.class)); verify(tseAdmReplyService, never()).sendNotifyEmailsToClaimant( - "4321", ccdRequest.getCaseDetails().getCaseData(), AUTH_TOKEN); + eq("4321"), any(CaseData.class), eq(AUTH_TOKEN)); verify(tseAdmReplyService, never()).clearTseAdmReplyDataFromCaseData( - ccdRequest.getCaseDetails().getCaseData()); + any(CaseData.class)); } @Test @@ -187,11 +190,11 @@ void aboutToSubmit_badRequest() throws Exception { .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isBadRequest()); verify(tseAdmReplyService, never()).saveTseAdmReplyDataFromCaseData( - ccdRequest.getCaseDetails().getCaseData()); + any(CaseData.class)); verify(tseAdmReplyService, never()).sendNotifyEmailsToClaimant( - "4321", ccdRequest.getCaseDetails().getCaseData(), AUTH_TOKEN); + eq("4321"), any(CaseData.class), eq(AUTH_TOKEN)); verify(tseAdmReplyService, never()).clearTseAdmReplyDataFromCaseData( - ccdRequest.getCaseDetails().getCaseData()); + any(CaseData.class)); } @Test diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/admin/TseAdminControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/admin/TseAdminControllerTest.java index 6f0dc02f91..07a169ae18 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/admin/TseAdminControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/admin/TseAdminControllerTest.java @@ -31,6 +31,7 @@ import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -141,8 +142,8 @@ void midDetailsTable_tokenOk() throws Exception { .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); verify(tseAdminService).initialTseAdminTableMarkUp( - ccdRequest.getCaseDetails().getCaseData(), - AUTH_TOKEN); + any(CaseData.class), + eq(AUTH_TOKEN)); } @Test @@ -154,8 +155,8 @@ void midDetailsTable_tokenFail() throws Exception { .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isForbidden()); verify(tseAdminService, never()).initialTseAdminTableMarkUp( - ccdRequest.getCaseDetails().getCaseData(), - AUTH_TOKEN); + any(CaseData.class), + eq(AUTH_TOKEN)); } @Test @@ -166,8 +167,8 @@ void midDetailsTable_badRequest() throws Exception { .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isBadRequest()); verify(tseAdminService, never()).initialTseAdminTableMarkUp( - ccdRequest.getCaseDetails().getCaseData(), - AUTH_TOKEN); + any(CaseData.class), + eq(AUTH_TOKEN)); } @Test @@ -182,7 +183,7 @@ void midValidateInput_tokenOk() throws Exception { .andExpect(jsonPath(JsonMapper.ERRORS, notNullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); verify(tseAdminService, times(1)) - .validateInput(ccdRequest.getCaseDetails().getCaseData()); + .validateInput(any(CaseData.class)); } @Test @@ -194,7 +195,7 @@ void midValidateInput_tokenFail() throws Exception { .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isForbidden()); verify(tseAdminService, never()) - .validateInput(ccdRequest.getCaseDetails().getCaseData()); + .validateInput(any(CaseData.class)); } @Test @@ -205,7 +206,7 @@ void midValidateInput_badRequest() throws Exception { .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isBadRequest()); verify(tseAdminService, never()) - .validateInput(ccdRequest.getCaseDetails().getCaseData()); + .validateInput(any(CaseData.class)); } @Test @@ -220,12 +221,12 @@ void aboutToSubmit_tokenOk() throws Exception { .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); verify(tseAdminService).saveTseAdminDataFromCaseData( - ccdRequest.getCaseDetails().getCaseData()); + any(CaseData.class)); verify(tseAdminService).sendEmailToClaimant( - ccdRequest.getCaseDetails().getCaseId(), - ccdRequest.getCaseDetails().getCaseData()); + eq(ccdRequest.getCaseDetails().getCaseId()), + any(CaseData.class)); verify(tseAdminService).clearTseAdminDataFromCaseData( - ccdRequest.getCaseDetails().getCaseData()); + any(CaseData.class)); verify(caseFlagsService, times(1)).setPrivateHearingFlag(any()); } @@ -238,12 +239,12 @@ void aboutToSubmit_tokenFail() throws Exception { .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isForbidden()); verify(tseAdminService, never()).saveTseAdminDataFromCaseData( - ccdRequest.getCaseDetails().getCaseData()); + any(CaseData.class)); verify(tseAdminService, never()).sendEmailToClaimant( - ccdRequest.getCaseDetails().getCaseId(), - ccdRequest.getCaseDetails().getCaseData()); + eq(ccdRequest.getCaseDetails().getCaseId()), + any(CaseData.class)); verify(tseAdminService, never()).clearTseAdminDataFromCaseData( - ccdRequest.getCaseDetails().getCaseData()); + any(CaseData.class)); } @Test @@ -254,12 +255,12 @@ void aboutToSubmit_badRequest() throws Exception { .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isBadRequest()); verify(tseAdminService, never()).saveTseAdminDataFromCaseData( - ccdRequest.getCaseDetails().getCaseData()); + any(CaseData.class)); verify(tseAdminService, never()).sendEmailToClaimant( - ccdRequest.getCaseDetails().getCaseId(), - ccdRequest.getCaseDetails().getCaseData()); + eq(ccdRequest.getCaseDetails().getCaseId()), + any(CaseData.class)); verify(tseAdminService, never()).clearTseAdminDataFromCaseData( - ccdRequest.getCaseDetails().getCaseData()); + any(CaseData.class)); } @Test @@ -307,7 +308,7 @@ void aboutToSubmitCloseApplication_tokenOk() throws Exception { .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); verify(tseAdmCloseService).aboutToSubmitCloseApplication( - ccdRequest.getCaseDetails().getCaseData()); + any(CaseData.class)); } @Test @@ -319,7 +320,7 @@ void aboutToSubmitCloseApplication_tokenFail() throws Exception { .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isForbidden()); verify(tseAdmCloseService, never()).aboutToSubmitCloseApplication( - ccdRequest.getCaseDetails().getCaseData()); + any(CaseData.class)); } @Test @@ -330,7 +331,7 @@ void aboutToSubmitCloseApplication_badRequest() throws Exception { .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isBadRequest()); verify(tseAdmCloseService, never()).aboutToSubmitCloseApplication( - ccdRequest.getCaseDetails().getCaseData()); + any(CaseData.class)); } @Test diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/claimant/ClaimantTellSomethingElseControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/claimant/ClaimantTellSomethingElseControllerTest.java index 14cb5683cb..6522bdb768 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/claimant/ClaimantTellSomethingElseControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/claimant/ClaimantTellSomethingElseControllerTest.java @@ -13,6 +13,7 @@ import org.springframework.test.web.servlet.MockMvc; import uk.gov.hmcts.et.common.model.ccd.CCDRequest; import uk.gov.hmcts.et.common.model.ccd.CaseData; +import uk.gov.hmcts.et.common.model.ccd.CaseDetails; import uk.gov.hmcts.et.common.model.ccd.items.GenericTseApplicationType; import uk.gov.hmcts.et.common.model.ccd.items.GenericTseApplicationTypeItem; import uk.gov.hmcts.ethos.replacement.docmosis.controllers.BaseControllerTest; @@ -33,6 +34,7 @@ import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mockStatic; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -147,8 +149,8 @@ void aboutToSubmitClaimantTSE_Success() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(tseService).createApplication(ccdRequest.getCaseDetails().getCaseData(), CLAIMANT_REP_TITLE); - verify(claimantTseService).sendEmails(ccdRequest.getCaseDetails()); + verify(tseService).createApplication(any(CaseData.class), eq(CLAIMANT_REP_TITLE)); + verify(claimantTseService).sendEmails(any(CaseDetails.class)); } @Test @@ -163,8 +165,8 @@ void aboutToSubmitClaimantTSE_NonSystemRespondent_Success() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(tseService).createApplication(ccdRequest.getCaseDetails().getCaseData(), CLAIMANT_REP_TITLE); - verify(claimantTseService).sendEmails(ccdRequest.getCaseDetails()); + verify(tseService).createApplication(any(CaseData.class), eq(CLAIMANT_REP_TITLE)); + verify(claimantTseService).sendEmails(any(CaseDetails.class)); } @Test @@ -180,7 +182,7 @@ void completeApplication_Success() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, nullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(claimantTseService).buildApplicationCompleteResponse(ccdRequest.getCaseDetails().getCaseData()); + verify(claimantTseService).buildApplicationCompleteResponse(any(CaseData.class)); } @Test @@ -194,7 +196,7 @@ void validateGiveDetails_Success() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, notNullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(claimantTseService).validateGiveDetails(ccdRequest.getCaseDetails().getCaseData()); + verify(claimantTseService).validateGiveDetails(any(CaseData.class)); } private List createApplicationCollection() { @@ -219,7 +221,7 @@ void displayClaimantApplicationsTable_Success() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(claimantTseService).generateClaimantApplicationTableMarkdown(ccdRequest.getCaseDetails().getCaseData()); + verify(claimantTseService).generateClaimantApplicationTableMarkdown(any(CaseData.class)); } @Test @@ -327,4 +329,4 @@ void midPopulateReply_badRequest() throws Exception { .contentType(APPLICATION_JSON)) .andExpect(status().isBadRequest()); } -} \ No newline at end of file +} diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/respondent/RespondentTellSomethingElseControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/respondent/RespondentTellSomethingElseControllerTest.java index 264ffea504..68e768fb98 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/respondent/RespondentTellSomethingElseControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/respondent/RespondentTellSomethingElseControllerTest.java @@ -13,6 +13,7 @@ import org.springframework.test.web.servlet.MockMvc; import uk.gov.hmcts.et.common.model.ccd.CCDRequest; import uk.gov.hmcts.et.common.model.ccd.CaseData; +import uk.gov.hmcts.et.common.model.ccd.CaseDetails; import uk.gov.hmcts.et.common.model.ccd.items.GenericTseApplicationType; import uk.gov.hmcts.et.common.model.ccd.items.GenericTseApplicationTypeItem; import uk.gov.hmcts.et.common.model.ccd.items.RespondentSumTypeItem; @@ -38,6 +39,7 @@ import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mockStatic; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -179,7 +181,7 @@ void validateGiveDetails_Success() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, notNullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(resTseService).validateGiveDetails(ccdRequest.getCaseDetails().getCaseData()); + verify(resTseService).validateGiveDetails(any(CaseData.class)); } @Test @@ -203,8 +205,8 @@ void aboutToSubmitRespondentTSE_Success() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(resTseService).sendEmails(ccdRequest.getCaseDetails(), AUTH_TOKEN); - verify(tseService).createApplication(ccdRequest.getCaseDetails().getCaseData(), RESPONDENT_REP_TITLE); + verify(resTseService).sendEmails(any(CaseDetails.class), eq(AUTH_TOKEN)); + verify(tseService).createApplication(any(CaseData.class), eq(RESPONDENT_REP_TITLE)); } @Test @@ -228,7 +230,7 @@ void displayRespondentApplicationsTable_Success() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(resTseService).generateTableMarkdown(ccdRequest.getCaseDetails().getCaseData()); + verify(resTseService).generateTableMarkdown(any(CaseData.class)); } @Test diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/notifications/respondent/PseRespondToTribunalControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/notifications/respondent/PseRespondToTribunalControllerTest.java index 5b727d6483..526350c191 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/notifications/respondent/PseRespondToTribunalControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/notifications/respondent/PseRespondToTribunalControllerTest.java @@ -13,6 +13,7 @@ import org.springframework.test.web.servlet.MockMvc; import uk.gov.hmcts.et.common.model.ccd.CCDRequest; import uk.gov.hmcts.et.common.model.ccd.CaseData; +import uk.gov.hmcts.et.common.model.ccd.CaseDetails; import uk.gov.hmcts.et.common.model.ccd.types.RespondentSumType; import uk.gov.hmcts.ethos.replacement.docmosis.helpers.Helper; import uk.gov.hmcts.ethos.replacement.docmosis.service.PseRespondToTribunalService; @@ -26,6 +27,7 @@ import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mockStatic; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -154,8 +156,8 @@ void midDetailsTable_Success() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(pseRespondToTribunalService).initialOrdReqDetailsTableMarkUp(ccdRequest.getCaseDetails().getCaseData(), - RESPONDENT_TITLE); + verify(pseRespondToTribunalService).initialOrdReqDetailsTableMarkUp( + any(CaseData.class), eq(RESPONDENT_TITLE)); } @Test @@ -179,7 +181,7 @@ void midValidateInput_Success() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, notNullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(pseRespondToTribunalService).validateRespondentInput(ccdRequest.getCaseDetails().getCaseData()); + verify(pseRespondToTribunalService).validateRespondentInput(any(CaseData.class)); } @Test @@ -203,9 +205,11 @@ void aboutToSubmit_Success() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(pseRespondToTribunalService, times(1)).sendAcknowledgeEmail(ccdRequest.getCaseDetails(), AUTH_TOKEN); - verify(pseRespondToTribunalService, times(1)).sendClaimantEmail(ccdRequest.getCaseDetails()); - verify(pseRespondToTribunalService, times(1)).sendTribunalEmail(ccdRequest.getCaseDetails(), RESPONDENT_TITLE); + verify(pseRespondToTribunalService, times(1)).sendAcknowledgeEmail( + any(CaseDetails.class), eq(AUTH_TOKEN)); + verify(pseRespondToTribunalService, times(1)).sendClaimantEmail(any(CaseDetails.class)); + verify(pseRespondToTribunalService, times(1)).sendTribunalEmail( + any(CaseDetails.class), eq(RESPONDENT_TITLE)); } @Test @@ -220,7 +224,7 @@ void aboutToSubmit_invalidToken() throws Exception { @Test void submitted_Success() throws Exception { - when(pseRespondToTribunalService.getRespondentSubmittedBody(ccdRequest.getCaseDetails().getCaseData())) + when(pseRespondToTribunalService.getRespondentSubmittedBody(any(CaseData.class))) .thenReturn("SubmittedBody"); when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); mockMvc.perform(post(SUBMITTED_URL) diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/notifications/respondent/PseRespondentViewControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/notifications/respondent/PseRespondentViewControllerTest.java index 7f572b5d25..bcb003adf8 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/notifications/respondent/PseRespondentViewControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/notifications/respondent/PseRespondentViewControllerTest.java @@ -20,6 +20,8 @@ import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.springframework.http.MediaType.APPLICATION_JSON; @@ -75,8 +77,7 @@ void aboutToStartView_Success() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(provideSomethingElseViewService).populateSelectDropdownView(ccdRequest.getCaseDetails().getCaseData(), - RESPONDENT_TITLE); + verify(provideSomethingElseViewService).populateSelectDropdownView(any(CaseData.class), eq(RESPONDENT_TITLE)); } @Test @@ -101,7 +102,7 @@ void midDetailsTable_Success() throws Exception { .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); verify(provideSomethingElseViewService).initialOrdReqDetailsTableMarkUp( - ccdRequest.getCaseDetails().getCaseData(), RESPONDENT_TITLE); + any(CaseData.class), eq(RESPONDENT_TITLE)); } @Test From 5b8ea9a7fc121eca9cde385b4bb606eea0fbbbc5 Mon Sep 17 00:00:00 2001 From: rajaram Date: Fri, 19 Jun 2026 11:22:25 +0100 Subject: [PATCH 010/100] Revert "Fixed all the test failures" This reverts commit 466cfa7b089869a9e20f73e6c4d42d6580a7d31f. --- .../docmosis/CallbackBindingSetupTest.java | 4 -- .../AllocateHearingControllerTest.java | 34 ++++++------- .../BundlesRespondentControllerTest.java | 7 ++- .../controllers/CaseAccessControllerTest.java | 3 +- .../controllers/CaseNotesControllerTest.java | 9 ++-- .../CaseTransferControllerTest.java | 21 ++++---- .../controllers/Et1ReppedControllerTest.java | 8 +-- .../Et1SubmissionControllerTest.java | 5 +- .../Et3ResponseControllerTest.java | 4 +- .../HearingDetailsControllerTest.java | 17 +++---- .../ListHearingControllerTest.java | 15 +++--- .../admin/TseAdmReplyControllerTest.java | 39 +++++++-------- .../admin/TseAdminControllerTest.java | 49 +++++++++---------- ...aimantTellSomethingElseControllerTest.java | 18 +++---- ...ondentTellSomethingElseControllerTest.java | 10 ++-- .../PseRespondToTribunalControllerTest.java | 18 +++---- .../PseRespondentViewControllerTest.java | 7 ++- 17 files changed, 121 insertions(+), 147 deletions(-) diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/CallbackBindingSetupTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/CallbackBindingSetupTest.java index 343846a806..a66d05e5e3 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/CallbackBindingSetupTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/CallbackBindingSetupTest.java @@ -5,7 +5,6 @@ import org.junit.jupiter.api.Test; import org.mockito.Answers; import org.mockito.Mockito; -import org.junit.jupiter.api.Assumptions; import org.springframework.beans.factory.ListableBeanFactory; import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; import org.springframework.core.annotation.AnnotatedElementUtils; @@ -54,9 +53,6 @@ private static Map loadCaseTypeDefinitions() Map definitions = new LinkedHashMap<>(); Class caseTypeDefinitionClass = Class.forName("uk.gov.hmcts.ccd.domain.model.definition.CaseTypeDefinition"); - Assumptions.assumeTrue(Files.isDirectory(DEFINITION_SNAPSHOTS_ROOT), - "CCD definition snapshots are generated by cftlib tasks and are not present"); - try (Stream paths = Files.walk(DEFINITION_SNAPSHOTS_ROOT)) { for (Path path : paths .filter(Files::isRegularFile) diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AllocateHearingControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AllocateHearingControllerTest.java index f3a358bcfd..efb598a279 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AllocateHearingControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AllocateHearingControllerTest.java @@ -9,7 +9,6 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.web.servlet.MockMvc; import uk.gov.hmcts.et.common.model.ccd.CCDRequest; -import uk.gov.hmcts.et.common.model.ccd.CaseData; import uk.gov.hmcts.ethos.replacement.docmosis.service.CaseManagementForCaseWorkerService; import uk.gov.hmcts.ethos.replacement.docmosis.service.VerifyTokenService; import uk.gov.hmcts.ethos.replacement.docmosis.service.hearings.allocatehearing.AllocateHearingService; @@ -19,7 +18,6 @@ import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; -import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -69,7 +67,7 @@ void testInitialiseHearingDynamicList() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(allocateHearingService, times(1)).initialiseAllocateHearing(any(CaseData.class)); + verify(allocateHearingService, times(1)).initialiseAllocateHearing(ccdRequest.getCaseDetails().getCaseData()); } @Test @@ -86,7 +84,7 @@ void testInitialiseHearingDynamicListInvalidToken() throws Exception { .content(jsonMapper.toJson(ccdRequest))) .andExpect(status().isForbidden()); - verify(allocateHearingService, never()).initialiseAllocateHearing(any(CaseData.class)); + verify(allocateHearingService, never()).initialiseAllocateHearing(ccdRequest.getCaseDetails().getCaseData()); } @Test @@ -106,7 +104,7 @@ void testHandleListingSelected() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(allocateHearingService, times(1)).handleListingSelected(any(CaseData.class)); + verify(allocateHearingService, times(1)).handleListingSelected(ccdRequest.getCaseDetails().getCaseData()); } @Test @@ -123,7 +121,7 @@ void testHandleListingSelectedInvalidToken() throws Exception { .content(jsonMapper.toJson(ccdRequest))) .andExpect(status().isForbidden()); - verify(allocateHearingService, never()).handleListingSelected(any(CaseData.class)); + verify(allocateHearingService, never()).handleListingSelected(ccdRequest.getCaseDetails().getCaseData()); } @Test @@ -139,7 +137,7 @@ void testHandleListingSelectedInvalidCaseTypeId() throws Exception { .header("Authorization", token) .content(jsonMapper.toJson(ccdRequest))) .andExpect(status().isBadRequest()); - verify(allocateHearingService, never()).handleListingSelected(any(CaseData.class)); + verify(allocateHearingService, never()).handleListingSelected(ccdRequest.getCaseDetails().getCaseData()); } @Test @@ -159,8 +157,8 @@ void testPopulateRoomsEnglandWales() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(allocateHearingService, times(1)).populateRooms(any(CaseData.class)); - verify(scotlandAllocateHearingService, never()).populateRooms(any(CaseData.class)); + verify(allocateHearingService, times(1)).populateRooms(ccdRequest.getCaseDetails().getCaseData()); + verify(scotlandAllocateHearingService, never()).populateRooms(ccdRequest.getCaseDetails().getCaseData()); } @Test @@ -180,8 +178,8 @@ void testPopulateRoomsScotland() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(scotlandAllocateHearingService, times(1)).populateRooms(any(CaseData.class)); - verify(allocateHearingService, never()).populateRooms(any(CaseData.class)); + verify(scotlandAllocateHearingService, times(1)).populateRooms(ccdRequest.getCaseDetails().getCaseData()); + verify(allocateHearingService, never()).populateRooms(ccdRequest.getCaseDetails().getCaseData()); } @Test @@ -198,7 +196,7 @@ void testPopulateRoomsInvalidToken() throws Exception { .content(jsonMapper.toJson(ccdRequest))) .andExpect(status().isForbidden()); - verify(allocateHearingService, never()).populateRooms(any(CaseData.class)); + verify(allocateHearingService, never()).populateRooms(ccdRequest.getCaseDetails().getCaseData()); } @Test @@ -218,8 +216,8 @@ void testAboutToSubmit_EnglandWales() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(allocateHearingService, times(1)).updateSelectedHearing(any(CaseData.class)); - verify(allocateHearingService, times(1)).updateCase(any(CaseData.class)); + verify(allocateHearingService, times(1)).updateSelectedHearing(ccdRequest.getCaseDetails().getCaseData()); + verify(allocateHearingService, times(1)).updateCase(ccdRequest.getCaseDetails().getCaseData()); } @Test @@ -239,8 +237,8 @@ void testAboutToSubmit_Scotland() throws Exception { .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(allocateHearingService, times(1)).updateSelectedHearing(any(CaseData.class)); - verify(scotlandAllocateHearingService, times(1)).updateCase(any(CaseData.class)); + verify(allocateHearingService, times(1)).updateSelectedHearing(ccdRequest.getCaseDetails().getCaseData()); + verify(scotlandAllocateHearingService, times(1)).updateCase(ccdRequest.getCaseDetails().getCaseData()); } @Test @@ -257,7 +255,7 @@ void testAboutToSubmitInvalidToken() throws Exception { .content(jsonMapper.toJson(ccdRequest))) .andExpect(status().isForbidden()); - verify(allocateHearingService, never()).updateSelectedHearing(any(CaseData.class)); - verify(allocateHearingService, never()).updateCase(any(CaseData.class)); + verify(allocateHearingService, never()).updateSelectedHearing(ccdRequest.getCaseDetails().getCaseData()); + verify(allocateHearingService, never()).updateCase(ccdRequest.getCaseDetails().getCaseData()); } } diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/BundlesRespondentControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/BundlesRespondentControllerTest.java index 712bb481e3..4ca371bb8b 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/BundlesRespondentControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/BundlesRespondentControllerTest.java @@ -11,7 +11,6 @@ import org.springframework.test.web.servlet.MockMvc; import org.webjars.NotFoundException; import uk.gov.hmcts.et.common.model.ccd.CCDRequest; -import uk.gov.hmcts.et.common.model.ccd.CaseData; import uk.gov.hmcts.ethos.replacement.docmosis.service.BundlesRespondentService; import uk.gov.hmcts.ethos.replacement.docmosis.service.FeatureToggleService; import uk.gov.hmcts.ethos.replacement.docmosis.service.SendNotificationService; @@ -117,7 +116,7 @@ void aboutToSubmit_tokenOk() throws Exception { .andExpect(jsonPath("$.data", notNullValue())) .andExpect(jsonPath("$.errors", nullValue())) .andExpect(jsonPath("$.warnings", nullValue())); - verify(bundlesRespondentService).clearInputData(any(CaseData.class)); + verify(bundlesRespondentService).clearInputData(ccdRequest.getCaseDetails().getCaseData()); } @Test @@ -128,7 +127,7 @@ void aboutToSubmit_tokenFail() throws Exception { .header("Authorization", AUTH_TOKEN) .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isForbidden()); - verify(bundlesRespondentService, never()).clearInputData(any(CaseData.class)); + verify(bundlesRespondentService, never()).clearInputData(ccdRequest.getCaseDetails().getCaseData()); } @Test @@ -138,7 +137,7 @@ void aboutToSubmit_badRequest() throws Exception { .header("Authorization", AUTH_TOKEN) .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isBadRequest()); - verify(bundlesRespondentService, never()).clearInputData(any(CaseData.class)); + verify(bundlesRespondentService, never()).clearInputData(ccdRequest.getCaseDetails().getCaseData()); } @Test diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseAccessControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseAccessControllerTest.java index 0e878cf5ef..f133e2ba7a 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseAccessControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseAccessControllerTest.java @@ -16,7 +16,6 @@ import org.springframework.web.context.WebApplicationContext; import uk.gov.hmcts.et.common.model.ccd.CCDRequest; import uk.gov.hmcts.et.common.model.ccd.CaseData; -import uk.gov.hmcts.et.common.model.ccd.CaseDetails; import uk.gov.hmcts.ethos.replacement.docmosis.DocmosisApplication; import uk.gov.hmcts.ethos.replacement.docmosis.service.CaseAccessService; import uk.gov.hmcts.ethos.replacement.docmosis.service.VerifyTokenService; @@ -89,7 +88,7 @@ void assignClaimantTransferredCaseAccess_success() throws Exception { @Test void assignClaimantTransferredCaseAccess_error() throws Exception { ccdRequest.getCaseDetails().getCaseData().setLinkedCaseCT(null); - doCallRealMethod().when(caseAccessService).assignExistingCaseRoles(any(CaseDetails.class)); + doCallRealMethod().when(caseAccessService).assignExistingCaseRoles(ccdRequest.getCaseDetails()); mockMvc.perform(post(CLAIMANT_TRANSFERRED_CASE_URL) .contentType(APPLICATION_JSON) diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseNotesControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseNotesControllerTest.java index 65d259bd0a..6b57d5cf66 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseNotesControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseNotesControllerTest.java @@ -32,7 +32,6 @@ import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; -import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doCallRealMethod; import static org.mockito.Mockito.when; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; @@ -125,7 +124,7 @@ void aboutToSubmitSingles_ok() throws Exception { @Test void manageCaseNote_aboutToStart_noNotes() throws Exception { when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); - doCallRealMethod().when(caseNotesService).populateCaseNoteList(any(CaseData.class)); + doCallRealMethod().when(caseNotesService).populateCaseNoteList(ccdRequest.getCaseDetails().getCaseData()); ccdRequest.getCaseDetails().getCaseData().setCaseNotesCollection(null); mockMvc.perform(post(SINGLES_MANAGE_ABOUT_TO_START_URL) .content(jsonMapper.toJson(ccdRequest)) @@ -140,7 +139,7 @@ void manageCaseNote_aboutToStart_noNotes() throws Exception { @Test void manageCaseNote_aboutToStart() throws Exception { when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); - doCallRealMethod().when(caseNotesService).populateCaseNoteList(any(CaseData.class)); + doCallRealMethod().when(caseNotesService).populateCaseNoteList(ccdRequest.getCaseDetails().getCaseData()); GenericTypeItem caseNoteItem = createCaseNoteItem(); ccdRequest.getCaseDetails().getCaseData().setCaseNotesCollection(List.of(caseNoteItem, caseNoteItem)); mockMvc.perform(post(SINGLES_MANAGE_ABOUT_TO_START_URL) @@ -155,7 +154,7 @@ void manageCaseNote_aboutToStart() throws Exception { @Test void manageCaseNote_midEvent() throws Exception { when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); - doCallRealMethod().when(caseNotesService).populateEditCaseNote(any(CaseData.class)); + doCallRealMethod().when(caseNotesService).populateEditCaseNote(ccdRequest.getCaseDetails().getCaseData()); GenericTypeItem caseNoteItem = createCaseNoteItem(); ccdRequest.getCaseDetails().getCaseData().setCaseNotesCollection(List.of(caseNoteItem)); ccdRequest.getCaseDetails().getCaseData().setEditOrDeleteCaseNote("Edit"); @@ -172,7 +171,7 @@ void manageCaseNote_midEvent() throws Exception { @Test void manageCaseNote_aboutToSubmit() throws Exception { when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); - doCallRealMethod().when(caseNotesService).submitCaseNoteUpdate(any(CaseData.class)); + doCallRealMethod().when(caseNotesService).submitCaseNoteUpdate(ccdRequest.getCaseDetails().getCaseData()); GenericTypeItem caseNoteItem = createCaseNoteItem(); ccdRequest.getCaseDetails().getCaseData().setCaseNotesCollection(List.of(caseNoteItem)); ccdRequest.getCaseDetails().getCaseData().setEditOrDeleteCaseNote("Delete"); diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseTransferControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseTransferControllerTest.java index ff02191e6e..c33b6dcf03 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseTransferControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseTransferControllerTest.java @@ -42,7 +42,6 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.mock; @@ -181,7 +180,7 @@ void testTransferSameCountry() throws Exception { .andExpect(jsonPath(JsonMapper.ERRORS, hasSize(0))) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(caseTransferSameCountryService, times(1)).transferCase(any(CaseDetails.class), eq(AUTH_TOKEN)); + verify(caseTransferSameCountryService, times(1)).transferCase(ccdRequest.getCaseDetails(), AUTH_TOKEN); } @Test @@ -206,7 +205,7 @@ void testTransferSameCountryForbidden() throws Exception { .content(jsonMapper.toJson(ccdRequest))) .andExpect(status().isForbidden()); - verify(caseTransferSameCountryService, never()).transferCase(any(CaseDetails.class), eq(AUTH_TOKEN)); + verify(caseTransferSameCountryService, never()).transferCase(ccdRequest.getCaseDetails(), AUTH_TOKEN); } @Test @@ -223,7 +222,7 @@ void testTransferSameCountryEccLinkedCase() throws Exception { .andExpect(jsonPath(JsonMapper.ERRORS, hasSize(0))) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(caseTransferSameCountryService, times(1)).updateEccLinkedCase(any(CaseDetails.class), eq(AUTH_TOKEN)); + verify(caseTransferSameCountryService, times(1)).updateEccLinkedCase(ccdRequest.getCaseDetails(), AUTH_TOKEN); } @Test @@ -245,10 +244,10 @@ void testTransferSameCountryEccLinkedCaseForbidden() throws Exception { mockMvc.perform(post(CASE_TRANSFER_SAME_COUNTRY_ECC_LINKED_CASE_URL) .header("Authorization", AUTH_TOKEN) .contentType(MediaType.APPLICATION_JSON) - .content(jsonMapper.toJson(ccdRequest))) + .content(jsonMapper.toJson(ccdRequest))) .andExpect(status().isForbidden()); - verify(caseTransferSameCountryService, never()).updateEccLinkedCase(any(CaseDetails.class), eq(AUTH_TOKEN)); + verify(caseTransferSameCountryService, never()).updateEccLinkedCase(ccdRequest.getCaseDetails(), AUTH_TOKEN); } @Test @@ -265,7 +264,7 @@ void testTransferDifferentCountry() throws Exception { .andExpect(jsonPath(JsonMapper.ERRORS, hasSize(0))) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(caseTransferDifferentCountryService, times(1)).transferCase(any(CaseDetails.class), eq(AUTH_TOKEN)); + verify(caseTransferDifferentCountryService, times(1)).transferCase(ccdRequest.getCaseDetails(), AUTH_TOKEN); } @Test @@ -287,10 +286,10 @@ void testTransferDifferentCountryForbidden() throws Exception { mockMvc.perform(post(CASE_TRANSFER_DIFFERENT_COUNTRY_URL) .header("Authorization", AUTH_TOKEN) .contentType(MediaType.APPLICATION_JSON) - .content(jsonMapper.toJson(ccdRequest))) + .content(jsonMapper.toJson(ccdRequest))) .andExpect(status().isForbidden()); - verify(caseTransferDifferentCountryService, never()).transferCase(any(CaseDetails.class), eq(AUTH_TOKEN)); + verify(caseTransferDifferentCountryService, never()).transferCase(ccdRequest.getCaseDetails(), AUTH_TOKEN); } @Test @@ -398,7 +397,7 @@ void testTransferSameCountryAddsCaseMgtLocationCode() throws Exception { .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); verify(caseManagementLocationService, times(1)) - .setCaseManagementLocationCode(any(CaseData.class)); + .setCaseManagementLocationCode(ccdRequest.getCaseDetails().getCaseData()); } @Test @@ -416,7 +415,7 @@ void testTransferDifferentCountryUpdatesCaseMgtLocation() throws Exception { .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); verify(caseManagementLocationService, times(1)) - .setCaseManagementLocationCode(any(CaseData.class)); + .setCaseManagementLocationCode(ccdRequest.getCaseDetails().getCaseData()); } diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1ReppedControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1ReppedControllerTest.java index f8cf542510..464da60ee6 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1ReppedControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1ReppedControllerTest.java @@ -1188,7 +1188,8 @@ void theMidEventAmendClaimantRepresentativeContact_ThrowsException() { StringUtils.EMPTY, "Et1ReppedService", "checkCaseData")).when(et1ReppedService) - .setMyHmctsOrganisationAddress(anyString(), any(CaseData.class)); + .setMyHmctsOrganisationAddress(AUTH_TOKEN, + ccdRequestWithClaimantRepresentative.getCaseDetails().getCaseData()); mockMvc.perform(post(MID_EVENT_AMEND_CLAIMANT_REPRESENTATIVE_CONTACT) .contentType(APPLICATION_JSON) .header(HttpHeaders.AUTHORIZATION, AUTH_TOKEN) @@ -1227,7 +1228,8 @@ void theAboutToSubmitAmendClaimantRepresentativeContact_ThrowsException() { StringUtils.EMPTY, "Et3ResponseService", "setRespondentRepresentsContactDetails")).when(et1ReppedService) - .setClaimantRepresentativeValues(anyString(), any(CaseData.class)); + .setClaimantRepresentativeValues(AUTH_TOKEN, + ccdRequestWithClaimantRepresentative.getCaseDetails().getCaseData()); mockMvc.perform(post(ABOUT_TO_SUBMIT_AMEND_CLAIMANT_REPRESENTATIVE_CONTACT) .contentType(APPLICATION_JSON) .header(HttpHeaders.AUTHORIZATION, AUTH_TOKEN) @@ -1238,4 +1240,4 @@ void theAboutToSubmitAmendClaimantRepresentativeContact_ThrowsException() { .andExpect(jsonPath("$.errors[0]", is(ERROR_CASE_DATA_NOT_FOUND))) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); } -} +} \ No newline at end of file diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1SubmissionControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1SubmissionControllerTest.java index 1839c67cbb..8bdc6c2c08 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1SubmissionControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1SubmissionControllerTest.java @@ -11,7 +11,6 @@ import org.springframework.test.web.servlet.MockMvc; import uk.gov.hmcts.et.common.model.ccd.CCDRequest; import uk.gov.hmcts.et.common.model.ccd.CaseData; -import uk.gov.hmcts.et.common.model.ccd.CaseDetails; import uk.gov.hmcts.ethos.replacement.docmosis.service.CaseManagementForCaseWorkerService; import uk.gov.hmcts.ethos.replacement.docmosis.service.Et1SubmissionService; import uk.gov.hmcts.ethos.replacement.docmosis.utils.JsonMapper; @@ -77,9 +76,9 @@ void addServiceId_success() throws Exception { .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); verify(caseManagementForCaseWorkerService, times(1)) - .setHmctsServiceIdSupplementary(any(CaseDetails.class)); + .setHmctsServiceIdSupplementary(ccdRequest.getCaseDetails()); verify(et1SubmissionService, times(1)) - .sendEt1ConfirmationClaimant(any(CaseDetails.class), eq(AUTH_TOKEN)); + .sendEt1ConfirmationClaimant(ccdRequest.getCaseDetails(), AUTH_TOKEN); } @Test diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et3ResponseControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et3ResponseControllerTest.java index 96c0bcea34..c37a3cac82 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et3ResponseControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et3ResponseControllerTest.java @@ -480,8 +480,8 @@ void downloadDraftAboutToSubmit_tokenOk() throws Exception { documentInfo.setMarkUp("Document"); documentInfo.setDescription("Document.pdf"); ccdRequest.setEventId("draftEt3"); - when(et3ResponseService.generateEt3ResponseDocument(any(CaseData.class), anyString(), - anyString(), anyString())).thenReturn(documentInfo); + when(et3ResponseService.generateEt3ResponseDocument(ccdRequest.getCaseDetails().getCaseData(), AUTH_TOKEN, + ENGLANDWALES_CASE_TYPE_ID, "draftEt3")).thenReturn(documentInfo); when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); mvc.perform(post(DOWNLOAD_DRAFT_ABOUT_TO_SUBMIT) .content(jsonMapper.toJson(ccdRequest)) diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/HearingDetailsControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/HearingDetailsControllerTest.java index 9f4a7aae39..fefa4ae8f4 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/HearingDetailsControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/HearingDetailsControllerTest.java @@ -9,8 +9,6 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.web.servlet.MockMvc; import uk.gov.hmcts.et.common.model.ccd.CCDRequest; -import uk.gov.hmcts.et.common.model.ccd.CaseData; -import uk.gov.hmcts.et.common.model.ccd.CaseDetails; import uk.gov.hmcts.ethos.replacement.docmosis.service.CaseManagementForCaseWorkerService; import uk.gov.hmcts.ethos.replacement.docmosis.service.VerifyTokenService; import uk.gov.hmcts.ethos.replacement.docmosis.service.hearings.hearingdetails.HearingDetailsService; @@ -20,7 +18,6 @@ import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; -import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -62,7 +59,7 @@ void testInitialiseHearingDynamicList() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(hearingDetailsService, times(1)).initialiseHearingDetails(any(CaseData.class)); + verify(hearingDetailsService, times(1)).initialiseHearingDetails(ccdRequest.getCaseDetails().getCaseData()); } @Test @@ -77,7 +74,7 @@ void testInitialiseHearingDynamicListInvalidToken() throws Exception { .content(jsonMapper.toJson(ccdRequest))) .andExpect(status().isForbidden()); - verify(hearingDetailsService, never()).initialiseHearingDetails(any(CaseData.class)); + verify(hearingDetailsService, never()).initialiseHearingDetails(ccdRequest.getCaseDetails().getCaseData()); } @Test @@ -95,7 +92,7 @@ void testHandleListingSelected() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(hearingDetailsService, times(1)).handleListingSelected(any(CaseData.class)); + verify(hearingDetailsService, times(1)).handleListingSelected(ccdRequest.getCaseDetails().getCaseData()); } @Test @@ -110,7 +107,7 @@ void testHandleListingSelectedInvalidToken() throws Exception { .content(jsonMapper.toJson(ccdRequest))) .andExpect(status().isForbidden()); - verify(hearingDetailsService, never()).handleListingSelected(any(CaseData.class)); + verify(hearingDetailsService, never()).handleListingSelected(ccdRequest.getCaseDetails().getCaseData()); } @Test @@ -142,7 +139,7 @@ void testhearingMidEventValidationInvalidToken() throws Exception { .content(jsonMapper.toJson(ccdRequest))) .andExpect(status().isForbidden()); - verify(hearingDetailsService, never()).handleListingSelected(any(CaseData.class)); + verify(hearingDetailsService, never()).handleListingSelected(ccdRequest.getCaseDetails().getCaseData()); } @Test @@ -160,7 +157,7 @@ void testAboutToSubmit() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(hearingDetailsService, times(1)).updateCase(any(CaseDetails.class)); + verify(hearingDetailsService, times(1)).updateCase(ccdRequest.getCaseDetails()); } @Test @@ -175,6 +172,6 @@ void testAboutToSubmitInvalidToken() throws Exception { .content(jsonMapper.toJson(ccdRequest))) .andExpect(status().isForbidden()); - verify(hearingDetailsService, never()).updateCase(any(CaseDetails.class)); + verify(hearingDetailsService, never()).updateCase(ccdRequest.getCaseDetails()); } } diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/ListHearingControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/ListHearingControllerTest.java index b3928b2263..9ed61600e3 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/ListHearingControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/ListHearingControllerTest.java @@ -9,7 +9,6 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.web.servlet.MockMvc; import uk.gov.hmcts.et.common.model.ccd.CCDRequest; -import uk.gov.hmcts.et.common.model.ccd.CaseData; import uk.gov.hmcts.ethos.replacement.docmosis.service.hearings.allocatehearing.ScotlandVenueSelectionService; import uk.gov.hmcts.ethos.replacement.docmosis.service.hearings.allocatehearing.VenueSelectionService; import uk.gov.hmcts.ethos.replacement.docmosis.utils.JsonMapper; @@ -17,7 +16,6 @@ import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; -import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -61,8 +59,8 @@ void testInitialiseHearingEnglandWales() throws Exception { .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(venueSelectionService, times(1)).initHearingCollection(any(CaseData.class)); - verify(scotlandVenueSelectionService, never()).initHearingCollection(any(CaseData.class)); + verify(venueSelectionService, times(1)).initHearingCollection(ccdRequest.getCaseDetails().getCaseData()); + verify(scotlandVenueSelectionService, never()).initHearingCollection(ccdRequest.getCaseDetails().getCaseData()); } @Test @@ -81,8 +79,9 @@ void testInitialiseHearingScotland() throws Exception { .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(scotlandVenueSelectionService, times(1)).initHearingCollection(any(CaseData.class)); - verify(venueSelectionService, never()).initHearingCollection(any(CaseData.class)); + verify(scotlandVenueSelectionService, times(1)).initHearingCollection( + ccdRequest.getCaseDetails().getCaseData()); + verify(venueSelectionService, never()).initHearingCollection(ccdRequest.getCaseDetails().getCaseData()); } @Test @@ -98,7 +97,7 @@ void testInitialiseHearingInvalidToken() throws Exception { .andExpect(status().isForbidden()); - verify(venueSelectionService, never()).initHearingCollection(any(CaseData.class)); - verify(scotlandVenueSelectionService, never()).initHearingCollection(any(CaseData.class)); + verify(venueSelectionService, never()).initHearingCollection(ccdRequest.getCaseDetails().getCaseData()); + verify(scotlandVenueSelectionService, never()).initHearingCollection(ccdRequest.getCaseDetails().getCaseData()); } } diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/admin/TseAdmReplyControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/admin/TseAdmReplyControllerTest.java index c9a4b26b1b..63a49f4b1a 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/admin/TseAdmReplyControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/admin/TseAdmReplyControllerTest.java @@ -10,7 +10,6 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.web.servlet.MockMvc; import uk.gov.hmcts.et.common.model.ccd.CCDRequest; -import uk.gov.hmcts.et.common.model.ccd.CaseData; import uk.gov.hmcts.et.common.model.ccd.CaseDetails; import uk.gov.hmcts.ethos.replacement.docmosis.controllers.BaseControllerTest; import uk.gov.hmcts.ethos.replacement.docmosis.service.applications.admin.TseAdmReplyService; @@ -23,8 +22,6 @@ import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -80,8 +77,8 @@ void midDetailsTable_tokenOk() throws Exception { .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); verify(tseAdmReplyService).initialTseAdmReplyTableMarkUp( - any(CaseData.class), - eq(AUTH_TOKEN)); + ccdRequest.getCaseDetails().getCaseData(), + AUTH_TOKEN); } @Test @@ -93,8 +90,8 @@ void midDetailsTable_tokenFail() throws Exception { .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isForbidden()); verify(tseAdmReplyService, never()).initialTseAdmReplyTableMarkUp( - any(CaseData.class), - eq(AUTH_TOKEN)); + ccdRequest.getCaseDetails().getCaseData(), + AUTH_TOKEN); } @Test @@ -105,8 +102,8 @@ void midDetailsTable_badRequest() throws Exception { .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isBadRequest()); verify(tseAdmReplyService, never()).initialTseAdmReplyTableMarkUp( - any(CaseData.class), - eq(AUTH_TOKEN)); + ccdRequest.getCaseDetails().getCaseData(), + AUTH_TOKEN); } @Test @@ -121,7 +118,7 @@ void midValidateInput_tokenOk() throws Exception { .andExpect(jsonPath(JsonMapper.ERRORS, notNullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); verify(tseAdmReplyService).validateInput( - any(CaseData.class)); + ccdRequest.getCaseDetails().getCaseData()); } @Test @@ -133,7 +130,7 @@ void midValidateInput_tokenFail() throws Exception { .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isForbidden()); verify(tseAdmReplyService, never()).validateInput( - any(CaseData.class)); + ccdRequest.getCaseDetails().getCaseData()); } @Test @@ -144,7 +141,7 @@ void midValidateInput_badRequest() throws Exception { .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isBadRequest()); verify(tseAdmReplyService, never()).validateInput( - any(CaseData.class)); + ccdRequest.getCaseDetails().getCaseData()); } @Test @@ -159,11 +156,11 @@ void aboutToSubmit_tokenOk() throws Exception { .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); verify(tseAdmReplyService).saveTseAdmReplyDataFromCaseData( - any(CaseData.class)); + ccdRequest.getCaseDetails().getCaseData()); verify(tseAdmReplyService).sendNotifyEmailsToClaimant( - eq(ccdRequest.getCaseDetails().getCaseId()), any(CaseData.class), eq(AUTH_TOKEN)); + ccdRequest.getCaseDetails().getCaseId(), ccdRequest.getCaseDetails().getCaseData(), AUTH_TOKEN); verify(tseAdmReplyService).clearTseAdmReplyDataFromCaseData( - any(CaseData.class)); + ccdRequest.getCaseDetails().getCaseData()); } @Test @@ -175,11 +172,11 @@ void aboutToSubmit_tokenFail() throws Exception { .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isForbidden()); verify(tseAdmReplyService, never()).saveTseAdmReplyDataFromCaseData( - any(CaseData.class)); + ccdRequest.getCaseDetails().getCaseData()); verify(tseAdmReplyService, never()).sendNotifyEmailsToClaimant( - eq("4321"), any(CaseData.class), eq(AUTH_TOKEN)); + "4321", ccdRequest.getCaseDetails().getCaseData(), AUTH_TOKEN); verify(tseAdmReplyService, never()).clearTseAdmReplyDataFromCaseData( - any(CaseData.class)); + ccdRequest.getCaseDetails().getCaseData()); } @Test @@ -190,11 +187,11 @@ void aboutToSubmit_badRequest() throws Exception { .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isBadRequest()); verify(tseAdmReplyService, never()).saveTseAdmReplyDataFromCaseData( - any(CaseData.class)); + ccdRequest.getCaseDetails().getCaseData()); verify(tseAdmReplyService, never()).sendNotifyEmailsToClaimant( - eq("4321"), any(CaseData.class), eq(AUTH_TOKEN)); + "4321", ccdRequest.getCaseDetails().getCaseData(), AUTH_TOKEN); verify(tseAdmReplyService, never()).clearTseAdmReplyDataFromCaseData( - any(CaseData.class)); + ccdRequest.getCaseDetails().getCaseData()); } @Test diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/admin/TseAdminControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/admin/TseAdminControllerTest.java index 07a169ae18..6f0dc02f91 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/admin/TseAdminControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/admin/TseAdminControllerTest.java @@ -31,7 +31,6 @@ import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -142,8 +141,8 @@ void midDetailsTable_tokenOk() throws Exception { .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); verify(tseAdminService).initialTseAdminTableMarkUp( - any(CaseData.class), - eq(AUTH_TOKEN)); + ccdRequest.getCaseDetails().getCaseData(), + AUTH_TOKEN); } @Test @@ -155,8 +154,8 @@ void midDetailsTable_tokenFail() throws Exception { .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isForbidden()); verify(tseAdminService, never()).initialTseAdminTableMarkUp( - any(CaseData.class), - eq(AUTH_TOKEN)); + ccdRequest.getCaseDetails().getCaseData(), + AUTH_TOKEN); } @Test @@ -167,8 +166,8 @@ void midDetailsTable_badRequest() throws Exception { .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isBadRequest()); verify(tseAdminService, never()).initialTseAdminTableMarkUp( - any(CaseData.class), - eq(AUTH_TOKEN)); + ccdRequest.getCaseDetails().getCaseData(), + AUTH_TOKEN); } @Test @@ -183,7 +182,7 @@ void midValidateInput_tokenOk() throws Exception { .andExpect(jsonPath(JsonMapper.ERRORS, notNullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); verify(tseAdminService, times(1)) - .validateInput(any(CaseData.class)); + .validateInput(ccdRequest.getCaseDetails().getCaseData()); } @Test @@ -195,7 +194,7 @@ void midValidateInput_tokenFail() throws Exception { .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isForbidden()); verify(tseAdminService, never()) - .validateInput(any(CaseData.class)); + .validateInput(ccdRequest.getCaseDetails().getCaseData()); } @Test @@ -206,7 +205,7 @@ void midValidateInput_badRequest() throws Exception { .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isBadRequest()); verify(tseAdminService, never()) - .validateInput(any(CaseData.class)); + .validateInput(ccdRequest.getCaseDetails().getCaseData()); } @Test @@ -221,12 +220,12 @@ void aboutToSubmit_tokenOk() throws Exception { .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); verify(tseAdminService).saveTseAdminDataFromCaseData( - any(CaseData.class)); + ccdRequest.getCaseDetails().getCaseData()); verify(tseAdminService).sendEmailToClaimant( - eq(ccdRequest.getCaseDetails().getCaseId()), - any(CaseData.class)); + ccdRequest.getCaseDetails().getCaseId(), + ccdRequest.getCaseDetails().getCaseData()); verify(tseAdminService).clearTseAdminDataFromCaseData( - any(CaseData.class)); + ccdRequest.getCaseDetails().getCaseData()); verify(caseFlagsService, times(1)).setPrivateHearingFlag(any()); } @@ -239,12 +238,12 @@ void aboutToSubmit_tokenFail() throws Exception { .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isForbidden()); verify(tseAdminService, never()).saveTseAdminDataFromCaseData( - any(CaseData.class)); + ccdRequest.getCaseDetails().getCaseData()); verify(tseAdminService, never()).sendEmailToClaimant( - eq(ccdRequest.getCaseDetails().getCaseId()), - any(CaseData.class)); + ccdRequest.getCaseDetails().getCaseId(), + ccdRequest.getCaseDetails().getCaseData()); verify(tseAdminService, never()).clearTseAdminDataFromCaseData( - any(CaseData.class)); + ccdRequest.getCaseDetails().getCaseData()); } @Test @@ -255,12 +254,12 @@ void aboutToSubmit_badRequest() throws Exception { .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isBadRequest()); verify(tseAdminService, never()).saveTseAdminDataFromCaseData( - any(CaseData.class)); + ccdRequest.getCaseDetails().getCaseData()); verify(tseAdminService, never()).sendEmailToClaimant( - eq(ccdRequest.getCaseDetails().getCaseId()), - any(CaseData.class)); + ccdRequest.getCaseDetails().getCaseId(), + ccdRequest.getCaseDetails().getCaseData()); verify(tseAdminService, never()).clearTseAdminDataFromCaseData( - any(CaseData.class)); + ccdRequest.getCaseDetails().getCaseData()); } @Test @@ -308,7 +307,7 @@ void aboutToSubmitCloseApplication_tokenOk() throws Exception { .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); verify(tseAdmCloseService).aboutToSubmitCloseApplication( - any(CaseData.class)); + ccdRequest.getCaseDetails().getCaseData()); } @Test @@ -320,7 +319,7 @@ void aboutToSubmitCloseApplication_tokenFail() throws Exception { .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isForbidden()); verify(tseAdmCloseService, never()).aboutToSubmitCloseApplication( - any(CaseData.class)); + ccdRequest.getCaseDetails().getCaseData()); } @Test @@ -331,7 +330,7 @@ void aboutToSubmitCloseApplication_badRequest() throws Exception { .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isBadRequest()); verify(tseAdmCloseService, never()).aboutToSubmitCloseApplication( - any(CaseData.class)); + ccdRequest.getCaseDetails().getCaseData()); } @Test diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/claimant/ClaimantTellSomethingElseControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/claimant/ClaimantTellSomethingElseControllerTest.java index 6522bdb768..14cb5683cb 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/claimant/ClaimantTellSomethingElseControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/claimant/ClaimantTellSomethingElseControllerTest.java @@ -13,7 +13,6 @@ import org.springframework.test.web.servlet.MockMvc; import uk.gov.hmcts.et.common.model.ccd.CCDRequest; import uk.gov.hmcts.et.common.model.ccd.CaseData; -import uk.gov.hmcts.et.common.model.ccd.CaseDetails; import uk.gov.hmcts.et.common.model.ccd.items.GenericTseApplicationType; import uk.gov.hmcts.et.common.model.ccd.items.GenericTseApplicationTypeItem; import uk.gov.hmcts.ethos.replacement.docmosis.controllers.BaseControllerTest; @@ -34,7 +33,6 @@ import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mockStatic; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -149,8 +147,8 @@ void aboutToSubmitClaimantTSE_Success() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(tseService).createApplication(any(CaseData.class), eq(CLAIMANT_REP_TITLE)); - verify(claimantTseService).sendEmails(any(CaseDetails.class)); + verify(tseService).createApplication(ccdRequest.getCaseDetails().getCaseData(), CLAIMANT_REP_TITLE); + verify(claimantTseService).sendEmails(ccdRequest.getCaseDetails()); } @Test @@ -165,8 +163,8 @@ void aboutToSubmitClaimantTSE_NonSystemRespondent_Success() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(tseService).createApplication(any(CaseData.class), eq(CLAIMANT_REP_TITLE)); - verify(claimantTseService).sendEmails(any(CaseDetails.class)); + verify(tseService).createApplication(ccdRequest.getCaseDetails().getCaseData(), CLAIMANT_REP_TITLE); + verify(claimantTseService).sendEmails(ccdRequest.getCaseDetails()); } @Test @@ -182,7 +180,7 @@ void completeApplication_Success() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, nullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(claimantTseService).buildApplicationCompleteResponse(any(CaseData.class)); + verify(claimantTseService).buildApplicationCompleteResponse(ccdRequest.getCaseDetails().getCaseData()); } @Test @@ -196,7 +194,7 @@ void validateGiveDetails_Success() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, notNullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(claimantTseService).validateGiveDetails(any(CaseData.class)); + verify(claimantTseService).validateGiveDetails(ccdRequest.getCaseDetails().getCaseData()); } private List createApplicationCollection() { @@ -221,7 +219,7 @@ void displayClaimantApplicationsTable_Success() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(claimantTseService).generateClaimantApplicationTableMarkdown(any(CaseData.class)); + verify(claimantTseService).generateClaimantApplicationTableMarkdown(ccdRequest.getCaseDetails().getCaseData()); } @Test @@ -329,4 +327,4 @@ void midPopulateReply_badRequest() throws Exception { .contentType(APPLICATION_JSON)) .andExpect(status().isBadRequest()); } -} +} \ No newline at end of file diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/respondent/RespondentTellSomethingElseControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/respondent/RespondentTellSomethingElseControllerTest.java index 68e768fb98..264ffea504 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/respondent/RespondentTellSomethingElseControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/respondent/RespondentTellSomethingElseControllerTest.java @@ -13,7 +13,6 @@ import org.springframework.test.web.servlet.MockMvc; import uk.gov.hmcts.et.common.model.ccd.CCDRequest; import uk.gov.hmcts.et.common.model.ccd.CaseData; -import uk.gov.hmcts.et.common.model.ccd.CaseDetails; import uk.gov.hmcts.et.common.model.ccd.items.GenericTseApplicationType; import uk.gov.hmcts.et.common.model.ccd.items.GenericTseApplicationTypeItem; import uk.gov.hmcts.et.common.model.ccd.items.RespondentSumTypeItem; @@ -39,7 +38,6 @@ import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mockStatic; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -181,7 +179,7 @@ void validateGiveDetails_Success() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, notNullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(resTseService).validateGiveDetails(any(CaseData.class)); + verify(resTseService).validateGiveDetails(ccdRequest.getCaseDetails().getCaseData()); } @Test @@ -205,8 +203,8 @@ void aboutToSubmitRespondentTSE_Success() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(resTseService).sendEmails(any(CaseDetails.class), eq(AUTH_TOKEN)); - verify(tseService).createApplication(any(CaseData.class), eq(RESPONDENT_REP_TITLE)); + verify(resTseService).sendEmails(ccdRequest.getCaseDetails(), AUTH_TOKEN); + verify(tseService).createApplication(ccdRequest.getCaseDetails().getCaseData(), RESPONDENT_REP_TITLE); } @Test @@ -230,7 +228,7 @@ void displayRespondentApplicationsTable_Success() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(resTseService).generateTableMarkdown(any(CaseData.class)); + verify(resTseService).generateTableMarkdown(ccdRequest.getCaseDetails().getCaseData()); } @Test diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/notifications/respondent/PseRespondToTribunalControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/notifications/respondent/PseRespondToTribunalControllerTest.java index 526350c191..5b727d6483 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/notifications/respondent/PseRespondToTribunalControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/notifications/respondent/PseRespondToTribunalControllerTest.java @@ -13,7 +13,6 @@ import org.springframework.test.web.servlet.MockMvc; import uk.gov.hmcts.et.common.model.ccd.CCDRequest; import uk.gov.hmcts.et.common.model.ccd.CaseData; -import uk.gov.hmcts.et.common.model.ccd.CaseDetails; import uk.gov.hmcts.et.common.model.ccd.types.RespondentSumType; import uk.gov.hmcts.ethos.replacement.docmosis.helpers.Helper; import uk.gov.hmcts.ethos.replacement.docmosis.service.PseRespondToTribunalService; @@ -27,7 +26,6 @@ import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mockStatic; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -156,8 +154,8 @@ void midDetailsTable_Success() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(pseRespondToTribunalService).initialOrdReqDetailsTableMarkUp( - any(CaseData.class), eq(RESPONDENT_TITLE)); + verify(pseRespondToTribunalService).initialOrdReqDetailsTableMarkUp(ccdRequest.getCaseDetails().getCaseData(), + RESPONDENT_TITLE); } @Test @@ -181,7 +179,7 @@ void midValidateInput_Success() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, notNullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(pseRespondToTribunalService).validateRespondentInput(any(CaseData.class)); + verify(pseRespondToTribunalService).validateRespondentInput(ccdRequest.getCaseDetails().getCaseData()); } @Test @@ -205,11 +203,9 @@ void aboutToSubmit_Success() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(pseRespondToTribunalService, times(1)).sendAcknowledgeEmail( - any(CaseDetails.class), eq(AUTH_TOKEN)); - verify(pseRespondToTribunalService, times(1)).sendClaimantEmail(any(CaseDetails.class)); - verify(pseRespondToTribunalService, times(1)).sendTribunalEmail( - any(CaseDetails.class), eq(RESPONDENT_TITLE)); + verify(pseRespondToTribunalService, times(1)).sendAcknowledgeEmail(ccdRequest.getCaseDetails(), AUTH_TOKEN); + verify(pseRespondToTribunalService, times(1)).sendClaimantEmail(ccdRequest.getCaseDetails()); + verify(pseRespondToTribunalService, times(1)).sendTribunalEmail(ccdRequest.getCaseDetails(), RESPONDENT_TITLE); } @Test @@ -224,7 +220,7 @@ void aboutToSubmit_invalidToken() throws Exception { @Test void submitted_Success() throws Exception { - when(pseRespondToTribunalService.getRespondentSubmittedBody(any(CaseData.class))) + when(pseRespondToTribunalService.getRespondentSubmittedBody(ccdRequest.getCaseDetails().getCaseData())) .thenReturn("SubmittedBody"); when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); mockMvc.perform(post(SUBMITTED_URL) diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/notifications/respondent/PseRespondentViewControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/notifications/respondent/PseRespondentViewControllerTest.java index bcb003adf8..7f572b5d25 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/notifications/respondent/PseRespondentViewControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/notifications/respondent/PseRespondentViewControllerTest.java @@ -20,8 +20,6 @@ import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.springframework.http.MediaType.APPLICATION_JSON; @@ -77,7 +75,8 @@ void aboutToStartView_Success() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(provideSomethingElseViewService).populateSelectDropdownView(any(CaseData.class), eq(RESPONDENT_TITLE)); + verify(provideSomethingElseViewService).populateSelectDropdownView(ccdRequest.getCaseDetails().getCaseData(), + RESPONDENT_TITLE); } @Test @@ -102,7 +101,7 @@ void midDetailsTable_Success() throws Exception { .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); verify(provideSomethingElseViewService).initialOrdReqDetailsTableMarkUp( - any(CaseData.class), eq(RESPONDENT_TITLE)); + ccdRequest.getCaseDetails().getCaseData(), RESPONDENT_TITLE); } @Test From 21021ff9f0383a3b05ff833ad8fd7fdcd25f37db Mon Sep 17 00:00:00 2001 From: rajaram Date: Fri, 19 Jun 2026 11:32:54 +0100 Subject: [PATCH 011/100] Reapply "Fixed all the test failures" This reverts commit 5b8ea9a7fc121eca9cde385b4bb606eea0fbbbc5. --- .../docmosis/CallbackBindingSetupTest.java | 4 ++ .../AllocateHearingControllerTest.java | 34 +++++++------ .../BundlesRespondentControllerTest.java | 7 +-- .../controllers/CaseAccessControllerTest.java | 3 +- .../controllers/CaseNotesControllerTest.java | 9 ++-- .../CaseTransferControllerTest.java | 21 ++++---- .../controllers/Et1ReppedControllerTest.java | 8 ++- .../Et1SubmissionControllerTest.java | 5 +- .../Et3ResponseControllerTest.java | 4 +- .../HearingDetailsControllerTest.java | 17 ++++--- .../ListHearingControllerTest.java | 15 +++--- .../admin/TseAdmReplyControllerTest.java | 39 ++++++++------- .../admin/TseAdminControllerTest.java | 49 ++++++++++--------- ...aimantTellSomethingElseControllerTest.java | 18 ++++--- ...ondentTellSomethingElseControllerTest.java | 10 ++-- .../PseRespondToTribunalControllerTest.java | 18 ++++--- .../PseRespondentViewControllerTest.java | 7 +-- 17 files changed, 147 insertions(+), 121 deletions(-) diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/CallbackBindingSetupTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/CallbackBindingSetupTest.java index a66d05e5e3..343846a806 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/CallbackBindingSetupTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/CallbackBindingSetupTest.java @@ -5,6 +5,7 @@ import org.junit.jupiter.api.Test; import org.mockito.Answers; import org.mockito.Mockito; +import org.junit.jupiter.api.Assumptions; import org.springframework.beans.factory.ListableBeanFactory; import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; import org.springframework.core.annotation.AnnotatedElementUtils; @@ -53,6 +54,9 @@ private static Map loadCaseTypeDefinitions() Map definitions = new LinkedHashMap<>(); Class caseTypeDefinitionClass = Class.forName("uk.gov.hmcts.ccd.domain.model.definition.CaseTypeDefinition"); + Assumptions.assumeTrue(Files.isDirectory(DEFINITION_SNAPSHOTS_ROOT), + "CCD definition snapshots are generated by cftlib tasks and are not present"); + try (Stream paths = Files.walk(DEFINITION_SNAPSHOTS_ROOT)) { for (Path path : paths .filter(Files::isRegularFile) diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AllocateHearingControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AllocateHearingControllerTest.java index efb598a279..f3a358bcfd 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AllocateHearingControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AllocateHearingControllerTest.java @@ -9,6 +9,7 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.web.servlet.MockMvc; import uk.gov.hmcts.et.common.model.ccd.CCDRequest; +import uk.gov.hmcts.et.common.model.ccd.CaseData; import uk.gov.hmcts.ethos.replacement.docmosis.service.CaseManagementForCaseWorkerService; import uk.gov.hmcts.ethos.replacement.docmosis.service.VerifyTokenService; import uk.gov.hmcts.ethos.replacement.docmosis.service.hearings.allocatehearing.AllocateHearingService; @@ -18,6 +19,7 @@ import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -67,7 +69,7 @@ void testInitialiseHearingDynamicList() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(allocateHearingService, times(1)).initialiseAllocateHearing(ccdRequest.getCaseDetails().getCaseData()); + verify(allocateHearingService, times(1)).initialiseAllocateHearing(any(CaseData.class)); } @Test @@ -84,7 +86,7 @@ void testInitialiseHearingDynamicListInvalidToken() throws Exception { .content(jsonMapper.toJson(ccdRequest))) .andExpect(status().isForbidden()); - verify(allocateHearingService, never()).initialiseAllocateHearing(ccdRequest.getCaseDetails().getCaseData()); + verify(allocateHearingService, never()).initialiseAllocateHearing(any(CaseData.class)); } @Test @@ -104,7 +106,7 @@ void testHandleListingSelected() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(allocateHearingService, times(1)).handleListingSelected(ccdRequest.getCaseDetails().getCaseData()); + verify(allocateHearingService, times(1)).handleListingSelected(any(CaseData.class)); } @Test @@ -121,7 +123,7 @@ void testHandleListingSelectedInvalidToken() throws Exception { .content(jsonMapper.toJson(ccdRequest))) .andExpect(status().isForbidden()); - verify(allocateHearingService, never()).handleListingSelected(ccdRequest.getCaseDetails().getCaseData()); + verify(allocateHearingService, never()).handleListingSelected(any(CaseData.class)); } @Test @@ -137,7 +139,7 @@ void testHandleListingSelectedInvalidCaseTypeId() throws Exception { .header("Authorization", token) .content(jsonMapper.toJson(ccdRequest))) .andExpect(status().isBadRequest()); - verify(allocateHearingService, never()).handleListingSelected(ccdRequest.getCaseDetails().getCaseData()); + verify(allocateHearingService, never()).handleListingSelected(any(CaseData.class)); } @Test @@ -157,8 +159,8 @@ void testPopulateRoomsEnglandWales() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(allocateHearingService, times(1)).populateRooms(ccdRequest.getCaseDetails().getCaseData()); - verify(scotlandAllocateHearingService, never()).populateRooms(ccdRequest.getCaseDetails().getCaseData()); + verify(allocateHearingService, times(1)).populateRooms(any(CaseData.class)); + verify(scotlandAllocateHearingService, never()).populateRooms(any(CaseData.class)); } @Test @@ -178,8 +180,8 @@ void testPopulateRoomsScotland() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(scotlandAllocateHearingService, times(1)).populateRooms(ccdRequest.getCaseDetails().getCaseData()); - verify(allocateHearingService, never()).populateRooms(ccdRequest.getCaseDetails().getCaseData()); + verify(scotlandAllocateHearingService, times(1)).populateRooms(any(CaseData.class)); + verify(allocateHearingService, never()).populateRooms(any(CaseData.class)); } @Test @@ -196,7 +198,7 @@ void testPopulateRoomsInvalidToken() throws Exception { .content(jsonMapper.toJson(ccdRequest))) .andExpect(status().isForbidden()); - verify(allocateHearingService, never()).populateRooms(ccdRequest.getCaseDetails().getCaseData()); + verify(allocateHearingService, never()).populateRooms(any(CaseData.class)); } @Test @@ -216,8 +218,8 @@ void testAboutToSubmit_EnglandWales() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(allocateHearingService, times(1)).updateSelectedHearing(ccdRequest.getCaseDetails().getCaseData()); - verify(allocateHearingService, times(1)).updateCase(ccdRequest.getCaseDetails().getCaseData()); + verify(allocateHearingService, times(1)).updateSelectedHearing(any(CaseData.class)); + verify(allocateHearingService, times(1)).updateCase(any(CaseData.class)); } @Test @@ -237,8 +239,8 @@ void testAboutToSubmit_Scotland() throws Exception { .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(allocateHearingService, times(1)).updateSelectedHearing(ccdRequest.getCaseDetails().getCaseData()); - verify(scotlandAllocateHearingService, times(1)).updateCase(ccdRequest.getCaseDetails().getCaseData()); + verify(allocateHearingService, times(1)).updateSelectedHearing(any(CaseData.class)); + verify(scotlandAllocateHearingService, times(1)).updateCase(any(CaseData.class)); } @Test @@ -255,7 +257,7 @@ void testAboutToSubmitInvalidToken() throws Exception { .content(jsonMapper.toJson(ccdRequest))) .andExpect(status().isForbidden()); - verify(allocateHearingService, never()).updateSelectedHearing(ccdRequest.getCaseDetails().getCaseData()); - verify(allocateHearingService, never()).updateCase(ccdRequest.getCaseDetails().getCaseData()); + verify(allocateHearingService, never()).updateSelectedHearing(any(CaseData.class)); + verify(allocateHearingService, never()).updateCase(any(CaseData.class)); } } diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/BundlesRespondentControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/BundlesRespondentControllerTest.java index 4ca371bb8b..712bb481e3 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/BundlesRespondentControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/BundlesRespondentControllerTest.java @@ -11,6 +11,7 @@ import org.springframework.test.web.servlet.MockMvc; import org.webjars.NotFoundException; import uk.gov.hmcts.et.common.model.ccd.CCDRequest; +import uk.gov.hmcts.et.common.model.ccd.CaseData; import uk.gov.hmcts.ethos.replacement.docmosis.service.BundlesRespondentService; import uk.gov.hmcts.ethos.replacement.docmosis.service.FeatureToggleService; import uk.gov.hmcts.ethos.replacement.docmosis.service.SendNotificationService; @@ -116,7 +117,7 @@ void aboutToSubmit_tokenOk() throws Exception { .andExpect(jsonPath("$.data", notNullValue())) .andExpect(jsonPath("$.errors", nullValue())) .andExpect(jsonPath("$.warnings", nullValue())); - verify(bundlesRespondentService).clearInputData(ccdRequest.getCaseDetails().getCaseData()); + verify(bundlesRespondentService).clearInputData(any(CaseData.class)); } @Test @@ -127,7 +128,7 @@ void aboutToSubmit_tokenFail() throws Exception { .header("Authorization", AUTH_TOKEN) .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isForbidden()); - verify(bundlesRespondentService, never()).clearInputData(ccdRequest.getCaseDetails().getCaseData()); + verify(bundlesRespondentService, never()).clearInputData(any(CaseData.class)); } @Test @@ -137,7 +138,7 @@ void aboutToSubmit_badRequest() throws Exception { .header("Authorization", AUTH_TOKEN) .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isBadRequest()); - verify(bundlesRespondentService, never()).clearInputData(ccdRequest.getCaseDetails().getCaseData()); + verify(bundlesRespondentService, never()).clearInputData(any(CaseData.class)); } @Test diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseAccessControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseAccessControllerTest.java index f133e2ba7a..0e878cf5ef 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseAccessControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseAccessControllerTest.java @@ -16,6 +16,7 @@ import org.springframework.web.context.WebApplicationContext; import uk.gov.hmcts.et.common.model.ccd.CCDRequest; import uk.gov.hmcts.et.common.model.ccd.CaseData; +import uk.gov.hmcts.et.common.model.ccd.CaseDetails; import uk.gov.hmcts.ethos.replacement.docmosis.DocmosisApplication; import uk.gov.hmcts.ethos.replacement.docmosis.service.CaseAccessService; import uk.gov.hmcts.ethos.replacement.docmosis.service.VerifyTokenService; @@ -88,7 +89,7 @@ void assignClaimantTransferredCaseAccess_success() throws Exception { @Test void assignClaimantTransferredCaseAccess_error() throws Exception { ccdRequest.getCaseDetails().getCaseData().setLinkedCaseCT(null); - doCallRealMethod().when(caseAccessService).assignExistingCaseRoles(ccdRequest.getCaseDetails()); + doCallRealMethod().when(caseAccessService).assignExistingCaseRoles(any(CaseDetails.class)); mockMvc.perform(post(CLAIMANT_TRANSFERRED_CASE_URL) .contentType(APPLICATION_JSON) diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseNotesControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseNotesControllerTest.java index 6b57d5cf66..65d259bd0a 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseNotesControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseNotesControllerTest.java @@ -32,6 +32,7 @@ import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doCallRealMethod; import static org.mockito.Mockito.when; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; @@ -124,7 +125,7 @@ void aboutToSubmitSingles_ok() throws Exception { @Test void manageCaseNote_aboutToStart_noNotes() throws Exception { when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); - doCallRealMethod().when(caseNotesService).populateCaseNoteList(ccdRequest.getCaseDetails().getCaseData()); + doCallRealMethod().when(caseNotesService).populateCaseNoteList(any(CaseData.class)); ccdRequest.getCaseDetails().getCaseData().setCaseNotesCollection(null); mockMvc.perform(post(SINGLES_MANAGE_ABOUT_TO_START_URL) .content(jsonMapper.toJson(ccdRequest)) @@ -139,7 +140,7 @@ void manageCaseNote_aboutToStart_noNotes() throws Exception { @Test void manageCaseNote_aboutToStart() throws Exception { when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); - doCallRealMethod().when(caseNotesService).populateCaseNoteList(ccdRequest.getCaseDetails().getCaseData()); + doCallRealMethod().when(caseNotesService).populateCaseNoteList(any(CaseData.class)); GenericTypeItem caseNoteItem = createCaseNoteItem(); ccdRequest.getCaseDetails().getCaseData().setCaseNotesCollection(List.of(caseNoteItem, caseNoteItem)); mockMvc.perform(post(SINGLES_MANAGE_ABOUT_TO_START_URL) @@ -154,7 +155,7 @@ void manageCaseNote_aboutToStart() throws Exception { @Test void manageCaseNote_midEvent() throws Exception { when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); - doCallRealMethod().when(caseNotesService).populateEditCaseNote(ccdRequest.getCaseDetails().getCaseData()); + doCallRealMethod().when(caseNotesService).populateEditCaseNote(any(CaseData.class)); GenericTypeItem caseNoteItem = createCaseNoteItem(); ccdRequest.getCaseDetails().getCaseData().setCaseNotesCollection(List.of(caseNoteItem)); ccdRequest.getCaseDetails().getCaseData().setEditOrDeleteCaseNote("Edit"); @@ -171,7 +172,7 @@ void manageCaseNote_midEvent() throws Exception { @Test void manageCaseNote_aboutToSubmit() throws Exception { when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); - doCallRealMethod().when(caseNotesService).submitCaseNoteUpdate(ccdRequest.getCaseDetails().getCaseData()); + doCallRealMethod().when(caseNotesService).submitCaseNoteUpdate(any(CaseData.class)); GenericTypeItem caseNoteItem = createCaseNoteItem(); ccdRequest.getCaseDetails().getCaseData().setCaseNotesCollection(List.of(caseNoteItem)); ccdRequest.getCaseDetails().getCaseData().setEditOrDeleteCaseNote("Delete"); diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseTransferControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseTransferControllerTest.java index c33b6dcf03..ff02191e6e 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseTransferControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseTransferControllerTest.java @@ -42,6 +42,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.mock; @@ -180,7 +181,7 @@ void testTransferSameCountry() throws Exception { .andExpect(jsonPath(JsonMapper.ERRORS, hasSize(0))) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(caseTransferSameCountryService, times(1)).transferCase(ccdRequest.getCaseDetails(), AUTH_TOKEN); + verify(caseTransferSameCountryService, times(1)).transferCase(any(CaseDetails.class), eq(AUTH_TOKEN)); } @Test @@ -205,7 +206,7 @@ void testTransferSameCountryForbidden() throws Exception { .content(jsonMapper.toJson(ccdRequest))) .andExpect(status().isForbidden()); - verify(caseTransferSameCountryService, never()).transferCase(ccdRequest.getCaseDetails(), AUTH_TOKEN); + verify(caseTransferSameCountryService, never()).transferCase(any(CaseDetails.class), eq(AUTH_TOKEN)); } @Test @@ -222,7 +223,7 @@ void testTransferSameCountryEccLinkedCase() throws Exception { .andExpect(jsonPath(JsonMapper.ERRORS, hasSize(0))) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(caseTransferSameCountryService, times(1)).updateEccLinkedCase(ccdRequest.getCaseDetails(), AUTH_TOKEN); + verify(caseTransferSameCountryService, times(1)).updateEccLinkedCase(any(CaseDetails.class), eq(AUTH_TOKEN)); } @Test @@ -244,10 +245,10 @@ void testTransferSameCountryEccLinkedCaseForbidden() throws Exception { mockMvc.perform(post(CASE_TRANSFER_SAME_COUNTRY_ECC_LINKED_CASE_URL) .header("Authorization", AUTH_TOKEN) .contentType(MediaType.APPLICATION_JSON) - .content(jsonMapper.toJson(ccdRequest))) + .content(jsonMapper.toJson(ccdRequest))) .andExpect(status().isForbidden()); - verify(caseTransferSameCountryService, never()).updateEccLinkedCase(ccdRequest.getCaseDetails(), AUTH_TOKEN); + verify(caseTransferSameCountryService, never()).updateEccLinkedCase(any(CaseDetails.class), eq(AUTH_TOKEN)); } @Test @@ -264,7 +265,7 @@ void testTransferDifferentCountry() throws Exception { .andExpect(jsonPath(JsonMapper.ERRORS, hasSize(0))) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(caseTransferDifferentCountryService, times(1)).transferCase(ccdRequest.getCaseDetails(), AUTH_TOKEN); + verify(caseTransferDifferentCountryService, times(1)).transferCase(any(CaseDetails.class), eq(AUTH_TOKEN)); } @Test @@ -286,10 +287,10 @@ void testTransferDifferentCountryForbidden() throws Exception { mockMvc.perform(post(CASE_TRANSFER_DIFFERENT_COUNTRY_URL) .header("Authorization", AUTH_TOKEN) .contentType(MediaType.APPLICATION_JSON) - .content(jsonMapper.toJson(ccdRequest))) + .content(jsonMapper.toJson(ccdRequest))) .andExpect(status().isForbidden()); - verify(caseTransferDifferentCountryService, never()).transferCase(ccdRequest.getCaseDetails(), AUTH_TOKEN); + verify(caseTransferDifferentCountryService, never()).transferCase(any(CaseDetails.class), eq(AUTH_TOKEN)); } @Test @@ -397,7 +398,7 @@ void testTransferSameCountryAddsCaseMgtLocationCode() throws Exception { .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); verify(caseManagementLocationService, times(1)) - .setCaseManagementLocationCode(ccdRequest.getCaseDetails().getCaseData()); + .setCaseManagementLocationCode(any(CaseData.class)); } @Test @@ -415,7 +416,7 @@ void testTransferDifferentCountryUpdatesCaseMgtLocation() throws Exception { .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); verify(caseManagementLocationService, times(1)) - .setCaseManagementLocationCode(ccdRequest.getCaseDetails().getCaseData()); + .setCaseManagementLocationCode(any(CaseData.class)); } diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1ReppedControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1ReppedControllerTest.java index 464da60ee6..f8cf542510 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1ReppedControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1ReppedControllerTest.java @@ -1188,8 +1188,7 @@ void theMidEventAmendClaimantRepresentativeContact_ThrowsException() { StringUtils.EMPTY, "Et1ReppedService", "checkCaseData")).when(et1ReppedService) - .setMyHmctsOrganisationAddress(AUTH_TOKEN, - ccdRequestWithClaimantRepresentative.getCaseDetails().getCaseData()); + .setMyHmctsOrganisationAddress(anyString(), any(CaseData.class)); mockMvc.perform(post(MID_EVENT_AMEND_CLAIMANT_REPRESENTATIVE_CONTACT) .contentType(APPLICATION_JSON) .header(HttpHeaders.AUTHORIZATION, AUTH_TOKEN) @@ -1228,8 +1227,7 @@ void theAboutToSubmitAmendClaimantRepresentativeContact_ThrowsException() { StringUtils.EMPTY, "Et3ResponseService", "setRespondentRepresentsContactDetails")).when(et1ReppedService) - .setClaimantRepresentativeValues(AUTH_TOKEN, - ccdRequestWithClaimantRepresentative.getCaseDetails().getCaseData()); + .setClaimantRepresentativeValues(anyString(), any(CaseData.class)); mockMvc.perform(post(ABOUT_TO_SUBMIT_AMEND_CLAIMANT_REPRESENTATIVE_CONTACT) .contentType(APPLICATION_JSON) .header(HttpHeaders.AUTHORIZATION, AUTH_TOKEN) @@ -1240,4 +1238,4 @@ void theAboutToSubmitAmendClaimantRepresentativeContact_ThrowsException() { .andExpect(jsonPath("$.errors[0]", is(ERROR_CASE_DATA_NOT_FOUND))) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); } -} \ No newline at end of file +} diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1SubmissionControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1SubmissionControllerTest.java index 8bdc6c2c08..1839c67cbb 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1SubmissionControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1SubmissionControllerTest.java @@ -11,6 +11,7 @@ import org.springframework.test.web.servlet.MockMvc; import uk.gov.hmcts.et.common.model.ccd.CCDRequest; import uk.gov.hmcts.et.common.model.ccd.CaseData; +import uk.gov.hmcts.et.common.model.ccd.CaseDetails; import uk.gov.hmcts.ethos.replacement.docmosis.service.CaseManagementForCaseWorkerService; import uk.gov.hmcts.ethos.replacement.docmosis.service.Et1SubmissionService; import uk.gov.hmcts.ethos.replacement.docmosis.utils.JsonMapper; @@ -76,9 +77,9 @@ void addServiceId_success() throws Exception { .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); verify(caseManagementForCaseWorkerService, times(1)) - .setHmctsServiceIdSupplementary(ccdRequest.getCaseDetails()); + .setHmctsServiceIdSupplementary(any(CaseDetails.class)); verify(et1SubmissionService, times(1)) - .sendEt1ConfirmationClaimant(ccdRequest.getCaseDetails(), AUTH_TOKEN); + .sendEt1ConfirmationClaimant(any(CaseDetails.class), eq(AUTH_TOKEN)); } @Test diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et3ResponseControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et3ResponseControllerTest.java index c37a3cac82..96c0bcea34 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et3ResponseControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et3ResponseControllerTest.java @@ -480,8 +480,8 @@ void downloadDraftAboutToSubmit_tokenOk() throws Exception { documentInfo.setMarkUp("Document"); documentInfo.setDescription("Document.pdf"); ccdRequest.setEventId("draftEt3"); - when(et3ResponseService.generateEt3ResponseDocument(ccdRequest.getCaseDetails().getCaseData(), AUTH_TOKEN, - ENGLANDWALES_CASE_TYPE_ID, "draftEt3")).thenReturn(documentInfo); + when(et3ResponseService.generateEt3ResponseDocument(any(CaseData.class), anyString(), + anyString(), anyString())).thenReturn(documentInfo); when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); mvc.perform(post(DOWNLOAD_DRAFT_ABOUT_TO_SUBMIT) .content(jsonMapper.toJson(ccdRequest)) diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/HearingDetailsControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/HearingDetailsControllerTest.java index fefa4ae8f4..9f4a7aae39 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/HearingDetailsControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/HearingDetailsControllerTest.java @@ -9,6 +9,8 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.web.servlet.MockMvc; import uk.gov.hmcts.et.common.model.ccd.CCDRequest; +import uk.gov.hmcts.et.common.model.ccd.CaseData; +import uk.gov.hmcts.et.common.model.ccd.CaseDetails; import uk.gov.hmcts.ethos.replacement.docmosis.service.CaseManagementForCaseWorkerService; import uk.gov.hmcts.ethos.replacement.docmosis.service.VerifyTokenService; import uk.gov.hmcts.ethos.replacement.docmosis.service.hearings.hearingdetails.HearingDetailsService; @@ -18,6 +20,7 @@ import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -59,7 +62,7 @@ void testInitialiseHearingDynamicList() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(hearingDetailsService, times(1)).initialiseHearingDetails(ccdRequest.getCaseDetails().getCaseData()); + verify(hearingDetailsService, times(1)).initialiseHearingDetails(any(CaseData.class)); } @Test @@ -74,7 +77,7 @@ void testInitialiseHearingDynamicListInvalidToken() throws Exception { .content(jsonMapper.toJson(ccdRequest))) .andExpect(status().isForbidden()); - verify(hearingDetailsService, never()).initialiseHearingDetails(ccdRequest.getCaseDetails().getCaseData()); + verify(hearingDetailsService, never()).initialiseHearingDetails(any(CaseData.class)); } @Test @@ -92,7 +95,7 @@ void testHandleListingSelected() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(hearingDetailsService, times(1)).handleListingSelected(ccdRequest.getCaseDetails().getCaseData()); + verify(hearingDetailsService, times(1)).handleListingSelected(any(CaseData.class)); } @Test @@ -107,7 +110,7 @@ void testHandleListingSelectedInvalidToken() throws Exception { .content(jsonMapper.toJson(ccdRequest))) .andExpect(status().isForbidden()); - verify(hearingDetailsService, never()).handleListingSelected(ccdRequest.getCaseDetails().getCaseData()); + verify(hearingDetailsService, never()).handleListingSelected(any(CaseData.class)); } @Test @@ -139,7 +142,7 @@ void testhearingMidEventValidationInvalidToken() throws Exception { .content(jsonMapper.toJson(ccdRequest))) .andExpect(status().isForbidden()); - verify(hearingDetailsService, never()).handleListingSelected(ccdRequest.getCaseDetails().getCaseData()); + verify(hearingDetailsService, never()).handleListingSelected(any(CaseData.class)); } @Test @@ -157,7 +160,7 @@ void testAboutToSubmit() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(hearingDetailsService, times(1)).updateCase(ccdRequest.getCaseDetails()); + verify(hearingDetailsService, times(1)).updateCase(any(CaseDetails.class)); } @Test @@ -172,6 +175,6 @@ void testAboutToSubmitInvalidToken() throws Exception { .content(jsonMapper.toJson(ccdRequest))) .andExpect(status().isForbidden()); - verify(hearingDetailsService, never()).updateCase(ccdRequest.getCaseDetails()); + verify(hearingDetailsService, never()).updateCase(any(CaseDetails.class)); } } diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/ListHearingControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/ListHearingControllerTest.java index 9ed61600e3..b3928b2263 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/ListHearingControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/ListHearingControllerTest.java @@ -9,6 +9,7 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.web.servlet.MockMvc; import uk.gov.hmcts.et.common.model.ccd.CCDRequest; +import uk.gov.hmcts.et.common.model.ccd.CaseData; import uk.gov.hmcts.ethos.replacement.docmosis.service.hearings.allocatehearing.ScotlandVenueSelectionService; import uk.gov.hmcts.ethos.replacement.docmosis.service.hearings.allocatehearing.VenueSelectionService; import uk.gov.hmcts.ethos.replacement.docmosis.utils.JsonMapper; @@ -16,6 +17,7 @@ import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -59,8 +61,8 @@ void testInitialiseHearingEnglandWales() throws Exception { .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(venueSelectionService, times(1)).initHearingCollection(ccdRequest.getCaseDetails().getCaseData()); - verify(scotlandVenueSelectionService, never()).initHearingCollection(ccdRequest.getCaseDetails().getCaseData()); + verify(venueSelectionService, times(1)).initHearingCollection(any(CaseData.class)); + verify(scotlandVenueSelectionService, never()).initHearingCollection(any(CaseData.class)); } @Test @@ -79,9 +81,8 @@ void testInitialiseHearingScotland() throws Exception { .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(scotlandVenueSelectionService, times(1)).initHearingCollection( - ccdRequest.getCaseDetails().getCaseData()); - verify(venueSelectionService, never()).initHearingCollection(ccdRequest.getCaseDetails().getCaseData()); + verify(scotlandVenueSelectionService, times(1)).initHearingCollection(any(CaseData.class)); + verify(venueSelectionService, never()).initHearingCollection(any(CaseData.class)); } @Test @@ -97,7 +98,7 @@ void testInitialiseHearingInvalidToken() throws Exception { .andExpect(status().isForbidden()); - verify(venueSelectionService, never()).initHearingCollection(ccdRequest.getCaseDetails().getCaseData()); - verify(scotlandVenueSelectionService, never()).initHearingCollection(ccdRequest.getCaseDetails().getCaseData()); + verify(venueSelectionService, never()).initHearingCollection(any(CaseData.class)); + verify(scotlandVenueSelectionService, never()).initHearingCollection(any(CaseData.class)); } } diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/admin/TseAdmReplyControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/admin/TseAdmReplyControllerTest.java index 63a49f4b1a..c9a4b26b1b 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/admin/TseAdmReplyControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/admin/TseAdmReplyControllerTest.java @@ -10,6 +10,7 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.web.servlet.MockMvc; import uk.gov.hmcts.et.common.model.ccd.CCDRequest; +import uk.gov.hmcts.et.common.model.ccd.CaseData; import uk.gov.hmcts.et.common.model.ccd.CaseDetails; import uk.gov.hmcts.ethos.replacement.docmosis.controllers.BaseControllerTest; import uk.gov.hmcts.ethos.replacement.docmosis.service.applications.admin.TseAdmReplyService; @@ -22,6 +23,8 @@ import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -77,8 +80,8 @@ void midDetailsTable_tokenOk() throws Exception { .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); verify(tseAdmReplyService).initialTseAdmReplyTableMarkUp( - ccdRequest.getCaseDetails().getCaseData(), - AUTH_TOKEN); + any(CaseData.class), + eq(AUTH_TOKEN)); } @Test @@ -90,8 +93,8 @@ void midDetailsTable_tokenFail() throws Exception { .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isForbidden()); verify(tseAdmReplyService, never()).initialTseAdmReplyTableMarkUp( - ccdRequest.getCaseDetails().getCaseData(), - AUTH_TOKEN); + any(CaseData.class), + eq(AUTH_TOKEN)); } @Test @@ -102,8 +105,8 @@ void midDetailsTable_badRequest() throws Exception { .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isBadRequest()); verify(tseAdmReplyService, never()).initialTseAdmReplyTableMarkUp( - ccdRequest.getCaseDetails().getCaseData(), - AUTH_TOKEN); + any(CaseData.class), + eq(AUTH_TOKEN)); } @Test @@ -118,7 +121,7 @@ void midValidateInput_tokenOk() throws Exception { .andExpect(jsonPath(JsonMapper.ERRORS, notNullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); verify(tseAdmReplyService).validateInput( - ccdRequest.getCaseDetails().getCaseData()); + any(CaseData.class)); } @Test @@ -130,7 +133,7 @@ void midValidateInput_tokenFail() throws Exception { .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isForbidden()); verify(tseAdmReplyService, never()).validateInput( - ccdRequest.getCaseDetails().getCaseData()); + any(CaseData.class)); } @Test @@ -141,7 +144,7 @@ void midValidateInput_badRequest() throws Exception { .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isBadRequest()); verify(tseAdmReplyService, never()).validateInput( - ccdRequest.getCaseDetails().getCaseData()); + any(CaseData.class)); } @Test @@ -156,11 +159,11 @@ void aboutToSubmit_tokenOk() throws Exception { .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); verify(tseAdmReplyService).saveTseAdmReplyDataFromCaseData( - ccdRequest.getCaseDetails().getCaseData()); + any(CaseData.class)); verify(tseAdmReplyService).sendNotifyEmailsToClaimant( - ccdRequest.getCaseDetails().getCaseId(), ccdRequest.getCaseDetails().getCaseData(), AUTH_TOKEN); + eq(ccdRequest.getCaseDetails().getCaseId()), any(CaseData.class), eq(AUTH_TOKEN)); verify(tseAdmReplyService).clearTseAdmReplyDataFromCaseData( - ccdRequest.getCaseDetails().getCaseData()); + any(CaseData.class)); } @Test @@ -172,11 +175,11 @@ void aboutToSubmit_tokenFail() throws Exception { .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isForbidden()); verify(tseAdmReplyService, never()).saveTseAdmReplyDataFromCaseData( - ccdRequest.getCaseDetails().getCaseData()); + any(CaseData.class)); verify(tseAdmReplyService, never()).sendNotifyEmailsToClaimant( - "4321", ccdRequest.getCaseDetails().getCaseData(), AUTH_TOKEN); + eq("4321"), any(CaseData.class), eq(AUTH_TOKEN)); verify(tseAdmReplyService, never()).clearTseAdmReplyDataFromCaseData( - ccdRequest.getCaseDetails().getCaseData()); + any(CaseData.class)); } @Test @@ -187,11 +190,11 @@ void aboutToSubmit_badRequest() throws Exception { .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isBadRequest()); verify(tseAdmReplyService, never()).saveTseAdmReplyDataFromCaseData( - ccdRequest.getCaseDetails().getCaseData()); + any(CaseData.class)); verify(tseAdmReplyService, never()).sendNotifyEmailsToClaimant( - "4321", ccdRequest.getCaseDetails().getCaseData(), AUTH_TOKEN); + eq("4321"), any(CaseData.class), eq(AUTH_TOKEN)); verify(tseAdmReplyService, never()).clearTseAdmReplyDataFromCaseData( - ccdRequest.getCaseDetails().getCaseData()); + any(CaseData.class)); } @Test diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/admin/TseAdminControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/admin/TseAdminControllerTest.java index 6f0dc02f91..07a169ae18 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/admin/TseAdminControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/admin/TseAdminControllerTest.java @@ -31,6 +31,7 @@ import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -141,8 +142,8 @@ void midDetailsTable_tokenOk() throws Exception { .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); verify(tseAdminService).initialTseAdminTableMarkUp( - ccdRequest.getCaseDetails().getCaseData(), - AUTH_TOKEN); + any(CaseData.class), + eq(AUTH_TOKEN)); } @Test @@ -154,8 +155,8 @@ void midDetailsTable_tokenFail() throws Exception { .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isForbidden()); verify(tseAdminService, never()).initialTseAdminTableMarkUp( - ccdRequest.getCaseDetails().getCaseData(), - AUTH_TOKEN); + any(CaseData.class), + eq(AUTH_TOKEN)); } @Test @@ -166,8 +167,8 @@ void midDetailsTable_badRequest() throws Exception { .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isBadRequest()); verify(tseAdminService, never()).initialTseAdminTableMarkUp( - ccdRequest.getCaseDetails().getCaseData(), - AUTH_TOKEN); + any(CaseData.class), + eq(AUTH_TOKEN)); } @Test @@ -182,7 +183,7 @@ void midValidateInput_tokenOk() throws Exception { .andExpect(jsonPath(JsonMapper.ERRORS, notNullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); verify(tseAdminService, times(1)) - .validateInput(ccdRequest.getCaseDetails().getCaseData()); + .validateInput(any(CaseData.class)); } @Test @@ -194,7 +195,7 @@ void midValidateInput_tokenFail() throws Exception { .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isForbidden()); verify(tseAdminService, never()) - .validateInput(ccdRequest.getCaseDetails().getCaseData()); + .validateInput(any(CaseData.class)); } @Test @@ -205,7 +206,7 @@ void midValidateInput_badRequest() throws Exception { .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isBadRequest()); verify(tseAdminService, never()) - .validateInput(ccdRequest.getCaseDetails().getCaseData()); + .validateInput(any(CaseData.class)); } @Test @@ -220,12 +221,12 @@ void aboutToSubmit_tokenOk() throws Exception { .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); verify(tseAdminService).saveTseAdminDataFromCaseData( - ccdRequest.getCaseDetails().getCaseData()); + any(CaseData.class)); verify(tseAdminService).sendEmailToClaimant( - ccdRequest.getCaseDetails().getCaseId(), - ccdRequest.getCaseDetails().getCaseData()); + eq(ccdRequest.getCaseDetails().getCaseId()), + any(CaseData.class)); verify(tseAdminService).clearTseAdminDataFromCaseData( - ccdRequest.getCaseDetails().getCaseData()); + any(CaseData.class)); verify(caseFlagsService, times(1)).setPrivateHearingFlag(any()); } @@ -238,12 +239,12 @@ void aboutToSubmit_tokenFail() throws Exception { .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isForbidden()); verify(tseAdminService, never()).saveTseAdminDataFromCaseData( - ccdRequest.getCaseDetails().getCaseData()); + any(CaseData.class)); verify(tseAdminService, never()).sendEmailToClaimant( - ccdRequest.getCaseDetails().getCaseId(), - ccdRequest.getCaseDetails().getCaseData()); + eq(ccdRequest.getCaseDetails().getCaseId()), + any(CaseData.class)); verify(tseAdminService, never()).clearTseAdminDataFromCaseData( - ccdRequest.getCaseDetails().getCaseData()); + any(CaseData.class)); } @Test @@ -254,12 +255,12 @@ void aboutToSubmit_badRequest() throws Exception { .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isBadRequest()); verify(tseAdminService, never()).saveTseAdminDataFromCaseData( - ccdRequest.getCaseDetails().getCaseData()); + any(CaseData.class)); verify(tseAdminService, never()).sendEmailToClaimant( - ccdRequest.getCaseDetails().getCaseId(), - ccdRequest.getCaseDetails().getCaseData()); + eq(ccdRequest.getCaseDetails().getCaseId()), + any(CaseData.class)); verify(tseAdminService, never()).clearTseAdminDataFromCaseData( - ccdRequest.getCaseDetails().getCaseData()); + any(CaseData.class)); } @Test @@ -307,7 +308,7 @@ void aboutToSubmitCloseApplication_tokenOk() throws Exception { .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); verify(tseAdmCloseService).aboutToSubmitCloseApplication( - ccdRequest.getCaseDetails().getCaseData()); + any(CaseData.class)); } @Test @@ -319,7 +320,7 @@ void aboutToSubmitCloseApplication_tokenFail() throws Exception { .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isForbidden()); verify(tseAdmCloseService, never()).aboutToSubmitCloseApplication( - ccdRequest.getCaseDetails().getCaseData()); + any(CaseData.class)); } @Test @@ -330,7 +331,7 @@ void aboutToSubmitCloseApplication_badRequest() throws Exception { .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isBadRequest()); verify(tseAdmCloseService, never()).aboutToSubmitCloseApplication( - ccdRequest.getCaseDetails().getCaseData()); + any(CaseData.class)); } @Test diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/claimant/ClaimantTellSomethingElseControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/claimant/ClaimantTellSomethingElseControllerTest.java index 14cb5683cb..6522bdb768 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/claimant/ClaimantTellSomethingElseControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/claimant/ClaimantTellSomethingElseControllerTest.java @@ -13,6 +13,7 @@ import org.springframework.test.web.servlet.MockMvc; import uk.gov.hmcts.et.common.model.ccd.CCDRequest; import uk.gov.hmcts.et.common.model.ccd.CaseData; +import uk.gov.hmcts.et.common.model.ccd.CaseDetails; import uk.gov.hmcts.et.common.model.ccd.items.GenericTseApplicationType; import uk.gov.hmcts.et.common.model.ccd.items.GenericTseApplicationTypeItem; import uk.gov.hmcts.ethos.replacement.docmosis.controllers.BaseControllerTest; @@ -33,6 +34,7 @@ import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mockStatic; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -147,8 +149,8 @@ void aboutToSubmitClaimantTSE_Success() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(tseService).createApplication(ccdRequest.getCaseDetails().getCaseData(), CLAIMANT_REP_TITLE); - verify(claimantTseService).sendEmails(ccdRequest.getCaseDetails()); + verify(tseService).createApplication(any(CaseData.class), eq(CLAIMANT_REP_TITLE)); + verify(claimantTseService).sendEmails(any(CaseDetails.class)); } @Test @@ -163,8 +165,8 @@ void aboutToSubmitClaimantTSE_NonSystemRespondent_Success() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(tseService).createApplication(ccdRequest.getCaseDetails().getCaseData(), CLAIMANT_REP_TITLE); - verify(claimantTseService).sendEmails(ccdRequest.getCaseDetails()); + verify(tseService).createApplication(any(CaseData.class), eq(CLAIMANT_REP_TITLE)); + verify(claimantTseService).sendEmails(any(CaseDetails.class)); } @Test @@ -180,7 +182,7 @@ void completeApplication_Success() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, nullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(claimantTseService).buildApplicationCompleteResponse(ccdRequest.getCaseDetails().getCaseData()); + verify(claimantTseService).buildApplicationCompleteResponse(any(CaseData.class)); } @Test @@ -194,7 +196,7 @@ void validateGiveDetails_Success() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, notNullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(claimantTseService).validateGiveDetails(ccdRequest.getCaseDetails().getCaseData()); + verify(claimantTseService).validateGiveDetails(any(CaseData.class)); } private List createApplicationCollection() { @@ -219,7 +221,7 @@ void displayClaimantApplicationsTable_Success() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(claimantTseService).generateClaimantApplicationTableMarkdown(ccdRequest.getCaseDetails().getCaseData()); + verify(claimantTseService).generateClaimantApplicationTableMarkdown(any(CaseData.class)); } @Test @@ -327,4 +329,4 @@ void midPopulateReply_badRequest() throws Exception { .contentType(APPLICATION_JSON)) .andExpect(status().isBadRequest()); } -} \ No newline at end of file +} diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/respondent/RespondentTellSomethingElseControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/respondent/RespondentTellSomethingElseControllerTest.java index 264ffea504..68e768fb98 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/respondent/RespondentTellSomethingElseControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/respondent/RespondentTellSomethingElseControllerTest.java @@ -13,6 +13,7 @@ import org.springframework.test.web.servlet.MockMvc; import uk.gov.hmcts.et.common.model.ccd.CCDRequest; import uk.gov.hmcts.et.common.model.ccd.CaseData; +import uk.gov.hmcts.et.common.model.ccd.CaseDetails; import uk.gov.hmcts.et.common.model.ccd.items.GenericTseApplicationType; import uk.gov.hmcts.et.common.model.ccd.items.GenericTseApplicationTypeItem; import uk.gov.hmcts.et.common.model.ccd.items.RespondentSumTypeItem; @@ -38,6 +39,7 @@ import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mockStatic; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -179,7 +181,7 @@ void validateGiveDetails_Success() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, notNullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(resTseService).validateGiveDetails(ccdRequest.getCaseDetails().getCaseData()); + verify(resTseService).validateGiveDetails(any(CaseData.class)); } @Test @@ -203,8 +205,8 @@ void aboutToSubmitRespondentTSE_Success() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(resTseService).sendEmails(ccdRequest.getCaseDetails(), AUTH_TOKEN); - verify(tseService).createApplication(ccdRequest.getCaseDetails().getCaseData(), RESPONDENT_REP_TITLE); + verify(resTseService).sendEmails(any(CaseDetails.class), eq(AUTH_TOKEN)); + verify(tseService).createApplication(any(CaseData.class), eq(RESPONDENT_REP_TITLE)); } @Test @@ -228,7 +230,7 @@ void displayRespondentApplicationsTable_Success() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(resTseService).generateTableMarkdown(ccdRequest.getCaseDetails().getCaseData()); + verify(resTseService).generateTableMarkdown(any(CaseData.class)); } @Test diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/notifications/respondent/PseRespondToTribunalControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/notifications/respondent/PseRespondToTribunalControllerTest.java index 5b727d6483..526350c191 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/notifications/respondent/PseRespondToTribunalControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/notifications/respondent/PseRespondToTribunalControllerTest.java @@ -13,6 +13,7 @@ import org.springframework.test.web.servlet.MockMvc; import uk.gov.hmcts.et.common.model.ccd.CCDRequest; import uk.gov.hmcts.et.common.model.ccd.CaseData; +import uk.gov.hmcts.et.common.model.ccd.CaseDetails; import uk.gov.hmcts.et.common.model.ccd.types.RespondentSumType; import uk.gov.hmcts.ethos.replacement.docmosis.helpers.Helper; import uk.gov.hmcts.ethos.replacement.docmosis.service.PseRespondToTribunalService; @@ -26,6 +27,7 @@ import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mockStatic; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -154,8 +156,8 @@ void midDetailsTable_Success() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(pseRespondToTribunalService).initialOrdReqDetailsTableMarkUp(ccdRequest.getCaseDetails().getCaseData(), - RESPONDENT_TITLE); + verify(pseRespondToTribunalService).initialOrdReqDetailsTableMarkUp( + any(CaseData.class), eq(RESPONDENT_TITLE)); } @Test @@ -179,7 +181,7 @@ void midValidateInput_Success() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, notNullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(pseRespondToTribunalService).validateRespondentInput(ccdRequest.getCaseDetails().getCaseData()); + verify(pseRespondToTribunalService).validateRespondentInput(any(CaseData.class)); } @Test @@ -203,9 +205,11 @@ void aboutToSubmit_Success() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(pseRespondToTribunalService, times(1)).sendAcknowledgeEmail(ccdRequest.getCaseDetails(), AUTH_TOKEN); - verify(pseRespondToTribunalService, times(1)).sendClaimantEmail(ccdRequest.getCaseDetails()); - verify(pseRespondToTribunalService, times(1)).sendTribunalEmail(ccdRequest.getCaseDetails(), RESPONDENT_TITLE); + verify(pseRespondToTribunalService, times(1)).sendAcknowledgeEmail( + any(CaseDetails.class), eq(AUTH_TOKEN)); + verify(pseRespondToTribunalService, times(1)).sendClaimantEmail(any(CaseDetails.class)); + verify(pseRespondToTribunalService, times(1)).sendTribunalEmail( + any(CaseDetails.class), eq(RESPONDENT_TITLE)); } @Test @@ -220,7 +224,7 @@ void aboutToSubmit_invalidToken() throws Exception { @Test void submitted_Success() throws Exception { - when(pseRespondToTribunalService.getRespondentSubmittedBody(ccdRequest.getCaseDetails().getCaseData())) + when(pseRespondToTribunalService.getRespondentSubmittedBody(any(CaseData.class))) .thenReturn("SubmittedBody"); when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); mockMvc.perform(post(SUBMITTED_URL) diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/notifications/respondent/PseRespondentViewControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/notifications/respondent/PseRespondentViewControllerTest.java index 7f572b5d25..bcb003adf8 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/notifications/respondent/PseRespondentViewControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/notifications/respondent/PseRespondentViewControllerTest.java @@ -20,6 +20,8 @@ import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.springframework.http.MediaType.APPLICATION_JSON; @@ -75,8 +77,7 @@ void aboutToStartView_Success() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(provideSomethingElseViewService).populateSelectDropdownView(ccdRequest.getCaseDetails().getCaseData(), - RESPONDENT_TITLE); + verify(provideSomethingElseViewService).populateSelectDropdownView(any(CaseData.class), eq(RESPONDENT_TITLE)); } @Test @@ -101,7 +102,7 @@ void midDetailsTable_Success() throws Exception { .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); verify(provideSomethingElseViewService).initialOrdReqDetailsTableMarkUp( - ccdRequest.getCaseDetails().getCaseData(), RESPONDENT_TITLE); + any(CaseData.class), eq(RESPONDENT_TITLE)); } @Test From 7beb100db43f190869ef000e02582af6fdac0191 Mon Sep 17 00:00:00 2001 From: Mehmet Tahir Dede Date: Fri, 19 Jun 2026 11:46:31 +0100 Subject: [PATCH 012/100] Updates to correct the lexicographic order of imports. --- .../ethos/replacement/docmosis/CallbackBindingSetupTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/CallbackBindingSetupTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/CallbackBindingSetupTest.java index 343846a806..6a7d2a6f79 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/CallbackBindingSetupTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/CallbackBindingSetupTest.java @@ -2,10 +2,10 @@ import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Assumptions; import org.junit.jupiter.api.Test; import org.mockito.Answers; import org.mockito.Mockito; -import org.junit.jupiter.api.Assumptions; import org.springframework.beans.factory.ListableBeanFactory; import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; import org.springframework.core.annotation.AnnotatedElementUtils; From b1b5612060e194e2b5a17d7a085f0d261fe3bf66 Mon Sep 17 00:00:00 2001 From: rajaram Date: Wed, 24 Jun 2026 10:34:13 +0100 Subject: [PATCH 013/100] Addressed review comments --- ...AmendClaimantRepresentativeController.java | 14 +++---- .../CaseFlagsDataMigrationController.java | 5 +-- ...dClaimantRepresentativeControllerTest.java | 42 +++++++++++++------ 3 files changed, 35 insertions(+), 26 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeController.java index f938f449fe..4d9ec96881 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeController.java @@ -68,6 +68,10 @@ public ResponseEntity aboutToSubmit( CaseData caseData = ccdRequest.getCaseDetails().getCaseData(); addAmendClaimantRepresentativeService.addAmendClaimantRepresentative(caseData); + if (featureToggleService.isCaseFlagsEnabled()) { + caseFlagsService.setupCaseFlags(caseData); + } + return getCallbackRespEntityNoErrors(caseData); } @@ -77,24 +81,16 @@ public ResponseEntity aboutToSubmit( @ApiResponse(responseCode = "400", description = "Bad Request"), @ApiResponse(responseCode = "500", description = "Internal Server Error") }) - public ResponseEntity amendClaimantRepSubmitted( + public void amendClaimantRepSubmitted( @RequestBody CallbackRequest callbackRequest, @RequestHeader(HttpHeaders.AUTHORIZATION) String userToken) { log.info("AMEND CLAIMANT REPRESENTATIVE SUBMITTED ---> " + LOG_MESSAGE + "{}", callbackRequest.getCaseDetails().getCaseId()); - CaseData caseData = callbackRequest.getCaseDetails().getCaseData(); - try { nocClaimantRepresentativeService.updateClaimantRepAccess(callbackRequest); - - if (featureToggleService.isCaseFlagsEnabled()) { - caseFlagsService.setupCaseFlags(caseData); - } } catch (IOException e) { throw new CcdInputOutputException("Failed to update claimant representatives access", e); } - - return getCallbackRespEntityNoErrors(caseData); } } diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsDataMigrationController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsDataMigrationController.java index cfc593dd6c..b6726dedbe 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsDataMigrationController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsDataMigrationController.java @@ -76,10 +76,7 @@ public ResponseEntity addCaseFlagsData( respondentFlags.setVisibility(INTERNAL); } - log.info("Migrating existing case: {} for claimant: {}, respondent: {},", - ccdRequest.getCaseDetails().getCaseTypeId(), - claimantFlags.getPartyName(), - respondentFlags.getPartyName()); + log.info("Migrating existing case: {}", ccdRequest.getCaseDetails().getCaseTypeId()); return getCallbackRespEntityErrors(List.of(), caseData); } diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeControllerTest.java index 255ed098e3..c6dfc669ba 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeControllerTest.java @@ -27,6 +27,7 @@ import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -97,14 +98,17 @@ void testAboutToSubmitSetsClaimantRepresentativeId() { verify(addAmendClaimantRepresentativeService, times(1)) .addAmendClaimantRepresentative(any()); + verify(caseFlagsService, never()).setupCaseFlags(any()); } @Test @SneakyThrows - void testAmendClaimantRepSubmitted() { + void testAboutToSubmitSetsUpCaseFlagsWhenEnabled() { when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); - mockMvc.perform(post(SUBMITTED_URL) - .content(jsonMapper.toJson(callbackRequest)) + when(featureToggleService.isCaseFlagsEnabled()).thenReturn(true); + + mockMvc.perform(post(ABOUT_TO_SUBMIT_URL) + .content(jsonMapper.toJson(ccdRequest)) .header("Authorization", AUTH_TOKEN) .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) @@ -112,28 +116,40 @@ void testAmendClaimantRepSubmitted() { .andExpect(jsonPath("$.errors", nullValue())) .andExpect(jsonPath("$.warnings", nullValue())); + verify(addAmendClaimantRepresentativeService, times(1)) + .addAmendClaimantRepresentative(any()); + verify(caseFlagsService, times(1)).setupCaseFlags(any()); + } + + @Test + @SneakyThrows + void testAmendClaimantRepSubmitted() { + when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); + mockMvc.perform(post(SUBMITTED_URL) + .content(jsonMapper.toJson(callbackRequest)) + .header("Authorization", AUTH_TOKEN) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + verify(nocClaimantRepresentativeService, times(1)) .updateClaimantRepAccess(any()); - verify(caseFlagsService, times(0)).setupCaseFlags(any()); + verify(caseFlagsService, never()).setupCaseFlags(any()); } @Test @SneakyThrows - void testAmendClaimantRepSubmittedSetsUpCaseFlagsWhenEnabled() { + void testAmendClaimantRepSubmittedDoesNotSetUpCaseFlagsWhenEnabled() { when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); when(featureToggleService.isCaseFlagsEnabled()).thenReturn(true); mockMvc.perform(post(SUBMITTED_URL) - .content(jsonMapper.toJson(callbackRequest)) - .header("Authorization", AUTH_TOKEN) - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.data", notNullValue())) - .andExpect(jsonPath("$.errors", nullValue())) - .andExpect(jsonPath("$.warnings", nullValue())); + .content(jsonMapper.toJson(callbackRequest)) + .header("Authorization", AUTH_TOKEN) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); verify(nocClaimantRepresentativeService, times(1)) .updateClaimantRepAccess(any()); - verify(caseFlagsService, times(1)).setupCaseFlags(any()); + verify(caseFlagsService, never()).setupCaseFlags(any()); } } From 1a3782ceadcbe0938de75a67ba747b27f9f49322 Mon Sep 17 00:00:00 2001 From: Mehmet Tahir Dede Date: Wed, 24 Jun 2026 11:13:22 +0100 Subject: [PATCH 014/100] Trigger CI build From a7b8fac61be21d36bb18bf3590eed14bc66b0095 Mon Sep 17 00:00:00 2001 From: rajaram Date: Wed, 24 Jun 2026 11:22:09 +0100 Subject: [PATCH 015/100] Addressed review comments --- .../docmosis/controllers/CaseFlagsDataMigrationController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsDataMigrationController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsDataMigrationController.java index b6726dedbe..2d16775c4b 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsDataMigrationController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsDataMigrationController.java @@ -76,7 +76,7 @@ public ResponseEntity addCaseFlagsData( respondentFlags.setVisibility(INTERNAL); } - log.info("Migrating existing case: {}", ccdRequest.getCaseDetails().getCaseTypeId()); + log.info("Migrating existing case: {}", ccdRequest.getCaseDetails().getCaseId()); return getCallbackRespEntityErrors(List.of(), caseData); } From 0862c53691b5c4ba6a7b78437bd17633e3e3e92c Mon Sep 17 00:00:00 2001 From: Mehmet Tahir Dede Date: Wed, 24 Jun 2026 11:54:33 +0100 Subject: [PATCH 016/100] Trigger CI build From 3415f65afcfa58eb0439fb5039f5e2ee303a6afc Mon Sep 17 00:00:00 2001 From: rajaram Date: Thu, 2 Jul 2026 15:18:15 +0100 Subject: [PATCH 017/100] Addressed review comments --- .../json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json | 4 ++-- .../json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json index 781128d76d..73efde5a32 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json @@ -32,8 +32,8 @@ { "CaseTypeID": "ET_EnglandWales", "ID": "requestSupport", - "Name": "Request support", - "Description": "Request support", + "Name": "Request Support", + "Description": "Request Support", "PreConditionState(s)": "*", "PostConditionState": "*", "SecurityClassification": "Public", diff --git a/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json index 02adb198f0..5e7c0aada9 100644 --- a/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json @@ -32,8 +32,8 @@ { "CaseTypeID": "ET_Scotland", "ID": "requestSupport", - "Name": "Request support", - "Description": "Request support", + "Name": "Request Support", + "Description": "Request Support", "PreConditionState(s)": "*", "PostConditionState": "*", "SecurityClassification": "Public", From 49d6361ccb54fd4812c619e8bc09b7bd0bc8b553 Mon Sep 17 00:00:00 2001 From: rajaram Date: Fri, 10 Jul 2026 15:53:11 +0100 Subject: [PATCH 018/100] Fixed build issue --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 266a661199..febb447e51 100644 --- a/build.gradle +++ b/build.gradle @@ -520,7 +520,7 @@ dependencies { implementation 'org.flywaydb:flyway-database-postgresql:11.20.3' implementation 'org.flywaydb:flyway-core:11.20.3' // CVE-2026-42198 - implementation group: 'org.postgresql', name: 'postgresql', version: '42.7.11' + implementation group: 'org.postgresql', name: 'postgresql', version: '42.7.12' implementation group: 'org.slf4j', name: 'slf4j-ext', version: '2.0.17' implementation group: 'org.springdoc', name: 'springdoc-openapi-starter-webmvc-ui', version: '2.5.0' implementation 'org.springframework.boot:spring-boot-configuration-processor' From c3d41379412c7c3100dbcc2c8fcc90cb9c6f9d2e Mon Sep 17 00:00:00 2001 From: rajaram Date: Wed, 15 Jul 2026 17:12:14 +0100 Subject: [PATCH 019/100] Fixed conflict issues --- .../docmosis/controllers/NoticeOfChangeController.java | 3 +-- .../AddAmendClaimantRepresentativeControllerTest.java | 5 ++--- .../docmosis/controllers/NoticeOfChangeControllerTest.java | 6 +++--- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/NoticeOfChangeController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/NoticeOfChangeController.java index 8e64215fba..beee4ed4b5 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/NoticeOfChangeController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/NoticeOfChangeController.java @@ -17,10 +17,9 @@ import uk.gov.hmcts.et.common.model.ccd.CallbackRequest; import uk.gov.hmcts.et.common.model.ccd.CaseData; import uk.gov.hmcts.et.common.model.ccd.CaseDetails; -import uk.gov.hmcts.ethos.replacement.docmosis.service.noc.CcdCaseAssignment; import uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService; -import uk.gov.hmcts.ethos.replacement.docmosis.service.CcdCaseAssignment; import uk.gov.hmcts.ethos.replacement.docmosis.service.FeatureToggleService; +import uk.gov.hmcts.ethos.replacement.docmosis.service.noc.CcdCaseAssignment; import uk.gov.hmcts.ethos.replacement.docmosis.service.noc.NocNotificationService; import uk.gov.hmcts.ethos.replacement.docmosis.service.noc.NocRepresentativeService; diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeControllerTest.java index f5b14956d8..a4e24110ab 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeControllerTest.java @@ -11,6 +11,7 @@ import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.web.servlet.MockMvc; +import uk.gov.hmcts.ecm.common.idam.models.UserDetails; import uk.gov.hmcts.et.common.model.ccd.CCDRequest; import uk.gov.hmcts.et.common.model.ccd.CallbackRequest; import uk.gov.hmcts.et.common.model.ccd.CaseData; @@ -150,11 +151,9 @@ void testAmendClaimantRepresentativeSubmitted() { .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(jsonPath("$.data", notNullValue())) - .andExpect(jsonPath("$.errors", nullValue())) + .andExpect(jsonPath("$.errors", empty())) .andExpect(jsonPath("$.warnings", nullValue())); - verify(addAmendClaimantRepresentativeService, times(1)) - .addAmendClaimantRepresentative(any()); verify(caseFlagsService, times(1)).setupCaseFlags(any()); } diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/NoticeOfChangeControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/NoticeOfChangeControllerTest.java index ae9ac1180e..67e4fb0eea 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/NoticeOfChangeControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/NoticeOfChangeControllerTest.java @@ -17,11 +17,11 @@ import uk.gov.hmcts.et.common.model.ccd.CCDCallbackResponse; import uk.gov.hmcts.et.common.model.ccd.CallbackRequest; import uk.gov.hmcts.et.common.model.ccd.CaseData; -import uk.gov.hmcts.ethos.replacement.docmosis.service.UserIdamService; -import uk.gov.hmcts.ethos.replacement.docmosis.service.VerifyTokenService; import uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService; -import uk.gov.hmcts.ethos.replacement.docmosis.service.CcdCaseAssignment; import uk.gov.hmcts.ethos.replacement.docmosis.service.FeatureToggleService; +import uk.gov.hmcts.ethos.replacement.docmosis.service.UserIdamService; +import uk.gov.hmcts.ethos.replacement.docmosis.service.VerifyTokenService; +import uk.gov.hmcts.ethos.replacement.docmosis.service.noc.CcdCaseAssignment; import uk.gov.hmcts.ethos.replacement.docmosis.service.noc.NocNotificationService; import uk.gov.hmcts.ethos.replacement.docmosis.service.noc.NocRepresentativeService; import uk.gov.hmcts.ethos.replacement.docmosis.service.noc.NocRespondentRepresentativeService; From 9de8de5b26fca6f94065039a29b8c21652711381 Mon Sep 17 00:00:00 2001 From: rajaram Date: Mon, 20 Jul 2026 11:52:56 +0100 Subject: [PATCH 020/100] Added new access profiles to preview env --- bin/preview/create-ccd-roles.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bin/preview/create-ccd-roles.sh b/bin/preview/create-ccd-roles.sh index eea64a1e8c..ae16e829f5 100755 --- a/bin/preview/create-ccd-roles.sh +++ b/bin/preview/create-ccd-roles.sh @@ -37,6 +37,8 @@ declare -a ET_ROLES=( "caseworker-wa-task-officer" "caseworker-employment-etjudge-leeds" "caseworker-employment-leeds" + "caseworker-employment-caseflags" + "caseworker-employment-support" ) echo "⏳ Waiting for CCD definition-store schema..." From 9ea598b4524cbeadb721c6ccb37f8700369a479f Mon Sep 17 00:00:00 2001 From: rajaram Date: Mon, 20 Jul 2026 12:51:00 +0100 Subject: [PATCH 021/100] Fixed functional test issues --- .../AddAmendClaimantRepresentativeController.java | 4 +++- .../docmosis/helpers/NocRespondentHelper.java | 4 +++- ...seActionsForCaseWorkerControllerFunctionalTest.java | 8 +++++++- .../AddAmendClaimantRepresentativeControllerTest.java | 10 ++++++++-- .../docmosis/helpers/NocRespondentHelperTest.java | 10 +++++++++- 5 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeController.java index 9cd92485be..ec2f41a7b2 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeController.java @@ -37,6 +37,7 @@ import static uk.gov.hmcts.ethos.replacement.docmosis.constants.NOCConstants.EXCEPTION_REPRESENTATIVE_ORGANISATION_NOT_FOUND; import static uk.gov.hmcts.ethos.replacement.docmosis.helpers.CallbackRespHelper.getCallbackRespEntityErrors; import static uk.gov.hmcts.ethos.replacement.docmosis.helpers.CallbackRespHelper.getCallbackRespEntityErrorsAndWarnings; +import static uk.gov.hmcts.ethos.replacement.docmosis.helpers.CallbackRespHelper.getCallbackRespEntityNoErrors; /** * REST controller for the addAmendClaimantRepresentative event. @@ -132,7 +133,7 @@ public ResponseEntity aboutToSubmit( @ApiResponse(responseCode = "400", description = "Bad Request"), @ApiResponse(responseCode = "500", description = "Internal Server Error") }) - public void amendClaimantRepSubmitted( + public ResponseEntity amendClaimantRepSubmitted( @RequestBody CallbackRequest callbackRequest, @RequestHeader(HttpHeaders.AUTHORIZATION) String userToken) { @@ -143,5 +144,6 @@ public void amendClaimantRepSubmitted( } catch (IOException e) { throw new CcdInputOutputException("Failed to update claimant representatives access", e); } + return getCallbackRespEntityNoErrors(callbackRequest.getCaseDetails().getCaseData()); } } diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/helpers/NocRespondentHelper.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/helpers/NocRespondentHelper.java index 67d9bfce5b..d18a6d70ee 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/helpers/NocRespondentHelper.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/helpers/NocRespondentHelper.java @@ -185,7 +185,9 @@ public void amendRespondentNameRepresentativeNames(CaseData caseData) { final List respondentCollection = caseData.getRespondentCollection(); Optional matchedRespondent = respondentCollection.stream() .filter(resp -> - resp.getId().equals(respondentRep.getValue().getRespondentId())).findFirst(); + StringUtils.isNotBlank(respondentRep.getValue().getRespondentId()) + && Objects.equals(resp.getId(), respondentRep.getValue().getRespondentId())) + .findFirst(); matchedRespondent.ifPresent(respondent -> updateRepWithRespondentDetails(respondent, respondentRep, respondentCollection)); diff --git a/src/test/apiTest/java/uk/gov/hmcts/ethos/replacement/apitest/CaseActionsForCaseWorkerControllerFunctionalTest.java b/src/test/apiTest/java/uk/gov/hmcts/ethos/replacement/apitest/CaseActionsForCaseWorkerControllerFunctionalTest.java index 8e72258dc8..c5c7236c62 100644 --- a/src/test/apiTest/java/uk/gov/hmcts/ethos/replacement/apitest/CaseActionsForCaseWorkerControllerFunctionalTest.java +++ b/src/test/apiTest/java/uk/gov/hmcts/ethos/replacement/apitest/CaseActionsForCaseWorkerControllerFunctionalTest.java @@ -27,7 +27,10 @@ public class CaseActionsForCaseWorkerControllerFunctionalTest extends BaseFuncti private static final String RESTRICTED_CASES_URL = "/restrictedCases"; private static final String AMEND_CLAIMANT_DETAILS_URL = "/amendClaimantDetails"; private static final String AMEND_RESPONDENT_DETAILS_URL = "/amendRespondentDetails"; - private static final String AMEND_RESPONDENT_REPRESENTATIVE_URL = "/amendRespondentRepresentative"; + private static final String AMEND_RESPONDENT_REPRESENTATIVE_URL = + "/respondentRepresentative/amendRespondentRepresentativeAboutToSubmit"; + private static final String RESPONDENT_ID = "respondent-id"; + private static final String REPRESENTATIVE_ID = "representative-id"; private static final String RESPONDENT_NAME = "Respondent Ltd"; private CCDRequest ccdRequest; @@ -39,6 +42,7 @@ public void setUpCaseData() { .withRespondent(RESPONDENT_NAME, NO, null, false) .build(); + caseData.getRespondentCollection().getFirst().setId(RESPONDENT_ID); caseData.setIcListingPreliminaryHearing(YES); caseData.setRepCollection(List.of(createRespondentRepresentative())); @@ -113,9 +117,11 @@ private RepresentedTypeRItem createRespondentRepresentative() { .myHmctsYesNo(NO) .dynamicRespRepName(DynamicFixedListType.of( DynamicValueType.create("R: " + RESPONDENT_NAME, RESPONDENT_NAME))) + .respondentId(RESPONDENT_ID) .build(); RepresentedTypeRItem item = new RepresentedTypeRItem(); + item.setId(REPRESENTATIVE_ID); item.setValue(representative); return item; diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeControllerTest.java index a4e24110ab..6161f4fb64 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeControllerTest.java @@ -165,7 +165,10 @@ void testAmendClaimantRepSubmitted() { .content(jsonMapper.toJson(callbackRequest)) .header("Authorization", AUTH_TOKEN) .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()); + .andExpect(status().isOk()) + .andExpect(jsonPath("$.data", notNullValue())) + .andExpect(jsonPath("$.errors", nullValue())) + .andExpect(jsonPath("$.warnings", nullValue())); verify(nocClaimantRepresentativeService, times(1)) .updateClaimantRepAccess(any()); @@ -182,7 +185,10 @@ void testAmendClaimantRepSubmittedDoesNotSetUpCaseFlagsWhenEnabled() { .content(jsonMapper.toJson(callbackRequest)) .header("Authorization", AUTH_TOKEN) .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()); + .andExpect(status().isOk()) + .andExpect(jsonPath("$.data", notNullValue())) + .andExpect(jsonPath("$.errors", nullValue())) + .andExpect(jsonPath("$.warnings", nullValue())); verify(nocClaimantRepresentativeService, times(1)) .updateClaimantRepAccess(any()); diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/helpers/NocRespondentHelperTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/helpers/NocRespondentHelperTest.java index 29d624ff42..f12413c0b3 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/helpers/NocRespondentHelperTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/helpers/NocRespondentHelperTest.java @@ -265,6 +265,14 @@ void amendRespondentNameRepresentativeNames() { assertThat(rep.getRespRepName()).isEqualTo(RESPONDENT_NAME_ONE); } + @Test + void amendRespondentNameRepresentativeNamesIgnoresRepresentativesWithoutRespondentId() { + caseData.getRespondentCollection().getFirst().setId(null); + caseData.getRepCollection().getFirst().getValue().setRespondentId(null); + + assertDoesNotThrow(() -> nocRespondentHelper.amendRespondentNameRepresentativeNames(caseData)); + } + @Test void generateNewRepDetails() { UserDetails userDetails = new UserDetails(); @@ -333,4 +341,4 @@ void theRemoveUnmatchedRepresentations() { assertThat(tmpCaseData.getRespondentCollection().getFirst().getValue().getRepresentativeId()).isNull(); assertThat(tmpCaseData.getRespondentCollection().getFirst().getValue().getRepresented()).isEqualTo(NO); } -} \ No newline at end of file +} From 61fdba03c60709149ef9d108ce6222bbf1962559 Mon Sep 17 00:00:00 2001 From: rajaram Date: Mon, 27 Jul 2026 17:34:37 +0100 Subject: [PATCH 022/100] RET-6728 and RET-6729 changes --- .../ClaimantRepresentativeController.java | 5 + .../docmosis/service/CaseFlagsService.java | 35 ++++++- .../CaseManagementForCaseWorkerService.java | 18 +++- .../apitest/BaseFunctionalTest.java | 28 +++--- ...epresentativeControllerFunctionalTest.java | 97 +++++++++++++++++++ .../apitest/IdamTestApiRequests.java | 4 +- .../ClaimantRepresentativeControllerTest.java | 65 ++++++++++--- .../service/CaseFlagsServiceTest.java | 68 +++++++++++++ ...aseManagementForCaseWorkerServiceTest.java | 41 +++++++- 9 files changed, 330 insertions(+), 31 deletions(-) create mode 100644 src/test/apiTest/java/uk/gov/hmcts/ethos/replacement/apitest/ClaimantRepresentativeControllerFunctionalTest.java diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/ClaimantRepresentativeController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/ClaimantRepresentativeController.java index 232d629f66..4d2c0d051d 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/ClaimantRepresentativeController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/ClaimantRepresentativeController.java @@ -103,13 +103,18 @@ public ResponseEntity removeOwnRepresentative( LOG_MESSAGE, ccdRequest.getCaseDetails().getCaseId()); CaseDetails caseDetails = ccdRequest.getCaseDetails(); CaseData caseData = caseDetails.getCaseData(); + if (StringUtils.isNotBlank(caseData.getClaimantRepresentedQuestion()) && NO.equals(caseData.getClaimantRepresentedQuestion())) { caseData.setRepresentativeClaimantType(null); caseData.setClaimantRepresentativeOrganisationPolicy( OrganisationPolicy.builder().orgPolicyCaseAssignedRole(CLAIMANTSOLICITOR.getCaseRoleLabel()).build() ); + + caseData.getAllPartyFlags().setClaimantRepresentativeFlags(null); + caseData.getAllPartyFlags().setClaimantRepresentativeExternalFlags(null); } + return getCallbackRespEntityNoErrors(ccdRequest.getCaseDetails().getCaseData()); } diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java index 95c78ea599..200a8660fb 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java @@ -27,6 +27,7 @@ import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.DISRUPTIVE_CUSTOMER; import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.EXTERNAL; import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.GRANTED; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.INACTIVE; import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.INTERNAL; import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.LANGUAGE_INTERPRETER; import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.NOT_INDEXED; @@ -59,7 +60,6 @@ @Slf4j @Service public class CaseFlagsService { - private static final List PARTY_FLAGS = List.of( claimantFlag(AllPartyFlags::getClaimantFlags, AllPartyFlags::setClaimantFlags, INTERNAL), claimantFlag(AllPartyFlags::getClaimantExternalFlags, AllPartyFlags::setClaimantExternalFlags, EXTERNAL), @@ -221,6 +221,39 @@ public void setPrivateHearingFlag(CaseData caseData) { caseData.setPrivateHearingRequiredFlag(shouldBePrivate ? YES : NO); } + /** + * Inactivates all case flag details for a respondent with the supplied reason comment. + * + * @param caseData Data about the current case + * @param respondentName Name of the respondent + * @param inactiveFlagComment Comment to add to each inactivated flag + */ + public void inactivateCaseFlags(CaseData caseData, String respondentName, String inactiveFlagComment) { + if (caseData == null || StringUtils.isBlank(respondentName)) { + return; + } + + PARTY_FLAGS.stream() + .filter(flag -> PartyType.RESPONDENT.equals(flag.partyType())) + .map(flag -> flag.get(caseData)) + .filter(flags -> flags != null && Objects.equals(respondentName, flags.getPartyName())) + .forEach(flags -> inactivateCaseFlags(flags, inactiveFlagComment)); + } + + private void inactivateCaseFlags(CaseFlagsType flags, String inactiveFlagComment) { + if (flags.getDetails() == null) { + return; + } + + flags.getDetails().stream() + .map(GenericTypeItem::getValue) + .filter(Objects::nonNull) + .forEach(flag -> { + flag.setStatus(INACTIVE); + flag.setFlagComment(inactiveFlagComment); + }); + } + private static PartyFlag claimantFlag( Function getter, BiConsumer setter, diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseManagementForCaseWorkerService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseManagementForCaseWorkerService.java index aba9fa3ed9..86da0b608b 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseManagementForCaseWorkerService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseManagementForCaseWorkerService.java @@ -85,6 +85,7 @@ public class CaseManagementForCaseWorkerService { private final CaseRetrievalForCaseWorkerService caseRetrievalForCaseWorkerService; private final CcdClient ccdClient; private final FeatureToggleService featureToggleService; + private final CaseFlagsService caseFlagsService; private final String hmctsServiceId; private final AdminUserService adminUserService; private final CaseManagementLocationService caseManagementLocationService; @@ -106,6 +107,9 @@ public class CaseManagementForCaseWorkerService { public static final String CASE_MANAGEMENT_LABEL = "Employment Tribunals"; public static final String CASE_MANAGEMENT_CODE = "Employment"; private static final String EMPLOYMENT_JURISDICTION = "EMPLOYMENT"; + private static final String RESPONDENT_NOT_CONTINUING_FLAG_COMMENT = + "The claim against the respondent is not continuing"; + private static final String RESPONDENT_STRUCK_OUT_FLAG_COMMENT = "The respondent has been struck out"; public static final String COUNTER_FIELD_INITIAL_VALUE = "1"; private final String ccdGatewayBaseUrl; private final List caseTypeIdsToCheck = List.of("ET_EnglandWales", "ET_Scotland", "Bristol", @@ -130,6 +134,7 @@ public class CaseManagementForCaseWorkerService { public CaseManagementForCaseWorkerService(CaseRetrievalForCaseWorkerService caseRetrievalForCaseWorkerService, CcdClient ccdClient, FeatureToggleService featureToggleService, + CaseFlagsService caseFlagsService, @Value("${hmcts_service_id}") String hmctsServiceId, AdminUserService adminUserService, CaseManagementLocationService caseManagementLocationService, @@ -140,6 +145,7 @@ public CaseManagementForCaseWorkerService(CaseRetrievalForCaseWorkerService case this.caseRetrievalForCaseWorkerService = caseRetrievalForCaseWorkerService; this.ccdClient = ccdClient; this.featureToggleService = featureToggleService; + this.caseFlagsService = caseFlagsService; this.hmctsServiceId = hmctsServiceId; this.adminUserService = adminUserService; this.caseManagementLocationService = caseManagementLocationService; @@ -442,6 +448,11 @@ public CaseData struckOutRespondents(CCDRequest ccdRequest) { if (respondentSumType.getResponseStruckOut() != null) { if (respondentSumType.getResponseStruckOut().equals(YES)) { struckRespondent.add(respondentSumTypeItem); + caseFlagsService.inactivateCaseFlags( + caseData, + respondentSumType.getRespondentName(), + RESPONDENT_STRUCK_OUT_FLAG_COMMENT + ); } else { activeRespondent.add(respondentSumTypeItem); } @@ -459,7 +470,7 @@ public CaseData struckOutRespondents(CCDRequest ccdRequest) { public CaseData continuingRespondent(CCDRequest ccdRequest) { CaseData caseData = ccdRequest.getCaseDetails().getCaseData(); - if (isEmpty(caseData.getRepCollection())) { + if (isNotEmpty(caseData.getRespondentCollection())) { List continuingRespondent = new ArrayList<>(); List notContinuingRespondent = new ArrayList<>(); for (RespondentSumTypeItem respondentSumTypeItem : caseData.getRespondentCollection()) { @@ -468,6 +479,11 @@ public CaseData continuingRespondent(CCDRequest ccdRequest) { continuingRespondent.add(respondentSumTypeItem); } else if (NO.equals(respondentSumType.getResponseContinue())) { notContinuingRespondent.add(respondentSumTypeItem); + caseFlagsService.inactivateCaseFlags( + caseData, + respondentSumType.getRespondentName(), + RESPONDENT_NOT_CONTINUING_FLAG_COMMENT + ); } else { respondentSumType.setResponseContinue(YES); continuingRespondent.add(respondentSumTypeItem); diff --git a/src/test/apiTest/java/uk/gov/hmcts/ethos/replacement/apitest/BaseFunctionalTest.java b/src/test/apiTest/java/uk/gov/hmcts/ethos/replacement/apitest/BaseFunctionalTest.java index a3f2602c44..f9ec09c51a 100644 --- a/src/test/apiTest/java/uk/gov/hmcts/ethos/replacement/apitest/BaseFunctionalTest.java +++ b/src/test/apiTest/java/uk/gov/hmcts/ethos/replacement/apitest/BaseFunctionalTest.java @@ -50,11 +50,12 @@ import static org.apache.http.client.methods.RequestBuilder.get; import static org.apache.http.client.methods.RequestBuilder.post; -@RunWith(SpringRunner.class) -@SpringBootTest(classes = {DocmosisApplication.class, TestCacheConfig.class}) -@Slf4j -@TestInstance(TestInstance.Lifecycle.PER_CLASS) -public abstract class BaseFunctionalTest { +@RunWith(SpringRunner.class) +@SpringBootTest(classes = {DocmosisApplication.class, TestCacheConfig.class}) +@Slf4j +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@SuppressWarnings("PMD.AbstractClassWithoutAbstractMethod") +public abstract class BaseFunctionalTest { public static final String AUTHORIZATION = "Authorization"; protected String userToken; @@ -132,9 +133,11 @@ protected JSONObject createCaseDataStore(String name, String payload, String cas .setHeader("ServiceAuthorization", serviceToken) .setHeader("Content-Type", "application/json"); - CloseableHttpResponse execute = client.execute(requestBuilder.build()); - JSONObject jsonObject = new JSONObject(EntityUtils.toString(execute.getEntity())); - String eventToken = jsonObject.getString("token"); + String eventToken; + try (CloseableHttpResponse execute = client.execute(requestBuilder.build())) { + JSONObject jsonObject = new JSONObject(EntityUtils.toString(execute.getEntity())); + eventToken = jsonObject.getString("token"); + } StringEntity caseEntity = new StringEntity(payload.replace("%EVENT_TOKEN%", eventToken)); @@ -145,10 +148,11 @@ protected JSONObject createCaseDataStore(String name, String payload, String cas .setHeader("Content-Type", "application/json") .setEntity(caseEntity); - CloseableHttpResponse postResponse = client.execute(submitRequest.build()); - String result = EntityUtils.toString(postResponse.getEntity()); - return new JSONObject(result); - } + try (CloseableHttpResponse postResponse = client.execute(submitRequest.build())) { + String result = EntityUtils.toString(postResponse.getEntity()); + return new JSONObject(result); + } + } public String readJsonResource(String name) throws IOException { Resource resource = resourceLoader.getResource(String.format("classpath:/%s.json", name)); diff --git a/src/test/apiTest/java/uk/gov/hmcts/ethos/replacement/apitest/ClaimantRepresentativeControllerFunctionalTest.java b/src/test/apiTest/java/uk/gov/hmcts/ethos/replacement/apitest/ClaimantRepresentativeControllerFunctionalTest.java new file mode 100644 index 0000000000..6814121e6e --- /dev/null +++ b/src/test/apiTest/java/uk/gov/hmcts/ethos/replacement/apitest/ClaimantRepresentativeControllerFunctionalTest.java @@ -0,0 +1,97 @@ +package uk.gov.hmcts.ethos.replacement.apitest; + +import io.restassured.RestAssured; +import io.restassured.http.ContentType; +import io.restassured.http.Header; +import lombok.extern.slf4j.Slf4j; +import org.apache.http.HttpStatus; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import uk.gov.hmcts.et.common.model.ccd.CCDRequest; +import uk.gov.hmcts.et.common.model.ccd.CaseData; +import uk.gov.hmcts.et.common.model.ccd.types.AllPartyFlags; +import uk.gov.hmcts.et.common.model.ccd.types.CaseFlagsType; +import uk.gov.hmcts.et.common.model.ccd.types.RepresentedTypeC; +import uk.gov.hmcts.ethos.utils.CCDRequestBuilder; +import uk.gov.hmcts.ethos.utils.CaseDataBuilder; + +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.nullValue; +import static uk.gov.hmcts.ecm.common.model.helper.Constants.NO; +import static uk.gov.hmcts.ecm.common.model.helper.Constants.YES; +import static uk.gov.hmcts.ethos.replacement.docmosis.domain.ClaimantSolicitorRole.CLAIMANTSOLICITOR; + +@Slf4j +public class ClaimantRepresentativeControllerFunctionalTest extends BaseFunctionalTest { + + private static final String REMOVE_OWN_REPRESENTATIVE_URL = "/claimantRepresentative/removeOwnRepresentative"; + private static final String CLAIMANT_NAME = "Claimant Name"; + private static final String REPRESENTATIVE_NAME = "Claimant Representative"; + + private CCDRequest claimantNotRepresentedRequest; + private CCDRequest claimantRepresentedRequest; + + @BeforeAll + public void setUpCaseData() { + claimantNotRepresentedRequest = CCDRequestBuilder.builder() + .withCaseData(caseDataWithClaimantRepresentativeFlags(NO)) + .withCaseId("1694206942069420") + .build(); + claimantRepresentedRequest = CCDRequestBuilder.builder() + .withCaseData(caseDataWithClaimantRepresentativeFlags(YES)) + .withCaseId("1694206942069421") + .build(); + } + + @Test + void removeOwnRepresentativeClearsClaimantRepresentativeFlags() { + RestAssured.given() + .spec(spec) + .contentType(ContentType.JSON) + .header(new Header(AUTHORIZATION, userToken)) + .body(claimantNotRepresentedRequest) + .post(REMOVE_OWN_REPRESENTATIVE_URL) + .then() + .statusCode(HttpStatus.SC_OK) + .body("data.representativeClaimantType", nullValue()) + .body("data.claimantRepresentativeOrganisationPolicy.OrgPolicyCaseAssignedRole", + equalTo(CLAIMANTSOLICITOR.getCaseRoleLabel())) + .body("data.claimantFlags.partyName", equalTo(CLAIMANT_NAME)) + .body("data.claimantRepresentativeFlags", nullValue()) + .body("data.claimantRepresentativeExternalFlags", nullValue()) + .log() + .all(true); + } + + @Test + void removeOwnRepresentativeKeepsClaimantRepresentativeFlagsWhenStillRepresented() { + RestAssured.given() + .spec(spec) + .contentType(ContentType.JSON) + .header(new Header(AUTHORIZATION, userToken)) + .body(claimantRepresentedRequest) + .post(REMOVE_OWN_REPRESENTATIVE_URL) + .then() + .statusCode(HttpStatus.SC_OK) + .body("data.representativeClaimantType.name_of_representative", equalTo(REPRESENTATIVE_NAME)) + .body("data.claimantRepresentativeFlags.partyName", equalTo(REPRESENTATIVE_NAME)) + .body("data.claimantRepresentativeExternalFlags.partyName", equalTo(REPRESENTATIVE_NAME)) + .log() + .all(true); + } + + private static CaseData caseDataWithClaimantRepresentativeFlags(String claimantRepresentedQuestion) { + CaseData caseData = CaseDataBuilder.builder() + .withClaimantRepresentedQuestion(claimantRepresentedQuestion) + .build(); + caseData.setRepresentativeClaimantType(RepresentedTypeC.builder() + .nameOfRepresentative(REPRESENTATIVE_NAME) + .build()); + caseData.setAllPartyFlags(AllPartyFlags.builder() + .claimantFlags(CaseFlagsType.builder().partyName(CLAIMANT_NAME).build()) + .claimantRepresentativeFlags(CaseFlagsType.builder().partyName(REPRESENTATIVE_NAME).build()) + .claimantRepresentativeExternalFlags(CaseFlagsType.builder().partyName(REPRESENTATIVE_NAME).build()) + .build()); + return caseData; + } +} diff --git a/src/test/apiTest/java/uk/gov/hmcts/ethos/replacement/apitest/IdamTestApiRequests.java b/src/test/apiTest/java/uk/gov/hmcts/ethos/replacement/apitest/IdamTestApiRequests.java index 8efcee91a9..4153e77c27 100644 --- a/src/test/apiTest/java/uk/gov/hmcts/ethos/replacement/apitest/IdamTestApiRequests.java +++ b/src/test/apiTest/java/uk/gov/hmcts/ethos/replacement/apitest/IdamTestApiRequests.java @@ -93,7 +93,7 @@ public String getLocalAccessToken() throws IOException { List cookies = idamAuth(); String auth = cookies.stream().filter(o -> o.startsWith("__auth__")).findFirst().get(); - return "Bearer " + auth.substring(9, auth.indexOf(";")); + return "Bearer " + auth.substring(9, auth.indexOf(';')); } /** @@ -105,7 +105,7 @@ public List idamAuth() throws IOException { List cookies = Arrays.stream(response.getHeaders("Set-Cookie")).map(o -> o.getValue().substring(0, - o.getValue().indexOf(";"))).collect(Collectors.toList()); + o.getValue().indexOf(';'))).collect(Collectors.toList()); cookies.add("seen_cookie_message=yes"); cookies.add("cookies_policy={ \"essential\": true, \"analytics\": false, \"apm\": false }"); diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/ClaimantRepresentativeControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/ClaimantRepresentativeControllerTest.java index 53c8a7c725..3030736477 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/ClaimantRepresentativeControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/ClaimantRepresentativeControllerTest.java @@ -1,5 +1,6 @@ package uk.gov.hmcts.ethos.replacement.docmosis.controllers; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; @@ -9,6 +10,10 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.web.servlet.MockMvc; import uk.gov.hmcts.et.common.model.ccd.CCDRequest; +import uk.gov.hmcts.et.common.model.ccd.CaseData; +import uk.gov.hmcts.et.common.model.ccd.types.AllPartyFlags; +import uk.gov.hmcts.et.common.model.ccd.types.CaseFlagsType; +import uk.gov.hmcts.et.common.model.ccd.types.RepresentedTypeC; import uk.gov.hmcts.ethos.replacement.docmosis.service.VerifyTokenService; import uk.gov.hmcts.ethos.replacement.docmosis.utils.JsonMapper; import uk.gov.hmcts.ethos.utils.CCDRequestBuilder; @@ -22,11 +27,18 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static uk.gov.hmcts.ecm.common.model.helper.Constants.NO; import static uk.gov.hmcts.ecm.common.model.helper.Constants.YES; +import static uk.gov.hmcts.ethos.replacement.docmosis.domain.ClaimantSolicitorRole.CLAIMANTSOLICITOR; @ExtendWith(SpringExtension.class) @WebMvcTest({ClaimantRepresentativeController.class, JsonMapper.class}) class ClaimantRepresentativeControllerTest { + private static final String DUMMY_TOKEN = "some-token"; + private static final String HEADER_AUTHORIZATION = "Authorization"; + private static final String REMOVE_OWN_REPRESENTATIVE_URL = "/claimantRepresentative/removeOwnRepresentative"; + private static final String CLAIMANT_NAME = "Claimant Name"; + private static final String REPRESENTATIVE_NAME = "Claimant Representative"; + @MockitoBean private VerifyTokenService verifyTokenService; @Autowired @@ -35,16 +47,19 @@ class ClaimantRepresentativeControllerTest { @Autowired private JsonMapper jsonMapper; + @BeforeEach + void setUp() { + when(verifyTokenService.verifyTokenSignature(DUMMY_TOKEN)).thenReturn(true); + } + @Test void testRemoveOwnRepresentative_ClaimantRepresentedQuestionEmpty() throws Exception { CCDRequest ccdRequest = CCDRequestBuilder.builder().withCaseData( CaseDataBuilder.builder().withClaimantRepresentedQuestion(null).build()).build(); - String token = "some-token"; - when(verifyTokenService.verifyTokenSignature(token)).thenReturn(true); - mockMvc.perform(post("/claimantRepresentative/removeOwnRepresentative") + mockMvc.perform(post(REMOVE_OWN_REPRESENTATIVE_URL) .contentType(MediaType.APPLICATION_JSON) - .header("Authorization", token) + .header(HEADER_AUTHORIZATION, DUMMY_TOKEN) .content(jsonMapper.toJson(ccdRequest))) .andExpect(status().isOk()) .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) @@ -55,17 +70,21 @@ void testRemoveOwnRepresentative_ClaimantRepresentedQuestionEmpty() throws Excep @Test void testRemoveOwnRepresentative_ClaimantRepresentedQuestionNo() throws Exception { CCDRequest ccdRequest = CCDRequestBuilder.builder().withCaseData( - CaseDataBuilder.builder().withClaimantRepresentedQuestion(NO).build()).build(); - String token = "some-token"; - when(verifyTokenService.verifyTokenSignature(token)).thenReturn(true); + caseDataWithClaimantRepresentativeFlags(NO)).build(); - mockMvc.perform(post("/claimantRepresentative/removeOwnRepresentative") + mockMvc.perform(post(REMOVE_OWN_REPRESENTATIVE_URL) .contentType(MediaType.APPLICATION_JSON) - .header("Authorization", token) + .header(HEADER_AUTHORIZATION, DUMMY_TOKEN) .content(jsonMapper.toJson(ccdRequest))) .andExpect(status().isOk()) .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) + .andExpect(jsonPath("$.data.representativeClaimantType").doesNotExist()) + .andExpect(jsonPath("$.data.claimantRepresentativeOrganisationPolicy.OrgPolicyCaseAssignedRole") + .value(CLAIMANTSOLICITOR.getCaseRoleLabel())) + .andExpect(jsonPath("$.data.claimantFlags.partyName").value(CLAIMANT_NAME)) + .andExpect(jsonPath("$.data.claimantRepresentativeFlags").doesNotExist()) + .andExpect(jsonPath("$.data.claimantRepresentativeExternalFlags").doesNotExist()) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); } @@ -73,18 +92,36 @@ void testRemoveOwnRepresentative_ClaimantRepresentedQuestionNo() throws Exceptio @Test void testRemoveOwnRepresentative_ClaimantRepresentedQuestionYes() throws Exception { CCDRequest ccdRequest = CCDRequestBuilder.builder().withCaseData( - CaseDataBuilder.builder().withClaimantRepresentedQuestion(YES).build()).build(); - String token = "some-token"; - when(verifyTokenService.verifyTokenSignature(token)).thenReturn(true); + caseDataWithClaimantRepresentativeFlags(YES)).build(); - mockMvc.perform(post("/claimantRepresentative/removeOwnRepresentative") + mockMvc.perform(post(REMOVE_OWN_REPRESENTATIVE_URL) .contentType(MediaType.APPLICATION_JSON) - .header("Authorization", token) + .header(HEADER_AUTHORIZATION, DUMMY_TOKEN) .content(jsonMapper.toJson(ccdRequest))) .andExpect(status().isOk()) .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) + .andExpect(jsonPath("$.data.representativeClaimantType.name_of_representative") + .value(REPRESENTATIVE_NAME)) + .andExpect(jsonPath("$.data.claimantRepresentativeFlags.partyName").value(REPRESENTATIVE_NAME)) + .andExpect(jsonPath("$.data.claimantRepresentativeExternalFlags.partyName") + .value(REPRESENTATIVE_NAME)) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); } + + private static CaseData caseDataWithClaimantRepresentativeFlags(String claimantRepresentedQuestion) { + CaseData caseData = CaseDataBuilder.builder() + .withClaimantRepresentedQuestion(claimantRepresentedQuestion) + .build(); + caseData.setRepresentativeClaimantType(RepresentedTypeC.builder() + .nameOfRepresentative(REPRESENTATIVE_NAME) + .build()); + caseData.setAllPartyFlags(AllPartyFlags.builder() + .claimantFlags(CaseFlagsType.builder().partyName(CLAIMANT_NAME).build()) + .claimantRepresentativeFlags(CaseFlagsType.builder().partyName(REPRESENTATIVE_NAME).build()) + .claimantRepresentativeExternalFlags(CaseFlagsType.builder().partyName(REPRESENTATIVE_NAME).build()) + .build()); + return caseData; + } } diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java index 1343481254..7f6fd91d67 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java @@ -80,6 +80,9 @@ class CaseFlagsServiceTest { public static final String CLAIMANT_REPRESENTATIVE_NAME = "Claimant Representative Name"; public static final String REPRESENTATIVE_NAME = "Representative Name"; public static final String RESPONDENT_NAME = "Respondent Name"; + private static final String RESPONDENT_NOT_CONTINUING_FLAG_COMMENT = + "The claim against the respondent is not continuing"; + private static final String RESPONDENT_STRUCK_OUT_FLAG_COMMENT = "The respondent has been struck out"; private CaseFlagsService caseFlagsService; private CaseData caseData; @@ -276,6 +279,71 @@ void rollbackCaseFlags_shouldNotCreateAllPartyFlagsWhenAbsent() { assertNull(caseData.getAllPartyFlags()); } + @Test + void inactivateCaseFlags_shouldSetAllMatchingRespondentFlagDetailsInactive() { + caseFlagsService.setupCaseFlags(caseData); + CaseFlagsType respondentInternalFlags = allPartyFlags(caseData).getRespondent1Flags(); + respondentInternalFlags.setDetails(ListTypeItem.from( + activeFlag("Internal flag 1"), + activeFlag("Internal flag 2") + )); + + CaseFlagsType respondentExternalFlags = allPartyFlags(caseData).getRespondent1ExternalFlags(); + CaseFlagsType otherRespondentFlags = allPartyFlags(caseData).getRespondent2Flags(); + CaseFlagsType claimantFlags = allPartyFlags(caseData).getClaimantFlags(); + respondentExternalFlags.setDetails(ListTypeItem.from(activeFlag("External flag"))); + otherRespondentFlags.setDetails(ListTypeItem.from(activeFlag("Other respondent flag"))); + claimantFlags.setDetails(ListTypeItem.from(activeFlag("Claimant flag"))); + + caseFlagsService.inactivateCaseFlags(caseData, respondentName(1), RESPONDENT_NOT_CONTINUING_FLAG_COMMENT); + + assertEquals(INACTIVE, respondentInternalFlags.getDetails().get(0).getValue().getStatus()); + assertEquals(INACTIVE, respondentInternalFlags.getDetails().get(1).getValue().getStatus()); + assertEquals(INACTIVE, respondentExternalFlags.getDetails().getFirst().getValue().getStatus()); + assertEquals(RESPONDENT_NOT_CONTINUING_FLAG_COMMENT, + respondentInternalFlags.getDetails().get(0).getValue().getFlagComment()); + assertEquals(RESPONDENT_NOT_CONTINUING_FLAG_COMMENT, + respondentInternalFlags.getDetails().get(1).getValue().getFlagComment()); + assertEquals(RESPONDENT_NOT_CONTINUING_FLAG_COMMENT, + respondentExternalFlags.getDetails().getFirst().getValue().getFlagComment()); + assertEquals(ACTIVE, otherRespondentFlags.getDetails().getFirst().getValue().getStatus()); + assertEquals(ACTIVE, claimantFlags.getDetails().getFirst().getValue().getStatus()); + assertNull(otherRespondentFlags.getDetails().getFirst().getValue().getFlagComment()); + assertNull(claimantFlags.getDetails().getFirst().getValue().getFlagComment()); + } + + @Test + void inactivateCaseFlags_shouldUseProvidedCommentWhenInactivatingRespondentFlags() { + caseFlagsService.setupCaseFlags(caseData); + CaseFlagsType respondentInternalFlags = allPartyFlags(caseData).getRespondentFlags(); + CaseFlagsType respondentExternalFlags = allPartyFlags(caseData).getRespondentExternalFlags(); + respondentInternalFlags.setDetails(ListTypeItem.from(activeFlag("Internal flag"))); + respondentExternalFlags.setDetails(ListTypeItem.from(activeFlag("External flag"))); + + caseFlagsService.inactivateCaseFlags(caseData, RESPONDENT_NAME, RESPONDENT_STRUCK_OUT_FLAG_COMMENT); + + assertEquals(INACTIVE, respondentInternalFlags.getDetails().getFirst().getValue().getStatus()); + assertEquals(INACTIVE, respondentExternalFlags.getDetails().getFirst().getValue().getStatus()); + assertEquals(RESPONDENT_STRUCK_OUT_FLAG_COMMENT, + respondentInternalFlags.getDetails().getFirst().getValue().getFlagComment()); + assertEquals(RESPONDENT_STRUCK_OUT_FLAG_COMMENT, + respondentExternalFlags.getDetails().getFirst().getValue().getFlagComment()); + } + + @Test + void inactivateCaseFlags_shouldIgnoreMissingPartyFlagsAndDetails() { + caseFlagsService.inactivateCaseFlags(caseData, RESPONDENT_NAME, RESPONDENT_NOT_CONTINUING_FLAG_COMMENT); + + assertNull(caseData.getAllPartyFlags()); + + caseFlagsService.setupCaseFlags(caseData); + allPartyFlags(caseData).getRespondentFlags().setDetails(null); + + caseFlagsService.inactivateCaseFlags(caseData, RESPONDENT_NAME, RESPONDENT_NOT_CONTINUING_FLAG_COMMENT); + + assertNull(allPartyFlags(caseData).getRespondentFlags().getDetails()); + } + @Test void setupCaseFlags_shouldUpdateClaimantFlagsWhenNameChanges() { caseFlagsService.setupCaseFlags(caseData); diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseManagementForCaseWorkerServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseManagementForCaseWorkerServiceTest.java index 3428fe84fd..cc2331adb1 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseManagementForCaseWorkerServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseManagementForCaseWorkerServiceTest.java @@ -104,6 +104,9 @@ class CaseManagementForCaseWorkerServiceTest { private static final String AUTH_TOKEN = "Bearer eyJhbGJbpjciOiJIUzI1NiJ9"; public static final String UNASSIGNED_OFFICE = "Unassigned"; private static final String HMCTS_SERVICE_ID = "BHA1"; + private static final String RESPONDENT_NOT_CONTINUING_FLAG_COMMENT = + "The claim against the respondent is not continuing"; + private static final String RESPONDENT_STRUCK_OUT_FLAG_COMMENT = "The respondent has been struck out"; @Value("${ccd_gateway_base_url}") private String ccdGatewayBaseUrl; @@ -134,6 +137,8 @@ class CaseManagementForCaseWorkerServiceTest { @MockitoBean private FeatureToggleService featureToggleService; @MockitoBean + private CaseFlagsService caseFlagsService; + @MockitoBean private AdminUserService adminUserService; @MockitoBean private CaseManagementLocationService caseManagementLocationService; @@ -158,7 +163,7 @@ void setUp() throws URISyntaxException, IOException { when(featureToggleService.isWorkAllocationEnabled()).thenReturn(true); when(adminUserService.getAdminUserToken()).thenReturn(AUTH_TOKEN); caseManagementForCaseWorkerService = new CaseManagementForCaseWorkerService( - caseRetrievalForCaseWorkerService, ccdClient, featureToggleService, HMCTS_SERVICE_ID, + caseRetrievalForCaseWorkerService, ccdClient, featureToggleService, caseFlagsService, HMCTS_SERVICE_ID, adminUserService, caseManagementLocationService, multipleReferenceService, ccdGatewayBaseUrl, multipleCasesSendingService, answersConverter); } @@ -492,6 +497,7 @@ void struckOutRespondentFirstToLast() { assertThat(caseData.getRespondentCollection().get(1).getValue().getResponseStruckOut()).isEqualTo(NO); assertThat(caseData.getRespondentCollection().get(2).getValue().getRespondentName()).isEqualTo("Juan Garcia"); assertThat(caseData.getRespondentCollection().get(2).getValue().getResponseStruckOut()).isEqualTo(YES); + verify(caseFlagsService).inactivateCaseFlags(caseData, "Juan Garcia", RESPONDENT_STRUCK_OUT_FLAG_COMMENT); } @Test @@ -550,6 +556,11 @@ void continuingRespondentFirstToLast() { assertThat(caseData.getRespondentCollection().get(2).getValue().getRespondentName()) .isEqualTo("Roberto Dondini"); assertThat(caseData.getRespondentCollection().get(2).getValue().getResponseContinue()).isEqualTo(NO); + verify(caseFlagsService).inactivateCaseFlags( + caseData, + "Roberto Dondini", + RESPONDENT_NOT_CONTINUING_FLAG_COMMENT + ); } @Test @@ -559,6 +570,34 @@ void continuingRespondentNull() { assertThat(caseData.getRespondentCollection().getFirst().getValue().getResponseContinue()).isEqualTo(YES); } + @Test + void continuingRespondentDefaultsResponseContinueWhenRepCollectionExists() { + CaseData caseData = scotlandCcdRequest3.getCaseDetails().getCaseData(); + caseData.setRepCollection(createRepCollection()); + caseData.getRespondentCollection().getFirst().getValue().setResponseContinue(null); + + caseManagementForCaseWorkerService.continuingRespondent(scotlandCcdRequest3); + + assertThat(caseData.getRespondentCollection().getFirst().getValue().getResponseContinue()).isEqualTo(YES); + verify(caseFlagsService, never()).inactivateCaseFlags(any(), anyString(), anyString()); + } + + @Test + void continuingRespondentInactivatesCaseFlagsWhenRepCollectionExistsAndResponseDoesNotContinue() { + CaseData caseData = scotlandCcdRequest3.getCaseDetails().getCaseData(); + caseData.setRepCollection(createRepCollection()); + caseData.getRespondentCollection().getFirst().getValue().setResponseContinue(NO); + + caseManagementForCaseWorkerService.continuingRespondent(scotlandCcdRequest3); + + assertThat(caseData.getRespondentCollection().getFirst().getValue().getResponseContinue()).isEqualTo(NO); + verify(caseFlagsService).inactivateCaseFlags( + caseData, + "Antonio Vazquez", + RESPONDENT_NOT_CONTINUING_FLAG_COMMENT + ); + } + @Test void continuingRespondentEmpty() { CaseData caseData = caseManagementForCaseWorkerService.continuingRespondent(scotlandCcdRequest5); From 7be97973979e82ea3bd8340448e984cf9eab4355 Mon Sep 17 00:00:00 2001 From: rajaram Date: Tue, 28 Jul 2026 16:24:31 +0100 Subject: [PATCH 023/100] RET-6729 changes --- .../ClaimantRepresentativeController.java | 5 - .../noc/ClaimantRepresentativeUtils.java | 9 ++ ...epresentativeControllerFunctionalTest.java | 97 ------------------- .../ClaimantRepresentativeControllerTest.java | 65 +++---------- .../noc/ClaimantRepresentativeUtilsTest.java | 26 +++++ 5 files changed, 49 insertions(+), 153 deletions(-) delete mode 100644 src/test/apiTest/java/uk/gov/hmcts/ethos/replacement/apitest/ClaimantRepresentativeControllerFunctionalTest.java diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/ClaimantRepresentativeController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/ClaimantRepresentativeController.java index 4d2c0d051d..232d629f66 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/ClaimantRepresentativeController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/ClaimantRepresentativeController.java @@ -103,18 +103,13 @@ public ResponseEntity removeOwnRepresentative( LOG_MESSAGE, ccdRequest.getCaseDetails().getCaseId()); CaseDetails caseDetails = ccdRequest.getCaseDetails(); CaseData caseData = caseDetails.getCaseData(); - if (StringUtils.isNotBlank(caseData.getClaimantRepresentedQuestion()) && NO.equals(caseData.getClaimantRepresentedQuestion())) { caseData.setRepresentativeClaimantType(null); caseData.setClaimantRepresentativeOrganisationPolicy( OrganisationPolicy.builder().orgPolicyCaseAssignedRole(CLAIMANTSOLICITOR.getCaseRoleLabel()).build() ); - - caseData.getAllPartyFlags().setClaimantRepresentativeFlags(null); - caseData.getAllPartyFlags().setClaimantRepresentativeExternalFlags(null); } - return getCallbackRespEntityNoErrors(ccdRequest.getCaseDetails().getCaseData()); } diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/utils/noc/ClaimantRepresentativeUtils.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/utils/noc/ClaimantRepresentativeUtils.java index 5e0a977551..8409751b29 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/utils/noc/ClaimantRepresentativeUtils.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/utils/noc/ClaimantRepresentativeUtils.java @@ -268,6 +268,7 @@ public static void addAmendClaimantRepresentative(CaseData caseData) { } caseData.setRepresentativeClaimantType(null); caseData.setClaimantRepresentedQuestion(NO); + clearClaimantRepresentativeFlags(caseData); caseData.setClaimantRepresentativeOrganisationPolicy(OrganisationPolicy.builder().organisation(null) .orgPolicyCaseAssignedRole(ClaimantSolicitorRole.CLAIMANTSOLICITOR.getCaseRoleLabel()).build()); @@ -278,6 +279,14 @@ public static void addAmendClaimantRepresentative(CaseData caseData) { setClaimantRepresentativeOrganisationPolicy(caseData); } + private static void clearClaimantRepresentativeFlags(CaseData caseData) { + if (caseData.getAllPartyFlags() == null) { + return; + } + caseData.getAllPartyFlags().setClaimantRepresentativeFlags(null); + caseData.getAllPartyFlags().setClaimantRepresentativeExternalFlags(null); + } + private static void setRepresentativeId(RepresentedTypeC claimantRepresentative) { if (claimantRepresentative == null) { return; diff --git a/src/test/apiTest/java/uk/gov/hmcts/ethos/replacement/apitest/ClaimantRepresentativeControllerFunctionalTest.java b/src/test/apiTest/java/uk/gov/hmcts/ethos/replacement/apitest/ClaimantRepresentativeControllerFunctionalTest.java deleted file mode 100644 index 6814121e6e..0000000000 --- a/src/test/apiTest/java/uk/gov/hmcts/ethos/replacement/apitest/ClaimantRepresentativeControllerFunctionalTest.java +++ /dev/null @@ -1,97 +0,0 @@ -package uk.gov.hmcts.ethos.replacement.apitest; - -import io.restassured.RestAssured; -import io.restassured.http.ContentType; -import io.restassured.http.Header; -import lombok.extern.slf4j.Slf4j; -import org.apache.http.HttpStatus; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import uk.gov.hmcts.et.common.model.ccd.CCDRequest; -import uk.gov.hmcts.et.common.model.ccd.CaseData; -import uk.gov.hmcts.et.common.model.ccd.types.AllPartyFlags; -import uk.gov.hmcts.et.common.model.ccd.types.CaseFlagsType; -import uk.gov.hmcts.et.common.model.ccd.types.RepresentedTypeC; -import uk.gov.hmcts.ethos.utils.CCDRequestBuilder; -import uk.gov.hmcts.ethos.utils.CaseDataBuilder; - -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.nullValue; -import static uk.gov.hmcts.ecm.common.model.helper.Constants.NO; -import static uk.gov.hmcts.ecm.common.model.helper.Constants.YES; -import static uk.gov.hmcts.ethos.replacement.docmosis.domain.ClaimantSolicitorRole.CLAIMANTSOLICITOR; - -@Slf4j -public class ClaimantRepresentativeControllerFunctionalTest extends BaseFunctionalTest { - - private static final String REMOVE_OWN_REPRESENTATIVE_URL = "/claimantRepresentative/removeOwnRepresentative"; - private static final String CLAIMANT_NAME = "Claimant Name"; - private static final String REPRESENTATIVE_NAME = "Claimant Representative"; - - private CCDRequest claimantNotRepresentedRequest; - private CCDRequest claimantRepresentedRequest; - - @BeforeAll - public void setUpCaseData() { - claimantNotRepresentedRequest = CCDRequestBuilder.builder() - .withCaseData(caseDataWithClaimantRepresentativeFlags(NO)) - .withCaseId("1694206942069420") - .build(); - claimantRepresentedRequest = CCDRequestBuilder.builder() - .withCaseData(caseDataWithClaimantRepresentativeFlags(YES)) - .withCaseId("1694206942069421") - .build(); - } - - @Test - void removeOwnRepresentativeClearsClaimantRepresentativeFlags() { - RestAssured.given() - .spec(spec) - .contentType(ContentType.JSON) - .header(new Header(AUTHORIZATION, userToken)) - .body(claimantNotRepresentedRequest) - .post(REMOVE_OWN_REPRESENTATIVE_URL) - .then() - .statusCode(HttpStatus.SC_OK) - .body("data.representativeClaimantType", nullValue()) - .body("data.claimantRepresentativeOrganisationPolicy.OrgPolicyCaseAssignedRole", - equalTo(CLAIMANTSOLICITOR.getCaseRoleLabel())) - .body("data.claimantFlags.partyName", equalTo(CLAIMANT_NAME)) - .body("data.claimantRepresentativeFlags", nullValue()) - .body("data.claimantRepresentativeExternalFlags", nullValue()) - .log() - .all(true); - } - - @Test - void removeOwnRepresentativeKeepsClaimantRepresentativeFlagsWhenStillRepresented() { - RestAssured.given() - .spec(spec) - .contentType(ContentType.JSON) - .header(new Header(AUTHORIZATION, userToken)) - .body(claimantRepresentedRequest) - .post(REMOVE_OWN_REPRESENTATIVE_URL) - .then() - .statusCode(HttpStatus.SC_OK) - .body("data.representativeClaimantType.name_of_representative", equalTo(REPRESENTATIVE_NAME)) - .body("data.claimantRepresentativeFlags.partyName", equalTo(REPRESENTATIVE_NAME)) - .body("data.claimantRepresentativeExternalFlags.partyName", equalTo(REPRESENTATIVE_NAME)) - .log() - .all(true); - } - - private static CaseData caseDataWithClaimantRepresentativeFlags(String claimantRepresentedQuestion) { - CaseData caseData = CaseDataBuilder.builder() - .withClaimantRepresentedQuestion(claimantRepresentedQuestion) - .build(); - caseData.setRepresentativeClaimantType(RepresentedTypeC.builder() - .nameOfRepresentative(REPRESENTATIVE_NAME) - .build()); - caseData.setAllPartyFlags(AllPartyFlags.builder() - .claimantFlags(CaseFlagsType.builder().partyName(CLAIMANT_NAME).build()) - .claimantRepresentativeFlags(CaseFlagsType.builder().partyName(REPRESENTATIVE_NAME).build()) - .claimantRepresentativeExternalFlags(CaseFlagsType.builder().partyName(REPRESENTATIVE_NAME).build()) - .build()); - return caseData; - } -} diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/ClaimantRepresentativeControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/ClaimantRepresentativeControllerTest.java index 3030736477..53c8a7c725 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/ClaimantRepresentativeControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/ClaimantRepresentativeControllerTest.java @@ -1,6 +1,5 @@ package uk.gov.hmcts.ethos.replacement.docmosis.controllers; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; @@ -10,10 +9,6 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.web.servlet.MockMvc; import uk.gov.hmcts.et.common.model.ccd.CCDRequest; -import uk.gov.hmcts.et.common.model.ccd.CaseData; -import uk.gov.hmcts.et.common.model.ccd.types.AllPartyFlags; -import uk.gov.hmcts.et.common.model.ccd.types.CaseFlagsType; -import uk.gov.hmcts.et.common.model.ccd.types.RepresentedTypeC; import uk.gov.hmcts.ethos.replacement.docmosis.service.VerifyTokenService; import uk.gov.hmcts.ethos.replacement.docmosis.utils.JsonMapper; import uk.gov.hmcts.ethos.utils.CCDRequestBuilder; @@ -27,18 +22,11 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static uk.gov.hmcts.ecm.common.model.helper.Constants.NO; import static uk.gov.hmcts.ecm.common.model.helper.Constants.YES; -import static uk.gov.hmcts.ethos.replacement.docmosis.domain.ClaimantSolicitorRole.CLAIMANTSOLICITOR; @ExtendWith(SpringExtension.class) @WebMvcTest({ClaimantRepresentativeController.class, JsonMapper.class}) class ClaimantRepresentativeControllerTest { - private static final String DUMMY_TOKEN = "some-token"; - private static final String HEADER_AUTHORIZATION = "Authorization"; - private static final String REMOVE_OWN_REPRESENTATIVE_URL = "/claimantRepresentative/removeOwnRepresentative"; - private static final String CLAIMANT_NAME = "Claimant Name"; - private static final String REPRESENTATIVE_NAME = "Claimant Representative"; - @MockitoBean private VerifyTokenService verifyTokenService; @Autowired @@ -47,19 +35,16 @@ class ClaimantRepresentativeControllerTest { @Autowired private JsonMapper jsonMapper; - @BeforeEach - void setUp() { - when(verifyTokenService.verifyTokenSignature(DUMMY_TOKEN)).thenReturn(true); - } - @Test void testRemoveOwnRepresentative_ClaimantRepresentedQuestionEmpty() throws Exception { CCDRequest ccdRequest = CCDRequestBuilder.builder().withCaseData( CaseDataBuilder.builder().withClaimantRepresentedQuestion(null).build()).build(); + String token = "some-token"; + when(verifyTokenService.verifyTokenSignature(token)).thenReturn(true); - mockMvc.perform(post(REMOVE_OWN_REPRESENTATIVE_URL) + mockMvc.perform(post("/claimantRepresentative/removeOwnRepresentative") .contentType(MediaType.APPLICATION_JSON) - .header(HEADER_AUTHORIZATION, DUMMY_TOKEN) + .header("Authorization", token) .content(jsonMapper.toJson(ccdRequest))) .andExpect(status().isOk()) .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) @@ -70,21 +55,17 @@ void testRemoveOwnRepresentative_ClaimantRepresentedQuestionEmpty() throws Excep @Test void testRemoveOwnRepresentative_ClaimantRepresentedQuestionNo() throws Exception { CCDRequest ccdRequest = CCDRequestBuilder.builder().withCaseData( - caseDataWithClaimantRepresentativeFlags(NO)).build(); + CaseDataBuilder.builder().withClaimantRepresentedQuestion(NO).build()).build(); + String token = "some-token"; + when(verifyTokenService.verifyTokenSignature(token)).thenReturn(true); - mockMvc.perform(post(REMOVE_OWN_REPRESENTATIVE_URL) + mockMvc.perform(post("/claimantRepresentative/removeOwnRepresentative") .contentType(MediaType.APPLICATION_JSON) - .header(HEADER_AUTHORIZATION, DUMMY_TOKEN) + .header("Authorization", token) .content(jsonMapper.toJson(ccdRequest))) .andExpect(status().isOk()) .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) - .andExpect(jsonPath("$.data.representativeClaimantType").doesNotExist()) - .andExpect(jsonPath("$.data.claimantRepresentativeOrganisationPolicy.OrgPolicyCaseAssignedRole") - .value(CLAIMANTSOLICITOR.getCaseRoleLabel())) - .andExpect(jsonPath("$.data.claimantFlags.partyName").value(CLAIMANT_NAME)) - .andExpect(jsonPath("$.data.claimantRepresentativeFlags").doesNotExist()) - .andExpect(jsonPath("$.data.claimantRepresentativeExternalFlags").doesNotExist()) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); } @@ -92,36 +73,18 @@ void testRemoveOwnRepresentative_ClaimantRepresentedQuestionNo() throws Exceptio @Test void testRemoveOwnRepresentative_ClaimantRepresentedQuestionYes() throws Exception { CCDRequest ccdRequest = CCDRequestBuilder.builder().withCaseData( - caseDataWithClaimantRepresentativeFlags(YES)).build(); + CaseDataBuilder.builder().withClaimantRepresentedQuestion(YES).build()).build(); + String token = "some-token"; + when(verifyTokenService.verifyTokenSignature(token)).thenReturn(true); - mockMvc.perform(post(REMOVE_OWN_REPRESENTATIVE_URL) + mockMvc.perform(post("/claimantRepresentative/removeOwnRepresentative") .contentType(MediaType.APPLICATION_JSON) - .header(HEADER_AUTHORIZATION, DUMMY_TOKEN) + .header("Authorization", token) .content(jsonMapper.toJson(ccdRequest))) .andExpect(status().isOk()) .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) - .andExpect(jsonPath("$.data.representativeClaimantType.name_of_representative") - .value(REPRESENTATIVE_NAME)) - .andExpect(jsonPath("$.data.claimantRepresentativeFlags.partyName").value(REPRESENTATIVE_NAME)) - .andExpect(jsonPath("$.data.claimantRepresentativeExternalFlags.partyName") - .value(REPRESENTATIVE_NAME)) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); } - - private static CaseData caseDataWithClaimantRepresentativeFlags(String claimantRepresentedQuestion) { - CaseData caseData = CaseDataBuilder.builder() - .withClaimantRepresentedQuestion(claimantRepresentedQuestion) - .build(); - caseData.setRepresentativeClaimantType(RepresentedTypeC.builder() - .nameOfRepresentative(REPRESENTATIVE_NAME) - .build()); - caseData.setAllPartyFlags(AllPartyFlags.builder() - .claimantFlags(CaseFlagsType.builder().partyName(CLAIMANT_NAME).build()) - .claimantRepresentativeFlags(CaseFlagsType.builder().partyName(REPRESENTATIVE_NAME).build()) - .claimantRepresentativeExternalFlags(CaseFlagsType.builder().partyName(REPRESENTATIVE_NAME).build()) - .build()); - return caseData; - } } diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/utils/noc/ClaimantRepresentativeUtilsTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/utils/noc/ClaimantRepresentativeUtilsTest.java index 063aa3276c..0e5f8e8412 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/utils/noc/ClaimantRepresentativeUtilsTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/utils/noc/ClaimantRepresentativeUtilsTest.java @@ -10,6 +10,8 @@ import uk.gov.hmcts.et.common.model.ccd.CaseDetails; import uk.gov.hmcts.et.common.model.ccd.CaseUserAssignment; import uk.gov.hmcts.et.common.model.ccd.items.RepresentedTypeRItem; +import uk.gov.hmcts.et.common.model.ccd.types.AllPartyFlags; +import uk.gov.hmcts.et.common.model.ccd.types.CaseFlagsType; import uk.gov.hmcts.et.common.model.ccd.types.ClaimantType; import uk.gov.hmcts.et.common.model.ccd.types.Organisation; import uk.gov.hmcts.et.common.model.ccd.types.OrganisationPolicy; @@ -222,24 +224,48 @@ void theAddAmendClaimantRepresentative() { ClaimantRepresentativeUtils.addAmendClaimantRepresentative(caseData); assertThat(caseData.getRepresentativeClaimantType()).isNull(); assertThat(caseData.getClaimantRepresentativeRemoved()).isNull(); + assertThat(caseData.getAllPartyFlags()).isNull(); assertThat(caseData.getClaimantRepresentativeOrganisationPolicy().getOrganisation()).isNull(); // when claimant represented question is no and there exists claimant representative should set claimant // representative removed Yes + CaseFlagsType claimantFlags = CaseFlagsType.builder().build(); + CaseFlagsType claimantRepresentativeFlags = CaseFlagsType.builder() + .partyName(CLAIMANT_REPRESENTATIVE_NAME) + .build(); + CaseFlagsType claimantRepresentativeExternalFlags = CaseFlagsType.builder() + .partyName(CLAIMANT_REPRESENTATIVE_NAME) + .build(); caseData.setClaimantRepresentedQuestion(NO); caseData.setRepresentativeClaimantType(RepresentedTypeC.builder().build()); + caseData.setAllPartyFlags(AllPartyFlags.builder() + .claimantFlags(claimantFlags) + .claimantRepresentativeFlags(claimantRepresentativeFlags) + .claimantRepresentativeExternalFlags(claimantRepresentativeExternalFlags) + .build()); ClaimantRepresentativeUtils.addAmendClaimantRepresentative(caseData); assertThat(caseData.getRepresentativeClaimantType()).isNull(); assertThat(caseData.getClaimantRepresentativeRemoved()).isEqualTo(YES); + assertThat(caseData.getAllPartyFlags().getClaimantFlags()).isSameAs(claimantFlags); + assertThat(caseData.getAllPartyFlags().getClaimantRepresentativeFlags()).isNull(); + assertThat(caseData.getAllPartyFlags().getClaimantRepresentativeExternalFlags()).isNull(); assertThat(caseData.getClaimantRepresentativeOrganisationPolicy().getOrganisation()).isNull(); // when claimant representative exists and claimant represented question is Yes should assign representative RepresentedTypeC claimantRepresentative = RepresentedTypeC.builder() .nameOfRepresentative(CLAIMANT_REPRESENTATIVE_NAME).build(); caseData.setRepresentativeClaimantType(claimantRepresentative); caseData.setClaimantRepresentedQuestion(YES); + caseData.setAllPartyFlags(AllPartyFlags.builder() + .claimantRepresentativeFlags(claimantRepresentativeFlags) + .claimantRepresentativeExternalFlags(claimantRepresentativeExternalFlags) + .build()); ClaimantRepresentativeUtils.addAmendClaimantRepresentative(caseData); assertThat(caseData.getClaimantRepresentativeRemoved()).isEqualTo(NO); assertThat(caseData.getRepresentativeClaimantType().getRepresentativeId()).isNotNull(); assertThat(caseData.getRepresentativeClaimantType().getOrganisationId()).isNotNull(); + assertThat(caseData.getAllPartyFlags().getClaimantRepresentativeFlags()) + .isSameAs(claimantRepresentativeFlags); + assertThat(caseData.getAllPartyFlags().getClaimantRepresentativeExternalFlags()) + .isSameAs(claimantRepresentativeExternalFlags); assertThat(caseData.getClaimantRepresentativeOrganisationPolicy().getOrganisation()).isNotNull(); assertThat(caseData.getClaimantRepresentativeOrganisationPolicy().getOrganisation().getOrganisationID()) .isEqualTo(caseData.getRepresentativeClaimantType().getOrganisationId()); From 94db089ade3f96fac121b1f30e3745c8230e1d1f Mon Sep 17 00:00:00 2001 From: rajaram Date: Tue, 4 Aug 2026 11:54:22 +0100 Subject: [PATCH 024/100] Merge conflicts resolved --- .../CaseManagementForCaseWorkerService.java | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseManagementForCaseWorkerService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseManagementForCaseWorkerService.java index 1d651c2229..6092d426ed 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseManagementForCaseWorkerService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseManagementForCaseWorkerService.java @@ -85,7 +85,6 @@ public class CaseManagementForCaseWorkerService { private final CaseRetrievalForCaseWorkerService caseRetrievalForCaseWorkerService; private final CcdClient ccdClient; private final FeatureToggleService featureToggleService; - private final CaseFlagsService caseFlagsService; private final String hmctsServiceId; private final AdminUserService adminUserService; private final CaseManagementLocationService caseManagementLocationService; @@ -107,9 +106,6 @@ public class CaseManagementForCaseWorkerService { public static final String CASE_MANAGEMENT_LABEL = "Employment Tribunals"; public static final String CASE_MANAGEMENT_CODE = "Employment"; private static final String EMPLOYMENT_JURISDICTION = "EMPLOYMENT"; - private static final String RESPONDENT_NOT_CONTINUING_FLAG_COMMENT = - "The claim against the respondent is not continuing"; - private static final String RESPONDENT_STRUCK_OUT_FLAG_COMMENT = "The respondent has been struck out"; public static final String COUNTER_FIELD_INITIAL_VALUE = "1"; private final String ccdGatewayBaseUrl; private final List caseTypeIdsToCheck = List.of("ET_EnglandWales", "ET_Scotland", "Bristol", @@ -134,7 +130,6 @@ public class CaseManagementForCaseWorkerService { public CaseManagementForCaseWorkerService(CaseRetrievalForCaseWorkerService caseRetrievalForCaseWorkerService, CcdClient ccdClient, FeatureToggleService featureToggleService, - CaseFlagsService caseFlagsService, @Value("${hmcts_service_id}") String hmctsServiceId, AdminUserService adminUserService, CaseManagementLocationService caseManagementLocationService, @@ -145,7 +140,6 @@ public CaseManagementForCaseWorkerService(CaseRetrievalForCaseWorkerService case this.caseRetrievalForCaseWorkerService = caseRetrievalForCaseWorkerService; this.ccdClient = ccdClient; this.featureToggleService = featureToggleService; - this.caseFlagsService = caseFlagsService; this.hmctsServiceId = hmctsServiceId; this.adminUserService = adminUserService; this.caseManagementLocationService = caseManagementLocationService; @@ -448,11 +442,6 @@ public CaseData struckOutRespondents(CCDRequest ccdRequest) { if (respondentSumType.getResponseStruckOut() != null) { if (respondentSumType.getResponseStruckOut().equals(YES)) { struckRespondent.add(respondentSumTypeItem); - caseFlagsService.inactivateCaseFlags( - caseData, - respondentSumType.getRespondentName(), - RESPONDENT_STRUCK_OUT_FLAG_COMMENT - ); } else { activeRespondent.add(respondentSumTypeItem); } @@ -481,11 +470,6 @@ public CaseData continuingRespondent(CCDRequest ccdRequest) { continuingRespondent.add(respondentSumTypeItem); } else if (NO.equals(respondentSumType.getResponseContinue())) { notContinuingRespondent.add(respondentSumTypeItem); - caseFlagsService.inactivateCaseFlags( - caseData, - respondentSumType.getRespondentName(), - RESPONDENT_NOT_CONTINUING_FLAG_COMMENT - ); } else { respondentSumType.setResponseContinue(YES); continuingRespondent.add(respondentSumTypeItem); From aea479d11d389acfe2b898215a4b9693c06a3cda Mon Sep 17 00:00:00 2001 From: rajaram Date: Tue, 4 Aug 2026 12:19:04 +0100 Subject: [PATCH 025/100] Merge conflicts resolved --- ...aseManagementForCaseWorkerServiceTest.java | 42 +------------------ 1 file changed, 1 insertion(+), 41 deletions(-) diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseManagementForCaseWorkerServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseManagementForCaseWorkerServiceTest.java index cc2331adb1..fa55e8d1dc 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseManagementForCaseWorkerServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseManagementForCaseWorkerServiceTest.java @@ -104,9 +104,6 @@ class CaseManagementForCaseWorkerServiceTest { private static final String AUTH_TOKEN = "Bearer eyJhbGJbpjciOiJIUzI1NiJ9"; public static final String UNASSIGNED_OFFICE = "Unassigned"; private static final String HMCTS_SERVICE_ID = "BHA1"; - private static final String RESPONDENT_NOT_CONTINUING_FLAG_COMMENT = - "The claim against the respondent is not continuing"; - private static final String RESPONDENT_STRUCK_OUT_FLAG_COMMENT = "The respondent has been struck out"; @Value("${ccd_gateway_base_url}") private String ccdGatewayBaseUrl; @@ -137,8 +134,6 @@ class CaseManagementForCaseWorkerServiceTest { @MockitoBean private FeatureToggleService featureToggleService; @MockitoBean - private CaseFlagsService caseFlagsService; - @MockitoBean private AdminUserService adminUserService; @MockitoBean private CaseManagementLocationService caseManagementLocationService; @@ -163,7 +158,7 @@ void setUp() throws URISyntaxException, IOException { when(featureToggleService.isWorkAllocationEnabled()).thenReturn(true); when(adminUserService.getAdminUserToken()).thenReturn(AUTH_TOKEN); caseManagementForCaseWorkerService = new CaseManagementForCaseWorkerService( - caseRetrievalForCaseWorkerService, ccdClient, featureToggleService, caseFlagsService, HMCTS_SERVICE_ID, + caseRetrievalForCaseWorkerService, ccdClient, featureToggleService, HMCTS_SERVICE_ID, adminUserService, caseManagementLocationService, multipleReferenceService, ccdGatewayBaseUrl, multipleCasesSendingService, answersConverter); } @@ -497,7 +492,6 @@ void struckOutRespondentFirstToLast() { assertThat(caseData.getRespondentCollection().get(1).getValue().getResponseStruckOut()).isEqualTo(NO); assertThat(caseData.getRespondentCollection().get(2).getValue().getRespondentName()).isEqualTo("Juan Garcia"); assertThat(caseData.getRespondentCollection().get(2).getValue().getResponseStruckOut()).isEqualTo(YES); - verify(caseFlagsService).inactivateCaseFlags(caseData, "Juan Garcia", RESPONDENT_STRUCK_OUT_FLAG_COMMENT); } @Test @@ -556,11 +550,6 @@ void continuingRespondentFirstToLast() { assertThat(caseData.getRespondentCollection().get(2).getValue().getRespondentName()) .isEqualTo("Roberto Dondini"); assertThat(caseData.getRespondentCollection().get(2).getValue().getResponseContinue()).isEqualTo(NO); - verify(caseFlagsService).inactivateCaseFlags( - caseData, - "Roberto Dondini", - RESPONDENT_NOT_CONTINUING_FLAG_COMMENT - ); } @Test @@ -569,35 +558,6 @@ void continuingRespondentNull() { assertThat(caseData.getRespondentCollection()).hasSize(1); assertThat(caseData.getRespondentCollection().getFirst().getValue().getResponseContinue()).isEqualTo(YES); } - - @Test - void continuingRespondentDefaultsResponseContinueWhenRepCollectionExists() { - CaseData caseData = scotlandCcdRequest3.getCaseDetails().getCaseData(); - caseData.setRepCollection(createRepCollection()); - caseData.getRespondentCollection().getFirst().getValue().setResponseContinue(null); - - caseManagementForCaseWorkerService.continuingRespondent(scotlandCcdRequest3); - - assertThat(caseData.getRespondentCollection().getFirst().getValue().getResponseContinue()).isEqualTo(YES); - verify(caseFlagsService, never()).inactivateCaseFlags(any(), anyString(), anyString()); - } - - @Test - void continuingRespondentInactivatesCaseFlagsWhenRepCollectionExistsAndResponseDoesNotContinue() { - CaseData caseData = scotlandCcdRequest3.getCaseDetails().getCaseData(); - caseData.setRepCollection(createRepCollection()); - caseData.getRespondentCollection().getFirst().getValue().setResponseContinue(NO); - - caseManagementForCaseWorkerService.continuingRespondent(scotlandCcdRequest3); - - assertThat(caseData.getRespondentCollection().getFirst().getValue().getResponseContinue()).isEqualTo(NO); - verify(caseFlagsService).inactivateCaseFlags( - caseData, - "Antonio Vazquez", - RESPONDENT_NOT_CONTINUING_FLAG_COMMENT - ); - } - @Test void continuingRespondentEmpty() { CaseData caseData = caseManagementForCaseWorkerService.continuingRespondent(scotlandCcdRequest5); From 340d292e8c85f5abd24dd2905e29bc52ff43d8fe Mon Sep 17 00:00:00 2001 From: rajaram Date: Tue, 4 Aug 2026 13:15:16 +0100 Subject: [PATCH 026/100] Merge conflicts resolved --- .../docmosis/service/CaseManagementForCaseWorkerServiceTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseManagementForCaseWorkerServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseManagementForCaseWorkerServiceTest.java index fa55e8d1dc..3428fe84fd 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseManagementForCaseWorkerServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseManagementForCaseWorkerServiceTest.java @@ -558,6 +558,7 @@ void continuingRespondentNull() { assertThat(caseData.getRespondentCollection()).hasSize(1); assertThat(caseData.getRespondentCollection().getFirst().getValue().getResponseContinue()).isEqualTo(YES); } + @Test void continuingRespondentEmpty() { CaseData caseData = caseManagementForCaseWorkerService.continuingRespondent(scotlandCcdRequest5); From 9d609a83a782948094f8a13214b8cca094d2569f Mon Sep 17 00:00:00 2001 From: rajaram Date: Fri, 7 Aug 2026 12:40:03 +0100 Subject: [PATCH 027/100] Fixed build issue --- .../controllers/BundlesClaimantControllerTest.java | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/BundlesClaimantControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/BundlesClaimantControllerTest.java index 25ce408b34..e161925dac 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/BundlesClaimantControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/BundlesClaimantControllerTest.java @@ -10,6 +10,8 @@ import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; import uk.gov.hmcts.et.common.model.ccd.CCDRequest; +import uk.gov.hmcts.et.common.model.ccd.CaseData; +import uk.gov.hmcts.et.common.model.ccd.CaseDetails; import uk.gov.hmcts.ethos.replacement.docmosis.service.BundlesClaimantService; import uk.gov.hmcts.ethos.replacement.docmosis.service.SendNotificationService; import uk.gov.hmcts.ethos.replacement.docmosis.service.VerifyTokenService; @@ -22,6 +24,7 @@ import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -96,8 +99,9 @@ void aboutToSubmit_success() throws Exception { .andExpect(jsonPath("$.data", notNullValue())) .andExpect(jsonPath("$.errors", nullValue())) .andExpect(jsonPath("$.warnings", nullValue())); - verify(bundlesClaimantService).addToBundlesCollection(ccdRequest.getCaseDetails().getCaseData()); - verify(bundlesClaimantService).clearInputData(ccdRequest.getCaseDetails().getCaseData()); + + verify(bundlesClaimantService).addToBundlesCollection(any(CaseData.class)); + verify(bundlesClaimantService).clearInputData(any(CaseData.class)); } @Test @@ -107,7 +111,7 @@ void aboutToSubmit_badRequest() throws Exception { .header("Authorization", AUTH_TOKEN) .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isBadRequest()); - verify(bundlesClaimantService, never()).clearInputData(ccdRequest.getCaseDetails().getCaseData()); + verify(bundlesClaimantService, never()).clearInputData(any(CaseData.class)); } @Test @@ -164,7 +168,8 @@ void submitted_success() throws Exception { .andExpect(jsonPath("$.warnings", nullValue())) .andExpect(jsonPath("$.confirmation_header", notNullValue())) .andExpect(jsonPath("$.confirmation_body", notNullValue())); - verify(sendNotificationService).notifyClaimantBundlesSubmitted(ccdRequest.getCaseDetails()); + + verify(sendNotificationService).notifyClaimantBundlesSubmitted(any(CaseDetails.class)); } @Test From bf1f19404580a92f132a641214ff5da601b60280 Mon Sep 17 00:00:00 2001 From: rajaram Date: Thu, 13 Aug 2026 15:40:56 +0100 Subject: [PATCH 028/100] Changes for RET 6828, 6745, 6739 and 6728 --- .../json/CaseEvent/CaseEvent-WA.json | 1 + .../scotland/json/CaseEvent/CaseEvent-WA.json | 1 + .../CaseActionsForCaseWorkerController.java | 17 + .../RespondentRepresentativeController.java | 116 +++- .../docmosis/helpers/NocRespondentHelper.java | 46 +- .../docmosis/service/CaseFlagsService.java | 386 +++++++++++- .../CaseManagementForCaseWorkerService.java | 19 + .../NocRespondentRepresentativeService.java | 352 +++++++++-- .../docmosis/service/noc/NocService.java | 4 +- ...aseActionsForCaseWorkerControllerTest.java | 31 + ...espondentRepresentativeControllerTest.java | 136 +++++ .../helpers/NocRespondentHelperTest.java | 20 +- .../NoticeOfChangeFieldPopulatorTest.java | 35 ++ .../service/CaseFlagsServiceTest.java | 559 +++++++++++++++++- ...aseManagementForCaseWorkerServiceTest.java | 43 +- ...ocRespondentRepresentativeServiceTest.java | 357 ++++++++++- .../docmosis/service/noc/NocServiceTest.java | 10 +- 17 files changed, 1970 insertions(+), 163 deletions(-) diff --git a/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent-WA.json b/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent-WA.json index 5be233711d..a8d7a699fc 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent-WA.json +++ b/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent-WA.json @@ -189,6 +189,7 @@ "PreConditionState(s)": "Accepted;Closed;Rejected", "PostConditionState": "*", "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/amendRespondentDetails", + "CallBackURLSubmittedEvent": "${ET_COS_URL}/amendRespondentDetailsSubmitted", "EventEnablingCondition": "managingOffice !=\"Unassigned\"", "SecurityClassification": "Public", "ShowEventNotes": "N", diff --git a/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent-WA.json b/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent-WA.json index ba04fb8b6d..7d2f41f1ae 100644 --- a/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent-WA.json +++ b/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent-WA.json @@ -140,6 +140,7 @@ "PostConditionState": "*", "EventEnablingCondition": "managingOffice !=\"Unassigned\"", "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/amendRespondentDetails", + "CallBackURLSubmittedEvent": "${ET_COS_URL}/amendRespondentDetailsSubmitted", "SecurityClassification": "Public", "ShowEventNotes": "N", "ShowSummary": "N", diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java index 2b8e37fae7..4592a3cd07 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java @@ -17,6 +17,7 @@ import uk.gov.hmcts.ecm.common.model.helper.DefaultValues; import uk.gov.hmcts.et.common.model.ccd.CCDCallbackResponse; import uk.gov.hmcts.et.common.model.ccd.CCDRequest; +import uk.gov.hmcts.et.common.model.ccd.CallbackRequest; import uk.gov.hmcts.et.common.model.ccd.CaseData; import uk.gov.hmcts.et.common.model.ccd.CaseDetails; import uk.gov.hmcts.ethos.replacement.docmosis.helpers.BFHelper; @@ -383,6 +384,7 @@ public ResponseEntity amendRespondentDetails( if (errors.isEmpty() && isNotEmpty(caseData.getRepCollection())) { //Needed to keep the respondent names in the rep collection sync nocRespondentHelper.amendRespondentNameRepresentativeNames(caseData); + caseData = nocRespondentRepresentativeService.prepopulateOrgPolicyAndNoc(caseData); } if (errors.isEmpty() && isNotEmpty(caseData.getRespondentCollection())) { @@ -407,6 +409,21 @@ public ResponseEntity amendRespondentDetails( return getCallbackRespEntityErrors(errors, caseData); } + @PostMapping(value = "/amendRespondentDetailsSubmitted", consumes = APPLICATION_JSON_VALUE) + @Operation(summary = "Realigns representative access after respondents have been reordered.") + public void amendRespondentDetailsSubmitted( + @RequestBody CallbackRequest callbackRequest, + @RequestHeader(AUTHORIZATION) String userToken) { + try { + nocRespondentRepresentativeService.realignRespondentRepresentativeAccess(callbackRequest); + } catch (RuntimeException exception) { + String caseId = callbackRequest == null || callbackRequest.getCaseDetails() == null + ? StringUtils.EMPTY + : callbackRequest.getCaseDetails().getCaseId(); + log.error("Unable to realign respondent representative access for case {}", caseId, exception); + } + } + @PostMapping(value = "/updateHearing", consumes = APPLICATION_JSON_VALUE) @Operation(summary = "update hearing details for a single case.") @ApiResponses(value = { diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/RespondentRepresentativeController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/RespondentRepresentativeController.java index 458b34121c..488feef0ee 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/RespondentRepresentativeController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/RespondentRepresentativeController.java @@ -9,6 +9,7 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Strings; import org.jetbrains.annotations.NotNull; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; @@ -26,6 +27,8 @@ import uk.gov.hmcts.ethos.replacement.docmosis.exceptions.GenericServiceException; import uk.gov.hmcts.ethos.replacement.docmosis.helpers.NocRespondentHelper; import uk.gov.hmcts.ethos.replacement.docmosis.helpers.dynamiclists.DynamicRespondentRepresentative; +import uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService; +import uk.gov.hmcts.ethos.replacement.docmosis.service.FeatureToggleService; import uk.gov.hmcts.ethos.replacement.docmosis.service.noc.NocRespondentRepresentativeService; import uk.gov.hmcts.ethos.replacement.docmosis.utils.CaseDataUtils; import uk.gov.hmcts.ethos.replacement.docmosis.utils.noc.NocUtils; @@ -33,6 +36,8 @@ import java.util.ArrayList; import java.util.List; +import java.util.Objects; +import java.util.stream.IntStream; import static org.springframework.http.HttpHeaders.AUTHORIZATION; import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; @@ -70,6 +75,8 @@ public class RespondentRepresentativeController { private final NocRespondentHelper nocRespondentHelper; private final NocRespondentRepresentativeService nocRespondentRepresentativeService; + private final FeatureToggleService featureToggleService; + private final CaseFlagsService caseFlagsService; @PostMapping(value = "/amendRespondentRepresentativeAboutToStart", consumes = APPLICATION_JSON_VALUE) @Operation(summary = "Populates the respondents names into a dynamic list") @@ -151,26 +158,30 @@ public ResponseEntity amendRespondentRepresentativeMidEvent @ApiResponse(responseCode = HTTP_CODE_FIVE_ZERO_THREE, description = HTTP_MESSAGE_FIVE_ZERO_THREE) }) public ResponseEntity amendRespondentRepresentativeAboutToSubmit( - @RequestBody @NotNull CCDRequest ccdRequest, + @RequestBody @NotNull CallbackRequest callbackRequest, @RequestHeader(AUTHORIZATION) String userToken) { - CaseDataUtils.validateCCDRequest(ccdRequest); + CaseDataUtils.validateCaseDetails(callbackRequest.getCaseDetails()); log.info("AMEND RESPONDENT REPRESENTATIVE ABOUT TO SUBMIT ---> {} {}", LOG_MESSAGE, - ccdRequest.getCaseDetails().getCaseId()); - CaseData caseData = ccdRequest.getCaseDetails().getCaseData(); + callbackRequest.getCaseDetails().getCaseId()); + CaseDetails caseDetails = callbackRequest.getCaseDetails(); + CaseData caseData = caseDetails.getCaseData(); List errors = new ArrayList<>(NocUtils.validateNocCaseData(caseData)); errors.addAll(nocRespondentRepresentativeService - .validateRespondentRepresentativesOrganisationMatch(ccdRequest.getCaseDetails())); + .validateRespondentRepresentativesOrganisationMatch(caseDetails)); if (errors.isEmpty()) { try { - NocUtils.mapRepresentativesToRespondents(caseData, ccdRequest.getCaseDetails().getCaseId()); + NocUtils.mapRepresentativesToRespondents(caseData, caseDetails.getCaseId()); nocRespondentHelper.removeUnmatchedRepresentations(caseData); nocRespondentRepresentativeService.prepopulateOrgAddress(caseData, userToken); NocUtils.assignNonMyHmctsOrganisationIds(caseData.getRepCollection()); - nocRespondentRepresentativeService.removeConflictingClaimantRepresentation(ccdRequest.getCaseDetails()); + nocRespondentRepresentativeService.removeConflictingClaimantRepresentation(caseDetails); } catch (GenericRuntimeException | GenericServiceException gse) { errors.addFirst(gse.getMessage()); } } + if (errors.isEmpty()) { + setupCaseFlagsIfRespondentRepresentativeChanged(callbackRequest); + } return getCallbackRespEntityErrors(errors, caseData); } @@ -245,6 +256,7 @@ public ResponseEntity updateRespOrgPolicyAboutToSubmit( // Clears the changeOrganisationRequestField to prevent errors in the existing representative process // and to allow further changes to be made caseData.setChangeOrganisationRequestField(null); + setupCaseFlagsIfRequired(caseData); return getCallbackRespEntityNoErrors(ccdRequest.getCaseDetails().getCaseData()); } @@ -275,6 +287,96 @@ public ResponseEntity removeOwnRepresentative( caseData.getRepCollection().removeAll(caseData.getRepCollectionToRemove()); caseData.setRepCollectionToRemove(null); } + setupCaseFlagsIfRequired(caseData); return getCallbackRespEntityNoErrors(ccdRequest.getCaseDetails().getCaseData()); } + + private void setupCaseFlagsIfRequired(CaseData caseData) { + if (featureToggleService.isCaseFlagsEnabled() && caseFlagsService.caseFlagsSetupRequired(caseData)) { + caseFlagsService.setupCaseFlags(caseData); + } + } + + private void setupCaseFlagsIfRespondentRepresentativeChanged(CallbackRequest callbackRequest) { + CaseData caseData = callbackRequest.getCaseDetails().getCaseData(); + List changedRepresentativeIndexes = changedRespondentRepresentativeIndexes(callbackRequest); + if (featureToggleService.isCaseFlagsEnabled() && CollectionUtils.isNotEmpty(changedRepresentativeIndexes)) { + caseFlagsService.clearRespondentRepresentativeFlags(caseData, changedRepresentativeIndexes); + caseFlagsService.setupCaseFlags(caseData); + } + } + + private static List changedRespondentRepresentativeIndexes(CallbackRequest callbackRequest) { + if (callbackRequest.getCaseDetailsBefore() == null + || callbackRequest.getCaseDetailsBefore().getCaseData() == null + || CollectionUtils.isEmpty(callbackRequest.getCaseDetailsBefore().getCaseData().getRepCollection()) + || CollectionUtils.isEmpty(callbackRequest.getCaseDetails().getCaseData().getRepCollection())) { + return List.of(); + } + List previousRepresentatives = + callbackRequest.getCaseDetailsBefore().getCaseData().getRepCollection(); + List currentRepresentatives = callbackRequest.getCaseDetails().getCaseData() + .getRepCollection(); + return IntStream.range(0, currentRepresentatives.size()) + .filter(currentIndex -> previousRepresentatives.stream() + .filter(previousRepresentative -> sameRepresentative(previousRepresentative, + currentRepresentatives.get(currentIndex))) + .anyMatch(previousRepresentative -> representativeChanged(previousRepresentative, + currentRepresentatives.get(currentIndex)))) + .boxed() + .distinct() + .toList(); + } + + private static boolean representativeChanged( + RepresentedTypeRItem previousRepresentative, + RepresentedTypeRItem currentRepresentative) { + return !Objects.equals(representativeName(previousRepresentative), representativeName(currentRepresentative)) + || !Strings.CI.equals(representativeEmail(previousRepresentative), + representativeEmail(currentRepresentative)); + } + + private static boolean sameRepresentative( + RepresentedTypeRItem previousRepresentative, + RepresentedTypeRItem currentRepresentative) { + if (previousRepresentative == null || currentRepresentative == null) { + return false; + } + if (StringUtils.isNotBlank(representativeId(previousRepresentative)) + && StringUtils.isNotBlank(representativeId(currentRepresentative))) { + return Objects.equals(representativeId(previousRepresentative), representativeId(currentRepresentative)); + } + return Objects.equals(representativeRespondentId(previousRepresentative), + representativeRespondentId(currentRepresentative)) + && Objects.equals(representativeRespondentName(previousRepresentative), + representativeRespondentName(currentRepresentative)); + } + + private static String representativeName(RepresentedTypeRItem representative) { + return representative == null || representative.getValue() == null + ? null + : representative.getValue().getNameOfRepresentative(); + } + + private static String representativeEmail(RepresentedTypeRItem representative) { + return representative == null || representative.getValue() == null + ? null + : representative.getValue().getRepresentativeEmailAddress(); + } + + private static String representativeId(RepresentedTypeRItem representative) { + return representative == null ? null : representative.getId(); + } + + private static String representativeRespondentId(RepresentedTypeRItem representative) { + return representative == null || representative.getValue() == null + ? null + : representative.getValue().getRespondentId(); + } + + private static String representativeRespondentName(RepresentedTypeRItem representative) { + return representative == null || representative.getValue() == null + ? null + : representative.getValue().getRespRepName(); + } } diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/helpers/NocRespondentHelper.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/helpers/NocRespondentHelper.java index d18a6d70ee..d1a382edae 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/helpers/NocRespondentHelper.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/helpers/NocRespondentHelper.java @@ -180,22 +180,40 @@ public static void resetRepresentation(RespondentSumTypeItem respondent) { } public void amendRespondentNameRepresentativeNames(CaseData caseData) { - List repCollection = new ArrayList<>(); - for (RepresentedTypeRItem respondentRep : emptyIfNull(caseData.getRepCollection())) { - final List respondentCollection = caseData.getRespondentCollection(); - Optional matchedRespondent = respondentCollection.stream() - .filter(resp -> - StringUtils.isNotBlank(respondentRep.getValue().getRespondentId()) - && Objects.equals(resp.getId(), respondentRep.getValue().getRespondentId())) - .findFirst(); - - matchedRespondent.ifPresent(respondent -> - updateRepWithRespondentDetails(respondent, respondentRep, respondentCollection)); - - repCollection.add(respondentRep); + List representatives = emptyIfNull(caseData.getRepCollection()); + List respondents = emptyIfNull(caseData.getRespondentCollection()); + List alignedRepCollection = new ArrayList<>(); + List unmatchedRepresentatives = new ArrayList<>(representatives); + + for (int index = 0; index < respondents.size() && index < SolicitorRole.values().length; index++) { + RespondentSumTypeItem respondent = respondents.get(index); + Optional matchedRepresentative = + findRepresentativeByRespondentId(respondent, unmatchedRepresentatives); + if (matchedRepresentative.isEmpty()) { + continue; + } + + RepresentedTypeRItem representative = matchedRepresentative.get(); + updateRepWithRespondentDetails(respondent, representative, respondents); + representative.getValue().setRole(SolicitorRole.values()[index].getCaseRoleLabel()); + alignedRepCollection.add(representative); + unmatchedRepresentatives.remove(representative); } - caseData.setRepCollection(repCollection); + alignedRepCollection.addAll(unmatchedRepresentatives); + caseData.setRepCollection(alignedRepCollection); + } + + private Optional findRepresentativeByRespondentId( + RespondentSumTypeItem respondent, List representatives) { + if (respondent == null || StringUtils.isBlank(respondent.getId())) { + return Optional.empty(); + } + return representatives.stream() + .filter(representative -> representative != null && representative.getValue() != null) + .filter(representative -> Objects.equals(respondent.getId(), + representative.getValue().getRespondentId())) + .findFirst(); } public void updateRepWithRespondentDetails(RespondentSumTypeItem respondent, RepresentedTypeRItem respondentRep, diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java index 200a8660fb..224c47cbfe 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java @@ -9,13 +9,21 @@ import uk.gov.hmcts.et.common.model.ccd.items.GenericTseApplicationTypeItem; import uk.gov.hmcts.et.common.model.ccd.items.GenericTypeItem; import uk.gov.hmcts.et.common.model.ccd.items.ListTypeItem; +import uk.gov.hmcts.et.common.model.ccd.items.RepresentedTypeRItem; +import uk.gov.hmcts.et.common.model.ccd.items.RespondentSumTypeItem; import uk.gov.hmcts.et.common.model.ccd.items.TseAdminRecordDecisionTypeItem; import uk.gov.hmcts.et.common.model.ccd.types.AllPartyFlags; import uk.gov.hmcts.et.common.model.ccd.types.CaseFlagsType; +import uk.gov.hmcts.et.common.model.ccd.types.RepresentedTypeR; +import uk.gov.hmcts.et.common.model.ccd.types.RespondentSumType; import uk.gov.hmcts.et.common.model.ccd.types.RestrictedReportingType; +import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.List; +import java.util.Locale; +import java.util.Map; import java.util.Objects; import java.util.function.BiConsumer; import java.util.function.Function; @@ -166,7 +174,8 @@ public boolean caseFlagsSetupRequired(CaseData caseData) { return getCaseFlags(caseData) == null || PARTY_FLAGS.stream() .filter(flag -> isRequired(caseData, flag)) - .anyMatch(flag -> isMissingRole(caseData, flag)); + .anyMatch(flag -> partyFlagSetupRequired(caseData, flag)) + || hasStaleRespondentRepresentativeFlags(caseData); } /** @@ -179,9 +188,14 @@ public void setupCaseFlags(CaseData caseData) { setCaseFlags(caseData, CaseFlagsType.builder().build()); } + List existingRepresentativeFlags = currentRespondentRepresentativeFlags(caseData); + alignIndexedFlagsWithCurrentOrder(caseData); PARTY_FLAGS.stream() .filter(flag -> hasParty(caseData, flag)) .forEach(flag -> setupPartyFlag(caseData, flag)); + + alignRespondentRepresentativeFlagDetails(caseData, existingRepresentativeFlags); + clearStaleRespondentRepresentativeFlags(caseData); } /** @@ -222,13 +236,12 @@ public void setPrivateHearingFlag(CaseData caseData) { } /** - * Inactivates all case flag details for a respondent with the supplied reason comment. + * Inactivates all case flag details for a respondent. * * @param caseData Data about the current case * @param respondentName Name of the respondent - * @param inactiveFlagComment Comment to add to each inactivated flag */ - public void inactivateCaseFlags(CaseData caseData, String respondentName, String inactiveFlagComment) { + public void inactivateRespondentCaseFlags(CaseData caseData, String respondentName) { if (caseData == null || StringUtils.isBlank(respondentName)) { return; } @@ -237,10 +250,10 @@ public void inactivateCaseFlags(CaseData caseData, String respondentName, String .filter(flag -> PartyType.RESPONDENT.equals(flag.partyType())) .map(flag -> flag.get(caseData)) .filter(flags -> flags != null && Objects.equals(respondentName, flags.getPartyName())) - .forEach(flags -> inactivateCaseFlags(flags, inactiveFlagComment)); + .forEach(this::inactivateCaseFlags); } - private void inactivateCaseFlags(CaseFlagsType flags, String inactiveFlagComment) { + private void inactivateCaseFlags(CaseFlagsType flags) { if (flags.getDetails() == null) { return; } @@ -248,10 +261,56 @@ private void inactivateCaseFlags(CaseFlagsType flags, String inactiveFlagComment flags.getDetails().stream() .map(GenericTypeItem::getValue) .filter(Objects::nonNull) - .forEach(flag -> { - flag.setStatus(INACTIVE); - flag.setFlagComment(inactiveFlagComment); - }); + .forEach(flag -> flag.setStatus(INACTIVE)); + } + + /** + * Inactivates respondent representative flags when the representative no longer has active respondents. + * + * @param caseData Data about the current case + * @param inactiveRespondent Respondent that has become struck out or no longer continuing + */ + public void inactivateRespondentRepresentativeCaseFlags( + CaseData caseData, RespondentSumTypeItem inactiveRespondent) { + if (caseData == null || inactiveRespondent == null || caseData.getRepCollection() == null) { + return; + } + + List inactiveRepresentativeIdentities = caseData.getRepCollection().stream() + .map(RepresentedTypeRItem::getValue) + .filter(Objects::nonNull) + .filter(representative -> representsRespondent(representative, inactiveRespondent)) + .map(CaseFlagsService::representativeIdentity) + .filter(Objects::nonNull) + .distinct() + .filter(identity -> !representsAnyActiveRespondent(caseData, identity)) + .toList(); + + if (inactiveRepresentativeIdentities.isEmpty()) { + return; + } + + PARTY_FLAGS.stream() + .filter(flag -> PartyType.RESPONDENT_REPRESENTATIVE.equals(flag.partyType())) + .filter(flag -> hasUniqueRepresentativeAtIndex(caseData, flag.index())) + .filter(flag -> inactiveRepresentativeIdentities.contains(representativeIdentity( + caseData.getRepCollection().get(flag.index()).getValue()))) + .map(flag -> flag.get(caseData)) + .filter(Objects::nonNull) + .forEach(this::inactivateCaseFlags); + } + + public void clearRespondentRepresentativeFlags(CaseData caseData, List representativeIndexes) { + if (caseData == null || representativeIndexes == null || representativeIndexes.isEmpty()) { + return; + } + + PARTY_FLAGS.stream() + .filter(flag -> PartyType.RESPONDENT_REPRESENTATIVE.equals(flag.partyType())) + .filter(flag -> representativeIndexes.contains(flag.index())) + .map(flag -> flag.get(caseData)) + .filter(Objects::nonNull) + .forEach(flags -> flags.setDetails(null)); } private static PartyFlag claimantFlag( @@ -310,7 +369,7 @@ private static boolean isRequired(CaseData caseData, PartyFlag flag) { return switch (flag.partyType()) { case CLAIMANT, CLAIMANT_REPRESENTATIVE -> true; case RESPONDENT -> respondentCount(caseData) > flag.index(); - case RESPONDENT_REPRESENTATIVE -> representativeCount(caseData) > flag.index(); + case RESPONDENT_REPRESENTATIVE -> hasUniqueRepresentativeAtIndex(caseData, flag.index()); }; } @@ -319,26 +378,119 @@ private static boolean hasParty(CaseData caseData, PartyFlag flag) { case CLAIMANT -> true; case RESPONDENT -> respondentCount(caseData) > flag.index(); case CLAIMANT_REPRESENTATIVE -> caseData.getRepresentativeClaimantType() != null; - case RESPONDENT_REPRESENTATIVE -> representativeCount(caseData) > flag.index(); + case RESPONDENT_REPRESENTATIVE -> hasUniqueRepresentativeAtIndex(caseData, flag.index()); }; } - private static boolean isMissingRole(CaseData caseData, PartyFlag flag) { + private static boolean partyFlagSetupRequired(CaseData caseData, PartyFlag flag) { CaseFlagsType flags = flag.get(caseData); - return flags == null || StringUtils.isEmpty(flags.getRoleOnCase()); + return flags == null + || StringUtils.isEmpty(flags.getRoleOnCase()) + || partyNameChanged(caseData, flag, flags); + } + + private static boolean partyNameChanged(CaseData caseData, PartyFlag flag, CaseFlagsType flags) { + return hasParty(caseData, flag) && !Objects.equals(getPartyName(caseData, flag), flags.getPartyName()); + } + + private static void alignIndexedFlagsWithCurrentOrder(CaseData caseData) { + // Discontinuance can move indexed parties, so keep flag details with the named party + // before refreshing slot-specific roles. + alignIndexedPartyFlags(caseData, PartyType.RESPONDENT, INTERNAL, respondentCount(caseData)); + alignIndexedPartyFlags(caseData, PartyType.RESPONDENT, EXTERNAL, respondentCount(caseData)); + alignIndexedPartyFlags( + caseData, PartyType.RESPONDENT_REPRESENTATIVE, INTERNAL, representativeCount(caseData)); + alignIndexedPartyFlags( + caseData, PartyType.RESPONDENT_REPRESENTATIVE, EXTERNAL, representativeCount(caseData)); + } + + private static void alignIndexedPartyFlags( + CaseData caseData, PartyType partyType, String visibility, int partyCount) { + List indexedFlags = PARTY_FLAGS.stream() + .filter(flag -> partyType.equals(flag.partyType())) + .filter(flag -> visibility.equals(flag.visibility())) + .toList(); + List currentPartyNames = currentPartyNames(caseData, indexedFlags, partyCount); + Map existingFlagsByPartyName = hasDuplicatePartyNames(currentPartyNames) + ? Map.of() + : existingFlagsByPartyName(caseData, indexedFlags); + List alignedFlags = new ArrayList<>(); + + for (PartyFlag flag : indexedFlags) { + if (flag.index() >= partyCount) { + alignedFlags.add(null); + continue; + } + + String partyName = getPartyName(caseData, flag); + CaseFlagsType matchedFlag = existingFlagsByPartyName.get(partyName); + CaseFlagsType currentFlag = flag.get(caseData); + alignedFlags.add(matchedFlag != null + ? matchedFlag + : keepCurrentFlagIfItDoesNotBelongToAnotherParty(currentFlag, currentPartyNames, partyName)); + } + + for (int i = 0; i < indexedFlags.size(); i++) { + indexedFlags.get(i).set(caseData, alignedFlags.get(i)); + } + } + + private static Map existingFlagsByPartyName( + CaseData caseData, List indexedFlags) { + Map flagsByPartyName = new HashMap<>(); + indexedFlags.stream() + .map(flag -> flag.get(caseData)) + .filter(Objects::nonNull) + .filter(flags -> StringUtils.isNotBlank(flags.getPartyName())) + .forEach(flags -> flagsByPartyName.putIfAbsent(flags.getPartyName(), flags)); + return flagsByPartyName; + } + + private static List currentPartyNames(CaseData caseData, List indexedFlags, int partyCount) { + return indexedFlags.stream() + .filter(flag -> flag.index() < partyCount) + .map(flag -> getPartyName(caseData, flag)) + .toList(); + } + + private static boolean hasDuplicatePartyNames(List partyNames) { + return partyNames.stream() + .filter(StringUtils::isNotBlank) + .distinct() + .count() < partyNames.stream() + .filter(StringUtils::isNotBlank) + .count(); + } + + private static CaseFlagsType keepCurrentFlagIfItDoesNotBelongToAnotherParty( + CaseFlagsType currentFlag, List currentPartyNames, String partyName) { + if (currentFlag == null + || Objects.equals(currentFlag.getPartyName(), partyName) + || !currentPartyNames.contains(currentFlag.getPartyName())) { + return currentFlag; + } + return null; } private static void setupPartyFlag(CaseData caseData, PartyFlag flag) { String partyName = getPartyName(caseData, flag); CaseFlagsType existingFlag = flag.get(caseData); - if (existingFlag == null || StringUtils.isEmpty(existingFlag.getRoleOnCase())) { + if (existingFlag == null + || StringUtils.isEmpty(existingFlag.getRoleOnCase()) + || shouldResetRespondentRepresentativeFlags(flag, existingFlag, partyName)) { flag.set(caseData, createShellFlag(partyName, flag.roleOnCase(), flag.visibility())); - } else if (!Objects.equals(partyName, existingFlag.getPartyName())) { - existingFlag.setPartyName(partyName); + } else { + updateShellFlag(existingFlag, partyName, flag.roleOnCase(), flag.visibility()); } } + private static boolean shouldResetRespondentRepresentativeFlags( + PartyFlag flag, CaseFlagsType existingFlag, String partyName) { + return PartyType.RESPONDENT_REPRESENTATIVE.equals(flag.partyType()) + && !Objects.equals(partyName, existingFlag.getPartyName()); + } + private static CaseFlagsType createShellFlag(String partyName, String roleOnCase, String visibility) { return CaseFlagsType.builder() .partyName(partyName) @@ -348,6 +500,14 @@ private static CaseFlagsType createShellFlag(String partyName, String roleOnCase .build(); } + private static void updateShellFlag(CaseFlagsType existingFlag, String partyName, String roleOnCase, + String visibility) { + existingFlag.setPartyName(partyName); + existingFlag.setRoleOnCase(roleOnCase); + existingFlag.setGroupId(roleOnCase); + existingFlag.setVisibility(visibility); + } + private static String getPartyName(CaseData caseData, PartyFlag flag) { return switch (flag.partyType()) { case CLAIMANT -> caseData.getClaimant(); @@ -367,10 +527,188 @@ private static int respondentCount(CaseData caseData) { return caseData.getRespondentCollection() == null ? 0 : caseData.getRespondentCollection().size(); } + private static boolean hasUniqueRepresentativeAtIndex(CaseData caseData, int index) { + return representativeCount(caseData) > index && !isDuplicateRepresentativeAtIndex(caseData, index); + } + private static int representativeCount(CaseData caseData) { return caseData.getRepCollection() == null ? 0 : caseData.getRepCollection().size(); } + private static boolean representsAnyActiveRespondent(CaseData caseData, RepresentativeIdentity identity) { + if (caseData.getRespondentCollection() == null) { + return false; + } + + return caseData.getRepCollection().stream() + .map(RepresentedTypeRItem::getValue) + .filter(Objects::nonNull) + .filter(representative -> Objects.equals(identity, representativeIdentity(representative))) + .anyMatch(representative -> caseData.getRespondentCollection().stream() + .filter(CaseFlagsService::isActiveRespondent) + .anyMatch(respondent -> representsRespondent(representative, respondent))); + } + + private static boolean representsRespondent(RepresentedTypeR representative, RespondentSumTypeItem respondent) { + if (representative == null || respondent == null || respondent.getValue() == null) { + return false; + } + + if (StringUtils.isNotBlank(representative.getRespondentId())) { + return Objects.equals(representative.getRespondentId(), respondent.getId()); + } + + return StringUtils.isNotBlank(representative.getRespRepName()) + && Objects.equals(representative.getRespRepName(), respondentName(respondent)); + } + + private static boolean isActiveRespondent(RespondentSumTypeItem respondent) { + if (respondent == null || respondent.getValue() == null) { + return false; + } + + RespondentSumType respondentValue = respondent.getValue(); + return !YES.equals(respondentValue.getResponseStruckOut()) + && !NO.equals(respondentValue.getResponseContinue()); + } + + private static String respondentName(RespondentSumTypeItem respondent) { + return respondent.getValue().getRespondentName(); + } + + private static boolean isDuplicateRepresentativeAtIndex(CaseData caseData, int index) { + RepresentativeIdentity identity = representativeIdentity(caseData.getRepCollection().get(index).getValue()); + if (identity == null) { + return false; + } + + for (int i = 0; i < index; i++) { + if (Objects.equals(identity, representativeIdentity(caseData.getRepCollection().get(i).getValue()))) { + return true; + } + } + + return false; + } + + @Nullable + private static RepresentativeIdentity representativeIdentity(RepresentedTypeR representative) { + if (representative == null + || StringUtils.isAllBlank( + representative.getNameOfRepresentative(), representative.getRepresentativeEmailAddress())) { + return null; + } + + return new RepresentativeIdentity( + normaliseRepresentativeIdentity(representative.getNameOfRepresentative()), + normaliseRepresentativeIdentity(representative.getRepresentativeEmailAddress()) + ); + } + + private static String normaliseRepresentativeIdentity(String value) { + return StringUtils.trimToEmpty(value).toLowerCase(Locale.ROOT); + } + + private static List currentRespondentRepresentativeFlags(CaseData caseData) { + return PARTY_FLAGS.stream() + .filter(flag -> PartyType.RESPONDENT_REPRESENTATIVE.equals(flag.partyType())) + .map(flag -> existingRepresentativeFlag(caseData, flag)) + .toList(); + } + + private static ExistingRepresentativeFlag existingRepresentativeFlag(CaseData caseData, PartyFlag flag) { + CaseFlagsType flags = flag.get(caseData); + return new ExistingRepresentativeFlag( + flag.index(), + flag.visibility(), + flags == null ? null : flags.getPartyName(), + flags == null ? null : flags.getDetails() + ); + } + + private static void alignRespondentRepresentativeFlagDetails( + CaseData caseData, List existingRepresentativeFlags) { + PARTY_FLAGS.stream() + .filter(flag -> PartyType.RESPONDENT_REPRESENTATIVE.equals(flag.partyType())) + .filter(flag -> hasUniqueRepresentativeAtIndex(caseData, flag.index())) + .forEach(flag -> alignRepresentativeFlagDetails(caseData, flag, existingRepresentativeFlags)); + } + + private static void alignRepresentativeFlagDetails( + CaseData caseData, + PartyFlag targetFlag, + List existingRepresentativeFlags) { + CaseFlagsType target = targetFlag.get(caseData); + if (target == null) { + return; + } + + target.setDetails(concatFlagDetails( + target.getDetails(), + staleRepresentativeFlagDetails(caseData, targetFlag, target, existingRepresentativeFlags))); + } + + private static ListTypeItem concatFlagDetails( + ListTypeItem existing, ListTypeItem additional) { + if (additional == null) { + return existing; + } + return ListTypeItem.concat(existing, additional); + } + + private static ListTypeItem staleRepresentativeFlagDetails( + CaseData caseData, + PartyFlag targetFlag, + CaseFlagsType target, + List existingRepresentativeFlags) { + String targetPartyName = target.getPartyName(); + if (StringUtils.isBlank(targetPartyName)) { + return null; + } + + ListTypeItem details = null; + for (ExistingRepresentativeFlag existingFlag : existingRepresentativeFlags) { + if (existingFlag.index() == targetFlag.index() + || existingRepresentativeFlagStillMatchesCurrentUniqueParty(caseData, existingFlag) + || Objects.equals(existingFlag.details(), target.getDetails()) + || !Objects.equals(existingFlag.visibility(), targetFlag.visibility()) + || !Objects.equals(existingFlag.partyName(), targetPartyName)) { + continue; + } + + details = concatFlagDetails(details, existingFlag.details()); + } + return details; + } + + private static boolean existingRepresentativeFlagStillMatchesCurrentUniqueParty( + CaseData caseData, ExistingRepresentativeFlag existingFlag) { + String currentPartyName = currentRepresentativePartyName(caseData, existingFlag.index()); + return hasUniqueRepresentativeAtIndex(caseData, existingFlag.index()) + && Objects.equals(existingFlag.partyName(), currentPartyName); + } + + private static String currentRepresentativePartyName(CaseData caseData, int index) { + if (representativeCount(caseData) <= index || caseData.getRepCollection().get(index).getValue() == null) { + return null; + } + return caseData.getRepCollection().get(index).getValue().getNameOfRepresentative(); + } + + private static void clearStaleRespondentRepresentativeFlags(CaseData caseData) { + PARTY_FLAGS.stream() + .filter(flag -> PartyType.RESPONDENT_REPRESENTATIVE.equals(flag.partyType())) + .filter(flag -> !hasUniqueRepresentativeAtIndex(caseData, flag.index())) + .forEach(flag -> flag.clear(caseData)); + } + + private static boolean hasStaleRespondentRepresentativeFlags(CaseData caseData) { + return PARTY_FLAGS.stream() + .filter(flag -> PartyType.RESPONDENT_REPRESENTATIVE.equals(flag.partyType())) + .filter(flag -> !hasUniqueRepresentativeAtIndex(caseData, flag.index())) + .anyMatch(flag -> flag.get(caseData) != null); + } + private boolean isFlaggedForRestrictedReporting(CaseData caseData) { RestrictedReportingType restricted = caseData.getRestrictedReporting(); return restricted != null && (YES.equals(restricted.getRule503b()) || YES.equals(restricted.getImposed())); @@ -461,4 +799,18 @@ private void clear(CaseData caseData) { } } } + + /** + * This lets the service move flag details when representative slots reorder, and then clear stale/duplicate + * representative flag slots. + */ + private record ExistingRepresentativeFlag( + int index, + String visibility, + String partyName, + ListTypeItem details) { + } + + private record RepresentativeIdentity(String name, String email) { + } } diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseManagementForCaseWorkerService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseManagementForCaseWorkerService.java index 6092d426ed..fe73080795 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseManagementForCaseWorkerService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseManagementForCaseWorkerService.java @@ -85,6 +85,7 @@ public class CaseManagementForCaseWorkerService { private final CaseRetrievalForCaseWorkerService caseRetrievalForCaseWorkerService; private final CcdClient ccdClient; private final FeatureToggleService featureToggleService; + private final CaseFlagsService caseFlagsService; private final String hmctsServiceId; private final AdminUserService adminUserService; private final CaseManagementLocationService caseManagementLocationService; @@ -130,6 +131,7 @@ public class CaseManagementForCaseWorkerService { public CaseManagementForCaseWorkerService(CaseRetrievalForCaseWorkerService caseRetrievalForCaseWorkerService, CcdClient ccdClient, FeatureToggleService featureToggleService, + CaseFlagsService caseFlagsService, @Value("${hmcts_service_id}") String hmctsServiceId, AdminUserService adminUserService, CaseManagementLocationService caseManagementLocationService, @@ -140,6 +142,7 @@ public CaseManagementForCaseWorkerService(CaseRetrievalForCaseWorkerService case this.caseRetrievalForCaseWorkerService = caseRetrievalForCaseWorkerService; this.ccdClient = ccdClient; this.featureToggleService = featureToggleService; + this.caseFlagsService = caseFlagsService; this.hmctsServiceId = hmctsServiceId; this.adminUserService = adminUserService; this.caseManagementLocationService = caseManagementLocationService; @@ -442,6 +445,14 @@ public CaseData struckOutRespondents(CCDRequest ccdRequest) { if (respondentSumType.getResponseStruckOut() != null) { if (respondentSumType.getResponseStruckOut().equals(YES)) { struckRespondent.add(respondentSumTypeItem); + caseFlagsService.inactivateRespondentCaseFlags( + caseData, + respondentSumType.getRespondentName() + ); + caseFlagsService.inactivateRespondentRepresentativeCaseFlags( + caseData, + respondentSumTypeItem + ); } else { activeRespondent.add(respondentSumTypeItem); } @@ -470,6 +481,14 @@ public CaseData continuingRespondent(CCDRequest ccdRequest) { continuingRespondent.add(respondentSumTypeItem); } else if (NO.equals(respondentSumType.getResponseContinue())) { notContinuingRespondent.add(respondentSumTypeItem); + caseFlagsService.inactivateRespondentCaseFlags( + caseData, + respondentSumType.getRespondentName() + ); + caseFlagsService.inactivateRespondentRepresentativeCaseFlags( + caseData, + respondentSumTypeItem + ); } else { respondentSumType.setResponseContinue(YES); continuingRespondent.add(respondentSumTypeItem); diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocRespondentRepresentativeService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocRespondentRepresentativeService.java index 5956bd36d3..71570d8db7 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocRespondentRepresentativeService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocRespondentRepresentativeService.java @@ -53,9 +53,12 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.Set; import java.util.UUID; import static org.apache.commons.lang3.ObjectUtils.getIfNull; @@ -158,6 +161,246 @@ public void updateRepresentativesAccess(CallbackRequest callbackRequest, String resetOrganisationPolicies(callbackRequest.getCaseDetails()); } + /** + * Realigns respondent representative case-user assignments after respondents have been reordered. + * + *

CCD field access is tied to indexed solicitor roles such as {@code [SOLICITORA]} and + * {@code [SOLICITORB]}. When an inactive respondent is moved to the end of the respondent collection, + * the representative records and organisation policies are reordered during the about-to-submit callback, + * but CCD's case-user assignments remain unchanged. This method compares the representative role for each + * stable respondent ID before and after the event. It also reconciles each representative user and organisation + * against the roles stored in the current representative collection. This allows an already-misaligned case to + * repair itself when the event is submitted again. The method grants newly required user-role pairs and then + * revokes obsolete pairs.

+ * + *

New roles are granted before old roles are revoked to avoid an access gap. If a grant or revoke fails, + * any roles added by this operation are revoked so the original assignments remain authoritative.

+ * + * @param callbackRequest callback containing the case state before and after respondent reordering + */ + public void realignRespondentRepresentativeAccess(CallbackRequest callbackRequest) { + if (!hasRoleRealignmentContext(callbackRequest)) { + return; + } + + CaseDetails currentCaseDetails = callbackRequest.getCaseDetails(); + Map roleChanges = representativeRoleChanges(callbackRequest); + RepresentativeAccessIndex accessIndex = representativeAccessIndex(currentCaseDetails.getCaseData()); + + String adminUserToken = adminUserService.getAdminUserToken(); + if (StringUtils.isBlank(adminUserToken)) { + return; + } + + CaseUserAssignmentData assignmentData = nocCcdService.retrieveCaseUserAssignments( + adminUserToken, currentCaseDetails.getCaseId()); + if (ObjectUtils.isEmpty(assignmentData) + || CollectionUtils.isEmpty(assignmentData.getCaseUserAssignments())) { + return; + } + + List solicitorAssignments = assignmentData.getCaseUserAssignments().stream() + .filter(NocRespondentRepresentativeService::isValidRespondentRepresentativeAssignment) + .toList(); + Set currentAssignments = userRoleAssignments(solicitorAssignments); + Set desiredAssignments = desiredUserRoleAssignments( + solicitorAssignments, roleChanges, accessIndex); + + List assignmentsToAdd = desiredAssignments.stream() + .filter(assignment -> !currentAssignments.contains(assignment)) + .toList(); + List assignmentsToRevoke = solicitorAssignments.stream() + .filter(assignment -> !desiredAssignments.contains(UserRoleAssignment.from(assignment))) + .toList(); + + List addedAssignments = new ArrayList<>(); + try { + for (UserRoleAssignment assignment : assignmentsToAdd) { + if (!nocService.grantCaseAccess( + assignment.userId(), currentCaseDetails.getCaseId(), assignment.caseRole())) { + throw new IllegalStateException("Failed to grant realigned respondent representative role " + + assignment.caseRole() + " for case " + currentCaseDetails.getCaseId()); + } + addedAssignments.add(assignment); + } + + if (CollectionUtils.isNotEmpty(assignmentsToRevoke)) { + nocCcdService.revokeCaseAssignments(adminUserToken, CaseUserAssignmentData.builder() + .caseUserAssignments(assignmentsToRevoke) + .build()); + } + } catch (RuntimeException exception) { + rollbackRealignedAssignments(adminUserToken, currentCaseDetails.getCaseId(), addedAssignments); + throw exception; + } + } + + private static boolean hasRoleRealignmentContext(CallbackRequest callbackRequest) { + return ObjectUtils.isNotEmpty(callbackRequest) + && CaseDataUtils.areCaseDetailsValid(callbackRequest.getCaseDetails()) + && StringUtils.isNotBlank(callbackRequest.getCaseDetails().getCaseId()); + } + + private static Map representativeRoleChanges(CallbackRequest callbackRequest) { + if (!CaseDataUtils.areCaseDetailsValid(callbackRequest.getCaseDetailsBefore())) { + return Map.of(); + } + return representativeRoleChanges( + callbackRequest.getCaseDetailsBefore().getCaseData(), callbackRequest.getCaseDetails().getCaseData()); + } + + private static Map representativeRoleChanges(CaseData previousCaseData, CaseData currentCaseData) { + Map previousRoles = representativeRolesByRespondentId(previousCaseData); + Map currentRoles = representativeRolesByRespondentId(currentCaseData); + Map roleChanges = new LinkedHashMap<>(); + + previousRoles.forEach((respondentId, previousRole) -> { + String currentRole = currentRoles.get(respondentId); + if (StringUtils.isNotBlank(currentRole) && !previousRole.equals(currentRole)) { + roleChanges.put(previousRole, currentRole); + } + }); + return roleChanges; + } + + private static Map representativeRolesByRespondentId(CaseData caseData) { + Map rolesByRespondentId = new LinkedHashMap<>(); + if (ObjectUtils.isEmpty(caseData) || CollectionUtils.isEmpty(caseData.getRepCollection())) { + return rolesByRespondentId; + } + + caseData.getRepCollection().stream() + .filter(RespondentRepresentativeUtils::isValidRepresentative) + .map(RepresentedTypeRItem::getValue) + .filter(representative -> StringUtils.isNotBlank(representative.getRespondentId())) + .filter(representative -> RoleUtils.isRespondentRepresentativeRole(representative.getRole())) + .forEach(representative -> rolesByRespondentId.putIfAbsent( + representative.getRespondentId(), representative.getRole())); + return rolesByRespondentId; + } + + private static boolean isValidRespondentRepresentativeAssignment(CaseUserAssignment assignment) { + return ObjectUtils.isNotEmpty(assignment) + && StringUtils.isNotBlank(assignment.getUserId()) + && RoleUtils.isRespondentRepresentativeRole(assignment.getCaseRole()); + } + + private static Set userRoleAssignments(List assignments) { + Set userRoles = new LinkedHashSet<>(); + assignments.forEach(assignment -> userRoles.add(new UserRoleAssignment( + assignment.getUserId(), assignment.getCaseRole()))); + return userRoles; + } + + private static Set desiredUserRoleAssignments( + List assignments, + Map roleChanges, + RepresentativeAccessIndex accessIndex) { + Set desiredAssignments = new LinkedHashSet<>(accessIndex.primaryUserAssignments()); + assignments.forEach(assignment -> { + Set currentRepresentativeRoles = accessIndex.rolesFor(assignment); + if (currentRepresentativeRoles.isEmpty()) { + desiredAssignments.add(new UserRoleAssignment(assignment.getUserId(), + roleChanges.getOrDefault(assignment.getCaseRole(), assignment.getCaseRole()))); + } else { + currentRepresentativeRoles.forEach(role -> desiredAssignments.add( + new UserRoleAssignment(assignment.getUserId(), role))); + } + }); + return desiredAssignments; + } + + private static RepresentativeAccessIndex representativeAccessIndex(CaseData caseData) { + Map> rolesByUserId = new LinkedHashMap<>(); + Map> rolesByOrganisationId = new LinkedHashMap<>(); + if (ObjectUtils.isEmpty(caseData) || CollectionUtils.isEmpty(caseData.getRepCollection())) { + return new RepresentativeAccessIndex(rolesByUserId, rolesByOrganisationId); + } + + caseData.getRepCollection().stream() + .filter(RespondentRepresentativeUtils::isValidRepresentative) + .map(RepresentedTypeRItem::getValue) + .filter(representative -> RoleUtils.isRespondentRepresentativeRole(representative.getRole())) + .forEach(representative -> addRepresentativeAccessTarget( + rolesByUserId, rolesByOrganisationId, representative)); + return new RepresentativeAccessIndex(rolesByUserId, rolesByOrganisationId); + } + + private static void addRepresentativeAccessTarget( + Map> rolesByUserId, + Map> rolesByOrganisationId, + RepresentedTypeR representative) { + addRole(rolesByUserId, representative.getIdamId(), representative.getRole()); + Organisation organisation = representative.getRespondentOrganisation(); + if (ObjectUtils.isNotEmpty(organisation)) { + addRole(rolesByOrganisationId, organisation.getOrganisationID(), representative.getRole()); + } + } + + private static void addRole(Map> rolesByIdentity, String identity, String role) { + if (StringUtils.isNotBlank(identity)) { + rolesByIdentity.computeIfAbsent(identity, ignored -> new LinkedHashSet<>()).add(role); + } + } + + private void rollbackRealignedAssignments( + String adminUserToken, String caseId, List addedAssignments) { + if (CollectionUtils.isEmpty(addedAssignments)) { + return; + } + + List assignmentsToRollback = addedAssignments.stream() + .map(assignment -> CaseUserAssignment.builder() + .caseId(caseId) + .userId(assignment.userId()) + .caseRole(assignment.caseRole()) + .build()) + .toList(); + try { + nocCcdService.revokeCaseAssignments(adminUserToken, CaseUserAssignmentData.builder() + .caseUserAssignments(assignmentsToRollback) + .build()); + } catch (RuntimeException rollbackException) { + log.error("Failed to roll back respondent representative role realignment for case {}", caseId, + rollbackException); + } + } + + /** + * This is used to compare “current access” vs. “desired access” during representative access realignment, + * and also to dedupe revocations when the same deleted representative has multiple records. + */ + private record UserRoleAssignment(String userId, String caseRole) { + private static UserRoleAssignment from(CaseUserAssignment assignment) { + return new UserRoleAssignment(assignment.getUserId(), assignment.getCaseRole()); + } + } + + /** + * This indexes the current repCollection. + * During respondent reorder realignment, it answers “for this existing CCD assignment, + * what roles should this user/organization currently have?” + * That is how the service works out which roles to grant and which old roles to revoke. + */ + private record RepresentativeAccessIndex( + Map> rolesByUserId, + Map> rolesByOrganisationId) { + + private Set rolesFor(CaseUserAssignment assignment) { + Set roles = new LinkedHashSet<>(); + roles.addAll(rolesByUserId.getOrDefault(assignment.getUserId(), Set.of())); + roles.addAll(rolesByOrganisationId.getOrDefault(assignment.getOrganisationId(), Set.of())); + return roles; + } + + private Set primaryUserAssignments() { + Set assignments = new LinkedHashSet<>(); + rolesByUserId.forEach((userId, roles) -> roles.forEach( + role -> assignments.add(new UserRoleAssignment(userId, role)))); + return assignments; + } + } + /** * Identifies respondent representatives removed between the previous and current case states, * sends removal notifications, and revokes their access by updating the case data. @@ -366,36 +609,30 @@ public List revokeOldRespondentRepresentativeAccess( || CollectionUtils.isEmpty(caseUserAssignments.getCaseUserAssignments())) { return Collections.emptyList(); } - // finds list of representatives whose assignment is revoked + List respondentRepresentativeAssignments = caseUserAssignments.getCaseUserAssignments() + .stream() + .filter(NocRespondentRepresentativeService::isValidRespondentRepresentativeAssignment) + .toList(); List representativesToRevoke = new ArrayList<>(); List caseUserAssignmentsToRevoke = new ArrayList<>(); - for (CaseUserAssignment caseUserAssignment : caseUserAssignments.getCaseUserAssignments()) { - if (!RoleUtils.isRespondentRepresentativeRole(caseUserAssignment.getCaseRole())) { + Set caseUserAssignmentsToRevokeIndex = new LinkedHashSet<>(); + for (RepresentedTypeRItem representative : representativesToRemove) { + if (!RespondentRepresentativeUtils.isValidRepresentative(representative)) { continue; } - for (RepresentedTypeRItem representative : representativesToRemove) { - String respondentName = RoleUtils.findRespondentNameByRole(oldCaseDetails.getCaseData(), - caseUserAssignment.getCaseRole()); - if (!RespondentRepresentativeUtils.isEligibleForAccessRevocation(representative, caseUserAssignment, - respondentName)) { - continue; - } - representativesToRevoke.add(representative); - caseUserAssignmentsToRevoke.add(caseUserAssignment); - // Assignments automatically created by CCD for representatives linked to other respondents. - // These are not recorded in the representative collection, but are added to support same company's - // representatives. This auto assignments business is still in architectural design check. - List remainingCaseUserAssignments = new ArrayList<>(caseUserAssignments - .getCaseUserAssignments()); - remainingCaseUserAssignments.remove(caseUserAssignment); - ClaimantRepresentativeUtils.removeClaimantRepresentativeAssignment(remainingCaseUserAssignments); - List otherAssignmentsToRemove = - findCaseAssignmentsToRevokeForRep(callbackRequest.getCaseDetails().getCaseId(), - remainingCaseUserAssignments, representative, caseUserAssignment.getCaseRole()); - if (CollectionUtils.isNotEmpty(otherAssignmentsToRemove)) { - caseUserAssignmentsToRevoke.addAll(otherAssignmentsToRemove); - } + List assignmentsForRepresentative = findCaseAssignmentsToRevokeForRep( + oldCaseDetails.getCaseId(), + respondentRepresentativeAssignments, + representative); + if (CollectionUtils.isEmpty(assignmentsForRepresentative)) { + continue; } + representativesToRevoke.add(representative); + assignmentsForRepresentative.forEach(assignment -> { + if (caseUserAssignmentsToRevokeIndex.add(UserRoleAssignment.from(assignment))) { + caseUserAssignmentsToRevoke.add(assignment); + } + }); } try { revokeCaseAssignments(userToken, caseUserAssignmentsToRevoke); @@ -409,17 +646,13 @@ public List revokeOldRespondentRepresentativeAccess( /** * Finds the case user assignments that should be revoked for the given representative. * - *

The method looks up the representative's user identifier using their email address, then - * filters the provided case user assignments to find assignments belonging to that representative. - * If the case no longer contains a matching representative with the same respondent ID and email - * address, those existing assignments are returned for revocation.

+ *

The method uses the representative's idam ID when available, otherwise it looks up the user + * identifier using their email address. It then filters the provided case user assignments to find + * respondent representative assignments belonging to that representative.

* - *

If the case details, representative details, case assignments, or representative email address - * are missing, an empty list is returned. An empty list is also returned if the representative user - * lookup fails.

- * - *

If the case representative collection is empty, all existing assignments for the representative - * are returned, as there are no remaining representative records on the case.

+ *

If the case details, representative details, case assignments, and both representative idam ID + * and email address are missing, an empty list is returned. An empty list is also returned if the + * representative user lookup fails.

* * @param caseUserAssignments the existing case user assignments for the case * @param representative the representative whose assignments should be checked for revocation @@ -428,42 +661,41 @@ public List revokeOldRespondentRepresentativeAccess( */ public List findCaseAssignmentsToRevokeForRep(String caseId, List caseUserAssignments, - RepresentedTypeRItem representative, - String role) { + RepresentedTypeRItem representative) { if (StringUtils.isBlank(caseId) || CollectionUtils.isEmpty(caseUserAssignments) || ObjectUtils.isEmpty(representative) || ObjectUtils.isEmpty(representative.getValue()) - || StringUtils.isEmpty(representative.getValue().getRepresentativeEmailAddress())) { + || (StringUtils.isBlank(representative.getValue().getIdamId()) + && StringUtils.isBlank(representative.getValue().getRepresentativeEmailAddress()))) { + return new ArrayList<>(); + } + String representativeUserId = representativeUserId(caseId, representative); + if (StringUtils.isBlank(representativeUserId)) { return new ArrayList<>(); } - AccountIdByEmailResponse accountIdByEmailResponse; + return RespondentRepresentativeUtils + .findCaseUserAssignmentsByRepresentativeId(caseUserAssignments, representativeUserId) + .stream() + .filter(NocRespondentRepresentativeService::isValidRespondentRepresentativeAssignment) + .toList(); + } + + private String representativeUserId(String caseId, RepresentedTypeRItem representative) { + String idamId = representative.getValue().getIdamId(); + if (StringUtils.isNotBlank(idamId)) { + return idamId; + } try { - accountIdByEmailResponse = nocService.findUserByEmail( - adminUserService.getAdminUserToken(), representative.getValue().getRepresentativeEmailAddress(), + AccountIdByEmailResponse accountIdByEmailResponse = nocService.findUserByEmail( + adminUserService.getAdminUserToken(), + representative.getValue().getRepresentativeEmailAddress(), caseId); + return accountIdByEmailResponse == null ? StringUtils.EMPTY : accountIdByEmailResponse.getUserIdentifier(); } catch (GenericServiceException e) { log.warn(e.getMessage()); - return new ArrayList<>(); - } - List representativeRemainingAssignments = RespondentRepresentativeUtils - .findCaseUserAssignmentsByRepresentativeId(caseUserAssignments, - accountIdByEmailResponse.getUserIdentifier()); - List caseUserAssignmentsToRevoke = new ArrayList<>(); - // finds representative's other case assignments - for (CaseUserAssignment caseUserAssignment : representativeRemainingAssignments) { - if (NocUtils.countAssignmentsByRole(caseUserAssignments, caseUserAssignment.getCaseRole()) > 1) { - caseUserAssignmentsToRevoke.add(caseUserAssignment); - } - } - caseUserAssignments.removeAll(caseUserAssignmentsToRevoke); - // finds role's other case assignments - List caseUserAssignmentsByRole = - NocUtils.filterCaseUserAssignmentsByRole(caseUserAssignments, role); - if (CollectionUtils.isNotEmpty(caseUserAssignmentsByRole)) { - caseUserAssignmentsToRevoke.addAll(caseUserAssignmentsByRole); + return StringUtils.EMPTY; } - return caseUserAssignmentsToRevoke; } /** diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocService.java index b365b44e0f..7bfddb91d5 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocService.java @@ -217,7 +217,7 @@ public AccountIdByEmailResponse findUserByEmail(String accessToken, * @param caseId the identifier of the case to which access is being granted * @param caseRole the case role to assign to the user */ - public void grantCaseAccess(String userId, String caseId, String caseRole) { + public boolean grantCaseAccess(String userId, String caseId, String caseRole) { CaseAssignmentUserRole caseAssignmentUserRole = CaseAssignmentUserRole.builder() .userId(userId) .caseDataId(caseId) @@ -227,8 +227,10 @@ public void grantCaseAccess(String userId, String caseId, String caseRole) { caseAssignment.addCaseUserRole(CaseAssignmentUserRolesRequest.builder() .caseAssignmentUserRoles(List.of(caseAssignmentUserRole)) .build()); + return true; } catch (IOException e) { log.error("Failed to add case assignment user role", e); + return false; } } } diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java index 136657f76b..e3f7a481ec 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java @@ -21,6 +21,7 @@ import uk.gov.hmcts.ecm.common.model.helper.DefaultValues; import uk.gov.hmcts.ecm.common.model.helper.TribunalOffice; import uk.gov.hmcts.et.common.model.ccd.CCDRequest; +import uk.gov.hmcts.et.common.model.ccd.CallbackRequest; import uk.gov.hmcts.et.common.model.ccd.CaseData; import uk.gov.hmcts.et.common.model.ccd.CaseDetails; import uk.gov.hmcts.et.common.model.ccd.SubmitEvent; @@ -93,6 +94,7 @@ class CaseActionsForCaseWorkerControllerTest extends BaseControllerTest { private static final String AMEND_CASE_DETAILS_URL = "/amendCaseDetails"; private static final String AMEND_CLAIMANT_DETAILS_URL = "/amendClaimantDetails"; private static final String AMEND_RESPONDENT_DETAILS_URL = "/amendRespondentDetails"; + private static final String AMEND_RESPONDENT_DETAILS_SUBMITTED_URL = "/amendRespondentDetailsSubmitted"; private static final String AMEND_RESPONDENT_REPRESENTATIVE_URL = "/amendRespondentRepresentative"; private static final String UPDATE_HEARING_URL = "/updateHearing"; private static final String RESTRICTED_CASES_URL = "/restrictedCases"; @@ -240,6 +242,8 @@ public void setUp() { .tribunalCorrespondenceDX("123456") .tribunalCorrespondenceEmail("manchester@gmail.com") .build(); + when(nocRespondentRepresentativeService.prepopulateOrgPolicyAndNoc(any(CaseData.class))) + .thenAnswer(invocation -> invocation.getArgument(0)); } @ParameterizedTest @@ -406,6 +410,9 @@ void amendRespondentDetails() { .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); verify(caseFlagsService, times(0)).setupCaseFlags(any(CaseData.class)); + verify(nocRespondentHelper, times(1)).amendRespondentNameRepresentativeNames(any(CaseData.class)); + verify(nocRespondentRepresentativeService, times(1)) + .prepopulateOrgPolicyAndNoc(any(CaseData.class)); } @Test @@ -448,6 +455,7 @@ void amendRespondentDetails_moreThan10Respondents() { .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); verify(nocRespondentHelper, times(0)).amendRespondentNameRepresentativeNames(any(CaseData.class)); + verify(nocRespondentRepresentativeService, never()).prepopulateOrgPolicyAndNoc(any(CaseData.class)); } @Test @@ -469,6 +477,7 @@ void amendRespondentDetails_noRepCollection() { .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); verify(nocRespondentHelper, times(0)).amendRespondentNameRepresentativeNames(any(CaseData.class)); + verify(nocRespondentRepresentativeService, never()).prepopulateOrgPolicyAndNoc(any(CaseData.class)); } @Test @@ -513,6 +522,28 @@ void amendRespondentDetailsContinuingClaim() { .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); } + @Test + @SneakyThrows + void amendRespondentDetailsSubmittedRealignsRepresentativeAccess() { + CaseDetails previousCaseDetails = new CaseDetails(); + previousCaseDetails.setCaseId(ccdRequest.getCaseDetails().getCaseId()); + previousCaseDetails.setCaseData(new CaseData()); + CallbackRequest callbackRequest = CallbackRequest.builder() + .caseDetailsBefore(previousCaseDetails) + .caseDetails(ccdRequest.getCaseDetails()) + .build(); + when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); + + mvc.perform(post(AMEND_RESPONDENT_DETAILS_SUBMITTED_URL) + .content(jsonMapper.toJson(callbackRequest)) + .header(AUTHORIZATION, AUTH_TOKEN) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + + verify(nocRespondentRepresentativeService) + .realignRespondentRepresentativeAccess(any(CallbackRequest.class)); + } + @Test @SneakyThrows void updateHearing() { diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/RespondentRepresentativeControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/RespondentRepresentativeControllerTest.java index 44a91e8917..f5af010acd 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/RespondentRepresentativeControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/RespondentRepresentativeControllerTest.java @@ -25,6 +25,8 @@ import uk.gov.hmcts.ethos.replacement.docmosis.exceptions.GenericRuntimeException; import uk.gov.hmcts.ethos.replacement.docmosis.exceptions.GenericServiceException; import uk.gov.hmcts.ethos.replacement.docmosis.helpers.NocRespondentHelper; +import uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService; +import uk.gov.hmcts.ethos.replacement.docmosis.service.FeatureToggleService; import uk.gov.hmcts.ethos.replacement.docmosis.service.VerifyTokenService; import uk.gov.hmcts.ethos.replacement.docmosis.service.noc.NocRespondentRepresentativeService; import uk.gov.hmcts.ethos.replacement.docmosis.utils.JsonMapper; @@ -38,6 +40,10 @@ import static org.hamcrest.Matchers.nullValue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; @@ -84,6 +90,10 @@ class RespondentRepresentativeControllerTest { private NocRespondentHelper nocRespondentHelper; @MockitoBean private NocRespondentRepresentativeService nocRespondentRepresentativeService; + @MockitoBean + private FeatureToggleService featureToggleService; + @MockitoBean + private CaseFlagsService caseFlagsService; @Autowired private JsonMapper jsonMapper; @@ -91,6 +101,8 @@ class RespondentRepresentativeControllerTest { @BeforeEach void setUp() { when(verifyTokenService.verifyTokenSignature(DUMMY_TOKEN)).thenReturn(true); + when(nocRespondentRepresentativeService.validateRespondentRepresentativesOrganisationMatch( + any(CaseDetails.class))).thenReturn(List.of()); } @Test @@ -158,6 +170,28 @@ void testRemoveOwnRepresentative_withRepCollection() throws Exception { .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); } + @Test + void testRemoveOwnRepresentativeSetsUpCaseFlagsWhenRequired() throws Exception { + CaseData caseData = CaseDataBuilder.builder().build(); + RepresentedTypeRItem representedTypeRItem = RepresentedTypeRItem.builder().id(ID_REPRESENTATIVE_1).build(); + caseData.setRepCollection(List.of(representedTypeRItem)); + caseData.setRepCollectionToRemove(List.of(representedTypeRItem)); + CCDRequest ccdRequest = CCDRequestBuilder.builder().withCaseData(caseData).build(); + when(featureToggleService.isCaseFlagsEnabled()).thenReturn(true); + when(caseFlagsService.caseFlagsSetupRequired(any(CaseData.class))).thenReturn(true); + + mockMvc.perform(post(URL_REMOVE_OWN_REPRESENTATIVE) + .contentType(MediaType.APPLICATION_JSON) + .header(HEADER_AUTHORIZATION, DUMMY_TOKEN) + .content(jsonMapper.toJson(ccdRequest))) + .andExpect(status().isOk()) + .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) + .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) + .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); + + verify(caseFlagsService, times(1)).setupCaseFlags(any(CaseData.class)); + } + @Test @SneakyThrows void amendRespondentRepresentativeAboutToStart() { @@ -208,6 +242,106 @@ void amendRespondentRepresentativeAboutToSubmit() { } + @Test + @SneakyThrows + void amendRespondentRepresentativeAboutToSubmitSetsUpCaseFlagsWhenNameChanges() { + CaseData previousCaseData = new CaseData(); + previousCaseData.setRepCollection(List.of(RepresentedTypeRItem.builder().id(ID_REPRESENTATIVE_1).value( + RepresentedTypeR.builder() + .nameOfRepresentative("Previous Representative Name") + .respondentId(ID_RESPONDENT_1) + .respRepName(RESPONDENT_NAME_1) + .build()).build())); + CaseData caseData = new CaseData(); + RespondentSumTypeItem respondent = new RespondentSumTypeItem(); + respondent.setValue(RespondentSumType.builder().respondentName(RESPONDENT_NAME_1).build()); + respondent.setId(ID_RESPONDENT_1); + caseData.setRespondentCollection(List.of(respondent)); + DynamicFixedListType dynamicFixedListType = new DynamicFixedListType(); + DynamicValueType dynamicValueType = new DynamicValueType(); + dynamicValueType.setLabel(RESPONDENT_NAME_1); + dynamicFixedListType.setValue(dynamicValueType); + caseData.setRepCollection(List.of(RepresentedTypeRItem.builder().id(ID_REPRESENTATIVE_1).value( + RepresentedTypeR.builder().dynamicRespRepName(dynamicFixedListType) + .nameOfRepresentative(REPRESENTATIVE_NAME).build()).build())); + CaseDetails caseDetails = new CaseDetails(); + caseDetails.setCaseId(DUMMY_SUBMISSION_REFERENCE); + caseDetails.setCaseData(caseData); + CaseDetails caseDetailsBefore = new CaseDetails(); + caseDetailsBefore.setCaseId(DUMMY_SUBMISSION_REFERENCE); + caseDetailsBefore.setCaseData(previousCaseData); + CallbackRequest callbackRequest = CallbackRequest.builder() + .caseDetails(caseDetails) + .caseDetailsBefore(caseDetailsBefore) + .build(); + when(featureToggleService.isCaseFlagsEnabled()).thenReturn(true); + + mockMvc.perform(post(URL_AMEND_RESPONDENT_REPRESENTATIVE_ABOUT_TO_SUBMIT) + .content(jsonMapper.toJson(callbackRequest)) + .header(HEADER_AUTHORIZATION, DUMMY_TOKEN) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) + .andExpect(jsonPath(JsonMapper.ERRORS, empty())) + .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); + + verify(caseFlagsService, times(1)).clearRespondentRepresentativeFlags( + any(CaseData.class), eq(List.of(0))); + verify(caseFlagsService, times(1)).setupCaseFlags(any(CaseData.class)); + } + + @Test + @SneakyThrows + void amendRespondentRepresentativeAboutToSubmitClearsAndSetsUpCaseFlagsWhenOnlyEmailChanges() { + CaseData previousCaseData = new CaseData(); + previousCaseData.setRepCollection(List.of(RepresentedTypeRItem.builder().id(ID_REPRESENTATIVE_1).value( + RepresentedTypeR.builder() + .nameOfRepresentative(REPRESENTATIVE_NAME) + .respondentId(ID_RESPONDENT_1) + .respRepName(RESPONDENT_NAME_1) + .representativeEmailAddress("old@example.com") + .build()).build())); + CaseData caseData = new CaseData(); + RespondentSumTypeItem respondent = new RespondentSumTypeItem(); + respondent.setValue(RespondentSumType.builder().respondentName(RESPONDENT_NAME_1).build()); + respondent.setId(ID_RESPONDENT_1); + caseData.setRespondentCollection(List.of(respondent)); + DynamicFixedListType dynamicFixedListType = new DynamicFixedListType(); + DynamicValueType dynamicValueType = new DynamicValueType(); + dynamicValueType.setLabel(RESPONDENT_NAME_1); + dynamicFixedListType.setValue(dynamicValueType); + caseData.setRepCollection(List.of(RepresentedTypeRItem.builder().id(ID_REPRESENTATIVE_1).value( + RepresentedTypeR.builder() + .dynamicRespRepName(dynamicFixedListType) + .nameOfRepresentative(REPRESENTATIVE_NAME) + .representativeEmailAddress("new@example.com") + .build()).build())); + CaseDetails caseDetails = new CaseDetails(); + caseDetails.setCaseId(DUMMY_SUBMISSION_REFERENCE); + caseDetails.setCaseData(caseData); + CaseDetails caseDetailsBefore = new CaseDetails(); + caseDetailsBefore.setCaseId(DUMMY_SUBMISSION_REFERENCE); + caseDetailsBefore.setCaseData(previousCaseData); + CallbackRequest callbackRequest = CallbackRequest.builder() + .caseDetails(caseDetails) + .caseDetailsBefore(caseDetailsBefore) + .build(); + when(featureToggleService.isCaseFlagsEnabled()).thenReturn(true); + + mockMvc.perform(post(URL_AMEND_RESPONDENT_REPRESENTATIVE_ABOUT_TO_SUBMIT) + .content(jsonMapper.toJson(callbackRequest)) + .header(HEADER_AUTHORIZATION, DUMMY_TOKEN) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) + .andExpect(jsonPath(JsonMapper.ERRORS, empty())) + .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); + + verify(caseFlagsService, times(1)).clearRespondentRepresentativeFlags( + any(CaseData.class), eq(List.of(0))); + verify(caseFlagsService, times(1)).setupCaseFlags(any(CaseData.class)); + } + @Test @SneakyThrows void amendRespondentRepresentativeAboutToSubmitWithError() { @@ -235,6 +369,8 @@ void amendRespondentRepresentativeAboutToSubmitWithError() { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, notNullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); + + verify(caseFlagsService, never()).setupCaseFlags(any(CaseData.class)); } @Test diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/helpers/NocRespondentHelperTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/helpers/NocRespondentHelperTest.java index f12413c0b3..45aca5e891 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/helpers/NocRespondentHelperTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/helpers/NocRespondentHelperTest.java @@ -244,25 +244,31 @@ void shouldReturnRespondent() { } @Test - void amendRespondentNameRepresentativeNames() { + void amendRespondentNameRepresentativeNamesReordersRepresentativesAndRolesWithRespondents() { RespondentSumTypeItem amendedRespondent = caseData.getRespondentCollection().get(2); amendedRespondent.getValue().setRespondentName(AMENDED_RESP_NAME); nocRespondentHelper.amendRespondentNameRepresentativeNames(caseData); RepresentedTypeR rep = caseData.getRepCollection().getFirst().getValue(); - assertThat(rep.getDynamicRespRepName().getSelectedCode()).isEqualTo("R: " + AMENDED_RESP_NAME); - assertThat(rep.getDynamicRespRepName().getSelectedLabel()).isEqualTo(AMENDED_RESP_NAME); - assertThat(rep.getRespRepName()).isEqualTo(AMENDED_RESP_NAME); + assertThat(caseData.getRepCollection().getFirst().getId()).isEqualTo(RESPONDENT_REP_ID_THREE); + assertThat(rep.getRole()).isEqualTo(SOLICITORA); + assertThat(rep.getDynamicRespRepName().getSelectedCode()).isEqualTo("R: " + RESPONDENT_NAME_ONE); + assertThat(rep.getDynamicRespRepName().getSelectedLabel()).isEqualTo(RESPONDENT_NAME_ONE); + assertThat(rep.getRespRepName()).isEqualTo(RESPONDENT_NAME_ONE); rep = caseData.getRepCollection().get(1).getValue(); + assertThat(caseData.getRepCollection().get(1).getId()).isEqualTo(RESPONDENT_REP_ID_TWO); + assertThat(rep.getRole()).isEqualTo(SOLICITORB); assertThat(rep.getDynamicRespRepName().getSelectedCode()).isEqualTo("R: " + RESPONDENT_NAME_TWO); assertThat(rep.getDynamicRespRepName().getSelectedLabel()).isEqualTo(RESPONDENT_NAME_TWO); assertThat(rep.getRespRepName()).isEqualTo(RESPONDENT_NAME_TWO); rep = caseData.getRepCollection().get(2).getValue(); - assertThat(rep.getDynamicRespRepName().getSelectedCode()).isEqualTo("R: " + RESPONDENT_NAME_ONE); - assertThat(rep.getDynamicRespRepName().getSelectedLabel()).isEqualTo(RESPONDENT_NAME_ONE); - assertThat(rep.getRespRepName()).isEqualTo(RESPONDENT_NAME_ONE); + assertThat(caseData.getRepCollection().get(2).getId()).isEqualTo(RESPONDENT_REP_ID); + assertThat(rep.getRole()).isEqualTo(SOLICITORC); + assertThat(rep.getDynamicRespRepName().getSelectedCode()).isEqualTo("R: " + AMENDED_RESP_NAME); + assertThat(rep.getDynamicRespRepName().getSelectedLabel()).isEqualTo(AMENDED_RESP_NAME); + assertThat(rep.getRespRepName()).isEqualTo(AMENDED_RESP_NAME); } @Test diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/helpers/NoticeOfChangeFieldPopulatorTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/helpers/NoticeOfChangeFieldPopulatorTest.java index 9e0bfc64f4..ef06fd663f 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/helpers/NoticeOfChangeFieldPopulatorTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/helpers/NoticeOfChangeFieldPopulatorTest.java @@ -179,4 +179,39 @@ void shouldGenerateClaimantOrganisationPolicyWithOrganisationWhenPresent() { assertThat(claimantPolicy.getOrgPolicyCaseAssignedRole()).isEqualTo("[CLAIMANTSOLICITOR]"); assertThat(claimantPolicy.getOrganisation()).isEqualTo(claimantOrganisation); } + + @Test + void shouldGenerateRespondentOrganisationPoliciesUsingCurrentRespondentOrder() { + caseData.setRespondentCollection(new ArrayList<>()); + caseData.getRespondentCollection().add(respondent1); + caseData.getRespondentCollection().add(respondent3); + caseData.getRespondentCollection().add(respondent2); + + when(policyConverter.generate(SolicitorRole.SOLICITORA, Optional.of(respondentRep1))).thenReturn( + ORG_POLICY_A); + when(policyConverter.generate(SolicitorRole.SOLICITORB, Optional.of(respondentRep3))).thenReturn( + ORG_POLICY_B); + when(policyConverter.generate(SolicitorRole.SOLICITORC, Optional.of(respondentRep2))).thenReturn( + ORG_POLICY_C); + when(policyConverter.generate(SolicitorRole.SOLICITORD, Optional.empty())).thenReturn(ORG_POLICY_D); + when(policyConverter.generate(SolicitorRole.SOLICITORE, Optional.empty())).thenReturn(ORG_POLICY_E); + when(policyConverter.generate(SolicitorRole.SOLICITORF, Optional.empty())).thenReturn(ORG_POLICY_F); + when(policyConverter.generate(SolicitorRole.SOLICITORG, Optional.empty())).thenReturn(ORG_POLICY_G); + when(policyConverter.generate(SolicitorRole.SOLICITORH, Optional.empty())).thenReturn(ORG_POLICY_H); + when(policyConverter.generate(SolicitorRole.SOLICITORI, Optional.empty())).thenReturn(ORG_POLICY_I); + when(policyConverter.generate(SolicitorRole.SOLICITORJ, Optional.empty())).thenReturn(ORG_POLICY_J); + + when(answersConverter.generateForSubmission(eq(respondent1), any())).thenReturn(ANSWERS_1); + when(answersConverter.generateForSubmission(eq(respondent2), any())).thenReturn(ANSWERS_2); + when(answersConverter.generateForSubmission(eq(respondent3), any())).thenReturn(ANSWERS_3); + + final Map data = noticeOfChangeFieldPopulator.generate(caseData); + + assertThat(data.get("noticeOfChangeAnswers0")).isEqualTo(ANSWERS_1); + assertThat(data.get("noticeOfChangeAnswers1")).isEqualTo(ANSWERS_3); + assertThat(data.get("noticeOfChangeAnswers2")).isEqualTo(ANSWERS_2); + assertThat(data.get("respondentOrganisationPolicy0")).isEqualTo(ORG_POLICY_A); + assertThat(data.get("respondentOrganisationPolicy1")).isEqualTo(ORG_POLICY_B); + assertThat(data.get("respondentOrganisationPolicy2")).isEqualTo(ORG_POLICY_C); + } } diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java index 7f6fd91d67..8940a17d31 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java @@ -80,9 +80,6 @@ class CaseFlagsServiceTest { public static final String CLAIMANT_REPRESENTATIVE_NAME = "Claimant Representative Name"; public static final String REPRESENTATIVE_NAME = "Representative Name"; public static final String RESPONDENT_NAME = "Respondent Name"; - private static final String RESPONDENT_NOT_CONTINUING_FLAG_COMMENT = - "The claim against the respondent is not continuing"; - private static final String RESPONDENT_STRUCK_OUT_FLAG_COMMENT = "The respondent has been struck out"; private CaseFlagsService caseFlagsService; private CaseData caseData; @@ -233,6 +230,206 @@ void setupCaseFlags_shouldOnlyCreateRespondentRepresentativeFlagsForExistingRepr }); } + @Test + void setupCaseFlags_shouldReuseRespondentRepresentativeFlagsForTheSameRepresentativeWithoutCompactingSlots() { + String sharedRepresentativeName = "Shared Representative"; + String otherRepresentativeName = "Other Representative"; + caseData.setRepCollection(List.of( + representativeItem("1", sharedRepresentativeName), + representativeItem("2", sharedRepresentativeName), + representativeItem("3", otherRepresentativeName) + )); + + caseFlagsService.setupCaseFlags(caseData); + + AllPartyFlags allPartyFlags = allPartyFlags(caseData); + assertAll( + () -> assertEquals(sharedRepresentativeName, allPartyFlags.getRepresentativeFlags().getPartyName()), + () -> assertEquals(REPRESENTATIVE1, allPartyFlags.getRepresentativeFlags().getRoleOnCase()), + () -> assertEquals(INTERNAL, allPartyFlags.getRepresentativeFlags().getVisibility()), + () -> assertEquals(sharedRepresentativeName, + allPartyFlags.getRepresentativeExternalFlags().getPartyName()), + () -> assertEquals(REPRESENTATIVE1, allPartyFlags.getRepresentativeExternalFlags().getRoleOnCase()), + () -> assertEquals(EXTERNAL, allPartyFlags.getRepresentativeExternalFlags().getVisibility()), + () -> assertNull(allPartyFlags.getRepresentative1Flags()), + () -> assertNull(allPartyFlags.getRepresentative1ExternalFlags()), + () -> assertEquals(otherRepresentativeName, allPartyFlags.getRepresentative2Flags().getPartyName()), + () -> assertEquals(REPRESENTATIVE3, allPartyFlags.getRepresentative2Flags().getRoleOnCase()), + () -> assertEquals(INTERNAL, allPartyFlags.getRepresentative2Flags().getVisibility()), + () -> assertEquals(otherRepresentativeName, + allPartyFlags.getRepresentative2ExternalFlags().getPartyName()), + () -> assertEquals(REPRESENTATIVE3, + allPartyFlags.getRepresentative2ExternalFlags().getRoleOnCase()), + () -> assertEquals(EXTERNAL, allPartyFlags.getRepresentative2ExternalFlags().getVisibility()), + () -> assertFalse(caseFlagsService.caseFlagsSetupRequired(caseData)) + ); + } + + @Test + void setupCaseFlags_shouldCreateSeparateRespondentRepresentativeFlagsForSameNameWithDifferentEmails() { + String sharedRepresentativeName = "Shared Representative"; + caseData.setRepCollection(List.of( + representativeItem("1", sharedRepresentativeName, "first@example.com"), + representativeItem("2", sharedRepresentativeName, "second@example.com") + )); + + caseFlagsService.setupCaseFlags(caseData); + AllPartyFlags allPartyFlags = allPartyFlags(caseData); + allPartyFlags.getRepresentativeFlags().setDetails(ListTypeItem.from(activeFlag("First representative flag"))); + allPartyFlags.getRepresentative1Flags().setDetails(ListTypeItem.from(activeFlag("Second representative flag"))); + + caseFlagsService.setupCaseFlags(caseData); + + assertAll( + () -> assertEquals(sharedRepresentativeName, allPartyFlags.getRepresentativeFlags().getPartyName()), + () -> assertEquals(REPRESENTATIVE1, allPartyFlags.getRepresentativeFlags().getRoleOnCase()), + () -> assertEquals("First representative flag", + allPartyFlags.getRepresentativeFlags().getDetails().getFirst().getValue().getName()), + () -> assertEquals(sharedRepresentativeName, allPartyFlags.getRepresentative1Flags().getPartyName()), + () -> assertEquals(REPRESENTATIVE2, allPartyFlags.getRepresentative1Flags().getRoleOnCase()), + () -> assertEquals("Second representative flag", + allPartyFlags.getRepresentative1Flags().getDetails().getFirst().getValue().getName()), + () -> assertFalse(caseFlagsService.caseFlagsSetupRequired(caseData)) + ); + } + + @Test + void caseFlagsSetupRequired_shouldBeTrueWhenCompactedRepresentativeNeedsMovingToRoleAlignedSlot() { + String representative1Name = "Representative 1"; + String representative2Name = "Representative 2"; + caseData.setRepCollection(List.of( + representativeItem("1", representative1Name), + representativeItem("2", representative1Name), + representativeItem("3", representative2Name) + )); + AllPartyFlags allPartyFlags = getOrCreateAllPartyFlags(caseData); + allPartyFlags.setCaseFlags(CaseFlagsType.builder().build()); + allPartyFlags.setRepresentativeFlags(representativeFlags( + representative1Name, REPRESENTATIVE1, INTERNAL, "Representative 1 internal flag")); + allPartyFlags.setRepresentativeExternalFlags(representativeFlags( + representative1Name, REPRESENTATIVE1, EXTERNAL, "Representative 1 external flag")); + allPartyFlags.setRepresentative1Flags(representativeFlags( + representative2Name, REPRESENTATIVE2, INTERNAL, "Representative 2 compacted internal flag")); + allPartyFlags.setRepresentative1ExternalFlags(representativeFlags( + representative2Name, REPRESENTATIVE2, EXTERNAL, "Representative 2 compacted external flag")); + + assertTrue(caseFlagsService.caseFlagsSetupRequired(caseData)); + + caseFlagsService.setupCaseFlags(caseData); + + assertAll( + () -> assertEquals(representative1Name, allPartyFlags.getRepresentativeFlags().getPartyName()), + () -> assertEquals(representative1Name, + allPartyFlags.getRepresentativeExternalFlags().getPartyName()), + () -> assertNull(allPartyFlags.getRepresentative1Flags()), + () -> assertNull(allPartyFlags.getRepresentative1ExternalFlags()), + () -> assertEquals(representative2Name, allPartyFlags.getRepresentative2Flags().getPartyName()), + () -> assertEquals(REPRESENTATIVE3, allPartyFlags.getRepresentative2Flags().getRoleOnCase()), + () -> assertEquals(INTERNAL, allPartyFlags.getRepresentative2Flags().getVisibility()), + () -> assertEquals("Representative 2 compacted internal flag", + allPartyFlags.getRepresentative2Flags().getDetails().getFirst().getValue().getName()), + () -> assertEquals(representative2Name, + allPartyFlags.getRepresentative2ExternalFlags().getPartyName()), + () -> assertEquals(REPRESENTATIVE3, + allPartyFlags.getRepresentative2ExternalFlags().getRoleOnCase()), + () -> assertEquals(EXTERNAL, allPartyFlags.getRepresentative2ExternalFlags().getVisibility()), + () -> assertEquals("Representative 2 compacted external flag", + allPartyFlags.getRepresentative2ExternalFlags().getDetails().getFirst().getValue().getName()), + () -> assertFalse(caseFlagsService.caseFlagsSetupRequired(caseData)) + ); + } + + @Test + void setupCaseFlags_shouldPreserveExistingDetailsWhenClearingDuplicateRepresentativeFlags() { + String sharedRepresentativeName = "Shared Representative"; + caseData.setRepCollection(List.of( + representativeItem("1", sharedRepresentativeName), + representativeItem("2", sharedRepresentativeName) + )); + caseFlagsService.setupCaseFlags(caseData); + allPartyFlags(caseData).getRepresentativeFlags().setDetails(null); + allPartyFlags(caseData).getRepresentativeExternalFlags().setDetails(null); + allPartyFlags(caseData).setRepresentative1Flags(CaseFlagsType.builder() + .partyName(sharedRepresentativeName) + .visibility(INTERNAL) + .details(ListTypeItem.from(activeFlag("Duplicate internal flag"))) + .build()); + allPartyFlags(caseData).setRepresentative1ExternalFlags(CaseFlagsType.builder() + .partyName(sharedRepresentativeName) + .visibility(EXTERNAL) + .details(ListTypeItem.from(activeFlag("Duplicate external flag"))) + .build()); + + caseFlagsService.setupCaseFlags(caseData); + + assertAll( + () -> assertEquals("Duplicate internal flag", + allPartyFlags(caseData).getRepresentativeFlags().getDetails().getFirst().getValue().getName()), + () -> assertEquals("Duplicate external flag", + allPartyFlags(caseData).getRepresentativeExternalFlags().getDetails().getFirst() + .getValue().getName()), + () -> assertNull(allPartyFlags(caseData).getRepresentative1Flags()), + () -> assertNull(allPartyFlags(caseData).getRepresentative1ExternalFlags()) + ); + } + + @Test + void setupCaseFlags_shouldKeepRoleAlignedSlotsWhenClearingDuplicateRepresentativeFlags() { + String representative1Name = "Representative 1"; + String representative2Name = "Representative 2"; + String representative3Name = "Representative 3"; + caseData.setRepCollection(List.of( + representativeItem("1", representative1Name), + representativeItem("2", representative2Name), + representativeItem("3", representative2Name), + representativeItem("4", representative3Name) + )); + AllPartyFlags allPartyFlags = getOrCreateAllPartyFlags(caseData); + allPartyFlags.setRepresentativeFlags(representativeFlags( + representative1Name, REPRESENTATIVE1, INTERNAL, "Representative 1 internal flag")); + allPartyFlags.setRepresentative1Flags(representativeFlags( + representative2Name, REPRESENTATIVE2, INTERNAL, "Representative 2 internal flag")); + allPartyFlags.setRepresentative2Flags(representativeFlags( + representative2Name, REPRESENTATIVE3, INTERNAL, "Duplicate representative 2 internal flag")); + allPartyFlags.setRepresentative3Flags(representativeFlags( + representative3Name, REPRESENTATIVE4, INTERNAL, "Representative 3 internal flag")); + allPartyFlags.setRepresentativeExternalFlags(representativeFlags( + representative1Name, REPRESENTATIVE1, EXTERNAL, "Representative 1 external flag")); + allPartyFlags.setRepresentative1ExternalFlags(representativeFlags( + representative2Name, REPRESENTATIVE2, EXTERNAL, "Representative 2 external flag")); + allPartyFlags.setRepresentative2ExternalFlags(representativeFlags( + representative2Name, REPRESENTATIVE3, EXTERNAL, "Duplicate representative 2 external flag")); + allPartyFlags.setRepresentative3ExternalFlags(representativeFlags( + representative3Name, REPRESENTATIVE4, EXTERNAL, "Representative 3 external flag")); + + caseFlagsService.setupCaseFlags(caseData); + + assertAll( + () -> assertEquals(representative1Name, allPartyFlags.getRepresentativeFlags().getPartyName()), + () -> assertEquals("Representative 1 internal flag", + allPartyFlags.getRepresentativeFlags().getDetails().getFirst().getValue().getName()), + () -> assertEquals(representative2Name, allPartyFlags.getRepresentative1Flags().getPartyName()), + () -> assertEquals("Representative 2 internal flag", + allPartyFlags.getRepresentative1Flags().getDetails().getFirst().getValue().getName()), + () -> assertEquals("Duplicate representative 2 internal flag", + allPartyFlags.getRepresentative1Flags().getDetails().get(1).getValue().getName()), + () -> assertNull(allPartyFlags.getRepresentative2Flags()), + () -> assertNull(allPartyFlags.getRepresentative2ExternalFlags()), + () -> assertEquals("Duplicate representative 2 external flag", + allPartyFlags.getRepresentative1ExternalFlags().getDetails().get(1).getValue().getName()), + () -> assertEquals(representative3Name, allPartyFlags.getRepresentative3Flags().getPartyName()), + () -> assertEquals(REPRESENTATIVE4, allPartyFlags.getRepresentative3Flags().getRoleOnCase()), + () -> assertEquals("Representative 3 internal flag", + allPartyFlags.getRepresentative3Flags().getDetails().getFirst().getValue().getName()), + () -> assertEquals(representative3Name, + allPartyFlags.getRepresentative3ExternalFlags().getPartyName()), + () -> assertEquals(REPRESENTATIVE4, + allPartyFlags.getRepresentative3ExternalFlags().getRoleOnCase()), + () -> assertEquals("Representative 3 external flag", + allPartyFlags.getRepresentative3ExternalFlags().getDetails().getFirst().getValue().getName()) + ); + } + @Test void setupCaseFlags_shouldNotCreateClaimantRepresentativeFlagsWhenClaimantRepresentativeIsAbsent() { caseData.setRepresentativeClaimantType(null); @@ -280,7 +477,7 @@ void rollbackCaseFlags_shouldNotCreateAllPartyFlagsWhenAbsent() { } @Test - void inactivateCaseFlags_shouldSetAllMatchingRespondentFlagDetailsInactive() { + void inactivateRespondentCaseFlags_shouldSetAllMatchingRespondentFlagDetailsInactive() { caseFlagsService.setupCaseFlags(caseData); CaseFlagsType respondentInternalFlags = allPartyFlags(caseData).getRespondent1Flags(); respondentInternalFlags.setDetails(ListTypeItem.from( @@ -295,17 +492,14 @@ void inactivateCaseFlags_shouldSetAllMatchingRespondentFlagDetailsInactive() { otherRespondentFlags.setDetails(ListTypeItem.from(activeFlag("Other respondent flag"))); claimantFlags.setDetails(ListTypeItem.from(activeFlag("Claimant flag"))); - caseFlagsService.inactivateCaseFlags(caseData, respondentName(1), RESPONDENT_NOT_CONTINUING_FLAG_COMMENT); + caseFlagsService.inactivateRespondentCaseFlags(caseData, respondentName(1)); assertEquals(INACTIVE, respondentInternalFlags.getDetails().get(0).getValue().getStatus()); assertEquals(INACTIVE, respondentInternalFlags.getDetails().get(1).getValue().getStatus()); assertEquals(INACTIVE, respondentExternalFlags.getDetails().getFirst().getValue().getStatus()); - assertEquals(RESPONDENT_NOT_CONTINUING_FLAG_COMMENT, - respondentInternalFlags.getDetails().get(0).getValue().getFlagComment()); - assertEquals(RESPONDENT_NOT_CONTINUING_FLAG_COMMENT, - respondentInternalFlags.getDetails().get(1).getValue().getFlagComment()); - assertEquals(RESPONDENT_NOT_CONTINUING_FLAG_COMMENT, - respondentExternalFlags.getDetails().getFirst().getValue().getFlagComment()); + assertNull(respondentInternalFlags.getDetails().get(0).getValue().getFlagComment()); + assertNull(respondentInternalFlags.getDetails().get(1).getValue().getFlagComment()); + assertNull(respondentExternalFlags.getDetails().getFirst().getValue().getFlagComment()); assertEquals(ACTIVE, otherRespondentFlags.getDetails().getFirst().getValue().getStatus()); assertEquals(ACTIVE, claimantFlags.getDetails().getFirst().getValue().getStatus()); assertNull(otherRespondentFlags.getDetails().getFirst().getValue().getFlagComment()); @@ -313,35 +507,260 @@ void inactivateCaseFlags_shouldSetAllMatchingRespondentFlagDetailsInactive() { } @Test - void inactivateCaseFlags_shouldUseProvidedCommentWhenInactivatingRespondentFlags() { + void inactivateRespondentCaseFlags_shouldIgnoreMissingPartyFlagsAndDetails() { + caseFlagsService.inactivateRespondentCaseFlags(caseData, RESPONDENT_NAME); + + assertNull(caseData.getAllPartyFlags()); + caseFlagsService.setupCaseFlags(caseData); - CaseFlagsType respondentInternalFlags = allPartyFlags(caseData).getRespondentFlags(); - CaseFlagsType respondentExternalFlags = allPartyFlags(caseData).getRespondentExternalFlags(); - respondentInternalFlags.setDetails(ListTypeItem.from(activeFlag("Internal flag"))); - respondentExternalFlags.setDetails(ListTypeItem.from(activeFlag("External flag"))); + allPartyFlags(caseData).getRespondentFlags().setDetails(null); - caseFlagsService.inactivateCaseFlags(caseData, RESPONDENT_NAME, RESPONDENT_STRUCK_OUT_FLAG_COMMENT); + caseFlagsService.inactivateRespondentCaseFlags(caseData, RESPONDENT_NAME); - assertEquals(INACTIVE, respondentInternalFlags.getDetails().getFirst().getValue().getStatus()); - assertEquals(INACTIVE, respondentExternalFlags.getDetails().getFirst().getValue().getStatus()); - assertEquals(RESPONDENT_STRUCK_OUT_FLAG_COMMENT, - respondentInternalFlags.getDetails().getFirst().getValue().getFlagComment()); - assertEquals(RESPONDENT_STRUCK_OUT_FLAG_COMMENT, - respondentExternalFlags.getDetails().getFirst().getValue().getFlagComment()); + assertNull(allPartyFlags(caseData).getRespondentFlags().getDetails()); } @Test - void inactivateCaseFlags_shouldIgnoreMissingPartyFlagsAndDetails() { - caseFlagsService.inactivateCaseFlags(caseData, RESPONDENT_NAME, RESPONDENT_NOT_CONTINUING_FLAG_COMMENT); + void inactivateRespondentRepresentativeCaseFlags_shouldInactivateRepresentativeWithNoOtherActiveRespondents() { + setupRepresentativeAccessScenario(); + RespondentSumTypeItem respondent1 = caseData.getRespondentCollection().getFirst(); + AllPartyFlags allPartyFlags = allPartyFlags(caseData); + allPartyFlags.getRepresentativeFlags() + .setDetails(ListTypeItem.from(activeFlag("Representative 1 internal flag"))); + allPartyFlags.getRepresentativeExternalFlags() + .setDetails(ListTypeItem.from(activeFlag("Representative 1 external flag"))); + allPartyFlags.getRepresentative1Flags() + .setDetails(ListTypeItem.from(activeFlag("Representative 2 internal flag"))); + + respondent1.getValue().setResponseStruckOut(YES); + + caseFlagsService.inactivateRespondentRepresentativeCaseFlags(caseData, respondent1); + + assertAll( + () -> assertEquals(INACTIVE, firstFlagStatus(allPartyFlags.getRepresentativeFlags())), + () -> assertEquals(INACTIVE, firstFlagStatus(allPartyFlags.getRepresentativeExternalFlags())), + () -> assertNull(firstFlagComment(allPartyFlags.getRepresentativeFlags())), + () -> assertNull(firstFlagComment(allPartyFlags.getRepresentativeExternalFlags())), + () -> assertEquals(ACTIVE, firstFlagStatus(allPartyFlags.getRepresentative1Flags())) + ); + } - assertNull(caseData.getAllPartyFlags()); + @Test + void inactivateRespondentRepresentativeCaseFlags_shouldKeepSharedRepresentativeActiveUntilAllInactive() { + setupRepresentativeAccessScenario(); + RespondentSumTypeItem respondent3 = caseData.getRespondentCollection().get(2); + AllPartyFlags allPartyFlags = allPartyFlags(caseData); + allPartyFlags.getRepresentative1Flags() + .setDetails(ListTypeItem.from(activeFlag("Representative 2 internal flag"))); + allPartyFlags.getRepresentative1ExternalFlags() + .setDetails(ListTypeItem.from(activeFlag("Representative 2 external flag"))); + + respondent3.getValue().setResponseContinue(NO); + caseFlagsService.inactivateRespondentRepresentativeCaseFlags(caseData, respondent3); + + assertAll( + () -> assertEquals(ACTIVE, firstFlagStatus(allPartyFlags.getRepresentative1Flags())), + () -> assertEquals(ACTIVE, firstFlagStatus(allPartyFlags.getRepresentative1ExternalFlags())) + ); + + RespondentSumTypeItem respondent2 = caseData.getRespondentCollection().get(1); + respondent2.getValue().setResponseStruckOut(YES); + caseFlagsService.inactivateRespondentRepresentativeCaseFlags(caseData, respondent2); + + assertAll( + () -> assertEquals(INACTIVE, firstFlagStatus(allPartyFlags.getRepresentative1Flags())), + () -> assertEquals(INACTIVE, firstFlagStatus(allPartyFlags.getRepresentative1ExternalFlags())), + () -> assertNull(firstFlagComment(allPartyFlags.getRepresentative1Flags())), + () -> assertNull(firstFlagComment(allPartyFlags.getRepresentative1ExternalFlags())) + ); + } + + @Test + void setupCaseFlags_shouldKeepDetailsWhenRepresentativeSlotsSwapAfterRespondentReorder() { + caseData.setRespondentCollection(respondentCollection(4)); + List respondents = caseData.getRespondentCollection(); + caseData.setRepCollection(List.of( + representativeItemForRespondent("1", "Representative 1", "rep1@example.com", respondents.get(0)), + representativeItemForRespondent("4", "Representative 3", "rep3@example.com", respondents.get(3)), + representativeItemForRespondent("2", "Representative 2", "rep2@example.com", respondents.get(1)), + representativeItemForRespondent("3", "Representative 2", "rep2@example.com", respondents.get(2)) + )); + AllPartyFlags allPartyFlags = getOrCreateAllPartyFlags(caseData); + allPartyFlags.setCaseFlags(CaseFlagsType.builder().build()); + allPartyFlags.setRepresentativeFlags(representativeFlags( + "Representative 1", REPRESENTATIVE1, INTERNAL, "Representative 1 internal flag")); + allPartyFlags.setRepresentative1Flags(representativeFlags( + "Representative 2", REPRESENTATIVE2, INTERNAL, "Representative 2 internal flag")); + allPartyFlags.setRepresentative2Flags(representativeFlags( + "Representative 3", REPRESENTATIVE3, INTERNAL, "Representative 3 internal flag")); + allPartyFlags.setRepresentativeExternalFlags(representativeFlags( + "Representative 1", REPRESENTATIVE1, EXTERNAL, "Representative 1 external flag")); + allPartyFlags.setRepresentative1ExternalFlags(representativeFlags( + "Representative 2", REPRESENTATIVE2, EXTERNAL, "Representative 2 external flag")); + allPartyFlags.setRepresentative2ExternalFlags(representativeFlags( + "Representative 3", REPRESENTATIVE3, EXTERNAL, "Representative 3 external flag")); + inactivateCaseFlags(allPartyFlags.getRepresentative1Flags()); + inactivateCaseFlags(allPartyFlags.getRepresentative1ExternalFlags()); caseFlagsService.setupCaseFlags(caseData); - allPartyFlags(caseData).getRespondentFlags().setDetails(null); - caseFlagsService.inactivateCaseFlags(caseData, RESPONDENT_NAME, RESPONDENT_NOT_CONTINUING_FLAG_COMMENT); + assertAll( + () -> assertRepresentativeFlags( + allPartyFlags.getRepresentative1Flags(), + "Representative 3", + REPRESENTATIVE2, + ACTIVE, + "Representative 3 internal flag" + ), + () -> assertRepresentativeFlags( + allPartyFlags.getRepresentative1ExternalFlags(), + "Representative 3", + REPRESENTATIVE2, + ACTIVE, + "Representative 3 external flag" + ), + () -> assertRepresentativeFlags( + allPartyFlags.getRepresentative2Flags(), + "Representative 2", + REPRESENTATIVE3, + INACTIVE, + "Representative 2 internal flag" + ), + () -> assertRepresentativeFlags( + allPartyFlags.getRepresentative2ExternalFlags(), + "Representative 2", + REPRESENTATIVE3, + INACTIVE, + "Representative 2 external flag" + ), + () -> assertNull(allPartyFlags.getRepresentative3Flags()), + () -> assertNull(allPartyFlags.getRepresentative3ExternalFlags()) + ); + } - assertNull(allPartyFlags(caseData).getRespondentFlags().getDetails()); + @Test + void clearRespondentRepresentativeFlags_shouldRemoveMatchingRepresentativeIndexFlagDetailsOnly() { + caseFlagsService.setupCaseFlags(caseData); + CaseFlagsType representativeInternalFlags = allPartyFlags(caseData).getRepresentative1Flags(); + CaseFlagsType representativeExternalFlags = allPartyFlags(caseData).getRepresentative1ExternalFlags(); + CaseFlagsType otherRepresentativeFlags = allPartyFlags(caseData).getRepresentative2Flags(); + representativeInternalFlags.setDetails(ListTypeItem.from(activeFlag("Representative internal flag"))); + representativeExternalFlags.setDetails(ListTypeItem.from(activeFlag("Representative external flag"))); + otherRepresentativeFlags.setDetails(ListTypeItem.from(activeFlag("Other representative flag"))); + CaseFlagsType respondentFlags = allPartyFlags(caseData).getRespondent1Flags(); + respondentFlags.setDetails(ListTypeItem.from(activeFlag("Respondent flag"))); + + caseFlagsService.clearRespondentRepresentativeFlags(caseData, List.of(1)); + + assertNull(representativeInternalFlags.getDetails()); + assertNull(representativeExternalFlags.getDetails()); + assertEquals(ACTIVE, otherRepresentativeFlags.getDetails().getFirst().getValue().getStatus()); + assertEquals(ACTIVE, respondentFlags.getDetails().getFirst().getValue().getStatus()); + } + + @Test + void setupCaseFlags_shouldMoveRespondentFlagsWithRespondentWhenCollectionIsReordered() { + caseData.setRespondentCollection(respondentCollection(3)); + caseFlagsService.setupCaseFlags(caseData); + allPartyFlags(caseData).getRespondent1Flags() + .setDetails(ListTypeItem.from(activeFlag("Respondent 2 internal flag"))); + allPartyFlags(caseData).getRespondent1ExternalFlags() + .setDetails(ListTypeItem.from(activeFlag("Respondent 2 external flag"))); + allPartyFlags(caseData).getRespondent2Flags() + .setDetails(ListTypeItem.from(activeFlag("Respondent 3 internal flag"))); + allPartyFlags(caseData).getRespondent2ExternalFlags() + .setDetails(ListTypeItem.from(activeFlag("Respondent 3 external flag"))); + + caseFlagsService.inactivateRespondentCaseFlags(caseData, respondentName(1)); + caseData.setRespondentCollection(List.of( + caseData.getRespondentCollection().get(0), + caseData.getRespondentCollection().get(2), + caseData.getRespondentCollection().get(1) + )); + caseFlagsService.setupCaseFlags(caseData); + + CaseFlagsType secondRespondentInternalFlags = allPartyFlags(caseData).getRespondent1Flags(); + assertEquals(respondentName(2), secondRespondentInternalFlags.getPartyName()); + assertEquals(RESPONDENT2, secondRespondentInternalFlags.getRoleOnCase()); + assertEquals(RESPONDENT2, secondRespondentInternalFlags.getGroupId()); + assertEquals(ACTIVE, secondRespondentInternalFlags.getDetails().getFirst().getValue().getStatus()); + assertEquals("Respondent 3 internal flag", + secondRespondentInternalFlags.getDetails().getFirst().getValue().getName()); + + CaseFlagsType secondRespondentExternalFlags = allPartyFlags(caseData).getRespondent1ExternalFlags(); + assertEquals(respondentName(2), secondRespondentExternalFlags.getPartyName()); + assertEquals(RESPONDENT2, secondRespondentExternalFlags.getRoleOnCase()); + assertEquals(RESPONDENT2, secondRespondentExternalFlags.getGroupId()); + assertEquals(ACTIVE, secondRespondentExternalFlags.getDetails().getFirst().getValue().getStatus()); + assertEquals("Respondent 3 external flag", + secondRespondentExternalFlags.getDetails().getFirst().getValue().getName()); + + CaseFlagsType discontinuedRespondentInternalFlags = allPartyFlags(caseData).getRespondent2Flags(); + assertEquals(respondentName(1), discontinuedRespondentInternalFlags.getPartyName()); + assertEquals(RESPONDENT3, discontinuedRespondentInternalFlags.getRoleOnCase()); + assertEquals(RESPONDENT3, discontinuedRespondentInternalFlags.getGroupId()); + assertEquals(INACTIVE, discontinuedRespondentInternalFlags.getDetails().getFirst().getValue().getStatus()); + assertNull(discontinuedRespondentInternalFlags.getDetails().getFirst().getValue().getFlagComment()); + assertEquals("Respondent 2 internal flag", + discontinuedRespondentInternalFlags.getDetails().getFirst().getValue().getName()); + + CaseFlagsType discontinuedRespondentExternalFlags = allPartyFlags(caseData).getRespondent2ExternalFlags(); + assertEquals(respondentName(1), discontinuedRespondentExternalFlags.getPartyName()); + assertEquals(RESPONDENT3, discontinuedRespondentExternalFlags.getRoleOnCase()); + assertEquals(RESPONDENT3, discontinuedRespondentExternalFlags.getGroupId()); + assertEquals(INACTIVE, discontinuedRespondentExternalFlags.getDetails().getFirst().getValue().getStatus()); + assertNull(discontinuedRespondentExternalFlags.getDetails().getFirst().getValue().getFlagComment()); + assertEquals("Respondent 2 external flag", + discontinuedRespondentExternalFlags.getDetails().getFirst().getValue().getName()); + } + + @Test + void setupCaseFlags_shouldMoveRepresentativeFlagsWithRepresentativeWhenCollectionIsReordered() { + caseData.setRepCollection(representativeCollection(3)); + caseFlagsService.setupCaseFlags(caseData); + allPartyFlags(caseData).getRepresentative1Flags() + .setDetails(ListTypeItem.from(activeFlag("Representative 2 internal flag"))); + allPartyFlags(caseData).getRepresentative1ExternalFlags() + .setDetails(ListTypeItem.from(activeFlag("Representative 2 external flag"))); + allPartyFlags(caseData).getRepresentative2Flags() + .setDetails(ListTypeItem.from(activeFlag("Representative 3 internal flag"))); + allPartyFlags(caseData).getRepresentative2ExternalFlags() + .setDetails(ListTypeItem.from(activeFlag("Representative 3 external flag"))); + + caseData.setRepCollection(List.of( + caseData.getRepCollection().get(0), + caseData.getRepCollection().get(2), + caseData.getRepCollection().get(1) + )); + caseFlagsService.setupCaseFlags(caseData); + + CaseFlagsType secondRepresentativeInternalFlags = allPartyFlags(caseData).getRepresentative1Flags(); + assertEquals(representativeName(2), secondRepresentativeInternalFlags.getPartyName()); + assertEquals(REPRESENTATIVE2, secondRepresentativeInternalFlags.getRoleOnCase()); + assertEquals(REPRESENTATIVE2, secondRepresentativeInternalFlags.getGroupId()); + assertEquals("Representative 3 internal flag", + secondRepresentativeInternalFlags.getDetails().getFirst().getValue().getName()); + + CaseFlagsType secondRepresentativeExternalFlags = allPartyFlags(caseData).getRepresentative1ExternalFlags(); + assertEquals(representativeName(2), secondRepresentativeExternalFlags.getPartyName()); + assertEquals(REPRESENTATIVE2, secondRepresentativeExternalFlags.getRoleOnCase()); + assertEquals(REPRESENTATIVE2, secondRepresentativeExternalFlags.getGroupId()); + assertEquals("Representative 3 external flag", + secondRepresentativeExternalFlags.getDetails().getFirst().getValue().getName()); + + CaseFlagsType thirdRepresentativeInternalFlags = allPartyFlags(caseData).getRepresentative2Flags(); + assertEquals(representativeName(1), thirdRepresentativeInternalFlags.getPartyName()); + assertEquals(REPRESENTATIVE3, thirdRepresentativeInternalFlags.getRoleOnCase()); + assertEquals(REPRESENTATIVE3, thirdRepresentativeInternalFlags.getGroupId()); + assertEquals("Representative 2 internal flag", + thirdRepresentativeInternalFlags.getDetails().getFirst().getValue().getName()); + + CaseFlagsType thirdRepresentativeExternalFlags = allPartyFlags(caseData).getRepresentative2ExternalFlags(); + assertEquals(representativeName(1), thirdRepresentativeExternalFlags.getPartyName()); + assertEquals(REPRESENTATIVE3, thirdRepresentativeExternalFlags.getRoleOnCase()); + assertEquals(REPRESENTATIVE3, thirdRepresentativeExternalFlags.getGroupId()); + assertEquals("Representative 2 external flag", + thirdRepresentativeExternalFlags.getDetails().getFirst().getValue().getName()); } @Test @@ -407,8 +826,9 @@ void setupCaseFlags_shouldUpdateClaimantRepresentativeFlagsWhenNameChanges() { @ParameterizedTest(name = "{0}") @MethodSource("respondentRepresentativePartyFlagSlots") - void setupCaseFlags_shouldUpdateRespondentRepresentativeFlagsWhenNameChanges(FlagSlot slot) { + void setupCaseFlags_shouldRemoveRespondentRepresentativeFlagDetailsWhenNameChanges(FlagSlot slot) { caseFlagsService.setupCaseFlags(caseData); + Objects.requireNonNull(slot.get(caseData)).setDetails(ListTypeItem.from(activeFlag("Previous rep flag"))); String updatedRepresentativeName = "Updated " + slot; caseData.getRepCollection() .get(slot.representativeIndex) @@ -421,6 +841,7 @@ void setupCaseFlags_shouldUpdateRespondentRepresentativeFlagsWhenNameChanges(Fla assertEquals(slot.roleOnCase, Objects.requireNonNull(slot.get(caseData)).getRoleOnCase()); assertEquals(slot.roleOnCase, Objects.requireNonNull(slot.get(caseData)).getGroupId()); assertEquals(slot.visibility, Objects.requireNonNull(slot.get(caseData)).getVisibility()); + assertNull(Objects.requireNonNull(slot.get(caseData)).getDetails()); } @Test @@ -816,6 +1237,51 @@ private static List representativeCollection(int numberOfR return representativeCollection; } + private static RepresentedTypeRItem representativeItem(String id, String name) { + RepresentedTypeR representative = RepresentedTypeR.builder() + .nameOfRepresentative(name) + .build(); + return representativeItem(id, representative); + } + + private static RepresentedTypeRItem representativeItem(String id, String name, String email) { + RepresentedTypeR representative = RepresentedTypeR.builder() + .nameOfRepresentative(name) + .representativeEmailAddress(email) + .build(); + return representativeItem(id, representative); + } + + private static RepresentedTypeRItem representativeItem(String id, RepresentedTypeR representative) { + RepresentedTypeRItem representativeItem = new RepresentedTypeRItem(); + representativeItem.setId(id); + representativeItem.setValue(representative); + return representativeItem; + } + + private static RepresentedTypeRItem representativeItemForRespondent( + String id, String name, String email, RespondentSumTypeItem respondent) { + RepresentedTypeR representative = RepresentedTypeR.builder() + .nameOfRepresentative(name) + .representativeEmailAddress(email) + .respondentId(respondent.getId()) + .respRepName(respondent.getValue().getRespondentName()) + .build(); + return representativeItem(id, representative); + } + + private void setupRepresentativeAccessScenario() { + caseData.setRespondentCollection(respondentCollection(4)); + List respondents = caseData.getRespondentCollection(); + caseData.setRepCollection(List.of( + representativeItemForRespondent("1", "Representative 1", "rep1@example.com", respondents.get(0)), + representativeItemForRespondent("2", "Representative 2", "rep2@example.com", respondents.get(1)), + representativeItemForRespondent("3", "Representative 2", "rep2@example.com", respondents.get(2)), + representativeItemForRespondent("4", "Representative 3", "rep3@example.com", respondents.get(3)) + )); + caseFlagsService.setupCaseFlags(caseData); + } + private static String respondentName(int index) { return index == 0 ? RESPONDENT_NAME : RESPONDENT_NAME + " " + (index + 1); } @@ -845,6 +1311,17 @@ private static void assertCaseFlag(FlagSlot slot, CaseFlagsType actual) { ); } + private static CaseFlagsType representativeFlags( + String partyName, String roleOnCase, String visibility, String flagName) { + return CaseFlagsType.builder() + .partyName(partyName) + .roleOnCase(roleOnCase) + .groupId(roleOnCase) + .visibility(visibility) + .details(ListTypeItem.from(activeFlag(flagName))) + .build(); + } + private static FlagDetailType activeFlag(String name) { return FlagDetailType.builder() .name(name) @@ -852,6 +1329,28 @@ private static FlagDetailType activeFlag(String name) { .build(); } + private static String firstFlagStatus(CaseFlagsType flags) { + return flags.getDetails().getFirst().getValue().getStatus(); + } + + private static String firstFlagComment(CaseFlagsType flags) { + return flags.getDetails().getFirst().getValue().getFlagComment(); + } + + private static void inactivateCaseFlags(CaseFlagsType flags) { + flags.getDetails().stream() + .forEach(flag -> flag.getValue().setStatus(INACTIVE)); + } + + private static void assertRepresentativeFlags( + CaseFlagsType flags, String partyName, String roleOnCase, String status, String flagName) { + assertEquals(partyName, flags.getPartyName()); + assertEquals(roleOnCase, flags.getRoleOnCase()); + assertEquals(roleOnCase, flags.getGroupId()); + assertEquals(status, firstFlagStatus(flags)); + assertEquals(flagName, flags.getDetails().getFirst().getValue().getName()); + } + private static GenericTseApplicationTypeItem tseApplication( String type, List adminDecisions) { return GenericTseApplicationTypeItem.builder() diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseManagementForCaseWorkerServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseManagementForCaseWorkerServiceTest.java index 3428fe84fd..2fd56e01be 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseManagementForCaseWorkerServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseManagementForCaseWorkerServiceTest.java @@ -134,6 +134,8 @@ class CaseManagementForCaseWorkerServiceTest { @MockitoBean private FeatureToggleService featureToggleService; @MockitoBean + private CaseFlagsService caseFlagsService; + @MockitoBean private AdminUserService adminUserService; @MockitoBean private CaseManagementLocationService caseManagementLocationService; @@ -158,7 +160,7 @@ void setUp() throws URISyntaxException, IOException { when(featureToggleService.isWorkAllocationEnabled()).thenReturn(true); when(adminUserService.getAdminUserToken()).thenReturn(AUTH_TOKEN); caseManagementForCaseWorkerService = new CaseManagementForCaseWorkerService( - caseRetrievalForCaseWorkerService, ccdClient, featureToggleService, HMCTS_SERVICE_ID, + caseRetrievalForCaseWorkerService, ccdClient, featureToggleService, caseFlagsService, HMCTS_SERVICE_ID, adminUserService, caseManagementLocationService, multipleReferenceService, ccdGatewayBaseUrl, multipleCasesSendingService, answersConverter); } @@ -492,6 +494,11 @@ void struckOutRespondentFirstToLast() { assertThat(caseData.getRespondentCollection().get(1).getValue().getResponseStruckOut()).isEqualTo(NO); assertThat(caseData.getRespondentCollection().get(2).getValue().getRespondentName()).isEqualTo("Juan Garcia"); assertThat(caseData.getRespondentCollection().get(2).getValue().getResponseStruckOut()).isEqualTo(YES); + verify(caseFlagsService).inactivateRespondentCaseFlags(caseData, "Juan Garcia"); + verify(caseFlagsService).inactivateRespondentRepresentativeCaseFlags( + caseData, + caseData.getRespondentCollection().get(2) + ); } @Test @@ -550,6 +557,11 @@ void continuingRespondentFirstToLast() { assertThat(caseData.getRespondentCollection().get(2).getValue().getRespondentName()) .isEqualTo("Roberto Dondini"); assertThat(caseData.getRespondentCollection().get(2).getValue().getResponseContinue()).isEqualTo(NO); + verify(caseFlagsService).inactivateRespondentCaseFlags(caseData, "Roberto Dondini"); + verify(caseFlagsService).inactivateRespondentRepresentativeCaseFlags( + caseData, + caseData.getRespondentCollection().get(2) + ); } @Test @@ -559,6 +571,35 @@ void continuingRespondentNull() { assertThat(caseData.getRespondentCollection().getFirst().getValue().getResponseContinue()).isEqualTo(YES); } + @Test + void continuingRespondentDefaultsResponseContinueWhenRepCollectionExists() { + CaseData caseData = scotlandCcdRequest3.getCaseDetails().getCaseData(); + caseData.setRepCollection(createRepCollection()); + caseData.getRespondentCollection().getFirst().getValue().setResponseContinue(null); + + caseManagementForCaseWorkerService.continuingRespondent(scotlandCcdRequest3); + + assertThat(caseData.getRespondentCollection().getFirst().getValue().getResponseContinue()).isEqualTo(YES); + verify(caseFlagsService, never()).inactivateRespondentCaseFlags(any(), anyString()); + verify(caseFlagsService, never()).inactivateRespondentRepresentativeCaseFlags(any(), any()); + } + + @Test + void continuingRespondentInactivatesCaseFlagsWhenRepCollectionExistsAndResponseDoesNotContinue() { + CaseData caseData = scotlandCcdRequest3.getCaseDetails().getCaseData(); + caseData.setRepCollection(createRepCollection()); + caseData.getRespondentCollection().getFirst().getValue().setResponseContinue(NO); + + caseManagementForCaseWorkerService.continuingRespondent(scotlandCcdRequest3); + + assertThat(caseData.getRespondentCollection().getFirst().getValue().getResponseContinue()).isEqualTo(NO); + verify(caseFlagsService).inactivateRespondentCaseFlags(caseData, "Antonio Vazquez"); + verify(caseFlagsService).inactivateRespondentRepresentativeCaseFlags( + caseData, + caseData.getRespondentCollection().getFirst() + ); + } + @Test void continuingRespondentEmpty() { CaseData caseData = caseManagementForCaseWorkerService.continuingRespondent(scotlandCcdRequest5); diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocRespondentRepresentativeServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocRespondentRepresentativeServiceTest.java index 15fe72056c..b6708fc4c9 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocRespondentRepresentativeServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocRespondentRepresentativeServiceTest.java @@ -8,6 +8,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.ArgumentCaptor; import org.mockito.InjectMocks; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; @@ -108,6 +109,7 @@ class NocRespondentRepresentativeServiceTest { private static final String ROLE_SOLICITORA = "[SOLICITORA]"; private static final String ROLE_SOLICITORB = "[SOLICITORB]"; private static final String ROLE_SOLICITORC = "[SOLICITORC]"; + private static final String ROLE_SOLICITORD = "[SOLICITORD]"; private static final String ORGANISATION_ID_ONE = "ORG1"; private static final String ORGANISATION_ID_TWO = "ORG2"; private static final String ORGANISATION_ID_THREE = "ORG3"; @@ -136,6 +138,7 @@ class NocRespondentRepresentativeServiceTest { private static final String RESPONDENT_ID_ONE = "106001"; private static final String RESPONDENT_ID_TWO = "106002"; private static final String RESPONDENT_ID_THREE = "106003"; + private static final String RESPONDENT_ID_FOUR = "106004"; private static final String ADMIN_USER_TOKEN = "adminUserToken"; private static final String USER_TOKEN = "userToken"; private static final String S2S_TOKEN = "someS2SToken"; @@ -685,8 +688,10 @@ void theRevokeOldRespondentRepresentativeAccessTest() { assertThat(nocRespondentRepresentativeService.revokeOldRespondentRepresentativeAccess(callbackRequest, USER_TOKEN, representativesToRemove)).isEmpty(); verifyNocCcdServiceCaseAssignmentsCall(LoggerTestUtils.INTEGER_EIGHT); - // when case user assignment role is equal to the role in representative should revoke case user assignment + // when case user assignment belongs to the representative should revoke case user assignment tmpRepresentative.getValue().setRole(ROLE_SOLICITORA); + tmpRepresentative.getValue().setIdamId(REPRESENTATIVE_ID_ONE); + caseUserAssignmentData.getCaseUserAssignments().getFirst().setUserId(REPRESENTATIVE_ID_ONE); when(ccdClient.revokeCaseAssignments(USER_TOKEN, caseUserAssignmentData)).thenReturn( String.valueOf(HttpStatus.OK.value())); CaseDetails caseDetails = new CaseDetails(); @@ -711,6 +716,247 @@ void theRevokeOldRespondentRepresentativeAccessTest() { USER_TOKEN, representativesToRemove)).isEmpty(); } + @Test + @SneakyThrows + void revokeOldRespondentRepresentativeAccessOnlyRevokesRemovedRepresentativeAssignments() { + RepresentedTypeRItem removedRepresentative = RepresentedTypeRItem.builder() + .id("rep-item-1") + .value(RepresentedTypeR.builder() + .respondentId(RESPONDENT_ID_ONE) + .respRepName(RESPONDENT_NAME_ONE) + .role(ROLE_SOLICITORA) + .idamId(REPRESENTATIVE_ID_ONE) + .myHmctsYesNo(YES) + .representativeEmailAddress(REPRESENTATIVE_EMAIL_1) + .respondentOrganisation(Organisation.builder().organisationID(ORGANISATION_ID_ONE).build()) + .build()) + .build(); + CaseData previousCaseData = new CaseData(); + previousCaseData.setRepCollection(List.of( + removedRepresentative, + representativeForRespondent("rep-item-2", RESPONDENT_ID_TWO, ROLE_SOLICITORB, + REPRESENTATIVE_ID_TWO, ORGANISATION_ID_TWO), + representativeForRespondent("rep-item-3", RESPONDENT_ID_THREE, ROLE_SOLICITORC, + REPRESENTATIVE_ID_TWO, ORGANISATION_ID_TWO), + representativeForRespondent("rep-item-4", RESPONDENT_ID_FOUR, ROLE_SOLICITORD, + REPRESENTATIVE_ID_THREE, ORGANISATION_ID_THREE) + )); + CaseDetails previousCaseDetails = new CaseDetails(); + previousCaseDetails.setCaseId(CASE_ID_1); + previousCaseDetails.setCaseData(previousCaseData); + CaseDetails currentCaseDetails = new CaseDetails(); + currentCaseDetails.setCaseId(CASE_ID_1); + currentCaseDetails.setCaseData(new CaseData()); + CallbackRequest callbackRequest = CallbackRequest.builder() + .caseDetailsBefore(previousCaseDetails) + .caseDetails(currentCaseDetails) + .build(); + + CaseUserAssignment removedPrimaryAssignment = assignment(REPRESENTATIVE_ID_ONE, ROLE_SOLICITORA); + CaseUserAssignment removedAdditionalAssignment = assignment(REPRESENTATIVE_ID_ONE, ROLE_SOLICITORC); + CaseUserAssignment remainingRep2Respondent2Assignment = assignment(REPRESENTATIVE_ID_TWO, ROLE_SOLICITORB); + CaseUserAssignment remainingRep2Respondent3Assignment = assignment(REPRESENTATIVE_ID_TWO, ROLE_SOLICITORC); + CaseUserAssignment remainingRep3Respondent4Assignment = assignment(REPRESENTATIVE_ID_THREE, ROLE_SOLICITORD); + CaseUserAssignmentData existingAssignments = CaseUserAssignmentData.builder() + .caseUserAssignments(List.of( + removedPrimaryAssignment, + remainingRep2Respondent2Assignment, + removedAdditionalAssignment, + remainingRep2Respondent3Assignment, + remainingRep3Respondent4Assignment + )) + .build(); + when(adminUserService.getAdminUserToken()).thenReturn(ADMIN_USER_TOKEN); + when(nocCcdService.retrieveCaseUserAssignments(ADMIN_USER_TOKEN, CASE_ID_1)) + .thenReturn(existingAssignments); + + List revokedRepresentatives = nocRespondentRepresentativeService + .revokeOldRespondentRepresentativeAccess(callbackRequest, USER_TOKEN, List.of(removedRepresentative)); + + assertThat(revokedRepresentatives).containsExactly(removedRepresentative); + ArgumentCaptor revokedAssignments = + ArgumentCaptor.forClass(CaseUserAssignmentData.class); + verify(ccdClient).revokeCaseAssignments(eq(USER_TOKEN), revokedAssignments.capture()); + assertThat(revokedAssignments.getValue().getCaseUserAssignments()) + .containsExactlyInAnyOrder(removedPrimaryAssignment, removedAdditionalAssignment); + } + + @Test + @SneakyThrows + void revokeOldRespondentRepresentativeAccessOnlyRevokesDeletedMiddleRepresentativeAssignments() { + RepresentedTypeRItem removedRespondentTwoRepresentative = removableRepresentativeForRespondent( + "rep-item-2", + RESPONDENT_ID_TWO, + RESPONDENT_NAME_TWO, + ROLE_SOLICITORB, + REPRESENTATIVE_ID_TWO, + REPRESENTATIVE_EMAIL_2, + ORGANISATION_ID_TWO); + RepresentedTypeRItem removedRespondentThreeRepresentative = removableRepresentativeForRespondent( + "rep-item-3", + RESPONDENT_ID_THREE, + RESPONDENT_NAME_THREE, + ROLE_SOLICITORC, + REPRESENTATIVE_ID_TWO, + REPRESENTATIVE_EMAIL_2, + ORGANISATION_ID_TWO); + CaseDetails previousCaseDetails = new CaseDetails(); + previousCaseDetails.setCaseId(CASE_ID_1); + previousCaseDetails.setCaseData(new CaseData()); + previousCaseDetails.getCaseData().setRepCollection(List.of( + representativeForRespondent("rep-item-1", RESPONDENT_ID_ONE, ROLE_SOLICITORA, + REPRESENTATIVE_ID_ONE, ORGANISATION_ID_ONE), + removedRespondentTwoRepresentative, + removedRespondentThreeRepresentative, + representativeForRespondent("rep-item-4", RESPONDENT_ID_FOUR, ROLE_SOLICITORD, + REPRESENTATIVE_ID_THREE, ORGANISATION_ID_THREE) + )); + CaseDetails currentCaseDetails = new CaseDetails(); + currentCaseDetails.setCaseId(CASE_ID_1); + currentCaseDetails.setCaseData(new CaseData()); + CallbackRequest callbackRequest = CallbackRequest.builder() + .caseDetailsBefore(previousCaseDetails) + .caseDetails(currentCaseDetails) + .build(); + + CaseUserAssignment remainingRep1Assignment = assignment(REPRESENTATIVE_ID_ONE, ROLE_SOLICITORA); + CaseUserAssignment removedRep2Respondent2Assignment = assignment(REPRESENTATIVE_ID_TWO, ROLE_SOLICITORB); + CaseUserAssignment removedRep2Respondent3Assignment = assignment(REPRESENTATIVE_ID_TWO, ROLE_SOLICITORC); + CaseUserAssignment remainingRep3Assignment = assignment(REPRESENTATIVE_ID_THREE, ROLE_SOLICITORD); + CaseUserAssignmentData existingAssignments = CaseUserAssignmentData.builder() + .caseUserAssignments(List.of( + remainingRep1Assignment, + removedRep2Respondent2Assignment, + removedRep2Respondent3Assignment, + remainingRep3Assignment + )) + .build(); + when(adminUserService.getAdminUserToken()).thenReturn(ADMIN_USER_TOKEN); + when(nocCcdService.retrieveCaseUserAssignments(ADMIN_USER_TOKEN, CASE_ID_1)) + .thenReturn(existingAssignments); + + List revokedRepresentatives = nocRespondentRepresentativeService + .revokeOldRespondentRepresentativeAccess(callbackRequest, USER_TOKEN, + List.of(removedRespondentTwoRepresentative, removedRespondentThreeRepresentative)); + + assertThat(revokedRepresentatives).containsExactlyInAnyOrder( + removedRespondentTwoRepresentative, removedRespondentThreeRepresentative); + ArgumentCaptor revokedAssignments = + ArgumentCaptor.forClass(CaseUserAssignmentData.class); + verify(ccdClient).revokeCaseAssignments(eq(USER_TOKEN), revokedAssignments.capture()); + assertThat(revokedAssignments.getValue().getCaseUserAssignments()) + .containsExactlyInAnyOrder(removedRep2Respondent2Assignment, removedRep2Respondent3Assignment); + } + + @Test + void realignRespondentRepresentativeAccessMovesAssignmentsWithRespondents() { + CaseData previousCaseData = new CaseData(); + previousCaseData.setRepCollection(List.of( + representativeForRespondent("rep-item-1", RESPONDENT_ID_ONE, ROLE_SOLICITORA), + representativeForRespondent("rep-item-2", RESPONDENT_ID_TWO, ROLE_SOLICITORB), + representativeForRespondent("rep-item-3", RESPONDENT_ID_THREE, ROLE_SOLICITORC), + representativeForRespondent("rep-item-4", RESPONDENT_ID_FOUR, ROLE_SOLICITORD) + )); + CaseData currentCaseData = new CaseData(); + currentCaseData.setRepCollection(List.of( + representativeForRespondent("rep-item-2", RESPONDENT_ID_TWO, ROLE_SOLICITORA), + representativeForRespondent("rep-item-3", RESPONDENT_ID_THREE, ROLE_SOLICITORB), + representativeForRespondent("rep-item-4", RESPONDENT_ID_FOUR, ROLE_SOLICITORC), + representativeForRespondent("rep-item-1", RESPONDENT_ID_ONE, ROLE_SOLICITORD) + )); + CaseDetails previousCaseDetails = new CaseDetails(); + previousCaseDetails.setCaseId(CASE_ID_1); + previousCaseDetails.setCaseData(previousCaseData); + CaseDetails currentCaseDetails = new CaseDetails(); + currentCaseDetails.setCaseId(CASE_ID_1); + currentCaseDetails.setCaseData(currentCaseData); + final CallbackRequest callbackRequest = CallbackRequest.builder() + .caseDetailsBefore(previousCaseDetails) + .caseDetails(currentCaseDetails) + .build(); + + CaseUserAssignmentData existingAssignments = CaseUserAssignmentData.builder() + .caseUserAssignments(List.of( + assignment(REPRESENTATIVE_ID_ONE, ROLE_SOLICITORA), + assignment(REPRESENTATIVE_ID_TWO, ROLE_SOLICITORB), + assignment(REPRESENTATIVE_ID_TWO, ROLE_SOLICITORC), + assignment(REPRESENTATIVE_ID_THREE, ROLE_SOLICITORD) + )) + .build(); + when(adminUserService.getAdminUserToken()).thenReturn(ADMIN_USER_TOKEN); + when(nocCcdService.retrieveCaseUserAssignments(ADMIN_USER_TOKEN, CASE_ID_1)) + .thenReturn(existingAssignments); + when(nocService.grantCaseAccess(anyString(), eq(CASE_ID_1), anyString())).thenReturn(true); + + nocRespondentRepresentativeService.realignRespondentRepresentativeAccess(callbackRequest); + + verify(nocService).grantCaseAccess(REPRESENTATIVE_ID_TWO, CASE_ID_1, ROLE_SOLICITORA); + verify(nocService).grantCaseAccess(REPRESENTATIVE_ID_THREE, CASE_ID_1, ROLE_SOLICITORC); + verify(nocService).grantCaseAccess(REPRESENTATIVE_ID_ONE, CASE_ID_1, ROLE_SOLICITORD); + verify(nocService, never()).grantCaseAccess(REPRESENTATIVE_ID_TWO, CASE_ID_1, ROLE_SOLICITORB); + + ArgumentCaptor revokedAssignments = + ArgumentCaptor.forClass(CaseUserAssignmentData.class); + verify(nocCcdService).revokeCaseAssignments(eq(ADMIN_USER_TOKEN), revokedAssignments.capture()); + assertThat(revokedAssignments.getValue().getCaseUserAssignments()) + .extracting(assignment -> assignment.getUserId() + ":" + assignment.getCaseRole()) + .containsExactlyInAnyOrder( + REPRESENTATIVE_ID_ONE + ":" + ROLE_SOLICITORA, + REPRESENTATIVE_ID_TWO + ":" + ROLE_SOLICITORC, + REPRESENTATIVE_ID_THREE + ":" + ROLE_SOLICITORD + ); + } + + @Test + void realignRespondentRepresentativeAccessRepairsExistingMisalignedCase() { + CaseData currentCaseData = new CaseData(); + currentCaseData.setRepCollection(List.of( + representativeForRespondent("rep-item-2", RESPONDENT_ID_TWO, ROLE_SOLICITORA, + REPRESENTATIVE_ID_TWO, ORGANISATION_ID_TWO), + representativeForRespondent("rep-item-3", RESPONDENT_ID_THREE, ROLE_SOLICITORB, + REPRESENTATIVE_ID_TWO, ORGANISATION_ID_TWO), + representativeForRespondent("rep-item-4", RESPONDENT_ID_FOUR, ROLE_SOLICITORC, + REPRESENTATIVE_ID_THREE, ORGANISATION_ID_THREE), + representativeForRespondent("rep-item-1", RESPONDENT_ID_ONE, ROLE_SOLICITORD, + REPRESENTATIVE_ID_ONE, ORGANISATION_ID_ONE) + )); + CaseDetails currentCaseDetails = new CaseDetails(); + currentCaseDetails.setCaseId(CASE_ID_1); + currentCaseDetails.setCaseData(currentCaseData); + final CallbackRequest callbackRequest = CallbackRequest.builder().caseDetails(currentCaseDetails).build(); + + CaseUserAssignmentData existingAssignments = CaseUserAssignmentData.builder() + .caseUserAssignments(List.of( + assignment(REPRESENTATIVE_ID_ONE, ROLE_SOLICITORA, ORGANISATION_ID_ONE), + assignment(REPRESENTATIVE_ID_TWO, ROLE_SOLICITORB, ORGANISATION_ID_TWO), + assignment(REPRESENTATIVE_ID_TWO, ROLE_SOLICITORC, ORGANISATION_ID_TWO), + assignment(REPRESENTATIVE_ID_THREE, ROLE_SOLICITORD, ORGANISATION_ID_THREE) + )) + .build(); + when(adminUserService.getAdminUserToken()).thenReturn(ADMIN_USER_TOKEN); + when(nocCcdService.retrieveCaseUserAssignments(ADMIN_USER_TOKEN, CASE_ID_1)) + .thenReturn(existingAssignments); + when(nocService.grantCaseAccess(anyString(), eq(CASE_ID_1), anyString())).thenReturn(true); + + nocRespondentRepresentativeService.realignRespondentRepresentativeAccess(callbackRequest); + + verify(nocService).grantCaseAccess(REPRESENTATIVE_ID_TWO, CASE_ID_1, ROLE_SOLICITORA); + verify(nocService).grantCaseAccess(REPRESENTATIVE_ID_THREE, CASE_ID_1, ROLE_SOLICITORC); + verify(nocService).grantCaseAccess(REPRESENTATIVE_ID_ONE, CASE_ID_1, ROLE_SOLICITORD); + verify(nocService, never()).grantCaseAccess(REPRESENTATIVE_ID_TWO, CASE_ID_1, ROLE_SOLICITORB); + + ArgumentCaptor revokedAssignments = + ArgumentCaptor.forClass(CaseUserAssignmentData.class); + verify(nocCcdService).revokeCaseAssignments(eq(ADMIN_USER_TOKEN), revokedAssignments.capture()); + assertThat(revokedAssignments.getValue().getCaseUserAssignments()) + .extracting(assignment -> assignment.getUserId() + ":" + assignment.getCaseRole()) + .containsExactlyInAnyOrder( + REPRESENTATIVE_ID_ONE + ":" + ROLE_SOLICITORA, + REPRESENTATIVE_ID_TWO + ":" + ROLE_SOLICITORC, + REPRESENTATIVE_ID_THREE + ":" + ROLE_SOLICITORD + ); + } + @Test @SneakyThrows void theFindCaseAssignmentsToRevokeForRep() { @@ -730,22 +976,22 @@ void theFindCaseAssignmentsToRevokeForRep() { caseUserAssignments.add(caseUserAssignmentSolicitorB2); RepresentedTypeRItem representativeB = RepresentedTypeRItem.builder().build(); assertThat(nocRespondentRepresentativeService.findCaseAssignmentsToRevokeForRep(null, - caseUserAssignments, representativeB, ROLE_SOLICITORB)).isEmpty(); + caseUserAssignments, representativeB)).isEmpty(); // when case user assignments is empty should return empty list assertThat(nocRespondentRepresentativeService.findCaseAssignmentsToRevokeForRep(CASE_ID_1, - List.of(), representativeB, ROLE_SOLICITORB)).isEmpty(); + List.of(), representativeB)).isEmpty(); // when representative is empty should return empty list assertThat(nocRespondentRepresentativeService.findCaseAssignmentsToRevokeForRep(CASE_ID_1, caseUserAssignments, - null, ROLE_SOLICITORB)).isEmpty(); + null)).isEmpty(); // when representative does not have value should return an empty list assertThat(nocRespondentRepresentativeService.findCaseAssignmentsToRevokeForRep(CASE_ID_1, caseUserAssignments, - representativeB, ROLE_SOLICITORB)).isEmpty(); + representativeB)).isEmpty(); // when representative does not have email address should return an empty list RepresentedTypeR representativeBValue = RepresentedTypeR.builder().build(); representativeB.setValue(representativeBValue); assertThat(nocRespondentRepresentativeService.findCaseAssignmentsToRevokeForRep(CASE_ID_1, caseUserAssignments, - representativeB, ROLE_SOLICITORB)).isEmpty(); - // when representativeB is removed and ROLE_SOLICITORB has remaining assignments should return those assignments + representativeB)).isEmpty(); + // when representativeB is removed should return only representativeB's remaining assignments representativeBValue.setRepresentativeEmailAddress(REPRESENTATIVE_EMAIL_1); when(adminUserService.getAdminUserToken()).thenReturn(ADMIN_USER_TOKEN); AccountIdByEmailResponse accountIdByEmailResponse = new AccountIdByEmailResponse(); @@ -758,20 +1004,17 @@ void theFindCaseAssignmentsToRevokeForRep() { caseUserAssignments.add(caseUserAssignmentSolicitorB1); caseUserAssignments.add(caseUserAssignmentSolicitorB2); assertThat(nocRespondentRepresentativeService.findCaseAssignmentsToRevokeForRep(CASE_ID_1, caseUserAssignments, - representativeB, ROLE_SOLICITORB)).isNotEmpty().hasSize(LoggerTestUtils.INTEGER_THREE) - .containsExactlyInAnyOrder(caseUserAssignmentSolicitorA2, caseUserAssignmentSolicitorB1, - caseUserAssignmentSolicitorB2); - // when there is only one assignment of ROLE_SOLICITORA should not return that assignment as it should not be - // revoked. + representativeB)).isNotEmpty().hasSize(LoggerTestUtils.INTEGER_TWO) + .containsExactlyInAnyOrder(caseUserAssignmentSolicitorA2, caseUserAssignmentSolicitorB1); + // when representativeB has a unique role assignment it should still be revoked. caseUserAssignments.clear(); caseUserAssignments.add(caseUserAssignmentSolicitorA2); caseUserAssignments.add(caseUserAssignmentSolicitorB1); caseUserAssignments.add(caseUserAssignmentSolicitorB2); assertThat(nocRespondentRepresentativeService.findCaseAssignmentsToRevokeForRep(CASE_ID_1, caseUserAssignments, - representativeB, ROLE_SOLICITORB)).isNotEmpty().hasSize(LoggerTestUtils.INTEGER_TWO) - .containsExactlyInAnyOrder(caseUserAssignmentSolicitorB1, caseUserAssignmentSolicitorB2); - // When representative A is removed and ROLE_SOLICITORA has remaining assignments should return those - // assignments + representativeB)).isNotEmpty().hasSize(LoggerTestUtils.INTEGER_TWO) + .containsExactlyInAnyOrder(caseUserAssignmentSolicitorA2, caseUserAssignmentSolicitorB1); + // When representative A is removed should return only representativeA's assignments. caseUserAssignments.clear(); caseUserAssignments.add(caseUserAssignmentSolicitorA1); caseUserAssignments.add(caseUserAssignmentSolicitorA2); @@ -784,18 +1027,16 @@ void theFindCaseAssignmentsToRevokeForRep() { when(nocService.findUserByEmail(ADMIN_USER_TOKEN, REPRESENTATIVE_EMAIL_2, CASE_ID_1)).thenReturn( accountIdByEmailResponse2); assertThat(nocRespondentRepresentativeService.findCaseAssignmentsToRevokeForRep(CASE_ID_1, caseUserAssignments, - representativeA, ROLE_SOLICITORA)).isNotEmpty().hasSize(LoggerTestUtils.INTEGER_THREE) - .containsExactlyInAnyOrder(caseUserAssignmentSolicitorA1, caseUserAssignmentSolicitorA2, - caseUserAssignmentSolicitorB2); - // when there is only one assignment of ROLE_SOLICITORB should not return that assignment as it should not be - // revoked. + representativeA)).isNotEmpty().hasSize(LoggerTestUtils.INTEGER_TWO) + .containsExactlyInAnyOrder(caseUserAssignmentSolicitorA1, caseUserAssignmentSolicitorB2); + // when representativeA has a unique role assignment it should still be revoked. caseUserAssignments.clear(); caseUserAssignments.add(caseUserAssignmentSolicitorA1); caseUserAssignments.add(caseUserAssignmentSolicitorA2); caseUserAssignments.add(caseUserAssignmentSolicitorB2); assertThat(nocRespondentRepresentativeService.findCaseAssignmentsToRevokeForRep(CASE_ID_1, caseUserAssignments, - representativeA, ROLE_SOLICITORA)).isNotEmpty().hasSize(LoggerTestUtils.INTEGER_TWO) - .containsExactlyInAnyOrder(caseUserAssignmentSolicitorA1, caseUserAssignmentSolicitorA2); + representativeA)).isNotEmpty().hasSize(LoggerTestUtils.INTEGER_TWO) + .containsExactlyInAnyOrder(caseUserAssignmentSolicitorA1, caseUserAssignmentSolicitorB2); // when noc service throws exception should return empty list. caseUserAssignments.clear(); caseUserAssignments.add(caseUserAssignmentSolicitorA1); @@ -805,7 +1046,7 @@ void theFindCaseAssignmentsToRevokeForRep() { when(nocService.findUserByEmail(ADMIN_USER_TOKEN, REPRESENTATIVE_EMAIL_1, CASE_ID_1)).thenThrow( new GenericServiceException(EXCEPTION_DUMMY_MESSAGE)); assertThat(nocRespondentRepresentativeService.findCaseAssignmentsToRevokeForRep(CASE_ID_1, - caseUserAssignments, representativeB, ROLE_SOLICITORB)).isEmpty(); + caseUserAssignments, representativeB)).isEmpty(); } private void verifyNocCcdServiceCaseAssignmentsCall(int callNumber) { @@ -854,7 +1095,9 @@ void theRevokeOldRepresentatives() { // when representatives revoked is not empty should remove organisation policies and noc answers when(adminUserService.getAdminUserToken()).thenReturn(ADMIN_USER_TOKEN); CaseUserAssignmentData caseUserAssignmentData = new CaseUserAssignmentData(); - caseUserAssignmentData.setCaseUserAssignments(List.of(CaseUserAssignment.builder().caseRole(ROLE_SOLICITORA) + caseUserAssignmentData.setCaseUserAssignments(List.of(CaseUserAssignment.builder() + .userId(REPRESENTATIVE_ID_ONE) + .caseRole(ROLE_SOLICITORA) .build())); when(nocCcdService.retrieveCaseUserAssignments(ADMIN_USER_TOKEN, CASE_ID_1)).thenReturn(caseUserAssignmentData); oldCaseDetails.getCaseData().setNoticeOfChangeAnswers0(NoticeOfChangeAnswers.builder() @@ -869,6 +1112,7 @@ void theRevokeOldRepresentatives() { newCaseDetails.setCaseTypeId(CASE_TYPE_ID_ENGLAND_WALES); newCaseDetails.setCaseId(CASE_ID_1); representative1.getValue().setRole(ROLE_SOLICITORA); + representative1.getValue().setIdamId(REPRESENTATIVE_ID_ONE); representative1.getValue().setMyHmctsYesNo(YES); representative1.getValue().setRespRepName(RESPONDENT_NAME_ONE); representative1.getValue().setRespondentOrganisation(Organisation.builder().organisationID(ORGANISATION_ID_ONE) @@ -1834,4 +2078,67 @@ void saveRespondentRepresentativeContactDetails_useMyHmcts_populatesFromOrg() th assertThat(repItem.getValue().getRepresentativeAddress().getAddressLine1()).isEqualTo("Org Street"); assertNull(caseData.getMyHmctsAddressText()); } + + private static RepresentedTypeRItem representativeForRespondent( + String itemId, String respondentId, String role) { + return RepresentedTypeRItem.builder() + .id(itemId) + .value(RepresentedTypeR.builder() + .respondentId(respondentId) + .role(role) + .build()) + .build(); + } + + private static RepresentedTypeRItem representativeForRespondent( + String itemId, String respondentId, String role, String userId, String organisationId) { + return RepresentedTypeRItem.builder() + .id(itemId) + .value(RepresentedTypeR.builder() + .respondentId(respondentId) + .role(role) + .idamId(userId) + .respondentOrganisation(Organisation.builder().organisationID(organisationId).build()) + .build()) + .build(); + } + + private static RepresentedTypeRItem removableRepresentativeForRespondent( + String itemId, + String respondentId, + String respondentName, + String role, + String userId, + String email, + String organisationId) { + return RepresentedTypeRItem.builder() + .id(itemId) + .value(RepresentedTypeR.builder() + .respondentId(respondentId) + .respRepName(respondentName) + .role(role) + .idamId(userId) + .myHmctsYesNo(YES) + .representativeEmailAddress(email) + .respondentOrganisation(Organisation.builder().organisationID(organisationId).build()) + .build()) + .build(); + } + + private static CaseUserAssignment assignment(String userId, String role) { + return CaseUserAssignment.builder() + .caseId(CASE_ID_1) + .userId(userId) + .caseRole(role) + .build(); + } + + private static CaseUserAssignment assignment(String userId, String role, String organisationId) { + return CaseUserAssignment.builder() + .caseId(CASE_ID_1) + .userId(userId) + .caseRole(role) + .organisationId(organisationId) + .build(); + } } diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocServiceTest.java index 7988776cdc..a65d36fad8 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocServiceTest.java @@ -176,7 +176,7 @@ void grantCaseAccess_shouldAddCaseUserRole() throws IOException { doNothing().when(caseAssignment).addCaseUserRole(any(CaseAssignmentUserRolesRequest.class)); - nocService.grantCaseAccess(userId, caseId, caseRole); + assertThat(nocService.grantCaseAccess(userId, caseId, caseRole)).isTrue(); ArgumentCaptor captor = ArgumentCaptor.forClass(CaseAssignmentUserRolesRequest.class); @@ -189,6 +189,14 @@ void grantCaseAccess_shouldAddCaseUserRole() throws IOException { assertEquals(caseRole, role.getCaseRole()); } + @Test + void grantCaseAccess_shouldReportFailure() throws IOException { + doThrow(new IOException("CCD unavailable")) + .when(caseAssignment).addCaseUserRole(any(CaseAssignmentUserRolesRequest.class)); + + assertThat(nocService.grantCaseAccess("userId", "case123", "[SOLICITORA]")).isFalse(); + } + private ChangeOrganisationRequest createChangeOrganisationRequest(Organisation organisationToAdd, Organisation organisationToRemove) { DynamicFixedListType caseRole = new DynamicFixedListType(); From b07c4cefc894eac7faab1132b92c36a903d92cd4 Mon Sep 17 00:00:00 2001 From: rajaram Date: Thu, 13 Aug 2026 17:19:57 +0100 Subject: [PATCH 029/100] Fixed functional test issue --- .../CaseActionsForCaseWorkerControllerFunctionalTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/apiTest/java/uk/gov/hmcts/ethos/replacement/apitest/CaseActionsForCaseWorkerControllerFunctionalTest.java b/src/test/apiTest/java/uk/gov/hmcts/ethos/replacement/apitest/CaseActionsForCaseWorkerControllerFunctionalTest.java index c5c7236c62..17786a2942 100644 --- a/src/test/apiTest/java/uk/gov/hmcts/ethos/replacement/apitest/CaseActionsForCaseWorkerControllerFunctionalTest.java +++ b/src/test/apiTest/java/uk/gov/hmcts/ethos/replacement/apitest/CaseActionsForCaseWorkerControllerFunctionalTest.java @@ -39,6 +39,7 @@ public void setUpCaseData() { CaseData caseData = CaseDataBuilder.builder() .withEthosCaseReference("6000001/2023") .withClaimant("claimant") + .withClaimantIndType("Claimant", "LastName") .withRespondent(RESPONDENT_NAME, NO, null, false) .build(); From 263e855db039f3e5bf0d4ddc142be5b1f1360dd0 Mon Sep 17 00:00:00 2001 From: rajaram Date: Fri, 14 Aug 2026 16:29:58 +0100 Subject: [PATCH 030/100] Changes for RET 6828, 6745, 6739 and 6728 --- ...AmendClaimantRepresentativeController.java | 16 ++- .../docmosis/service/CaseFlagsService.java | 134 ++++++++++++++---- .../noc/NocClaimantRepresentativeService.java | 26 +++- ...epresentativeControllerFunctionalTest.java | 55 +++++-- .../service/CaseFlagsServiceTest.java | 134 ++++++++++++++++++ .../NocClaimantRepresentativeServiceTest.java | 54 ++++++- 6 files changed, 371 insertions(+), 48 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeController.java index ec2f41a7b2..d26125a971 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeController.java @@ -90,7 +90,7 @@ public ResponseEntity amendClaimantRepresentativeMidEvent( /** * AboutToSubmit for addAmendClaimantRepresentative. Sets the claimant rep's id. * - * @param ccdRequest holds the request and case data + * @param callbackRequest holds the request and case data * @return Callback response entity with case data attached. */ @PostMapping(value = "/aboutToSubmit", consumes = APPLICATION_JSON_VALUE) @@ -105,22 +105,26 @@ public ResponseEntity amendClaimantRepresentativeMidEvent( @ApiResponse(responseCode = "500", description = "Internal Server Error") }) public ResponseEntity aboutToSubmit( - @RequestBody CCDRequest ccdRequest) { - CaseDataUtils.validateCCDRequest(ccdRequest); + @RequestBody CallbackRequest callbackRequest) { + CaseDataUtils.validateCaseDetails(callbackRequest.getCaseDetails()); List errors = new ArrayList<>(); String error = nocClaimantRepresentativeService.validateClaimantRepresentativeOrganisationMatch( - ccdRequest.getCaseDetails()); + callbackRequest.getCaseDetails()); if (StringUtils.isNotBlank(error)) { errors.add(error); } - CaseData caseData = ccdRequest.getCaseDetails().getCaseData(); + CaseData caseData = callbackRequest.getCaseDetails().getCaseData(); if (errors.isEmpty()) { ClaimantRepresentativeUtils.addAmendClaimantRepresentative(caseData); nocRespondentRepresentativeService.revokeRespondentRepresentativesWithSameOrganisationAsClaimant( - ccdRequest.getCaseDetails()); + callbackRequest.getCaseDetails()); } if (featureToggleService.isCaseFlagsEnabled()) { + caseFlagsService.clearClaimantRepresentativeFlagsIfRepresentativeChanged(caseData, + callbackRequest.getCaseDetailsBefore() == null + ? null + : callbackRequest.getCaseDetailsBefore().getCaseData()); caseFlagsService.setupCaseFlags(caseData); } diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java index 224c47cbfe..0b8f640cf6 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java @@ -14,9 +14,11 @@ import uk.gov.hmcts.et.common.model.ccd.items.TseAdminRecordDecisionTypeItem; import uk.gov.hmcts.et.common.model.ccd.types.AllPartyFlags; import uk.gov.hmcts.et.common.model.ccd.types.CaseFlagsType; +import uk.gov.hmcts.et.common.model.ccd.types.RepresentedTypeC; import uk.gov.hmcts.et.common.model.ccd.types.RepresentedTypeR; import uk.gov.hmcts.et.common.model.ccd.types.RespondentSumType; import uk.gov.hmcts.et.common.model.ccd.types.RestrictedReportingType; +import uk.gov.hmcts.ethos.replacement.docmosis.utils.noc.RoleUtils; import java.util.ArrayList; import java.util.Arrays; @@ -292,9 +294,9 @@ public void inactivateRespondentRepresentativeCaseFlags( PARTY_FLAGS.stream() .filter(flag -> PartyType.RESPONDENT_REPRESENTATIVE.equals(flag.partyType())) - .filter(flag -> hasUniqueRepresentativeAtIndex(caseData, flag.index())) + .filter(flag -> hasUniqueRepresentativeForFlagSlot(caseData, flag.index())) .filter(flag -> inactiveRepresentativeIdentities.contains(representativeIdentity( - caseData.getRepCollection().get(flag.index()).getValue()))) + representativeForFlagSlot(caseData, flag.index())))) .map(flag -> flag.get(caseData)) .filter(Objects::nonNull) .forEach(this::inactivateCaseFlags); @@ -305,14 +307,42 @@ public void clearRespondentRepresentativeFlags(CaseData caseData, List return; } + List representativeFlagSlotIndexes = representativeFlagSlotIndexes(caseData, representativeIndexes); PARTY_FLAGS.stream() .filter(flag -> PartyType.RESPONDENT_REPRESENTATIVE.equals(flag.partyType())) - .filter(flag -> representativeIndexes.contains(flag.index())) + .filter(flag -> representativeFlagSlotIndexes.contains(flag.index())) .map(flag -> flag.get(caseData)) .filter(Objects::nonNull) .forEach(flags -> flags.setDetails(null)); } + public void clearClaimantRepresentativeFlagsIfRepresentativeChanged(CaseData caseData, CaseData caseDataBefore) { + if (caseData == null || caseDataBefore == null + || !claimantRepresentativeChanged(caseData.getRepresentativeClaimantType(), + caseDataBefore.getRepresentativeClaimantType())) { + return; + } + + PARTY_FLAGS.stream() + .filter(flag -> PartyType.CLAIMANT_REPRESENTATIVE.equals(flag.partyType())) + .map(flag -> flag.get(caseData)) + .filter(Objects::nonNull) + .forEach(flags -> flags.setDetails(null)); + } + + private static boolean claimantRepresentativeChanged(RepresentedTypeC current, RepresentedTypeC previous) { + if (current == null || previous == null) { + return false; + } + + return !Objects.equals( + normaliseRepresentativeIdentity(current.getNameOfRepresentative()), + normaliseRepresentativeIdentity(previous.getNameOfRepresentative())) + || !Objects.equals( + normaliseRepresentativeIdentity(current.getRepresentativeEmailAddress()), + normaliseRepresentativeIdentity(previous.getRepresentativeEmailAddress())); + } + private static PartyFlag claimantFlag( Function getter, BiConsumer setter, @@ -369,7 +399,7 @@ private static boolean isRequired(CaseData caseData, PartyFlag flag) { return switch (flag.partyType()) { case CLAIMANT, CLAIMANT_REPRESENTATIVE -> true; case RESPONDENT -> respondentCount(caseData) > flag.index(); - case RESPONDENT_REPRESENTATIVE -> hasUniqueRepresentativeAtIndex(caseData, flag.index()); + case RESPONDENT_REPRESENTATIVE -> hasUniqueRepresentativeForFlagSlot(caseData, flag.index()); }; } @@ -378,7 +408,7 @@ private static boolean hasParty(CaseData caseData, PartyFlag flag) { case CLAIMANT -> true; case RESPONDENT -> respondentCount(caseData) > flag.index(); case CLAIMANT_REPRESENTATIVE -> caseData.getRepresentativeClaimantType() != null; - case RESPONDENT_REPRESENTATIVE -> hasUniqueRepresentativeAtIndex(caseData, flag.index()); + case RESPONDENT_REPRESENTATIVE -> hasUniqueRepresentativeForFlagSlot(caseData, flag.index()); }; } @@ -399,9 +429,9 @@ private static void alignIndexedFlagsWithCurrentOrder(CaseData caseData) { alignIndexedPartyFlags(caseData, PartyType.RESPONDENT, INTERNAL, respondentCount(caseData)); alignIndexedPartyFlags(caseData, PartyType.RESPONDENT, EXTERNAL, respondentCount(caseData)); alignIndexedPartyFlags( - caseData, PartyType.RESPONDENT_REPRESENTATIVE, INTERNAL, representativeCount(caseData)); + caseData, PartyType.RESPONDENT_REPRESENTATIVE, INTERNAL, representativeFlagSlotCount(caseData)); alignIndexedPartyFlags( - caseData, PartyType.RESPONDENT_REPRESENTATIVE, EXTERNAL, representativeCount(caseData)); + caseData, PartyType.RESPONDENT_REPRESENTATIVE, EXTERNAL, representativeFlagSlotCount(caseData)); } private static void alignIndexedPartyFlags( @@ -516,10 +546,7 @@ private static String getPartyName(CaseData caseData, PartyFlag flag) { .getValue() .getRespondentName(); case CLAIMANT_REPRESENTATIVE -> caseData.getRepresentativeClaimantType().getNameOfRepresentative(); - case RESPONDENT_REPRESENTATIVE -> caseData.getRepCollection() - .get(flag.index()) - .getValue() - .getNameOfRepresentative(); + case RESPONDENT_REPRESENTATIVE -> representativePartyNameForFlagSlot(caseData, flag.index()); }; } @@ -527,14 +554,71 @@ private static int respondentCount(CaseData caseData) { return caseData.getRespondentCollection() == null ? 0 : caseData.getRespondentCollection().size(); } - private static boolean hasUniqueRepresentativeAtIndex(CaseData caseData, int index) { - return representativeCount(caseData) > index && !isDuplicateRepresentativeAtIndex(caseData, index); + private static boolean hasUniqueRepresentativeForFlagSlot(CaseData caseData, int index) { + return representativeForFlagSlot(caseData, index) != null + && !isDuplicateRepresentativeAtFlagSlot(caseData, index); } private static int representativeCount(CaseData caseData) { return caseData.getRepCollection() == null ? 0 : caseData.getRepCollection().size(); } + private static int representativeFlagSlotCount(CaseData caseData) { + if (caseData.getRepCollection() == null) { + return 0; + } + + int slotCount = 0; + for (int i = 0; i < caseData.getRepCollection().size(); i++) { + slotCount = Math.max(slotCount, representativeFlagSlotIndex(caseData.getRepCollection().get(i), i) + 1); + } + return slotCount; + } + + private static List representativeFlagSlotIndexes(CaseData caseData, List representativeIndexes) { + if (caseData.getRepCollection() == null) { + return representativeIndexes; + } + + return representativeIndexes.stream() + .map(index -> representativeIndexToFlagSlotIndex(caseData, index)) + .filter(index -> index >= 0) + .toList(); + } + + private static int representativeIndexToFlagSlotIndex(CaseData caseData, int representativeIndex) { + if (representativeIndex < 0 || representativeIndex >= representativeCount(caseData)) { + return -1; + } + return representativeFlagSlotIndex(caseData.getRepCollection().get(representativeIndex), representativeIndex); + } + + @Nullable + private static RepresentedTypeR representativeForFlagSlot(CaseData caseData, int slotIndex) { + if (caseData.getRepCollection() == null) { + return null; + } + + for (int i = 0; i < caseData.getRepCollection().size(); i++) { + RepresentedTypeRItem representative = caseData.getRepCollection().get(i); + if (representative != null + && representative.getValue() != null + && representativeFlagSlotIndex(representative, i) == slotIndex) { + return representative.getValue(); + } + } + return null; + } + + private static int representativeFlagSlotIndex(RepresentedTypeRItem representative, int fallbackIndex) { + if (representative == null || representative.getValue() == null) { + return fallbackIndex; + } + + int roleIndex = RoleUtils.findRoleIndexByRoleLabel(representative.getValue().getRole()); + return roleIndex >= 0 ? roleIndex : fallbackIndex; + } + private static boolean representsAnyActiveRespondent(CaseData caseData, RepresentativeIdentity identity) { if (caseData.getRespondentCollection() == null) { return false; @@ -576,14 +660,14 @@ private static String respondentName(RespondentSumTypeItem respondent) { return respondent.getValue().getRespondentName(); } - private static boolean isDuplicateRepresentativeAtIndex(CaseData caseData, int index) { - RepresentativeIdentity identity = representativeIdentity(caseData.getRepCollection().get(index).getValue()); + private static boolean isDuplicateRepresentativeAtFlagSlot(CaseData caseData, int index) { + RepresentativeIdentity identity = representativeIdentity(representativeForFlagSlot(caseData, index)); if (identity == null) { return false; } for (int i = 0; i < index; i++) { - if (Objects.equals(identity, representativeIdentity(caseData.getRepCollection().get(i).getValue()))) { + if (Objects.equals(identity, representativeIdentity(representativeForFlagSlot(caseData, i)))) { return true; } } @@ -630,7 +714,7 @@ private static void alignRespondentRepresentativeFlagDetails( CaseData caseData, List existingRepresentativeFlags) { PARTY_FLAGS.stream() .filter(flag -> PartyType.RESPONDENT_REPRESENTATIVE.equals(flag.partyType())) - .filter(flag -> hasUniqueRepresentativeAtIndex(caseData, flag.index())) + .filter(flag -> hasUniqueRepresentativeForFlagSlot(caseData, flag.index())) .forEach(flag -> alignRepresentativeFlagDetails(caseData, flag, existingRepresentativeFlags)); } @@ -683,29 +767,27 @@ private static ListTypeItem staleRepresentativeFlagDetails( private static boolean existingRepresentativeFlagStillMatchesCurrentUniqueParty( CaseData caseData, ExistingRepresentativeFlag existingFlag) { - String currentPartyName = currentRepresentativePartyName(caseData, existingFlag.index()); - return hasUniqueRepresentativeAtIndex(caseData, existingFlag.index()) + String currentPartyName = representativePartyNameForFlagSlot(caseData, existingFlag.index()); + return hasUniqueRepresentativeForFlagSlot(caseData, existingFlag.index()) && Objects.equals(existingFlag.partyName(), currentPartyName); } - private static String currentRepresentativePartyName(CaseData caseData, int index) { - if (representativeCount(caseData) <= index || caseData.getRepCollection().get(index).getValue() == null) { - return null; - } - return caseData.getRepCollection().get(index).getValue().getNameOfRepresentative(); + private static String representativePartyNameForFlagSlot(CaseData caseData, int index) { + RepresentedTypeR representative = representativeForFlagSlot(caseData, index); + return representative == null ? null : representative.getNameOfRepresentative(); } private static void clearStaleRespondentRepresentativeFlags(CaseData caseData) { PARTY_FLAGS.stream() .filter(flag -> PartyType.RESPONDENT_REPRESENTATIVE.equals(flag.partyType())) - .filter(flag -> !hasUniqueRepresentativeAtIndex(caseData, flag.index())) + .filter(flag -> !hasUniqueRepresentativeForFlagSlot(caseData, flag.index())) .forEach(flag -> flag.clear(caseData)); } private static boolean hasStaleRespondentRepresentativeFlags(CaseData caseData) { return PARTY_FLAGS.stream() .filter(flag -> PartyType.RESPONDENT_REPRESENTATIVE.equals(flag.partyType())) - .filter(flag -> !hasUniqueRepresentativeAtIndex(caseData, flag.index())) + .filter(flag -> !hasUniqueRepresentativeForFlagSlot(caseData, flag.index())) .anyMatch(flag -> flag.get(caseData) != null); } diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocClaimantRepresentativeService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocClaimantRepresentativeService.java index a4f336990d..7c5eab2871 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocClaimantRepresentativeService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocClaimantRepresentativeService.java @@ -29,6 +29,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.Locale; import java.util.Objects; import java.util.Optional; import static uk.gov.hmcts.ecm.common.model.helper.Constants.NO; @@ -265,13 +266,13 @@ public void updateClaimantRepAccess(CallbackRequest callbackRequest) } public ChangeOrganisationRequest identifyRepresentationChanges(CaseData after, CaseData before) { - Organisation newRepOrg = after.getRepresentativeClaimantType() != null - ? after.getRepresentativeClaimantType().getMyHmctsOrganisation() : null; - Organisation oldRepOrg = before.getRepresentativeClaimantType() != null - ? before.getRepresentativeClaimantType().getMyHmctsOrganisation() : null; + RepresentedTypeC newRep = after.getRepresentativeClaimantType(); + RepresentedTypeC oldRep = before.getRepresentativeClaimantType(); + Organisation newRepOrg = newRep != null ? newRep.getMyHmctsOrganisation() : null; + Organisation oldRepOrg = oldRep != null ? oldRep.getMyHmctsOrganisation() : null; ChangeOrganisationRequest changeRequests; - if (!Objects.equals(newRepOrg, oldRepOrg)) { + if (!Objects.equals(newRepOrg, oldRepOrg) || claimantRepresentativeChanged(newRep, oldRep)) { changeRequests = NocUtils.buildApprovedChangeOrganisationRequest(newRepOrg, oldRepOrg, ClaimantSolicitorRole.CLAIMANTSOLICITOR.getCaseRoleLabel()); } else { @@ -281,4 +282,19 @@ public ChangeOrganisationRequest identifyRepresentationChanges(CaseData after, return changeRequests; } + + private static boolean claimantRepresentativeChanged(RepresentedTypeC current, RepresentedTypeC previous) { + if (current == null || previous == null) { + return false; + } + + return !Objects.equals(normaliseRepresentativeIdentity(current.getNameOfRepresentative()), + normaliseRepresentativeIdentity(previous.getNameOfRepresentative())) + || !Objects.equals(normaliseRepresentativeIdentity(current.getRepresentativeEmailAddress()), + normaliseRepresentativeIdentity(previous.getRepresentativeEmailAddress())); + } + + private static String normaliseRepresentativeIdentity(String value) { + return StringUtils.trimToEmpty(value).toLowerCase(Locale.ROOT); + } } diff --git a/src/test/apiTest/java/uk/gov/hmcts/ethos/replacement/apitest/AddAmendClaimantRepresentativeControllerFunctionalTest.java b/src/test/apiTest/java/uk/gov/hmcts/ethos/replacement/apitest/AddAmendClaimantRepresentativeControllerFunctionalTest.java index aa5540aa59..8daab0c79c 100644 --- a/src/test/apiTest/java/uk/gov/hmcts/ethos/replacement/apitest/AddAmendClaimantRepresentativeControllerFunctionalTest.java +++ b/src/test/apiTest/java/uk/gov/hmcts/ethos/replacement/apitest/AddAmendClaimantRepresentativeControllerFunctionalTest.java @@ -8,36 +8,42 @@ import org.json.JSONObject; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import uk.gov.hmcts.et.common.model.ccd.CCDRequest; import uk.gov.hmcts.et.common.model.ccd.CallbackRequest; import uk.gov.hmcts.et.common.model.ccd.CaseData; import uk.gov.hmcts.et.common.model.ccd.CaseDetails; +import uk.gov.hmcts.et.common.model.ccd.items.FlagDetailType; +import uk.gov.hmcts.et.common.model.ccd.items.ListTypeItem; +import uk.gov.hmcts.et.common.model.ccd.types.AllPartyFlags; +import uk.gov.hmcts.et.common.model.ccd.types.CaseFlagsType; import uk.gov.hmcts.et.common.model.ccd.types.Organisation; import uk.gov.hmcts.et.common.model.ccd.types.RepresentedTypeC; -import uk.gov.hmcts.ethos.utils.CCDRequestBuilder; import uk.gov.hmcts.ethos.utils.CaseDataBuilder; import java.io.IOException; import java.util.ArrayList; +import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.ACTIVE; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.CLAIMANT_REPRESENTATIVE; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.EXTERNAL; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.INTERNAL; import static uk.gov.hmcts.ecm.common.model.helper.Constants.EMPLOYMENT; import static uk.gov.hmcts.ecm.common.model.helper.Constants.SCOTLAND_CASE_TYPE_ID; +import static uk.gov.hmcts.ecm.common.model.helper.Constants.YES; @Slf4j public class AddAmendClaimantRepresentativeControllerFunctionalTest extends BaseFunctionalTest { private static final String ABOUT_TO_SUBMIT_URL = "/addAmendClaimantRepresentative/aboutToSubmit"; private static final String SUBMITTED_URL = "/addAmendClaimantRepresentative/amendClaimantRepSubmitted"; - private CCDRequest ccdRequest; + private static final String OLD_REPRESENTATIVE_NAME = "Old Claimant Representative"; + private static final String NEW_REPRESENTATIVE_NAME = "New Claimant Representative"; + private CallbackRequest callbackRequest; @BeforeAll public void setUpCaseData() throws IOException { - ccdRequest = CCDRequestBuilder.builder() - .withCaseData(CaseDataBuilder.builder().build()) - .withCaseId("1234567890123456") - .build(); final JSONObject createdCase = createSinglesCaseDataStore(); CaseData caseDataBefore = CaseDataBuilder.builder() @@ -50,7 +56,10 @@ public void setUpCaseData() throws IOException { .build(); caseDataBefore.setRespondentCollection(new ArrayList<>()); caseDataAfter.setRespondentCollection(new ArrayList<>()); - caseDataAfter.setRepresentativeClaimantType(createClaimantRepresentative()); + caseDataBefore.setRepresentativeClaimantType(createClaimantRepresentative(OLD_REPRESENTATIVE_NAME)); + caseDataAfter.setClaimantRepresentedQuestion(YES); + caseDataAfter.setRepresentativeClaimantType(createClaimantRepresentative(NEW_REPRESENTATIVE_NAME)); + caseDataAfter.setAllPartyFlags(createClaimantRepresentativeFlags(OLD_REPRESENTATIVE_NAME)); CaseDetails caseDetailsBefore = createCaseDetails(String.valueOf(createdCase.getLong("id")), caseDataBefore); CaseDetails caseDetails = createCaseDetails(String.valueOf(createdCase.getLong("id")), caseDataAfter); @@ -67,10 +76,15 @@ void aboutToSubmitSuccessResponse() { .spec(spec) .contentType(ContentType.JSON) .header(new Header(AUTHORIZATION, userToken)) - .body(ccdRequest) + .body(callbackRequest) .post(ABOUT_TO_SUBMIT_URL) .then() .statusCode(HttpStatus.SC_OK) + .body("data.allPartyFlags.claimantRepresentativeFlags.partyName", equalTo(NEW_REPRESENTATIVE_NAME)) + .body("data.allPartyFlags.claimantRepresentativeFlags.details", nullValue()) + .body("data.allPartyFlags.claimantRepresentativeExternalFlags.partyName", + equalTo(NEW_REPRESENTATIVE_NAME)) + .body("data.allPartyFlags.claimantRepresentativeExternalFlags.details", nullValue()) .log() .all(true); } @@ -102,8 +116,9 @@ private CaseDetails createCaseDetails(String caseId, CaseData caseData) { return caseDetails; } - private RepresentedTypeC createClaimantRepresentative() { + private RepresentedTypeC createClaimantRepresentative(String representativeName) { RepresentedTypeC claimantRepresentative = new RepresentedTypeC(); + claimantRepresentative.setNameOfRepresentative(representativeName); claimantRepresentative.setMyHmctsOrganisation(Organisation.builder() .organisationID("ORG1") .organisationName("ET Org 1") @@ -111,4 +126,24 @@ private RepresentedTypeC createClaimantRepresentative() { return claimantRepresentative; } + + private AllPartyFlags createClaimantRepresentativeFlags(String representativeName) { + return AllPartyFlags.builder() + .claimantRepresentativeFlags(createCaseFlags(representativeName, INTERNAL, "Internal flag")) + .claimantRepresentativeExternalFlags(createCaseFlags(representativeName, EXTERNAL, "External flag")) + .build(); + } + + private CaseFlagsType createCaseFlags(String representativeName, String visibility, String flagName) { + return CaseFlagsType.builder() + .partyName(representativeName) + .roleOnCase(CLAIMANT_REPRESENTATIVE) + .groupId(CLAIMANT_REPRESENTATIVE) + .visibility(visibility) + .details(ListTypeItem.from(FlagDetailType.builder() + .name(flagName) + .status(ACTIVE) + .build())) + .build(); + } } diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java index 8940a17d31..28e6dcf19a 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java @@ -230,6 +230,39 @@ void setupCaseFlags_shouldOnlyCreateRespondentRepresentativeFlagsForExistingRepr }); } + @Test + void setupCaseFlags_shouldUseSolicitorRoleForRepresentativeFlagSlotWhenRespondentHasNoRepresentative() { + caseData.setRespondentCollection(respondentCollection(4)); + List respondents = caseData.getRespondentCollection(); + caseData.setRepCollection(List.of( + representativeItemForRespondent( + "1", "Representative 1", "rep1@example.com", respondents.get(0), "[SOLICITORA]"), + representativeItemForRespondent( + "2", "Representative 2", "rep2@example.com", respondents.get(1), "[SOLICITORB]"), + representativeItemForRespondent( + "4", "Representative 3", "rep3@example.com", respondents.get(3), "[SOLICITORD]") + )); + + caseFlagsService.setupCaseFlags(caseData); + + AllPartyFlags allPartyFlags = allPartyFlags(caseData); + assertAll( + () -> assertEquals("Representative 1", allPartyFlags.getRepresentativeFlags().getPartyName()), + () -> assertEquals("Representative 2", allPartyFlags.getRepresentative1Flags().getPartyName()), + () -> assertNull(allPartyFlags.getRepresentative2Flags()), + () -> assertNull(allPartyFlags.getRepresentative2ExternalFlags()), + () -> assertEquals("Representative 3", allPartyFlags.getRepresentative3Flags().getPartyName()), + () -> assertEquals(REPRESENTATIVE4, allPartyFlags.getRepresentative3Flags().getRoleOnCase()), + () -> assertEquals(INTERNAL, allPartyFlags.getRepresentative3Flags().getVisibility()), + () -> assertEquals( + "Representative 3", allPartyFlags.getRepresentative3ExternalFlags().getPartyName()), + () -> assertEquals( + REPRESENTATIVE4, allPartyFlags.getRepresentative3ExternalFlags().getRoleOnCase()), + () -> assertEquals(EXTERNAL, allPartyFlags.getRepresentative3ExternalFlags().getVisibility()), + () -> assertFalse(caseFlagsService.caseFlagsSetupRequired(caseData)) + ); + } + @Test void setupCaseFlags_shouldReuseRespondentRepresentativeFlagsForTheSameRepresentativeWithoutCompactingSlots() { String sharedRepresentativeName = "Shared Representative"; @@ -658,6 +691,36 @@ void clearRespondentRepresentativeFlags_shouldRemoveMatchingRepresentativeIndexF assertEquals(ACTIVE, respondentFlags.getDetails().getFirst().getValue().getStatus()); } + @Test + void clearRespondentRepresentativeFlags_shouldClearTheRepresentativesRoleAlignedFlagSlot() { + caseData.setRespondentCollection(respondentCollection(4)); + List respondents = caseData.getRespondentCollection(); + caseData.setRepCollection(List.of( + representativeItemForRespondent( + "1", "Representative 1", "rep1@example.com", respondents.get(0), "[SOLICITORA]"), + representativeItemForRespondent( + "2", "Representative 2", "rep2@example.com", respondents.get(1), "[SOLICITORB]"), + representativeItemForRespondent( + "4", "Representative 3", "rep3@example.com", respondents.get(3), "[SOLICITORD]") + )); + caseFlagsService.setupCaseFlags(caseData); + AllPartyFlags allPartyFlags = allPartyFlags(caseData); + CaseFlagsType representativeInternalFlags = allPartyFlags.getRepresentative3Flags(); + CaseFlagsType representativeExternalFlags = allPartyFlags.getRepresentative3ExternalFlags(); + representativeInternalFlags.setDetails(ListTypeItem.from(activeFlag("Representative internal flag"))); + representativeExternalFlags.setDetails(ListTypeItem.from(activeFlag("Representative external flag"))); + + caseFlagsService.clearRespondentRepresentativeFlags(caseData, List.of(2)); + + assertAll( + () -> assertNull(representativeInternalFlags.getDetails()), + () -> assertNull(representativeExternalFlags.getDetails()), + () -> assertNotNull(allPartyFlags.getRepresentativeFlags()), + () -> assertNotNull(allPartyFlags.getRepresentative1Flags()), + () -> assertNull(allPartyFlags.getRepresentative2Flags()) + ); + } + @Test void setupCaseFlags_shouldMoveRespondentFlagsWithRespondentWhenCollectionIsReordered() { caseData.setRespondentCollection(respondentCollection(3)); @@ -824,6 +887,71 @@ void setupCaseFlags_shouldUpdateClaimantRepresentativeFlagsWhenNameChanges() { assertEquals(EXTERNAL, claimantRepresentativeExternalFlags.getVisibility()); } + @Test + void clearClaimantRepresentativeFlagsIfRepresentativeChanged_shouldRemoveDetailsWhenNameChanges() { + CaseData caseDataBefore = CaseDataBuilder.builder().build(); + caseDataBefore.setRepresentativeClaimantType(RepresentedTypeC.builder() + .nameOfRepresentative(CLAIMANT_REPRESENTATIVE_NAME) + .representativeEmailAddress("claimant.rep@example.com") + .build()); + caseData.getRepresentativeClaimantType().setRepresentativeEmailAddress("claimant.rep@example.com"); + caseFlagsService.setupCaseFlags(caseData); + allPartyFlags(caseData).getClaimantRepresentativeFlags() + .setDetails(ListTypeItem.from(activeFlag("Previous internal rep flag"))); + allPartyFlags(caseData).getClaimantRepresentativeExternalFlags() + .setDetails(ListTypeItem.from(activeFlag("Previous external rep flag"))); + caseData.getRepresentativeClaimantType().setNameOfRepresentative("Updated Claimant Representative Name"); + + caseFlagsService.clearClaimantRepresentativeFlagsIfRepresentativeChanged(caseData, caseDataBefore); + caseFlagsService.setupCaseFlags(caseData); + + assertNull(allPartyFlags(caseData).getClaimantRepresentativeFlags().getDetails()); + assertNull(allPartyFlags(caseData).getClaimantRepresentativeExternalFlags().getDetails()); + assertEquals("Updated Claimant Representative Name", + allPartyFlags(caseData).getClaimantRepresentativeExternalFlags().getPartyName()); + } + + @Test + void clearClaimantRepresentativeFlagsIfRepresentativeChanged_shouldRemoveDetailsWhenEmailChanges() { + CaseData caseDataBefore = CaseDataBuilder.builder().build(); + caseDataBefore.setRepresentativeClaimantType(RepresentedTypeC.builder() + .nameOfRepresentative(CLAIMANT_REPRESENTATIVE_NAME) + .representativeEmailAddress("old.claimant.rep@example.com") + .build()); + caseData.getRepresentativeClaimantType().setRepresentativeEmailAddress("new.claimant.rep@example.com"); + caseFlagsService.setupCaseFlags(caseData); + allPartyFlags(caseData).getClaimantRepresentativeFlags() + .setDetails(ListTypeItem.from(activeFlag("Previous internal rep flag"))); + allPartyFlags(caseData).getClaimantRepresentativeExternalFlags() + .setDetails(ListTypeItem.from(activeFlag("Previous external rep flag"))); + + caseFlagsService.clearClaimantRepresentativeFlagsIfRepresentativeChanged(caseData, caseDataBefore); + caseFlagsService.setupCaseFlags(caseData); + + assertNull(allPartyFlags(caseData).getClaimantRepresentativeFlags().getDetails()); + assertNull(allPartyFlags(caseData).getClaimantRepresentativeExternalFlags().getDetails()); + assertEquals(CLAIMANT_REPRESENTATIVE_NAME, + allPartyFlags(caseData).getClaimantRepresentativeExternalFlags().getPartyName()); + } + + @Test + void clearClaimantRepresentativeFlagsIfRepresentativeChanged_shouldKeepDetailsWhenOnlyOrganisationChanges() { + CaseData caseDataBefore = CaseDataBuilder.builder().build(); + caseDataBefore.setRepresentativeClaimantType(RepresentedTypeC.builder() + .nameOfRepresentative(CLAIMANT_REPRESENTATIVE_NAME) + .representativeEmailAddress("claimant.rep@example.com") + .build()); + caseData.getRepresentativeClaimantType().setRepresentativeEmailAddress("claimant.rep@example.com"); + caseFlagsService.setupCaseFlags(caseData); + allPartyFlags(caseData).getClaimantRepresentativeExternalFlags() + .setDetails(ListTypeItem.from(activeFlag("Existing external rep flag"))); + + caseFlagsService.clearClaimantRepresentativeFlagsIfRepresentativeChanged(caseData, caseDataBefore); + caseFlagsService.setupCaseFlags(caseData); + + assertNotNull(allPartyFlags(caseData).getClaimantRepresentativeExternalFlags().getDetails()); + } + @ParameterizedTest(name = "{0}") @MethodSource("respondentRepresentativePartyFlagSlots") void setupCaseFlags_shouldRemoveRespondentRepresentativeFlagDetailsWhenNameChanges(FlagSlot slot) { @@ -1261,11 +1389,17 @@ private static RepresentedTypeRItem representativeItem(String id, RepresentedTyp private static RepresentedTypeRItem representativeItemForRespondent( String id, String name, String email, RespondentSumTypeItem respondent) { + return representativeItemForRespondent(id, name, email, respondent, null); + } + + private static RepresentedTypeRItem representativeItemForRespondent( + String id, String name, String email, RespondentSumTypeItem respondent, String role) { RepresentedTypeR representative = RepresentedTypeR.builder() .nameOfRepresentative(name) .representativeEmailAddress(email) .respondentId(respondent.getId()) .respRepName(respondent.getValue().getRespondentName()) + .role(role) .build(); return representativeItem(id, representative); } diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocClaimantRepresentativeServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocClaimantRepresentativeServiceTest.java index 4dce890005..e3b9b90d44 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocClaimantRepresentativeServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocClaimantRepresentativeServiceTest.java @@ -255,6 +255,58 @@ void shouldReturnChangeRequestWhenOrganisationUnchanged() { assertThat(result).isSameAs(expected); } + @Test + void shouldReturnChangeRequestWithOrganisationToRemoveWhenNameChanges() { + Organisation org = Organisation.builder().organisationID("SAME").build(); + CaseData after = new CaseData(); + CaseData before = new CaseData(); + after.setRepresentativeClaimantType(RepresentedTypeC.builder() + .nameOfRepresentative("New Representative") + .representativeEmailAddress("claimant.rep@example.com") + .myHmctsOrganisation(org) + .build()); + before.setRepresentativeClaimantType(RepresentedTypeC.builder() + .nameOfRepresentative("Old Representative") + .representativeEmailAddress("claimant.rep@example.com") + .myHmctsOrganisation(org) + .build()); + + ChangeOrganisationRequest expected = ChangeOrganisationRequest.builder().build(); + when(NocUtils.buildApprovedChangeOrganisationRequest(org, org, + ClaimantSolicitorRole.CLAIMANTSOLICITOR.getCaseRoleLabel())).thenReturn(expected); + + ChangeOrganisationRequest result = + nocClaimantRepresentativeService.identifyRepresentationChanges(after, before); + + assertThat(result).isSameAs(expected); + } + + @Test + void shouldReturnChangeRequestWithOrganisationToRemoveWhenEmailChanges() { + Organisation org = Organisation.builder().organisationID("SAME").build(); + CaseData after = new CaseData(); + CaseData before = new CaseData(); + after.setRepresentativeClaimantType(RepresentedTypeC.builder() + .nameOfRepresentative("Claimant Representative") + .representativeEmailAddress("new.claimant.rep@example.com") + .myHmctsOrganisation(org) + .build()); + before.setRepresentativeClaimantType(RepresentedTypeC.builder() + .nameOfRepresentative("Claimant Representative") + .representativeEmailAddress("old.claimant.rep@example.com") + .myHmctsOrganisation(org) + .build()); + + ChangeOrganisationRequest expected = ChangeOrganisationRequest.builder().build(); + when(NocUtils.buildApprovedChangeOrganisationRequest(org, org, + ClaimantSolicitorRole.CLAIMANTSOLICITOR.getCaseRoleLabel())).thenReturn(expected); + + ChangeOrganisationRequest result = + nocClaimantRepresentativeService.identifyRepresentationChanges(after, before); + + assertThat(result).isSameAs(expected); + } + @Test void shouldHandleNullRepresentativeClaimantType() { CaseData after = new CaseData(); @@ -340,4 +392,4 @@ void theValidateClaimantRepresentativeOrganisationMatch() { assertThat(nocClaimantRepresentativeService.validateClaimantRepresentativeOrganisationMatch(tmpCaseDetails)) .isEmpty(); } -} \ No newline at end of file +} From fe25bda773cbd0e4d0efae018ea03e53f1f729c8 Mon Sep 17 00:00:00 2001 From: rajaram Date: Fri, 14 Aug 2026 17:11:05 +0100 Subject: [PATCH 031/100] Function test failure fixed --- ...aimantRepresentativeControllerFunctionalTest.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/test/apiTest/java/uk/gov/hmcts/ethos/replacement/apitest/AddAmendClaimantRepresentativeControllerFunctionalTest.java b/src/test/apiTest/java/uk/gov/hmcts/ethos/replacement/apitest/AddAmendClaimantRepresentativeControllerFunctionalTest.java index 8daab0c79c..dac281d612 100644 --- a/src/test/apiTest/java/uk/gov/hmcts/ethos/replacement/apitest/AddAmendClaimantRepresentativeControllerFunctionalTest.java +++ b/src/test/apiTest/java/uk/gov/hmcts/ethos/replacement/apitest/AddAmendClaimantRepresentativeControllerFunctionalTest.java @@ -79,14 +79,14 @@ void aboutToSubmitSuccessResponse() { .body(callbackRequest) .post(ABOUT_TO_SUBMIT_URL) .then() + .log() + .ifValidationFails() .statusCode(HttpStatus.SC_OK) - .body("data.allPartyFlags.claimantRepresentativeFlags.partyName", equalTo(NEW_REPRESENTATIVE_NAME)) - .body("data.allPartyFlags.claimantRepresentativeFlags.details", nullValue()) - .body("data.allPartyFlags.claimantRepresentativeExternalFlags.partyName", + .body("data.claimantRepresentativeFlags.partyName", equalTo(NEW_REPRESENTATIVE_NAME)) + .body("data.claimantRepresentativeFlags.details", nullValue()) + .body("data.claimantRepresentativeExternalFlags.partyName", equalTo(NEW_REPRESENTATIVE_NAME)) - .body("data.allPartyFlags.claimantRepresentativeExternalFlags.details", nullValue()) - .log() - .all(true); + .body("data.claimantRepresentativeExternalFlags.details", nullValue()); } @Test From f356d7d4c9b3c51e661a77249b11735b82ede820 Mon Sep 17 00:00:00 2001 From: rajaram Date: Tue, 18 Aug 2026 16:16:47 +0100 Subject: [PATCH 032/100] RET-6897 - Implementation with tests --- .../CaseFlagsDataMigrationController.java | 28 +- .../CaseFlagReferenceDataDetail.java | 20 + .../caseflags/CaseFlagReferenceDataGroup.java | 18 + .../CaseFlagReferenceDataResponse.java | 16 + .../rdprofessional/OrganisationClient.java | 15 + .../CaseFlagsReferenceDataService.java | 98 ++ .../docmosis/service/CaseFlagsService.java | 204 ++++ .../CaseFlagsDataMigrationControllerTest.java | 56 +- .../CaseFlagsReferenceDataServiceTest.java | 78 ++ .../service/CaseFlagsServiceTest.java | 181 +++- .../requests/caseFlagMigrationRequest.json | 901 ++++++++++++++++++ 11 files changed, 1551 insertions(+), 64 deletions(-) create mode 100644 src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/domain/caseflags/CaseFlagReferenceDataDetail.java create mode 100644 src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/domain/caseflags/CaseFlagReferenceDataGroup.java create mode 100644 src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/domain/caseflags/CaseFlagReferenceDataResponse.java create mode 100644 src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsReferenceDataService.java create mode 100644 src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsReferenceDataServiceTest.java create mode 100644 src/test/resources/requests/caseFlagMigrationRequest.json diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsDataMigrationController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsDataMigrationController.java index 2d16775c4b..6fd31346b2 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsDataMigrationController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsDataMigrationController.java @@ -15,7 +15,7 @@ import uk.gov.hmcts.et.common.model.ccd.CCDCallbackResponse; import uk.gov.hmcts.et.common.model.ccd.CCDRequest; import uk.gov.hmcts.et.common.model.ccd.CaseData; -import uk.gov.hmcts.et.common.model.ccd.types.CaseFlagsType; +import uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsReferenceDataService; import uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService; import uk.gov.hmcts.ethos.replacement.docmosis.service.VerifyTokenService; @@ -23,9 +23,6 @@ import static org.springframework.http.HttpStatus.FORBIDDEN; import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; -import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.CLAIMANT; -import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.INTERNAL; -import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.RESPONDENT1; import static uk.gov.hmcts.ethos.replacement.docmosis.helpers.CallbackRespHelper.getCallbackRespEntityErrors; @Slf4j @@ -37,9 +34,10 @@ public class CaseFlagsDataMigrationController { private final VerifyTokenService verifyTokenService; private final CaseFlagsService caseFlagsService; + private final CaseFlagsReferenceDataService caseFlagsReferenceDataService; @PostMapping(value = "/case-flags-migration/about-to-submit", consumes = APPLICATION_JSON_VALUE) - @Operation(summary = "update existing cases with default values for case flags.") + @Operation(summary = "migrate existing party case flags into internal and external sections.") @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Accessed successfully", content = {@Content(mediaType = "application/json", @@ -59,22 +57,10 @@ public ResponseEntity addCaseFlagsData( } CaseData caseData = ccdRequest.getCaseDetails().getCaseData(); - caseFlagsService.setupCaseFlags(caseData); - CaseFlagsType claimantFlags = caseData.getAllPartyFlags().getClaimantFlags(); - CaseFlagsType respondentFlags = caseData.getAllPartyFlags().getRespondentFlags(); - - /* Add visibility and group ID fields for the claimant and the first respondent records - that were already migrated in Case Flag v1.0. */ - if (claimantFlags.getGroupId() == null) { - claimantFlags.setGroupId(CLAIMANT); - claimantFlags.setVisibility(INTERNAL); - } - - if (respondentFlags.getGroupId() == null) { - respondentFlags.setRoleOnCase(RESPONDENT1); - respondentFlags.setGroupId(RESPONDENT1); - respondentFlags.setVisibility(INTERNAL); - } + caseFlagsService.migrateExistingClaimantAndRespondentCaseFlags( + caseData, + caseFlagsReferenceDataService.getPartyFlagVisibilities(userToken) + ); log.info("Migrating existing case: {}", ccdRequest.getCaseDetails().getCaseId()); diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/domain/caseflags/CaseFlagReferenceDataDetail.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/domain/caseflags/CaseFlagReferenceDataDetail.java new file mode 100644 index 0000000000..d1c7a9dae2 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/domain/caseflags/CaseFlagReferenceDataDetail.java @@ -0,0 +1,20 @@ +package uk.gov.hmcts.ethos.replacement.docmosis.domain.caseflags; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@JsonIgnoreProperties(ignoreUnknown = true) +public class CaseFlagReferenceDataDetail { + private String name; + private Boolean externallyAvailable; + private String flagCode; + private String nativeFlagCode; + private List childFlags; +} diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/domain/caseflags/CaseFlagReferenceDataGroup.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/domain/caseflags/CaseFlagReferenceDataGroup.java new file mode 100644 index 0000000000..6cd9667158 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/domain/caseflags/CaseFlagReferenceDataGroup.java @@ -0,0 +1,18 @@ +package uk.gov.hmcts.ethos.replacement.docmosis.domain.caseflags; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@JsonIgnoreProperties(ignoreUnknown = true) +public class CaseFlagReferenceDataGroup { + @JsonProperty("FlagDetails") + private List flagDetails; +} diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/domain/caseflags/CaseFlagReferenceDataResponse.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/domain/caseflags/CaseFlagReferenceDataResponse.java new file mode 100644 index 0000000000..4d9a1d18a6 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/domain/caseflags/CaseFlagReferenceDataResponse.java @@ -0,0 +1,16 @@ +package uk.gov.hmcts.ethos.replacement.docmosis.domain.caseflags; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@JsonIgnoreProperties(ignoreUnknown = true) +public class CaseFlagReferenceDataResponse { + private List flags; +} diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/rdprofessional/OrganisationClient.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/rdprofessional/OrganisationClient.java index d9dc71ffdc..ccd473b05e 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/rdprofessional/OrganisationClient.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/rdprofessional/OrganisationClient.java @@ -11,6 +11,7 @@ import uk.gov.hmcts.et.common.model.ccd.types.OrganisationUsersResponse; import uk.gov.hmcts.et.common.model.ccd.types.OrganisationsResponse; import uk.gov.hmcts.ethos.replacement.docmosis.domain.AccountIdByEmailResponse; +import uk.gov.hmcts.ethos.replacement.docmosis.domain.caseflags.CaseFlagReferenceDataResponse; import java.util.List; import static org.springframework.http.HttpHeaders.AUTHORIZATION; @@ -72,4 +73,18 @@ ResponseEntity getAccountIdByEmail( @RequestParam("email") String email ); + @GetMapping( + value = "/refdata/commondata/caseflags/service-id={serviceId}", + consumes = MediaType.APPLICATION_JSON_VALUE, + produces = MediaType.APPLICATION_JSON_VALUE + ) + CaseFlagReferenceDataResponse getCaseFlags( + @RequestHeader(AUTHORIZATION) String authorisation, + @RequestHeader(SERVICE_AUTHORIZATION) String serviceAuthorisation, + @PathVariable("serviceId") String serviceId, + @RequestParam("flag-type") String flagType, + @RequestParam("welsh-required") String welshRequired, + @RequestParam("available-external-flag") String availableExternalFlag + ); + } diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsReferenceDataService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsReferenceDataService.java new file mode 100644 index 0000000000..9c5d77922f --- /dev/null +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsReferenceDataService.java @@ -0,0 +1,98 @@ +package uk.gov.hmcts.ethos.replacement.docmosis.service; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import uk.gov.hmcts.ethos.replacement.docmosis.domain.caseflags.CaseFlagReferenceDataDetail; +import uk.gov.hmcts.ethos.replacement.docmosis.domain.caseflags.CaseFlagReferenceDataGroup; +import uk.gov.hmcts.ethos.replacement.docmosis.domain.caseflags.CaseFlagReferenceDataResponse; +import uk.gov.hmcts.ethos.replacement.docmosis.rdprofessional.OrganisationClient; +import uk.gov.hmcts.reform.authorisation.generators.AuthTokenGenerator; + +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Objects; + +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.EXTERNAL; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.INTERNAL; + +@Service +public class CaseFlagsReferenceDataService { + private static final String PARTY_FLAG_TYPE = "PARTY"; + private static final String WELSH_REQUIRED = "Y"; + private static final String AVAILABLE_EXTERNAL_FLAG = "N"; + + private final OrganisationClient organisationClient; + private final AuthTokenGenerator authTokenGenerator; + private final String hmctsServiceId; + + public CaseFlagsReferenceDataService( + OrganisationClient organisationClient, + AuthTokenGenerator authTokenGenerator, + @Value("${hmcts_service_id:BHA1}") String hmctsServiceId) { + this.organisationClient = organisationClient; + this.authTokenGenerator = authTokenGenerator; + this.hmctsServiceId = hmctsServiceId; + } + + public Map getPartyFlagVisibilities(String userToken) { + CaseFlagReferenceDataResponse response = organisationClient.getCaseFlags( + userToken, + authTokenGenerator.generate(), + hmctsServiceId, + PARTY_FLAG_TYPE, + WELSH_REQUIRED, + AVAILABLE_EXTERNAL_FLAG + ); + + return visibilityByFlagCodeOrName(response); + } + + Map visibilityByFlagCodeOrName(CaseFlagReferenceDataResponse response) { + Map visibilityByKey = new HashMap<>(); + if (response == null || response.getFlags() == null) { + return visibilityByKey; + } + + response.getFlags().stream() + .map(CaseFlagReferenceDataGroup::getFlagDetails) + .filter(Objects::nonNull) + .flatMap(List::stream) + .forEach(flag -> addFlagVisibility(visibilityByKey, flag)); + return visibilityByKey; + } + + private static void addFlagVisibility(Map visibilityByKey, CaseFlagReferenceDataDetail flag) { + if (flag == null) { + return; + } + + String visibility = Boolean.TRUE.equals(flag.getExternallyAvailable()) ? EXTERNAL : INTERNAL; + putVisibility(visibilityByKey, flag.getFlagCode(), visibility); + putVisibility(visibilityByKey, flag.getNativeFlagCode(), visibility); + putVisibility(visibilityByKey, flag.getName(), visibility); + + if (flag.getChildFlags() != null) { + flag.getChildFlags().forEach(childFlag -> addFlagVisibility(visibilityByKey, childFlag)); + } + } + + private static void putVisibility(Map visibilityByKey, String key, String visibility) { + String normalisedKey = normaliseCaseFlagReferenceKey(key); + if (StringUtils.isBlank(normalisedKey)) { + return; + } + + visibilityByKey.merge( + normalisedKey, + visibility, + (existing, candidate) -> Objects.equals(existing, candidate) ? existing : StringUtils.EMPTY + ); + } + + public static String normaliseCaseFlagReferenceKey(String value) { + return StringUtils.trimToEmpty(value).toLowerCase(Locale.ROOT); + } +} diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java index 0b8f640cf6..d61b117c86 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java @@ -66,6 +66,7 @@ import static uk.gov.hmcts.ecm.common.model.helper.Constants.NO; import static uk.gov.hmcts.ecm.common.model.helper.Constants.TSE_APP_RESTRICT_PUBLICITY; import static uk.gov.hmcts.ecm.common.model.helper.Constants.YES; +import static uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsReferenceDataService.normaliseCaseFlagReferenceKey; @Slf4j @Service @@ -200,6 +201,37 @@ public void setupCaseFlags(CaseData caseData) { clearStaleRespondentRepresentativeFlags(caseData); } + /** + * Migrates existing claimant and respondent case flags from the v1.0 fields into + * the v2.1 internal and external sections. + * + * @param caseData Data about the current case + */ + public void migrateExistingClaimantAndRespondentCaseFlags(CaseData caseData) { + migrateExistingClaimantAndRespondentCaseFlags(caseData, Map.of()); + } + + /** + * Migrates existing claimant and respondent case flags from the v1.0 fields into + * the v2.1 internal and external sections. + * + * @param caseData Data about the current case + * @param referenceDataVisibilityByFlagCodeOrName flag visibility from reference data, keyed by flag code or name + */ + public void migrateExistingClaimantAndRespondentCaseFlags( + CaseData caseData, + Map referenceDataVisibilityByFlagCodeOrName) { + if (caseData == null) { + return; + } + + Map referenceDataVisibility = normaliseCaseFlagVisibility( + referenceDataVisibilityByFlagCodeOrName); + List existingFlagDetails = currentClaimantAndRespondentFlagDetails(caseData); + setupCaseFlags(caseData); + existingFlagDetails.forEach(details -> migrateExistingFlagDetails(caseData, details, referenceDataVisibility)); + } + /** * Sets case flags for Claimant, Respondent, Representative and Case level to null. * @@ -538,6 +570,171 @@ private static void updateShellFlag(CaseFlagsType existingFlag, String partyName existingFlag.setVisibility(visibility); } + private static List currentClaimantAndRespondentFlagDetails(CaseData caseData) { + return PARTY_FLAGS.stream() + .filter(flag -> PartyType.CLAIMANT.equals(flag.partyType()) + || PartyType.RESPONDENT.equals(flag.partyType())) + .filter(flag -> INTERNAL.equals(flag.visibility())) + .filter(flag -> isRequired(caseData, flag)) + .map(flag -> existingPartyFlagDetails(caseData, flag)) + .filter(details -> !details.details().isEmpty()) + .toList(); + } + + private static ExistingPartyFlagDetails existingPartyFlagDetails(CaseData caseData, PartyFlag internalFlag) { + PartyFlag externalFlag = matchingExternalPartyFlag(internalFlag); + CaseFlagsType internalFlags = internalFlag.get(caseData); + CaseFlagsType externalFlags = externalFlag.get(caseData); + return new ExistingPartyFlagDetails( + internalFlag.partyType(), + internalFlag.index(), + existingPartyName(caseData, internalFlag, internalFlags, externalFlags), + existingDetails(internalFlags, externalFlags) + ); + } + + private static String existingPartyName( + CaseData caseData, PartyFlag internalFlag, CaseFlagsType internalFlags, CaseFlagsType externalFlags) { + return StringUtils.firstNonBlank( + internalFlags == null ? null : internalFlags.getPartyName(), + externalFlags == null ? null : externalFlags.getPartyName(), + getPartyName(caseData, internalFlag) + ); + } + + private static PartyFlag matchingExternalPartyFlag(PartyFlag internalFlag) { + return PARTY_FLAGS.stream() + .filter(flag -> EXTERNAL.equals(flag.visibility())) + .filter(flag -> internalFlag.partyType().equals(flag.partyType())) + .filter(flag -> internalFlag.index() == flag.index()) + .findFirst() + .orElseThrow(); + } + + @SafeVarargs + private static List> existingDetails(CaseFlagsType...flags) { + List> details = new ArrayList<>(); + for (CaseFlagsType flagsType : flags) { + if (flagsType == null || flagsType.getDetails() == null) { + continue; + } + + flagsType.getDetails().stream() + .filter(item -> item != null && item.getValue() != null) + .filter(item -> details.stream().noneMatch(existing -> sameFlagDetailItem(existing, item))) + .forEach(details::add); + } + return details; + } + + private static boolean sameFlagDetailItem( + GenericTypeItem existing, GenericTypeItem candidate) { + if (StringUtils.isNotBlank(existing.getId()) && StringUtils.isNotBlank(candidate.getId())) { + return Objects.equals(existing.getId(), candidate.getId()); + } + return existing == candidate || existing.getValue() == candidate.getValue(); + } + + private static Map normaliseCaseFlagVisibility(Map visibilityByKey) { + if (visibilityByKey == null || visibilityByKey.isEmpty()) { + return Map.of(); + } + + Map normalisedVisibilityByKey = new HashMap<>(); + visibilityByKey.forEach((key, visibility) -> { + if (StringUtils.isNotBlank(key) && (INTERNAL.equals(visibility) || EXTERNAL.equals(visibility))) { + normalisedVisibilityByKey.put(normaliseCaseFlagReferenceKey(key), visibility); + } + }); + return normalisedVisibilityByKey; + } + + private static void migrateExistingFlagDetails( + CaseData caseData, + ExistingPartyFlagDetails existingFlagDetails, + Map referenceDataVisibility) { + PartyFlag internalFlag = matchingCurrentInternalPartyFlag(caseData, existingFlagDetails); + if (internalFlag == null) { + return; + } + + PartyFlag externalFlag = matchingExternalPartyFlag(internalFlag); + CaseFlagsType internalFlags = internalFlag.get(caseData); + CaseFlagsType externalFlags = externalFlag.get(caseData); + if (internalFlags == null || externalFlags == null) { + return; + } + + internalFlags.setDetails(detailsForVisibility( + existingFlagDetails.details(), INTERNAL, referenceDataVisibility)); + externalFlags.setDetails(detailsForVisibility( + existingFlagDetails.details(), EXTERNAL, referenceDataVisibility)); + } + + @Nullable + private static PartyFlag matchingCurrentInternalPartyFlag( + CaseData caseData, ExistingPartyFlagDetails existingFlagDetails) { + List requiredInternalFlags = PARTY_FLAGS.stream() + .filter(flag -> existingFlagDetails.partyType().equals(flag.partyType())) + .filter(flag -> INTERNAL.equals(flag.visibility())) + .filter(flag -> isRequired(caseData, flag)) + .toList(); + + if (StringUtils.isNotBlank(existingFlagDetails.partyName()) + && !hasDuplicateCurrentPartyNames(caseData, requiredInternalFlags)) { + return requiredInternalFlags.stream() + .filter(flag -> Objects.equals(existingFlagDetails.partyName(), getPartyName(caseData, flag))) + .findFirst() + .orElseGet(() -> matchingInternalPartyFlagAtIndex(requiredInternalFlags, + existingFlagDetails.index())); + } + + return matchingInternalPartyFlagAtIndex(requiredInternalFlags, existingFlagDetails.index()); + } + + private static boolean hasDuplicateCurrentPartyNames(CaseData caseData, List flags) { + return hasDuplicatePartyNames(flags.stream() + .map(flag -> getPartyName(caseData, flag)) + .toList()); + } + + @Nullable + private static PartyFlag matchingInternalPartyFlagAtIndex(List flags, int index) { + return flags.stream() + .filter(flag -> flag.index() == index) + .findFirst() + .orElse(null); + } + + private static ListTypeItem detailsForVisibility( + List> details, + String visibility, + Map referenceDataVisibility) { + ListTypeItem matchingDetails = new ListTypeItem<>(); + details.stream() + .filter(detail -> isExternalFlag(detail.getValue(), referenceDataVisibility) == EXTERNAL + .equals(visibility)) + .forEach(matchingDetails::add); + + return matchingDetails.isEmpty() ? null : matchingDetails; + } + + private static boolean isExternalFlag( + FlagDetailType flagDetail, Map referenceDataVisibility) { + String referenceDataVisibilityValue = StringUtils.firstNonBlank( + referenceDataVisibility.get(normaliseCaseFlagReferenceKey(flagDetail.getFlagCode())), + referenceDataVisibility.get(normaliseCaseFlagReferenceKey(flagDetail.getName())) + ); + if (StringUtils.isNotBlank(referenceDataVisibilityValue)) { + return EXTERNAL.equals(referenceDataVisibilityValue); + } + + String availableExternally = StringUtils.trimToEmpty(flagDetail.getAvailableExternally()); + return YES.equalsIgnoreCase(availableExternally) + || Boolean.TRUE.toString().equalsIgnoreCase(availableExternally) + || EXTERNAL.equalsIgnoreCase(availableExternally); + } + private static String getPartyName(CaseData caseData, PartyFlag flag) { return switch (flag.partyType()) { case CLAIMANT -> caseData.getClaimant(); @@ -893,6 +1090,13 @@ private record ExistingRepresentativeFlag( ListTypeItem details) { } + private record ExistingPartyFlagDetails( + PartyType partyType, + int index, + String partyName, + List> details) { + } + private record RepresentativeIdentity(String name, String email) { } } diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsDataMigrationControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsDataMigrationControllerTest.java index a12ca4a399..df4e473fdf 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsDataMigrationControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsDataMigrationControllerTest.java @@ -2,7 +2,6 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.SneakyThrows; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -19,6 +18,7 @@ import org.springframework.web.context.WebApplicationContext; import uk.gov.hmcts.et.common.model.ccd.CaseData; import uk.gov.hmcts.ethos.replacement.docmosis.DocmosisApplication; +import uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsReferenceDataService; import uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService; import uk.gov.hmcts.ethos.replacement.docmosis.service.VerifyTokenService; import uk.gov.hmcts.ethos.replacement.docmosis.utils.JsonMapper; @@ -26,12 +26,14 @@ import java.io.File; import java.io.IOException; import java.net.URISyntaxException; +import java.util.Map; import java.util.Objects; import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; @@ -53,6 +55,9 @@ class CaseFlagsDataMigrationControllerTest { @MockitoBean private CaseFlagsService caseFlagsService; + @MockitoBean + private CaseFlagsReferenceDataService caseFlagsReferenceDataService; + @Autowired private WebApplicationContext applicationContext; private JsonNode requestContent; @@ -71,6 +76,9 @@ void setUp() throws URISyntaxException, IOException { @SneakyThrows void shouldMigrateCaseFlags() { when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); + Map partyFlagVisibilities = Map.of("ra0010", "External"); + when(caseFlagsReferenceDataService.getPartyFlagVisibilities(AUTH_TOKEN)).thenReturn(partyFlagVisibilities); + mvc.perform(post(CASE_FLAGS_DATA_MIGRATION) .content(requestContent.toString()) .header(AUTHORIZATION, AUTH_TOKEN) @@ -81,52 +89,16 @@ void shouldMigrateCaseFlags() { .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); ArgumentCaptor caseDataCaptor = ArgumentCaptor.forClass(CaseData.class); - verify(caseFlagsService).setupCaseFlags(caseDataCaptor.capture()); + verify(caseFlagsReferenceDataService).getPartyFlagVisibilities(AUTH_TOKEN); + verify(caseFlagsService).migrateExistingClaimantAndRespondentCaseFlags( + caseDataCaptor.capture(), + eq(partyFlagVisibilities) + ); assertNotNull(caseDataCaptor.getValue().getAllPartyFlags()); assertNotNull(caseDataCaptor.getValue().getAllPartyFlags().getClaimantFlags()); assertNotNull(caseDataCaptor.getValue().getAllPartyFlags().getRespondentFlags()); } - @Test - @SneakyThrows - void shouldAddCaseFlagGroupIdAndVisibilityForPreviouslyMigratedFlags() { - when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); - - mvc.perform(post(CASE_FLAGS_DATA_MIGRATION) - .content(requestContent.toString()) - .header(AUTHORIZATION, AUTH_TOKEN) - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.data.claimantFlags.groupId").value("Claimant")) - .andExpect(jsonPath("$.data.claimantFlags.visibility").value("Internal")) - .andExpect(jsonPath("$.data.respondentFlags.groupId").value("Respondent 1")) - .andExpect(jsonPath("$.data.respondentFlags.visibility").value("Internal")); - } - - @Test - @SneakyThrows - void shouldNotOverwriteExistingCaseFlagGroupIdAndVisibility() { - when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); - - ObjectNode caseData = (ObjectNode) requestContent.at("/case_details/case_data"); - ObjectNode claimantFlags = (ObjectNode) caseData.get("claimantFlags"); - claimantFlags.put("groupId", "existing-claimant-group"); - claimantFlags.put("visibility", "Internal"); - ObjectNode respondentFlags = (ObjectNode) caseData.get("respondentFlags"); - respondentFlags.put("groupId", "existing-respondent-group"); - respondentFlags.put("visibility", "Internal"); - - mvc.perform(post(CASE_FLAGS_DATA_MIGRATION) - .content(requestContent.toString()) - .header(AUTHORIZATION, AUTH_TOKEN) - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.data.claimantFlags.groupId").value("existing-claimant-group")) - .andExpect(jsonPath("$.data.claimantFlags.visibility").value("Internal")) - .andExpect(jsonPath("$.data.respondentFlags.groupId").value("existing-respondent-group")) - .andExpect(jsonPath("$.data.respondentFlags.visibility").value("Internal")); - } - @Test @SneakyThrows void shouldMigrateCaseFlags_tokenFail() { diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsReferenceDataServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsReferenceDataServiceTest.java new file mode 100644 index 0000000000..62219cd820 --- /dev/null +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsReferenceDataServiceTest.java @@ -0,0 +1,78 @@ +package uk.gov.hmcts.ethos.replacement.docmosis.service; + +import org.junit.jupiter.api.Test; +import uk.gov.hmcts.ethos.replacement.docmosis.domain.caseflags.CaseFlagReferenceDataDetail; +import uk.gov.hmcts.ethos.replacement.docmosis.domain.caseflags.CaseFlagReferenceDataGroup; +import uk.gov.hmcts.ethos.replacement.docmosis.domain.caseflags.CaseFlagReferenceDataResponse; +import uk.gov.hmcts.ethos.replacement.docmosis.rdprofessional.OrganisationClient; +import uk.gov.hmcts.reform.authorisation.generators.AuthTokenGenerator; + +import java.util.List; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.EXTERNAL; +import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.INTERNAL; + +class CaseFlagsReferenceDataServiceTest { + private static final String USER_TOKEN = "user-token"; + private static final String SERVICE_TOKEN = "service-token"; + private static final String HMCTS_SERVICE_ID = "BHA1"; + + @Test + void getPartyFlagVisibilities_shouldFlattenReferenceDataByCodeNativeCodeAndName() { + OrganisationClient client = mock(OrganisationClient.class); + AuthTokenGenerator authTokenGenerator = mock(AuthTokenGenerator.class); + CaseFlagsReferenceDataService service = + new CaseFlagsReferenceDataService(client, authTokenGenerator, HMCTS_SERVICE_ID); + when(authTokenGenerator.generate()).thenReturn(SERVICE_TOKEN); + when(client.getCaseFlags(USER_TOKEN, SERVICE_TOKEN, HMCTS_SERVICE_ID, "PARTY", "Y", "N")) + .thenReturn(new CaseFlagReferenceDataResponse(List.of(new CaseFlagReferenceDataGroup(List.of( + flag("Reasonable adjustment", false, "CATGRY", "RA0001", List.of( + flag("Documents in a specified colour", true, "RA0010", "RA0010", List.of()), + flag("Guidance on how to complete forms", false, "RA0017", "RA0017", List.of()) + )) + ))))); + + Map actual = service.getPartyFlagVisibilities(USER_TOKEN); + + assertEquals(INTERNAL, actual.get("ra0001")); + assertEquals(EXTERNAL, actual.get("ra0010")); + assertEquals(EXTERNAL, actual.get("documents in a specified colour")); + assertEquals(INTERNAL, actual.get("ra0017")); + assertEquals(INTERNAL, actual.get("guidance on how to complete forms")); + verify(client).getCaseFlags(USER_TOKEN, SERVICE_TOKEN, HMCTS_SERVICE_ID, "PARTY", "Y", "N"); + } + + @Test + void getPartyFlagVisibilities_shouldIgnoreAmbiguousNames() { + OrganisationClient client = mock(OrganisationClient.class); + AuthTokenGenerator authTokenGenerator = mock(AuthTokenGenerator.class); + CaseFlagsReferenceDataService service = + new CaseFlagsReferenceDataService(client, authTokenGenerator, HMCTS_SERVICE_ID); + when(authTokenGenerator.generate()).thenReturn(SERVICE_TOKEN); + when(client.getCaseFlags(USER_TOKEN, SERVICE_TOKEN, HMCTS_SERVICE_ID, "PARTY", "Y", "N")) + .thenReturn(new CaseFlagReferenceDataResponse(List.of(new CaseFlagReferenceDataGroup(List.of( + flag("Other", true, "OT0001", "OT0001", List.of()), + flag("Other", false, "OT0002", "OT0002", List.of()) + ))))); + + Map actual = service.getPartyFlagVisibilities(USER_TOKEN); + + assertEquals("", actual.get("other")); + assertEquals(EXTERNAL, actual.get("ot0001")); + assertEquals(INTERNAL, actual.get("ot0002")); + } + + private static CaseFlagReferenceDataDetail flag( + String name, + boolean externallyAvailable, + String flagCode, + String nativeFlagCode, + List childFlags) { + return new CaseFlagReferenceDataDetail(name, externallyAvailable, flagCode, nativeFlagCode, childFlags); + } +} diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java index aa6d0b24cb..23cde50924 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java @@ -1,5 +1,6 @@ package uk.gov.hmcts.ethos.replacement.docmosis.service; +import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; @@ -22,8 +23,11 @@ import uk.gov.hmcts.et.common.model.ccd.types.TseAdminRecordDecisionType; import uk.gov.hmcts.ethos.utils.CaseDataBuilder; +import java.io.IOException; +import java.nio.file.Path; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.function.BiConsumer; import java.util.function.Function; @@ -37,6 +41,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertTrue; import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.ACTIVE; import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.CLAIMANT; @@ -73,6 +78,8 @@ import static uk.gov.hmcts.ecm.common.model.helper.Constants.YES; class CaseFlagsServiceTest { + private static final Path EXISTING_CASE_SAMPLE = + Path.of("src", "test", "resources", "requests", "caseFlagMigrationRequest.json"); public static final String CLAIMANT_NAME = "Claimant Name"; public static final String CLAIMANT_REPRESENTATIVE_NAME = "Claimant Representative Name"; public static final String REPRESENTATIVE_NAME = "Representative Name"; @@ -197,6 +204,129 @@ void setupCaseFlags_shouldCreateAllPartyFlagsHolderWhenAbsent() { assertNotNull(allPartyFlags(caseData).getClaimantExternalFlags()); } + @Test + void migrateExistingClaimantAndRespondentCaseFlags_shouldMoveFlagsToInternalAndExternalSections() { + caseData.setRespondentCollection(respondentCollection(2)); + FlagDetailType claimantInternal = flagDetail("Claimant internal", ACTIVE, NO); + FlagDetailType claimantExternal = flagDetail("Claimant external", INACTIVE, YES); + FlagDetailType respondent1Internal = flagDetail("Respondent 1 internal", INACTIVE, NO); + FlagDetailType respondent1External = flagDetail("Respondent 1 external", ACTIVE, YES); + FlagDetailType respondent2Internal = flagDetail("Respondent 2 internal", ACTIVE, "false"); + FlagDetailType respondent2External = flagDetail("Respondent 2 external", INACTIVE, "true"); + + AllPartyFlags allPartyFlags = getOrCreateAllPartyFlags(caseData); + allPartyFlags.setClaimantFlags(legacyCaseFlags(claimantInternal, claimantExternal)); + allPartyFlags.setRespondentFlags(legacyCaseFlags(respondent1External, respondent1Internal)); + allPartyFlags.setRespondent1Flags(legacyCaseFlags(respondent2Internal, respondent2External)); + + caseFlagsService.migrateExistingClaimantAndRespondentCaseFlags(caseData); + + AllPartyFlags migratedFlags = allPartyFlags(caseData); + assertMigratedFlag(migratedFlags.getClaimantFlags(), CLAIMANT_NAME, CLAIMANT, INTERNAL, claimantInternal); + assertMigratedFlag(migratedFlags.getClaimantExternalFlags(), CLAIMANT_NAME, CLAIMANT, EXTERNAL, + claimantExternal); + assertMigratedFlag(migratedFlags.getRespondentFlags(), RESPONDENT_NAME, RESPONDENT1, INTERNAL, + respondent1Internal); + assertMigratedFlag(migratedFlags.getRespondentExternalFlags(), RESPONDENT_NAME, RESPONDENT1, EXTERNAL, + respondent1External); + assertMigratedFlag(migratedFlags.getRespondent1Flags(), respondentName(1), RESPONDENT2, INTERNAL, + respondent2Internal); + assertMigratedFlag(migratedFlags.getRespondent1ExternalFlags(), respondentName(1), RESPONDENT2, EXTERNAL, + respondent2External); + } + + @Test + void migrateExistingClaimantAndRespondentCaseFlags_shouldUseLegacyVisibilityWhenMissingFromReferenceData() { + FlagDetailType claimantFlagMissingFromReferenceData = flagDetail("Missing claimant flag", ACTIVE, YES); + FlagDetailType respondentFlagMissingFromReferenceData = flagDetail("Missing respondent flag", ACTIVE, NO); + AllPartyFlags allPartyFlags = getOrCreateAllPartyFlags(caseData); + allPartyFlags.setClaimantFlags(legacyCaseFlags(claimantFlagMissingFromReferenceData)); + allPartyFlags.setRespondentFlags(legacyCaseFlags(respondentFlagMissingFromReferenceData)); + + caseFlagsService.migrateExistingClaimantAndRespondentCaseFlags( + caseData, + Map.of("Current reference data flag", EXTERNAL) + ); + + assertNull(allPartyFlags(caseData).getClaimantFlags().getDetails()); + assertMigratedFlag(allPartyFlags(caseData).getClaimantExternalFlags(), CLAIMANT_NAME, CLAIMANT, EXTERNAL, + claimantFlagMissingFromReferenceData); + assertMigratedFlag(allPartyFlags(caseData).getRespondentFlags(), RESPONDENT_NAME, RESPONDENT1, INTERNAL, + respondentFlagMissingFromReferenceData); + assertNull(allPartyFlags(caseData).getRespondentExternalFlags().getDetails()); + } + + @Test + void migrateExistingClaimantAndRespondentCaseFlags_shouldMigrateExistingCaseSample() throws IOException { + CaseData existingCase = new ObjectMapper().readValue(EXISTING_CASE_SAMPLE.toFile(), CaseData.class); + final ListTypeItem existingClaimantDetails = + existingCase.getAllPartyFlags().getClaimantFlags().getDetails(); + final ListTypeItem existingRespondentDetails = + existingCase.getAllPartyFlags().getRespondentFlags().getDetails(); + + caseFlagsService.migrateExistingClaimantAndRespondentCaseFlags( + existingCase, + Map.of( + "PF0002", INTERNAL, + "RA0010", EXTERNAL + ) + ); + + AllPartyFlags migratedFlags = existingCase.getAllPartyFlags(); + assertEquals(List.of("PF0015", "PF0002"), flagCodes(migratedFlags.getClaimantFlags())); + assertNull(migratedFlags.getClaimantExternalFlags().getDetails()); + assertEquals(List.of("PF0015"), flagCodes(migratedFlags.getRespondentFlags())); + assertEquals(List.of("RA0010"), flagCodes(migratedFlags.getRespondentExternalFlags())); + assertSame(existingClaimantDetails.get(0), migratedFlags.getClaimantFlags().getDetails().get(0)); + assertSame(existingClaimantDetails.get(1), migratedFlags.getClaimantFlags().getDetails().get(1)); + assertSame(existingRespondentDetails.get(0), + migratedFlags.getRespondentFlags().getDetails().getFirst()); + assertSame(existingRespondentDetails.get(1), + migratedFlags.getRespondentExternalFlags().getDetails().getFirst()); + } + + @Test + void migrateExistingClaimantAndRespondentCaseFlags_shouldUseReferenceDataVisibilityFirst() { + FlagDetailType internalByReferenceData = flagDetail("Internal by reference data", "PF0002", ACTIVE, YES); + FlagDetailType externalByReferenceData = flagDetail("External by reference data", "RA0010", INACTIVE, NO); + getOrCreateAllPartyFlags(caseData).setClaimantFlags( + legacyCaseFlags(internalByReferenceData, externalByReferenceData)); + + caseFlagsService.migrateExistingClaimantAndRespondentCaseFlags( + caseData, + Map.of( + "PF0002", INTERNAL, + "RA0010", EXTERNAL + ) + ); + + assertMigratedFlag(allPartyFlags(caseData).getClaimantFlags(), CLAIMANT_NAME, CLAIMANT, INTERNAL, + internalByReferenceData); + assertMigratedFlag(allPartyFlags(caseData).getClaimantExternalFlags(), CLAIMANT_NAME, CLAIMANT, EXTERNAL, + externalByReferenceData); + } + + @Test + void migrateExistingClaimantAndRespondentCaseFlags_shouldKeepFlagsWithNamedRespondentAfterReorder() { + caseData.setRespondentCollection(respondentCollection(2)); + FlagDetailType respondent1External = flagDetail("Respondent 1 external", ACTIVE, YES); + FlagDetailType respondent2Internal = flagDetail("Respondent 2 internal", INACTIVE, NO); + + AllPartyFlags allPartyFlags = getOrCreateAllPartyFlags(caseData); + allPartyFlags.setRespondentFlags(legacyCaseFlags(respondentName(1), respondent2Internal)); + allPartyFlags.setRespondent1Flags(legacyCaseFlags(RESPONDENT_NAME, respondent1External)); + + caseFlagsService.migrateExistingClaimantAndRespondentCaseFlags(caseData); + + AllPartyFlags migratedFlags = allPartyFlags(caseData); + assertNull(migratedFlags.getRespondentFlags().getDetails()); + assertMigratedFlag(migratedFlags.getRespondentExternalFlags(), RESPONDENT_NAME, RESPONDENT1, EXTERNAL, + respondent1External); + assertMigratedFlag(migratedFlags.getRespondent1Flags(), respondentName(1), RESPONDENT2, INTERNAL, + respondent2Internal); + assertNull(migratedFlags.getRespondent1ExternalFlags().getDetails()); + } + @Test void setupCaseFlags_shouldOnlyCreateRespondentFlagsForExistingRespondents() { caseData.setRespondentCollection(respondentCollection(3)); @@ -1453,6 +1583,36 @@ private static CaseFlagsType representativeFlags( .build(); } + private static CaseFlagsType legacyCaseFlags(FlagDetailType...details) { + return CaseFlagsType.builder() + .details(ListTypeItem.from(details)) + .build(); + } + + private static CaseFlagsType legacyCaseFlags(String partyName, FlagDetailType...details) { + return CaseFlagsType.builder() + .partyName(partyName) + .details(ListTypeItem.from(details)) + .build(); + } + + private static FlagDetailType flagDetail(String name, String status, String availableExternally) { + return FlagDetailType.builder() + .name(name) + .status(status) + .availableExternally(availableExternally) + .build(); + } + + private static FlagDetailType flagDetail(String name, String flagCode, String status, String availableExternally) { + return FlagDetailType.builder() + .name(name) + .flagCode(flagCode) + .status(status) + .availableExternally(availableExternally) + .build(); + } + private static FlagDetailType activeFlag(String name) { return FlagDetailType.builder() .name(name) @@ -1469,7 +1629,7 @@ private static String firstFlagComment(CaseFlagsType flags) { } private static void inactivateCaseFlags(CaseFlagsType flags) { - flags.getDetails().stream() + flags.getDetails() .forEach(flag -> flag.getValue().setStatus(INACTIVE)); } @@ -1482,6 +1642,25 @@ private static void assertRepresentativeFlags( assertEquals(flagName, flags.getDetails().getFirst().getValue().getName()); } + private static void assertMigratedFlag( + CaseFlagsType flags, String partyName, String roleOnCase, String visibility, FlagDetailType detail) { + assertNotNull(flags); + assertAll(roleOnCase + " " + visibility, + () -> assertEquals(partyName, flags.getPartyName()), + () -> assertEquals(roleOnCase, flags.getRoleOnCase()), + () -> assertEquals(roleOnCase, flags.getGroupId()), + () -> assertEquals(visibility, flags.getVisibility()), + () -> assertEquals(1, flags.getDetails().size()), + () -> assertSame(detail, flags.getDetails().getFirst().getValue()) + ); + } + + private static List flagCodes(CaseFlagsType flags) { + return flags.getDetails().stream() + .map(item -> item.getValue().getFlagCode()) + .toList(); + } + private static GenericTseApplicationTypeItem tseApplication( String type, List adminDecisions) { return GenericTseApplicationTypeItem.builder() diff --git a/src/test/resources/requests/caseFlagMigrationRequest.json b/src/test/resources/requests/caseFlagMigrationRequest.json new file mode 100644 index 0000000000..b65bc27994 --- /dev/null +++ b/src/test/resources/requests/caseFlagMigrationRequest.json @@ -0,0 +1,901 @@ +{ + "caseType": "Single", + "claimant": "Test Company", + "caseFlags": { + "details": [ + { + "id": "1061a022-2518-493b-a0aa-d7db0d5d19d2", + "value": { + "name": "Urgent case", + "path": [ + { + "id": "5ad87e2f-91fe-436a-a310-00dec1ef175c", + "value": "Case" + } + ], + "status": "Inactive", + "name_cy": "Achos brys", + "flagCode": "CF0007", + "flagComment": "test", + "dateTimeCreated": "2025-09-20T18:21:32.471Z", + "hearingRelevant": "No", + "dateTimeModified": "2025-09-20T18:23:15.447Z", + "availableExternally": "No" + } + } + ] + }, + "docMarkUp": "
ACAS Certificate - Henry Marsh's coffee shop - R444444/89/74.pdf", + "trackType": "Open", + "caseSource": "ET1 Online", + "claimantId": "b328966e-ab3f-4217-ba69-af17a43e4423", + "respondent": "Henry Marsh's coffee shop", + "receiptDate": "2024-06-24", + "claimantType": { + "claimant_addressUK": { + "Country": "England", + "PostCode": "LS9 9HE", + "PostTown": "Leeds", + "AddressLine1": "3, Skelton Avenue" + }, + "claimant_phone_number": "07898787676", + "claimant_email_address": "Ethan.Materassi9186@email.com", + "claimant_contact_preference": "Email" + }, + "multipleFlag": "No", + "positionType": "ET1 Online submission", + "typesOfClaim": [ + "discrimination", + "whistleBlowing" + ], + "ClaimantPcqId": "1e28e8a4-8f2d-418d-935b-1353f3a28d76", + "claimantFlags": { + "details": [ + { + "id": "a76c2949-c5ec-4824-ad89-f0a5cc922868", + "value": { + "name": "Language Interpreter", + "path": [ + { + "id": "f56e8781-b7b8-4f4a-8f35-f8e67216a0ef", + "value": "Party" + } + ], + "status": "Active", + "name_cy": "Cyfieithydd", + "flagCode": "PF0015", + "subTypeKey": "tam", + "flagComment": "test", + "subTypeValue": "Tamil", + "dateTimeCreated": "2026-08-17T15:13:24.412Z", + "hearingRelevant": "Yes", + "availableExternally": "No" + } + }, + { + "id": "ae6413f6-ce55-4f46-9995-67136badb891", + "value": { + "name": "Vulnerable user", + "path": [ + { + "id": "cd6e276e-7078-45ed-9e30-41fedd063cfb", + "value": "Party" + } + ], + "status": "Active", + "name_cy": "Defnyddiwr bregus", + "flagCode": "PF0002", + "dateTimeCreated": "2026-08-17T15:12:55.942Z", + "hearingRelevant": "Yes", + "availableExternally": "No" + } + } + ], + "partyName": "Test Company", + "roleOnCase": "claimant" + }, + "icCompletedBy": "test test", + "preAcceptCase": { + "caseAccepted": "Yes", + "dateAccepted": "2024-06-24" + }, + "repCollection": [ + { + "id": "cf2679ed-3f99-4213-8f21-17c96a5aaf90", + "value": { + "role": "[SOLICITORA]", + "idamId": "b6577c8d-16b7-4f97-90b4-4d1fc028c587", + "myHmctsYesNo": "Yes", + "respondentId": "15419256-e1c2-4e70-9b6f-d8b861f66293", + "resp_rep_name": "Henry Marsh's coffee shop", + "name_of_organisation": "ET Test Factory Solicitor", + "dynamic_resp_rep_name": { + "value": { + "code": "Henry Marsh's coffee shop", + "label": "Henry Marsh's coffee shop" + }, + "selectedCode": "Henry Marsh's coffee shop", + "selectedLabel": "Henry Marsh's coffee shop" + }, + "name_of_representative": "ET Legal Representative", + "representative_address": { + "PostCode": "SN1 4ET", + "PostTown": "SWINDON", + "AddressLine1": "10, GROVELANDS AVENUE" + }, + "respondentOrganisation": { + "OrganisationID": "PG7Q7JU", + "OrganisationName": "ET Test Factory Solicitor" + }, + "representative_email_address": "et.legalrep.1@gmail.com" + } + } + ], + "SearchCriteria": { + "SearchParties": [ + { + "id": "ae988fd7-5617-47d6-a9fc-7437add38bae", + "value": { + "Name": "Ethan Materassi", + "PostCode": "LS9 9HE", + "DateOfBirth": "1989-01-01", + "AddressLine1": "3, Skelton Avenue", + "EmailAddress": "Ethan.Materassi9186@email.com" + } + }, + { + "id": "8de5c1dc-a6e3-4513-a32b-c6d140d65570", + "value": { + "Name": "Henry Marsh's coffee shop", + "PostCode": "LS7 4QE", + "AddressLine1": "7, Valley Gardens" + } + }, + { + "id": "1885d08a-f85d-44f8-b3a6-5b26668ee47e", + "value": { + "Name": "Henry Marsh's coffee shop", + "PostCode": "SN1 4ET", + "AddressLine1": "10, GROVELANDS AVENUE", + "EmailAddress": "et.legalrep.1@gmail.com" + } + } + ], + "OtherCaseReferences": [ + { + "id": "1b3cbb58-2754-488d-9777-f7591175a491", + "value": "6015303/2024" + } + ] + }, + "dateToPosition": "2024-06-24", + "etICCanProceed": "Yes", + "managingOffice": "Leeds", + "publicCaseName": "Test Company vs Henry Marsh's coffee shop", + "claimantIndType": { + "claimant_sex": "Male", + "claimant_last_name": "Materassi", + "claimant_first_names": "Ethan", + "claimant_date_of_birth": "1989-01-01", + "claimant_preferred_title": "Mr" + }, + "companyPremises": { + "address": { + "Country": "United Kingdom", + "PostCode": "LS16 6NB", + "PostTown": "Leeds", + "AddressLine1": "Cookridge Court", + "AddressLine2": "Iveson Rise" + } + }, + "currentPosition": "ET1 Online submission", + "icDateCompleted": "27 Nov 2024", + "respondentFlags": { + "details": [ + { + "id": "d50baf8c-2c64-487a-beb5-05cb2136b56f", + "value": { + "name": "Language Interpreter", + "path": [ + { + "id": "08f2ff93-a33c-4da3-b4b3-1ea6ef13ff33", + "value": "Party" + } + ], + "status": "Active", + "name_cy": "Cyfieithydd", + "flagCode": "PF0015", + "subTypeKey": "tel", + "flagComment": "test", + "subTypeValue": "Telugu", + "dateTimeCreated": "2026-08-17T15:14:21.959Z", + "hearingRelevant": "Yes", + "availableExternally": "No" + } + }, + { + "id": "ae27af96-9e3b-41e5-a6b4-345885efe105", + "value": { + "name": "Documents in a specified colour", + "path": [ + { + "id": "707e7c37-4f91-4851-832b-03e9a731793b", + "value": "Party" + }, + { + "id": "74bde6fe-8217-4f6a-8bce-3e320b3ef89c", + "value": "Reasonable adjustment" + }, + { + "id": "80ce846d-896c-4ca6-8325-cb12deb0716b", + "value": "I need documents in an alternative format" + } + ], + "status": "Active", + "name_cy": "Dogfennau mewn lliw penodol", + "flagCode": "RA0010", + "flagComment": "test", + "dateTimeCreated": "2026-08-17T15:13:52.039Z", + "hearingRelevant": "Yes", + "availableExternally": "Yes" + } + } + ], + "partyName": "Henry Marsh's coffee shop", + "roleOnCase": "respondent" + }, + "triageQuestions": { + "caseType": "Single", + "postcode": "LS9 9HE", + "acasMultiple": "Yes", + "typesOfClaim": [ + "discrimination", + "whistleBlowing" + ], + "claimantRepresentedQuestion": "No" + }, + "claimantRequests": { + "linked_cases": "No", + "claim_outcome": [ + "compensation", + "tribunal", + "oldJob" + ], + "whistleblowing": "Yes", + "claim_description": "Discrimination, Dismissal and Pay Cut.", + "discrimination_claims": [ + "Age", + "Disability" + ], + "whistleblowing_authority": "Rupert Regulator", + "claimant_compensation_text": "Seeking months wage and job back", + "claimant_compensation_amount": "2000", + "claimant_tribunal_recommendation": "Get Job back and my boss to say sorry" + }, + "claimant_Company": "Test Company", + "et1DateCompleted": "24 Jun 2024", + "claimantOtherType": { + "pastEmployer": "Yes", + "stillWorking": "Working", + "claimant_benefits": "Yes", + "claimant_pay_cycle": "Weeks", + "claimant_occupation": "Tester", + "claimant_employed_from": "2014-04-20", + "claimant_notice_period": "Yes", + "claimant_pay_after_tax": "35000", + "claimant_pay_before_tax": "40000", + "claimant_notice_period_unit": "Weeks", + "claimant_average_weekly_hours": "20", + "claimant_pension_contribution": "Yes", + "claimant_notice_period_duration": "4", + "claimant_pension_weekly_contribution": "200" + }, + "conciliationTrack": "Open Track", + "et1TribunalRegion": "Leeds", + "feeGroupReference": "1719217306281635", + "hearingCollection": [ + { + "id": "84e10ed7-54ab-43c1-ab20-029d687e11ad", + "value": { + "Hearing_type": "Costs Hearing", + "Hearing_venue": { + "value": { + "code": "Hull", + "label": "Hull" + }, + "list_items": [ + { + "code": "Harrogate CJC", + "label": "Harrogate CJC" + }, + { + "code": "Hull", + "label": "Hull" + }, + { + "code": "Hull Combined Court Centre", + "label": "Hull Combined Court Centre" + }, + { + "code": "IAC", + "label": "IAC" + }, + { + "code": "Leeds", + "label": "Leeds" + }, + { + "code": "Scarborough", + "label": "Scarborough" + }, + { + "code": "Sheffield Combi", + "label": "Sheffield Combined Court" + }, + { + "code": "Teesside ET", + "label": "Teesside ET" + }, + { + "code": "Wakefield Count", + "label": "Wakefield Civil and Family Justice Centre" + } + ], + "selectedCode": "Hull", + "selectedLabel": "Hull" + }, + "hearingFormat": [ + "In person" + ], + "hearingNumber": "1", + "hearingSitAlone": "Sit Alone", + "judicialMediation": "No", + "hearingEstLengthNum": "1", + "hearingDateCollection": [ + { + "id": "5b1f7401-eca5-46e1-adec-3c707a0e2849", + "value": { + "listedDate": "2024-01-08T12:00:00.000", + "Hearing_status": "Listed", + "hearingVenueDay": { + "value": { + "code": "Hull", + "label": "Hull" + }, + "list_items": [ + { + "code": "Harrogate CJC", + "label": "Harrogate CJC" + }, + { + "code": "Hull", + "label": "Hull" + }, + { + "code": "Hull Combined Court Centre", + "label": "Hull Combined Court Centre" + }, + { + "code": "IAC", + "label": "IAC" + }, + { + "code": "Leeds", + "label": "Leeds" + }, + { + "code": "Scarborough", + "label": "Scarborough" + }, + { + "code": "Sheffield Combi", + "label": "Sheffield Combined Court" + }, + { + "code": "Teesside ET", + "label": "Teesside ET" + }, + { + "code": "Wakefield Count", + "label": "Wakefield Civil and Family Justice Centre" + } + ], + "selectedCode": "Hull", + "selectedLabel": "Hull" + }, + "hearingTimingStart": "2024-01-08T12:00:00.000", + "hearingTimingFinish": "2024-01-08T12:00:00.000" + } + } + ], + "hearingEstLengthNumType": "Days" + } + } + ], + "hmctsCaseCategory": "Employment Tribunals", + "isLocationCorrect": "Yes", + "targetHearingDate": "2024-12-21", + "documentCollection": [ + { + "id": "9639390d-5e55-4efb-880a-5c931f816c57", + "value": { + "docNumber": "1", + "documentType": "ET1", + "typeOfDocument": "ET1", + "shortDescription": "ET1 - Ethan Materassi", + "uploadedDocument": { + "category_id": "C11", + "document_url": "http://dm-store-aat.service.core-compute-aat.internal/documents/afb613b7-fe7d-4b10-8636-ce6f71788972", + "document_filename": "ET1 - Ethan Materassi.pdf", + "document_binary_url": "http://dm-store-aat.service.core-compute-aat.internal/documents/afb613b7-fe7d-4b10-8636-ce6f71788972/binary" + }, + "topLevelDocuments": "Starting a Claim", + "dateOfCorrespondence": "2024-06-24", + "startingClaimDocuments": "ET1" + } + }, + { + "id": "6ec9c4aa-aa88-4792-9dfc-42115f77ffa6", + "value": { + "docNumber": "2", + "documentType": "ACAS Certificate", + "typeOfDocument": "ACAS Certificate", + "shortDescription": "ACAS Certificate - Henry Marsh - R444444_89_74", + "uploadedDocument": { + "category_id": "C13", + "document_url": "http://dm-store-aat.service.core-compute-aat.internal/documents/bd757431-0947-4f99-bcd8-37a10bde8af2", + "document_filename": "ACAS Certificate - Henry Marsh - R444444_89_74.pdf", + "document_binary_url": "http://dm-store-aat.service.core-compute-aat.internal/documents/bd757431-0947-4f99-bcd8-37a10bde8af2/binary" + }, + "topLevelDocuments": "Starting a Claim", + "dateOfCorrespondence": "2024-06-24", + "startingClaimDocuments": "ACAS Certificate" + } + }, + { + "id": "7a36863e-5f1c-4aeb-9493-1cc43b59a10b", + "value": { + "docNumber": "3", + "documentType": "ET1 Vetting", + "uploadedDocument": { + "category_id": "C71", + "document_url": "http://dm-store-aat.service.core-compute-aat.internal/documents/b84551d7-89ed-4321-9bf3-0d33464179b9", + "document_filename": "ET1 Vetting - Ethan Materassi.pdf", + "document_binary_url": "http://dm-store-aat.service.core-compute-aat.internal/documents/b84551d7-89ed-4321-9bf3-0d33464179b9/binary" + }, + "topLevelDocuments": "Starting a Claim", + "dateOfCorrespondence": "2024-06-24", + "startingClaimDocuments": "ET1 Vetting" + } + }, + { + "id": "18512a28-c30d-4d85-ba28-f5974ba2dcf1", + "value": { + "docNumber": "4", + "documentType": "Initial Consideration", + "uploadedDocument": { + "category_id": "C23", + "document_url": "http://dm-store-aat.service.core-compute-aat.internal/documents/b1fc1631-a67c-4c55-94ae-03134c73953f", + "document_filename": "Initial Consideration.pdf", + "document_binary_url": "http://dm-store-aat.service.core-compute-aat.internal/documents/b1fc1631-a67c-4c55-94ae-03134c73953f/binary" + }, + "topLevelDocuments": "Initial Consideration", + "dateOfCorrespondence": "2024-11-27", + "initialConsiderationDocuments": "Initial Consideration" + } + } + ], + "et1VettingDocument": { + "document_url": "http://dm-store-aat.service.core-compute-aat.internal/documents/b84551d7-89ed-4321-9bf3-0d33464179b9", + "document_filename": "ET1 Vetting - Ethan Materassi.pdf", + "document_binary_url": "http://dm-store-aat.service.core-compute-aat.internal/documents/b84551d7-89ed-4321-9bf3-0d33464179b9/binary" + }, + "ethosCaseReference": "6015303/2024", + "flagsImageFileName": "EMP-TRIB-000000000000000.jpg", + "jurCodesCollection": [ + { + "id": "1d9b6d69-4df3-4481-b24c-68ce31ae9bb3", + "value": { + "juridictionCodesList": "DDA" + } + }, + { + "id": "cfaaf947-12f2-4e7d-8839-169a21e70a2e", + "value": { + "juridictionCodesList": "PID" + } + }, + { + "id": "4a23d8f3-344f-42d7-9287-3023586e9564", + "value": { + "juridictionCodesList": "DAG" + } + } + ], + "referralCollection": [ + { + "id": "b59e63fb-178a-49b8-90de-6fab608bf03a", + "value": { + "isUrgent": "No", + "referredBy": "test test", + "referCaseTo": "Admin", + "referralDate": "10 Oct 2024", + "referralNumber": "1", + "referralStatus": "Awaiting instructions", + "referralDetails": "asdsdadas", + "referralSubject": "ET1", + "referralSummaryPdf": { + "document_url": "http://dm-store-aat.service.core-compute-aat.internal/documents/6dd86b59-02e5-4b1b-a138-16c40ab20a3d", + "document_filename": "Referral Summary.pdf", + "document_binary_url": "http://dm-store-aat.service.core-compute-aat.internal/documents/6dd86b59-02e5-4b1b-a138-16c40ab20a3d/binary" + }, + "referralHearingDate": "None", + "referralInstruction": "dsadsaasd" + } + }, + { + "id": "34f86e2f-9c18-440b-9cad-488a26db5f6f", + "value": { + "isUrgent": "Yes", + "referredBy": "test test", + "referCaseTo": "Admin", + "referralDate": "03 Apr 2025", + "referralNumber": "2", + "referralStatus": "Awaiting instructions", + "referralDetails": "aa", + "referralSubject": "ET3/ECC", + "referralSummaryPdf": { + "document_url": "http://dm-store-aat.service.core-compute-aat.internal/documents/f7030980-7743-45c6-b15d-87833c4db1d6", + "document_filename": "Referral Summary.pdf", + "document_binary_url": "http://dm-store-aat.service.core-compute-aat.internal/documents/f7030980-7743-45c6-b15d-87833c4db1d6/binary" + }, + "referralHearingDate": "None" + } + }, + { + "id": "bd3109aa-4827-4d71-b6e7-50f1cd15d92a", + "value": { + "isUrgent": "Yes", + "referredBy": "test test", + "referCaseTo": "Judge", + "referralDate": "03 Apr 2025", + "referralNumber": "3", + "referralStatus": "Awaiting instructions", + "referralDetails": "data from one case session copied over to another \nJudge urgent yes", + "referralSubject": "ET1", + "referralSummaryPdf": { + "document_url": "http://dm-store-aat.service.core-compute-aat.internal/documents/ed331f77-4303-4d00-9ae6-4a1b877ecb90", + "document_filename": "Referral Summary.pdf", + "document_binary_url": "http://dm-store-aat.service.core-compute-aat.internal/documents/ed331f77-4303-4d00-9ae6-4a1b877ecb90/binary" + }, + "referralHearingDate": "None", + "referralInstruction": "instructions" + } + }, + { + "id": "b0c4b60d-e264-45f7-bdc1-55a7fef09c75", + "value": { + "isUrgent": "Yes", + "referredBy": "ET LegalOps", + "referCaseTo": "Legal officer", + "referralDate": "13 Jul 2026", + "referralNumber": "4", + "referralStatus": "Awaiting instructions", + "referralDetails": "test", + "referralSubject": "ET3/ECC", + "referralSummaryPdf": { + "document_url": "http://dm-store-aat.service.core-compute-aat.internal/documents/7d905893-f75e-4c04-a002-6cb55ad7f4fa", + "document_filename": "Referral Summary.pdf", + "document_binary_url": "http://dm-store-aat.service.core-compute-aat.internal/documents/7d905893-f75e-4c04-a002-6cb55ad7f4fa/binary" + }, + "referralHearingDate": "None" + } + }, + { + "id": "47a21bc2-7b0a-4c7a-a4ff-68ff4b135493", + "value": { + "isUrgent": "No", + "referredBy": "ET LegalOps", + "referCaseTo": "Admin", + "referralDate": "13 Jul 2026", + "referralNumber": "5", + "referralStatus": "Awaiting instructions", + "referralDetails": "test test", + "referralSubject": "Withdraw claim", + "referralSummaryPdf": { + "document_url": "http://dm-store-aat.service.core-compute-aat.internal/documents/a3ef7b17-d61b-402e-857c-99f44212d4a5", + "document_filename": "Referral Summary.pdf", + "document_binary_url": "http://dm-store-aat.service.core-compute-aat.internal/documents/a3ef7b17-d61b-402e-857c-99f44212d4a5/binary" + }, + "referralHearingDate": "None" + } + } + ], + "et1OnlineSubmission": "Yes", + "areTheseCodesCorrect": "Yes", + "respondentCollection": [ + { + "id": "15419256-e1c2-4e70-9b6f-d8b861f66293", + "value": { + "idamId": "61ea2f83-4431-42dd-9d29-b80fed24f585", + "et3Status": "inProgress", + "represented": "Yes", + "respondentEcc": "No", + "respondentType": "Organisation", + "respondent_ACAS": "R444444/89/74", + "respondent_name": "Henry Marsh's coffee shop", + "representativeId": "cf2679ed-3f99-4213-8f21-17c96a5aaf90", + "responseContinue": "Yes", + "responseReceived": "No", + "responseStruckOut": "No", + "extensionRequested": "No", + "respondent_address": { + "Country": "England", + "PostCode": "LS7 4QE", + "PostTown": "Leeds", + "AddressLine1": "7, Valley Gardens" + }, + "et3HubLinksStatuses": { + "contestClaim": "notStartedYet", + "contactDetails": "notStartedYet", + "checkYorAnswers": "cannotStartYet", + "employerDetails": "notStartedYet", + "payPensionBenefitDetails": "notStartedYet", + "conciliationAndEmployeeDetails": "notStartedYet" + }, + "representativeRemoved": "No", + "respondentOrganisation": "Henry Marsh's coffee shop", + "respondent_ACAS_question": "Yes", + "et3CaseDetailsLinksStatuses": { + "documents": "optional", + "et1ClaimForm": "notViewedYet", + "hearingDetails": "notAvailableYet", + "tribunalOrders": "notAvailableYet", + "contactTribunal": "optional", + "personalDetails": "notAvailableYet", + "respondentResponse": "notStartedYet", + "tribunalJudgements": "notAvailableYet", + "claimantApplications": "notAvailableYet", + "respondentRequestsAndApplications": "notAvailableYet" + } + } + } + ], + "caseNameHmctsInternal": "Test Company vs Henry Marsh's coffee shop", + "et1GovOrMajorQuestion": "No", + "et1VettingCompletedBy": "et api1", + "caseManagementCategory": { + "value": { + "code": "Employment Tribunals", + "label": "Employment" + }, + "list_items": [ + { + "code": "Employment Tribunals", + "label": "Employment" + } + ], + "selectedCode": "Employment Tribunals", + "selectedLabel": "Employment" + }, + "caseManagementLocation": { + "region": "3", + "baseLocation": "36313" + }, + "claimantTaskListChecks": { + "claimDetailsCheck": "Yes", + "personalDetailsCheck": "Yes", + "employmentAndRespondentCheck": "Yes" + }, + "et1SuggestHearingVenue": "No", + "noticeOfChangeAnswers0": { + "respondentName": "Henry Marsh", + "claimantLastName": "Materassi", + "claimantFirstName": "Ethan" + }, + "suggestedHearingVenues": { + "list_items": [ + { + "code": "Harrogate CJC", + "label": "Harrogate CJC" + }, + { + "code": "Hull", + "label": "Hull" + }, + { + "code": "Hull Combined Court Centre", + "label": "Hull Combined Court Centre" + }, + { + "code": "IAC", + "label": "IAC" + }, + { + "code": "Leeds", + "label": "Leeds" + }, + { + "code": "Scarborough", + "label": "Scarborough" + }, + { + "code": "Sheffield Combi", + "label": "Sheffield Combined Court" + }, + { + "code": "Teesside ET", + "label": "Teesside ET" + }, + { + "code": "Wakefield Count", + "label": "Wakefield Civil and Family Justice Centre" + } + ] + }, + "claimant_TypeOfClaimant": "Company", + "et1VideoHearingQuestion": "Yes", + "listedDateInPastWarning": "Yes", + "etICHearingAlreadyListed": "No", + "etICHearingNotListedList": [ + "List for preliminary hearing", + "List for final hearing" + ], + "isTrackAllocationCorrect": "Yes", + "tribunalCorrespondenceDX": "DX 742940 Leeds 75", + "claimantHearingPreference": { + "contact_language": "English", + "hearing_preferences": [ + "Video" + ], + "reasonable_adjustments": "No" + }, + "tribunalCorrespondenceFax": "01264 785136", + "caseManagementLocationCode": "36313", + "claimantDocumentCollection": [ + { + "id": "9639390d-5e55-4efb-880a-5c931f816c57", + "value": { + "docNumber": "1", + "documentType": "ET1", + "typeOfDocument": "ET1", + "shortDescription": "ET1 - Ethan Materassi", + "uploadedDocument": { + "category_id": "C11", + "document_url": "http://dm-store-aat.service.core-compute-aat.internal/documents/afb613b7-fe7d-4b10-8636-ce6f71788972", + "document_filename": "ET1 - Ethan Materassi.pdf", + "document_binary_url": "http://dm-store-aat.service.core-compute-aat.internal/documents/afb613b7-fe7d-4b10-8636-ce6f71788972/binary" + }, + "topLevelDocuments": "Starting a Claim", + "dateOfCorrespondence": "2024-06-24", + "startingClaimDocuments": "ET1" + } + }, + { + "id": "6ec9c4aa-aa88-4792-9dfc-42115f77ffa6", + "value": { + "docNumber": "2", + "documentType": "ACAS Certificate", + "typeOfDocument": "ACAS Certificate", + "shortDescription": "ACAS Certificate - Henry Marsh - R444444_89_74", + "uploadedDocument": { + "category_id": "C13", + "document_url": "http://dm-store-aat.service.core-compute-aat.internal/documents/bd757431-0947-4f99-bcd8-37a10bde8af2", + "document_filename": "ACAS Certificate - Henry Marsh - R444444_89_74.pdf", + "document_binary_url": "http://dm-store-aat.service.core-compute-aat.internal/documents/bd757431-0947-4f99-bcd8-37a10bde8af2/binary" + }, + "topLevelDocuments": "Starting a Claim", + "dateOfCorrespondence": "2024-06-24", + "startingClaimDocuments": "ACAS Certificate" + } + } + ], + "etIcHearingPanelPreference": "|Claimant's hearing panel preference | |\n|-------------|:------------|\n|Panel Preference | -|\n|Reason for Panel Preference | -|", + "privateHearingRequiredFlag": "No", + "representativeClaimantType": { + "myHmctsOrganisation": { + "OrganisationID": "HEBFGBR" + }, + "name_of_organisation": "NFD Solicitor Organisation", + "name_of_representative": "User Test", + "representative_address": { + "County": "Westminster", + "PostCode": "SW1H 9AJ", + "PostTown": "London", + "AddressLine1": "102 Petty France" + }, + "representative_email_address": "TEST_SOLICITORONLY_USER@mailinator.com" + }, + "claimantRepresentedQuestion": "Yes", + "claimantWorkAddressQuestion": "Yes", + "etICJuridictionCodesInvalid": "No", + "tribunalCorrespondenceEmail": "LeedsET@justice.gov.uk", + "et1VettingAcasCertIsYesOrNo1": "Yes", + "claimantRepresentativeRemoved": "No", + "etInitialConsiderationHearing": "|Hearing details | |\r\n|-------------|:------------|\r\n|Date | -|\r\n|Type | -|\r\n|Duration | -|", + "respondentOrganisationPolicy0": { + "Organisation": { + "OrganisationID": "PG7Q7JU", + "OrganisationName": "ET Test Factory Solicitor" + }, + "OrgPolicyCaseAssignedRole": "[SOLICITORA]" + }, + "respondentOrganisationPolicy1": { + "OrgPolicyCaseAssignedRole": "[SOLICITORB]" + }, + "respondentOrganisationPolicy2": { + "OrgPolicyCaseAssignedRole": "[SOLICITORC]" + }, + "respondentOrganisationPolicy3": { + "OrgPolicyCaseAssignedRole": "[SOLICITORD]" + }, + "respondentOrganisationPolicy4": { + "OrgPolicyCaseAssignedRole": "[SOLICITORE]" + }, + "respondentOrganisationPolicy5": { + "OrgPolicyCaseAssignedRole": "[SOLICITORF]" + }, + "respondentOrganisationPolicy6": { + "OrgPolicyCaseAssignedRole": "[SOLICITORG]" + }, + "respondentOrganisationPolicy7": { + "OrgPolicyCaseAssignedRole": "[SOLICITORH]" + }, + "respondentOrganisationPolicy8": { + "OrgPolicyCaseAssignedRole": "[SOLICITORI]" + }, + "respondentOrganisationPolicy9": { + "OrgPolicyCaseAssignedRole": "[SOLICITORJ]" + }, + "tribunalCorrespondenceAddress": { + "PostCode": "LS1 2RP", + "PostTown": "Leeds", + "AddressLine1": "Westgate", + "AddressLine2": "6 Grace Street" + }, + "changeOrganisationRequestField": { + "OrganisationToAdd": {} + }, + "et1VettingCanServeClaimYesOrNo": "Yes", + "etInitialConsiderationDocument": { + "document_url": "http://dm-store-aat.service.core-compute-aat.internal/documents/b1fc1631-a67c-4c55-94ae-03134c73953f", + "document_filename": "Initial Consideration.pdf", + "document_binary_url": "http://dm-store-aat.service.core-compute-aat.internal/documents/b1fc1631-a67c-4c55-94ae-03134c73953f/binary" + }, + "tribunalCorrespondenceTelephone": "0300 323 0196", + "et1ReasonableAdjustmentsQuestion": "No", + "etInitialConsiderationRespondent": "| Respondent 1 name given | |\r\n|-------------|:------------|\r\n|In ET1 by claimant | Henry Marsh's coffee shop|\r\n|In ET3 by respondent | |", + "icRespondentHearingPanelPreference": "| Respondent 1 hearing panel preference | |\r\n|-------------|:------------|\r\n|Preference | -|\r\n|Reason | -|", + "etICHearingNotListedListForFinalHearing": { + "etICTypeOfFinalHearing": [ + "Telephone", + "Video", + "F2F" + ], + "etICLengthOfFinalHearing": "2", + "finalHearingLengthNumType": "Hours" + }, + "etInitialConsiderationJurisdictionCodes": "

Jurisdiction codes

View all jurisdiction codes and descriptors (opens in new tab)

DDA - Suffered a detriment, discrimination, including indirect discrimination, and discrimination based on association or perception, harassment and/or dismissal on grounds of disability or failure of employer to make reasonable adjustments

PID - Suffered a detriment and/or dismissal due to exercising rights under the Public Interest Disclosure Act

DAG - Discrimination, including harassment or discrimination based on association or perception on grounds of age


", + "claimantRepresentativeOrganisationPolicy": { + "Organisation": { + "OrganisationID": "HEBFGBR" + }, + "OrgPolicyCaseAssignedRole": "[CLAIMANTSOLICITOR]" + }, + "etICHearingNotListedListForPrelimHearing": { + "etICLengthOfPrelimHearing": "2", + "prelimHearingLengthNumType": "Days", + "etICTypeOfPreliminaryHearing": [ + "Telephone", + "Video", + "F2F" + ], + "etICGiveDetailsOfHearingNotice": "Test", + "etICPurposeOfPreliminaryHearing": [ + "Case management", + "Preliminary issue", + "Strike out", + "Deposit" + ] + } +} \ No newline at end of file From 5e7384967537cb7bfdc64d068a6dc56fbadfe68b Mon Sep 17 00:00:00 2001 From: rajaram Date: Tue, 18 Aug 2026 16:46:27 +0100 Subject: [PATCH 033/100] Fixed build issue --- .../ethos/replacement/docmosis/service/CaseFlagsService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java index d61b117c86..6290b60d56 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java @@ -632,7 +632,7 @@ private static boolean sameFlagDetailItem( if (StringUtils.isNotBlank(existing.getId()) && StringUtils.isNotBlank(candidate.getId())) { return Objects.equals(existing.getId(), candidate.getId()); } - return existing == candidate || existing.getValue() == candidate.getValue(); + return existing.equals(candidate) || existing.getValue().equals(candidate.getValue()); } private static Map normaliseCaseFlagVisibility(Map visibilityByKey) { From 9ea61f52114ade92053571701b3aa02807f8b11b Mon Sep 17 00:00:00 2001 From: rajaram Date: Thu, 20 Aug 2026 15:08:21 +0100 Subject: [PATCH 034/100] RET-6897 - Default to internal in case of missing ref data config --- .../docmosis/service/CaseFlagsService.java | 6 ++-- .../service/CaseFlagsServiceTest.java | 28 +++++++++++++++---- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java index 6290b60d56..b66e50c913 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java @@ -729,10 +729,8 @@ private static boolean isExternalFlag( return EXTERNAL.equals(referenceDataVisibilityValue); } - String availableExternally = StringUtils.trimToEmpty(flagDetail.getAvailableExternally()); - return YES.equalsIgnoreCase(availableExternally) - || Boolean.TRUE.toString().equalsIgnoreCase(availableExternally) - || EXTERNAL.equalsIgnoreCase(availableExternally); + // A legacy flag no longer configured in Reference Data defaults to Internal. + return false; } private static String getPartyName(CaseData caseData, PartyFlag flag) { diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java index 23cde50924..10d80dc30e 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java @@ -219,7 +219,17 @@ void migrateExistingClaimantAndRespondentCaseFlags_shouldMoveFlagsToInternalAndE allPartyFlags.setRespondentFlags(legacyCaseFlags(respondent1External, respondent1Internal)); allPartyFlags.setRespondent1Flags(legacyCaseFlags(respondent2Internal, respondent2External)); - caseFlagsService.migrateExistingClaimantAndRespondentCaseFlags(caseData); + caseFlagsService.migrateExistingClaimantAndRespondentCaseFlags( + caseData, + Map.of( + claimantInternal.getName(), INTERNAL, + claimantExternal.getName(), EXTERNAL, + respondent1Internal.getName(), INTERNAL, + respondent1External.getName(), EXTERNAL, + respondent2Internal.getName(), INTERNAL, + respondent2External.getName(), EXTERNAL + ) + ); AllPartyFlags migratedFlags = allPartyFlags(caseData); assertMigratedFlag(migratedFlags.getClaimantFlags(), CLAIMANT_NAME, CLAIMANT, INTERNAL, claimantInternal); @@ -236,9 +246,9 @@ void migrateExistingClaimantAndRespondentCaseFlags_shouldMoveFlagsToInternalAndE } @Test - void migrateExistingClaimantAndRespondentCaseFlags_shouldUseLegacyVisibilityWhenMissingFromReferenceData() { + void migrateExistingClaimantAndRespondentCaseFlags_shouldKeepFlagsMissingFromReferenceDataInternal() { FlagDetailType claimantFlagMissingFromReferenceData = flagDetail("Missing claimant flag", ACTIVE, YES); - FlagDetailType respondentFlagMissingFromReferenceData = flagDetail("Missing respondent flag", ACTIVE, NO); + FlagDetailType respondentFlagMissingFromReferenceData = flagDetail("Missing respondent flag", ACTIVE, YES); AllPartyFlags allPartyFlags = getOrCreateAllPartyFlags(caseData); allPartyFlags.setClaimantFlags(legacyCaseFlags(claimantFlagMissingFromReferenceData)); allPartyFlags.setRespondentFlags(legacyCaseFlags(respondentFlagMissingFromReferenceData)); @@ -248,9 +258,9 @@ void migrateExistingClaimantAndRespondentCaseFlags_shouldUseLegacyVisibilityWhen Map.of("Current reference data flag", EXTERNAL) ); - assertNull(allPartyFlags(caseData).getClaimantFlags().getDetails()); - assertMigratedFlag(allPartyFlags(caseData).getClaimantExternalFlags(), CLAIMANT_NAME, CLAIMANT, EXTERNAL, + assertMigratedFlag(allPartyFlags(caseData).getClaimantFlags(), CLAIMANT_NAME, CLAIMANT, INTERNAL, claimantFlagMissingFromReferenceData); + assertNull(allPartyFlags(caseData).getClaimantExternalFlags().getDetails()); assertMigratedFlag(allPartyFlags(caseData).getRespondentFlags(), RESPONDENT_NAME, RESPONDENT1, INTERNAL, respondentFlagMissingFromReferenceData); assertNull(allPartyFlags(caseData).getRespondentExternalFlags().getDetails()); @@ -316,7 +326,13 @@ void migrateExistingClaimantAndRespondentCaseFlags_shouldKeepFlagsWithNamedRespo allPartyFlags.setRespondentFlags(legacyCaseFlags(respondentName(1), respondent2Internal)); allPartyFlags.setRespondent1Flags(legacyCaseFlags(RESPONDENT_NAME, respondent1External)); - caseFlagsService.migrateExistingClaimantAndRespondentCaseFlags(caseData); + caseFlagsService.migrateExistingClaimantAndRespondentCaseFlags( + caseData, + Map.of( + respondent1External.getName(), EXTERNAL, + respondent2Internal.getName(), INTERNAL + ) + ); AllPartyFlags migratedFlags = allPartyFlags(caseData); assertNull(migratedFlags.getRespondentFlags().getDetails()); From 76316e5e71d9f0d64ea404f1d89efa255a4d7084 Mon Sep 17 00:00:00 2001 From: rajaram Date: Mon, 24 Aug 2026 16:12:42 +0100 Subject: [PATCH 035/100] CUIYS changes --- .../AuthorisationCaseField-CaseFlagsCaseLinking.json | 12 ++++++++++++ .../AuthorisationCaseField-CaseFlagsCaseLinking.json | 6 ++++++ 2 files changed, 18 insertions(+) diff --git a/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json index 98e9f71331..354efa0409 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json @@ -982,5 +982,17 @@ "CaseFieldID": "representative9ExternalFlags", "UserRole": "caseworker-employment-api", "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "claimantExternalFlags", + "UserRole": "[CREATOR]", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "respondentExternalFlags", + "UserRole": "[DEFENDANT]", + "CRUD": "CRU" } ] diff --git a/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json index 522ea17fb3..848ee5027a 100644 --- a/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json @@ -982,5 +982,11 @@ "CaseFieldID": "representative9ExternalFlags", "UserRole": "caseworker-employment-api", "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "claimantExternalFlags", + "UserRole": "citizen", + "CRUD": "R" } ] From c6567193186d71a91a5c2beaa5290ca6eeb4526e Mon Sep 17 00:00:00 2001 From: rajaram Date: Sat, 29 Aug 2026 14:32:32 +0100 Subject: [PATCH 036/100] RET-6946 and RET-6977 implemented and RET-6739 AC4 fixed --- ...AmendClaimantRepresentativeController.java | 2 +- .../CaseActionsForCaseWorkerController.java | 30 ++-- .../CaseFlagsDataMigrationController.java | 20 ++- .../controllers/Et1ReppedController.java | 5 +- .../controllers/NoticeOfChangeController.java | 2 +- .../RespondentRepresentativeController.java | 35 +++- .../docmosis/service/CaseFlagsService.java | 123 +++++++++++++- .../CaseManagementForCaseWorkerService.java | 40 +++-- .../service/FeatureToggleService.java | 13 ++ .../NocRespondentRepresentativeService.java | 39 ++++- .../syaapi/service/FeatureToggleService.java | 13 ++ ...dClaimantRepresentativeControllerTest.java | 6 +- ...aseActionsForCaseWorkerControllerTest.java | 37 +++- .../controllers/CaseFlagsControllerTest.java | 1 + .../CaseFlagsDataMigrationControllerTest.java | 117 +++++++++++++ .../controllers/Et1ReppedControllerTest.java | 4 +- .../NoticeOfChangeControllerTest.java | 3 +- ...espondentRepresentativeControllerTest.java | 115 ++++++++++++- .../service/CaseFlagsServiceTest.java | 160 +++++++++++++++++- ...aseManagementForCaseWorkerServiceTest.java | 11 ++ .../service/FeatureToggleServiceTest.java | 26 ++- ...ocRespondentRepresentativeServiceTest.java | 45 +++++ .../service/FeatureToggleServiceTest.java | 26 ++- 23 files changed, 805 insertions(+), 68 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeController.java index d26125a971..b535c83119 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeController.java @@ -120,7 +120,7 @@ public ResponseEntity aboutToSubmit( callbackRequest.getCaseDetails()); } - if (featureToggleService.isCaseFlagsEnabled()) { + if (featureToggleService.isCaseFlagsV2Enabled(callbackRequest.getCaseDetails().getCaseTypeId())) { caseFlagsService.clearClaimantRepresentativeFlagsIfRepresentativeChanged(caseData, callbackRequest.getCaseDetailsBefore() == null ? null diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java index 4592a3cd07..86e91a41fc 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java @@ -166,10 +166,10 @@ public ResponseEntity postDefaultValues( } defaultValuesReaderService.setPositionAndOffice(caseDetails.getCaseTypeId(), caseData); - boolean caseFlagsToggle = featureToggleService.isCaseFlagsEnabled(); - log.info("Caseflags feature flag is {}", caseFlagsToggle); - if (caseFlagsToggle && caseFlagsService.caseFlagsSetupRequired(caseData)) { - caseFlagsService.setupCaseFlags(caseData); + boolean caseFlagsToggle = featureToggleService.isCaseFlagsV2Enabled(caseDetails.getCaseTypeId()) + || featureToggleService.isCaseFlagsEnabled(); + if (caseFlagsToggle && caseFlagsSetupRequired(caseDetails.getCaseTypeId(), caseData)) { + setupCaseFlags(caseDetails.getCaseTypeId(), caseData); } boolean hmcToggle = featureToggleService.isHmcEnabled(); @@ -343,9 +343,7 @@ public ResponseEntity amendClaimantDetails( caseManagementForCaseWorkerService.setPublicCaseName(caseData); } - if (featureToggleService.isCaseFlagsEnabled()) { - caseFlagsService.setupCaseFlags(caseData); - } + setupCaseFlags(ccdRequest.getCaseDetails().getCaseTypeId(), caseData); caseManagementForCaseWorkerService.setNextListedDate(caseData); removeSpacesFromPartyNames(caseData); @@ -400,9 +398,7 @@ public ResponseEntity amendRespondentDetails( caseManagementForCaseWorkerService.setPublicCaseName(caseData); } - if (featureToggleService.isCaseFlagsEnabled()) { - caseFlagsService.setupCaseFlags(caseData); - } + setupCaseFlags(ccdRequest.getCaseDetails().getCaseTypeId(), caseData); caseManagementForCaseWorkerService.updateWorkAllocationField(errors, caseData); removeSpacesFromPartyNames(caseData); @@ -911,6 +907,20 @@ private DefaultValues getPostDefaultValues(CaseDetails caseDetails) { return defaultValuesReaderService.getDefaultValues(caseDetails.getCaseData().getManagingOffice()); } + private boolean caseFlagsSetupRequired(String caseTypeId, CaseData caseData) { + return featureToggleService.isCaseFlagsV2Enabled(caseTypeId) + ? caseFlagsService.caseFlagsSetupRequired(caseData) + : caseFlagsService.legacyCaseFlagsSetupRequired(caseData); + } + + private void setupCaseFlags(String caseTypeId, CaseData caseData) { + if (featureToggleService.isCaseFlagsV2Enabled(caseTypeId)) { + caseFlagsService.setupCaseFlags(caseData); + } else { + caseFlagsService.setupLegacyCaseFlags(caseData); + } + } + private void generateEthosCaseReference(CaseData caseData, CCDRequest ccdRequest) { if (StringUtils.isBlank(caseData.getEthosCaseReference())) { String reference = singleReferenceService.createReference(ccdRequest.getCaseDetails().getCaseTypeId()); diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsDataMigrationController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsDataMigrationController.java index 6fd31346b2..f8a111629a 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsDataMigrationController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsDataMigrationController.java @@ -17,6 +17,7 @@ import uk.gov.hmcts.et.common.model.ccd.CaseData; import uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsReferenceDataService; import uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService; +import uk.gov.hmcts.ethos.replacement.docmosis.service.FeatureToggleService; import uk.gov.hmcts.ethos.replacement.docmosis.service.VerifyTokenService; import java.util.List; @@ -35,6 +36,7 @@ public class CaseFlagsDataMigrationController { private final VerifyTokenService verifyTokenService; private final CaseFlagsService caseFlagsService; private final CaseFlagsReferenceDataService caseFlagsReferenceDataService; + private final FeatureToggleService featureToggleService; @PostMapping(value = "/case-flags-migration/about-to-submit", consumes = APPLICATION_JSON_VALUE) @Operation(summary = "migrate existing party case flags into internal and external sections.") @@ -57,10 +59,14 @@ public ResponseEntity addCaseFlagsData( } CaseData caseData = ccdRequest.getCaseDetails().getCaseData(); - caseFlagsService.migrateExistingClaimantAndRespondentCaseFlags( - caseData, - caseFlagsReferenceDataService.getPartyFlagVisibilities(userToken) - ); + if (featureToggleService.isCaseFlagsV2Enabled(ccdRequest.getCaseDetails().getCaseTypeId())) { + caseFlagsService.migrateExistingClaimantAndRespondentCaseFlags( + caseData, + caseFlagsReferenceDataService.getPartyFlagVisibilities(userToken) + ); + } else { + caseFlagsService.setupLegacyCaseFlags(caseData); + } log.info("Migrating existing case: {}", ccdRequest.getCaseDetails().getCaseId()); @@ -88,7 +94,11 @@ public ResponseEntity rollbackCaseFlagsData( } CaseData caseData = ccdRequest.getCaseDetails().getCaseData(); - caseFlagsService.rollbackCaseFlags(caseData); + if (featureToggleService.isCaseFlagsV2Enabled(ccdRequest.getCaseDetails().getCaseTypeId())) { + caseFlagsService.rollbackCaseFlags(caseData); + } else { + caseFlagsService.rollbackLegacyCaseFlags(caseData); + } return getCallbackRespEntityErrors(List.of(), caseData); } diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1ReppedController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1ReppedController.java index b8337197de..22a0f1898f 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1ReppedController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1ReppedController.java @@ -521,9 +521,8 @@ public ResponseEntity submitClaim( Et1ReppedHelper.clearEt1ReppedCreationFields(caseData); caseData = nocRespondentRepresentativeService.prepopulateOrgPolicyAndNoc(caseData); - boolean caseFlagsToggle = featureToggleService.isCaseFlagsEnabled(); - log.info("Case flags feature flag is {}", caseFlagsToggle); - if (caseFlagsToggle && caseFlagsService.caseFlagsSetupRequired(caseData)) { + boolean caseFlagsV2Toggle = featureToggleService.isCaseFlagsV2Enabled(caseDetails.getCaseTypeId()); + if (caseFlagsV2Toggle && caseFlagsService.caseFlagsSetupRequired(caseData)) { caseFlagsService.setupCaseFlags(caseData); caseFlagsService.processNewlySetCaseFlags(caseData); } diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/NoticeOfChangeController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/NoticeOfChangeController.java index beee4ed4b5..79eb1f09dc 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/NoticeOfChangeController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/NoticeOfChangeController.java @@ -75,7 +75,7 @@ public ResponseEntity handleAboutToSubmit(@RequestHeader("A CaseData caseData = nocRepresentativeService .updateRepresentation(callbackRequest.getCaseDetails(), userToken); - if (featureToggleService.isCaseFlagsEnabled()) { + if (featureToggleService.isCaseFlagsV2Enabled(callbackRequest.getCaseDetails().getCaseTypeId())) { caseFlagsService.setupCaseFlags(caseData); } diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/RespondentRepresentativeController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/RespondentRepresentativeController.java index 488feef0ee..4ac5bbfb99 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/RespondentRepresentativeController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/RespondentRepresentativeController.java @@ -256,7 +256,7 @@ public ResponseEntity updateRespOrgPolicyAboutToSubmit( // Clears the changeOrganisationRequestField to prevent errors in the existing representative process // and to allow further changes to be made caseData.setChangeOrganisationRequestField(null); - setupCaseFlagsIfRequired(caseData); + setupCaseFlagsIfRequired(caseDetails); return getCallbackRespEntityNoErrors(ccdRequest.getCaseDetails().getCaseData()); } @@ -287,12 +287,14 @@ public ResponseEntity removeOwnRepresentative( caseData.getRepCollection().removeAll(caseData.getRepCollectionToRemove()); caseData.setRepCollectionToRemove(null); } - setupCaseFlagsIfRequired(caseData); + setupCaseFlagsIfRequired(caseDetails); return getCallbackRespEntityNoErrors(ccdRequest.getCaseDetails().getCaseData()); } - private void setupCaseFlagsIfRequired(CaseData caseData) { - if (featureToggleService.isCaseFlagsEnabled() && caseFlagsService.caseFlagsSetupRequired(caseData)) { + private void setupCaseFlagsIfRequired(CaseDetails caseDetails) { + CaseData caseData = caseDetails.getCaseData(); + if (featureToggleService.isCaseFlagsV2Enabled(caseDetails.getCaseTypeId()) + && caseFlagsService.caseFlagsSetupRequired(caseData)) { caseFlagsService.setupCaseFlags(caseData); } } @@ -300,12 +302,33 @@ private void setupCaseFlagsIfRequired(CaseData caseData) { private void setupCaseFlagsIfRespondentRepresentativeChanged(CallbackRequest callbackRequest) { CaseData caseData = callbackRequest.getCaseDetails().getCaseData(); List changedRepresentativeIndexes = changedRespondentRepresentativeIndexes(callbackRequest); - if (featureToggleService.isCaseFlagsEnabled() && CollectionUtils.isNotEmpty(changedRepresentativeIndexes)) { - caseFlagsService.clearRespondentRepresentativeFlags(caseData, changedRepresentativeIndexes); + boolean representativeRemoved = respondentRepresentativeRemoved(callbackRequest); + if (featureToggleService.isCaseFlagsV2Enabled(callbackRequest.getCaseDetails().getCaseTypeId()) + && (CollectionUtils.isNotEmpty(changedRepresentativeIndexes) || representativeRemoved)) { + if (CollectionUtils.isNotEmpty(changedRepresentativeIndexes)) { + caseFlagsService.clearRespondentRepresentativeFlags(caseData, changedRepresentativeIndexes); + } caseFlagsService.setupCaseFlags(caseData); } } + private static boolean respondentRepresentativeRemoved(CallbackRequest callbackRequest) { + if (callbackRequest.getCaseDetailsBefore() == null + || callbackRequest.getCaseDetailsBefore().getCaseData() == null + || CollectionUtils.isEmpty(callbackRequest.getCaseDetailsBefore().getCaseData().getRepCollection())) { + return false; + } + + List previousRepresentatives = + callbackRequest.getCaseDetailsBefore().getCaseData().getRepCollection(); + List currentRepresentatives = callbackRequest.getCaseDetails().getCaseData() + .getRepCollection(); + return previousRepresentatives.stream().anyMatch(previousRepresentative -> + CollectionUtils.isEmpty(currentRepresentatives) + || currentRepresentatives.stream().noneMatch(currentRepresentative -> + sameRepresentative(previousRepresentative, currentRepresentative))); + } + private static List changedRespondentRepresentativeIndexes(CallbackRequest callbackRequest) { if (callbackRequest.getCaseDetailsBefore() == null || callbackRequest.getCaseDetailsBefore().getCaseData() == null diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java index b66e50c913..f428a56697 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java @@ -181,6 +181,14 @@ public boolean caseFlagsSetupRequired(CaseData caseData) { || hasStaleRespondentRepresentativeFlags(caseData); } + public boolean legacyCaseFlagsSetupRequired(CaseData caseData) { + return getCaseFlags(caseData) == null + || legacyPartyFlagSetupRequired(caseData.getAllPartyFlags() == null + ? null : caseData.getAllPartyFlags().getClaimantFlags()) + || legacyPartyFlagSetupRequired(caseData.getAllPartyFlags() == null + ? null : caseData.getAllPartyFlags().getRespondentFlags()); + } + /** * Setup case flags for Claimant, Respondent, Representative and Case level. * @@ -201,6 +209,22 @@ public void setupCaseFlags(CaseData caseData) { clearStaleRespondentRepresentativeFlags(caseData); } + /** + * Preserves the Case Flags v1.0 setup for case types that have not moved to v2.1. + * + * @param caseData Data about the current case + */ + public void setupLegacyCaseFlags(CaseData caseData) { + if (getCaseFlags(caseData) == null) { + setCaseFlags(caseData, CaseFlagsType.builder().build()); + } + + AllPartyFlags flags = getOrCreateAllPartyFlags(caseData); + flags.setClaimantFlags(setupLegacyPartyFlag(flags.getClaimantFlags(), caseData.getClaimant(), CLAIMANT)); + flags.setRespondentFlags(setupLegacyPartyFlag(flags.getRespondentFlags(), caseData.getRespondent(), + "respondent")); + } + /** * Migrates existing claimant and respondent case flags from the v1.0 fields into * the v2.1 internal and external sections. @@ -233,13 +257,106 @@ public void migrateExistingClaimantAndRespondentCaseFlags( } /** - * Sets case flags for Claimant, Respondent, Representative and Case level to null. + * Consolidates v2.1 party flags into the sections retained during rollback. * * @param caseData Data about the current case */ public void rollbackCaseFlags(CaseData caseData) { + if (caseData == null || caseData.getAllPartyFlags() == null) { + return; + } + + PartyFlag claimantInternal = partyFlag(PartyType.CLAIMANT, INTERNAL, NOT_INDEXED); + consolidateFlagDetails(caseData, claimantInternal, partyFlags(PartyType.CLAIMANT, null)); + partyFlag(PartyType.CLAIMANT, EXTERNAL, NOT_INDEXED).clear(caseData); + + PartyFlag firstRespondentInternal = partyFlag(PartyType.RESPONDENT, INTERNAL, 0); + consolidateFlagDetails(caseData, firstRespondentInternal, partyFlags(PartyType.RESPONDENT, null)); + + PARTY_FLAGS.stream() + .filter(flag -> PartyType.RESPONDENT.equals(flag.partyType())) + .filter(flag -> flag.index() > 0 || EXTERNAL.equals(flag.visibility())) + .forEach(flag -> flag.clear(caseData)); + PARTY_FLAGS.stream() + .filter(flag -> PartyType.CLAIMANT_REPRESENTATIVE.equals(flag.partyType()) + || PartyType.RESPONDENT_REPRESENTATIVE.equals(flag.partyType())) + .forEach(flag -> flag.clear(caseData)); + + AllPartyFlags flags = caseData.getAllPartyFlags(); + flags.setClaimantFlags(setupLegacyPartyFlag(flags.getClaimantFlags(), caseData.getClaimant(), CLAIMANT)); + flags.setRespondentFlags(setupLegacyPartyFlag(flags.getRespondentFlags(), caseData.getRespondent(), + "respondent")); + } + + private static void consolidateFlagDetails( + CaseData caseData, PartyFlag destination, List sourceFlags) { + List sources = sourceFlags.stream() + .map(flag -> flag.get(caseData)) + .filter(Objects::nonNull) + .toList(); + List> details = existingDetails(sources.toArray(CaseFlagsType[]::new)); + CaseFlagsType destinationFlags = destination.get(caseData); + + if (destinationFlags == null && !details.isEmpty()) { + String partyName = rollbackDestinationPartyName(caseData, destination, sources); + destinationFlags = createShellFlag(partyName, destination.roleOnCase(), destination.visibility()); + destination.set(caseData, destinationFlags); + } + + if (destinationFlags != null) { + destinationFlags.setDetails(details.isEmpty() ? null : ListTypeItem.from(details.stream())); + } + } + + private static String rollbackDestinationPartyName( + CaseData caseData, PartyFlag destination, List sources) { + String currentPartyName = hasParty(caseData, destination) ? getPartyName(caseData, destination) : null; + return StringUtils.firstNonBlank( + currentPartyName, + sources.stream() + .map(CaseFlagsType::getPartyName) + .filter(StringUtils::isNotBlank) + .findFirst() + .orElse(null)); + } + + private static List partyFlags(PartyType partyType, @Nullable String visibility) { + return PARTY_FLAGS.stream() + .filter(flag -> partyType.equals(flag.partyType())) + .filter(flag -> visibility == null || visibility.equals(flag.visibility())) + .toList(); + } + + private static PartyFlag partyFlag(PartyType partyType, String visibility, int index) { + return PARTY_FLAGS.stream() + .filter(flag -> partyType.equals(flag.partyType())) + .filter(flag -> visibility.equals(flag.visibility())) + .filter(flag -> index == flag.index()) + .findFirst() + .orElseThrow(); + } + + public void rollbackLegacyCaseFlags(CaseData caseData) { setCaseFlags(caseData, null); - PARTY_FLAGS.forEach(flag -> flag.clear(caseData)); + if (caseData.getAllPartyFlags() != null) { + caseData.getAllPartyFlags().setClaimantFlags(null); + caseData.getAllPartyFlags().setRespondentFlags(null); + } + } + + private static boolean legacyPartyFlagSetupRequired(CaseFlagsType flags) { + return flags == null || StringUtils.isEmpty(flags.getRoleOnCase()); + } + + private static CaseFlagsType setupLegacyPartyFlag(CaseFlagsType flags, String partyName, String roleOnCase) { + if (flags == null) { + return CaseFlagsType.builder().partyName(partyName).roleOnCase(roleOnCase).build(); + } + flags.setPartyName(partyName); + flags.setRoleOnCase(roleOnCase); + flags.setGroupId(null); + flags.setVisibility(null); + return flags; } /** @@ -729,7 +846,7 @@ private static boolean isExternalFlag( return EXTERNAL.equals(referenceDataVisibilityValue); } - // A legacy flag no longer configured in Reference Data defaults to Internal. + // Flags no longer present in Reference Data are treated as internal. return false; } diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseManagementForCaseWorkerService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseManagementForCaseWorkerService.java index fe73080795..dfd4de2b59 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseManagementForCaseWorkerService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseManagementForCaseWorkerService.java @@ -437,6 +437,8 @@ public void setMigratedCaseLinkDetails(String authToken, CaseDetails caseDetails public CaseData struckOutRespondents(CCDRequest ccdRequest) { CaseData caseData = ccdRequest.getCaseDetails().getCaseData(); + boolean caseFlagsEnabled = featureToggleService.isCaseFlagsV2Enabled( + ccdRequest.getCaseDetails().getCaseTypeId()); if (caseData.getRespondentCollection() != null && !caseData.getRespondentCollection().isEmpty()) { List activeRespondent = new ArrayList<>(); List struckRespondent = new ArrayList<>(); @@ -445,14 +447,16 @@ public CaseData struckOutRespondents(CCDRequest ccdRequest) { if (respondentSumType.getResponseStruckOut() != null) { if (respondentSumType.getResponseStruckOut().equals(YES)) { struckRespondent.add(respondentSumTypeItem); - caseFlagsService.inactivateRespondentCaseFlags( - caseData, - respondentSumType.getRespondentName() - ); - caseFlagsService.inactivateRespondentRepresentativeCaseFlags( - caseData, - respondentSumTypeItem - ); + if (caseFlagsEnabled) { + caseFlagsService.inactivateRespondentCaseFlags( + caseData, + respondentSumType.getRespondentName() + ); + caseFlagsService.inactivateRespondentRepresentativeCaseFlags( + caseData, + respondentSumTypeItem + ); + } } else { activeRespondent.add(respondentSumTypeItem); } @@ -470,6 +474,8 @@ public CaseData struckOutRespondents(CCDRequest ccdRequest) { public CaseData continuingRespondent(CCDRequest ccdRequest) { CaseData caseData = ccdRequest.getCaseDetails().getCaseData(); + boolean caseFlagsEnabled = featureToggleService.isCaseFlagsV2Enabled( + ccdRequest.getCaseDetails().getCaseTypeId()); if (isEmpty(caseData.getRespondentCollection())) { return caseData; } @@ -481,14 +487,16 @@ public CaseData continuingRespondent(CCDRequest ccdRequest) { continuingRespondent.add(respondentSumTypeItem); } else if (NO.equals(respondentSumType.getResponseContinue())) { notContinuingRespondent.add(respondentSumTypeItem); - caseFlagsService.inactivateRespondentCaseFlags( - caseData, - respondentSumType.getRespondentName() - ); - caseFlagsService.inactivateRespondentRepresentativeCaseFlags( - caseData, - respondentSumTypeItem - ); + if (caseFlagsEnabled) { + caseFlagsService.inactivateRespondentCaseFlags( + caseData, + respondentSumType.getRespondentName() + ); + caseFlagsService.inactivateRespondentRepresentativeCaseFlags( + caseData, + respondentSumTypeItem + ); + } } else { respondentSumType.setResponseContinue(YES); continuingRespondent.add(respondentSumTypeItem); diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/FeatureToggleService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/FeatureToggleService.java index 7fe6944dc2..9baadb2fb2 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/FeatureToggleService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/FeatureToggleService.java @@ -4,6 +4,9 @@ import org.springframework.stereotype.Service; import uk.gov.hmcts.ecm.common.launchdarkly.FeatureToggleApi; +import static uk.gov.hmcts.ecm.common.model.helper.Constants.ENGLANDWALES_CASE_TYPE_ID; +import static uk.gov.hmcts.ecm.common.model.helper.Constants.SCOTLAND_CASE_TYPE_ID; + @Service public class FeatureToggleService { @@ -26,6 +29,16 @@ public boolean isCaseFlagsEnabled() { return this.featureToggleApi.isFeatureEnabled("case-flags-linking-enabled"); } + public boolean isCaseFlagsV2Enabled(String caseTypeId) { + if (ENGLANDWALES_CASE_TYPE_ID.equals(caseTypeId)) { + return this.featureToggleApi.isFeatureEnabled("case-flags-v2-enabled-england-wales"); + } + if (SCOTLAND_CASE_TYPE_ID.equals(caseTypeId)) { + return this.featureToggleApi.isFeatureEnabled("case-flags-v2-enabled-scotland"); + } + return false; + } + public boolean isHmcEnabled() { return this.featureToggleApi.isFeatureEnabled("hmc"); } diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocRespondentRepresentativeService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocRespondentRepresentativeService.java index 71570d8db7..b6c7632f7e 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocRespondentRepresentativeService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocRespondentRepresentativeService.java @@ -5,6 +5,7 @@ import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Strings; import org.jspecify.annotations.NonNull; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; @@ -60,6 +61,7 @@ import java.util.Optional; import java.util.Set; import java.util.UUID; +import java.util.stream.Collectors; import static org.apache.commons.lang3.ObjectUtils.getIfNull; import static org.apache.commons.lang3.ObjectUtils.isEmpty; @@ -616,14 +618,20 @@ public List revokeOldRespondentRepresentativeAccess( List representativesToRevoke = new ArrayList<>(); List caseUserAssignmentsToRevoke = new ArrayList<>(); Set caseUserAssignmentsToRevokeIndex = new LinkedHashSet<>(); + CaseData currentCaseData = callbackRequest.getCaseDetails() == null + ? null : callbackRequest.getCaseDetails().getCaseData(); for (RepresentedTypeRItem representative : representativesToRemove) { if (!RespondentRepresentativeUtils.isValidRepresentative(representative)) { continue; } + Set currentRepresentativeRoles = currentRespondentRepresentativeRoles( + currentCaseData, representative); List assignmentsForRepresentative = findCaseAssignmentsToRevokeForRep( oldCaseDetails.getCaseId(), respondentRepresentativeAssignments, - representative); + representative).stream() + .filter(assignment -> !currentRepresentativeRoles.contains(assignment.getCaseRole())) + .toList(); if (CollectionUtils.isEmpty(assignmentsForRepresentative)) { continue; } @@ -643,6 +651,35 @@ public List revokeOldRespondentRepresentativeAccess( return representativesToRevoke; } + private static Set currentRespondentRepresentativeRoles( + CaseData caseData, RepresentedTypeRItem removedRepresentative) { + if (ObjectUtils.isEmpty(caseData) || CollectionUtils.isEmpty(caseData.getRepCollection()) + || !RespondentRepresentativeUtils.isValidRepresentative(removedRepresentative)) { + return Set.of(); + } + + RepresentedTypeR removedRepresentativeValue = removedRepresentative.getValue(); + return caseData.getRepCollection().stream() + .filter(RespondentRepresentativeUtils::isValidRepresentative) + .map(RepresentedTypeRItem::getValue) + .filter(currentRepresentative -> sameRepresentativeUser( + removedRepresentativeValue, currentRepresentative)) + .map(RepresentedTypeR::getRole) + .filter(RoleUtils::isRespondentRepresentativeRole) + .collect(Collectors.toSet()); + } + + private static boolean sameRepresentativeUser( + RepresentedTypeR firstRepresentative, RepresentedTypeR secondRepresentative) { + if (StringUtils.isNotBlank(firstRepresentative.getIdamId()) + && StringUtils.isNotBlank(secondRepresentative.getIdamId())) { + return Strings.CS.equals(firstRepresentative.getIdamId(), secondRepresentative.getIdamId()); + } + return StringUtils.isNotBlank(firstRepresentative.getRepresentativeEmailAddress()) + && Strings.CI.equals(firstRepresentative.getRepresentativeEmailAddress(), + secondRepresentative.getRepresentativeEmailAddress()); + } + /** * Finds the case user assignments that should be revoked for the given representative. * diff --git a/src/main/java/uk/gov/hmcts/reform/et/syaapi/service/FeatureToggleService.java b/src/main/java/uk/gov/hmcts/reform/et/syaapi/service/FeatureToggleService.java index 34c3479250..6278d128c4 100644 --- a/src/main/java/uk/gov/hmcts/reform/et/syaapi/service/FeatureToggleService.java +++ b/src/main/java/uk/gov/hmcts/reform/et/syaapi/service/FeatureToggleService.java @@ -5,6 +5,9 @@ import org.springframework.stereotype.Service; import uk.gov.hmcts.ecm.common.launchdarkly.FeatureToggleApi; +import static uk.gov.hmcts.ecm.common.model.helper.Constants.ENGLANDWALES_CASE_TYPE_ID; +import static uk.gov.hmcts.ecm.common.model.helper.Constants.SCOTLAND_CASE_TYPE_ID; + @Slf4j @Service("syaFeatureToggleService") public class FeatureToggleService { @@ -24,6 +27,16 @@ public boolean isCaseFlagsEnabled() { return this.featureToggleApi.isFeatureEnabled("case-flags-linking-enabled"); } + public boolean isCaseFlagsV2Enabled(String caseTypeId) { + if (ENGLANDWALES_CASE_TYPE_ID.equals(caseTypeId)) { + return this.featureToggleApi.isFeatureEnabled("case-flags-v2-enabled-england-wales"); + } + if (SCOTLAND_CASE_TYPE_ID.equals(caseTypeId)) { + return this.featureToggleApi.isFeatureEnabled("case-flags-v2-enabled-scotland"); + } + return false; + } + public boolean isBundlesEnabled() { return this.featureToggleApi.isFeatureEnabled("bundles"); } diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeControllerTest.java index 6161f4fb64..1069b8085d 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeControllerTest.java @@ -34,6 +34,7 @@ import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; @@ -93,6 +94,7 @@ void setUp() { ccdRequest = CCDRequestBuilder.builder() .withCaseData(caseDetails.getCaseData()) .withCaseId(CASE_ID) + .withCaseTypeId(ENGLANDWALES_CASE_TYPE_ID) .build(); callbackRequest = CallbackRequest.builder() .caseDetails(caseDetails) @@ -143,7 +145,7 @@ void testAboutToSubmitSetsClaimantRepresentativeId_WithErrors() { @SneakyThrows void testAmendClaimantRepresentativeSubmitted() { when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); - when(featureToggleService.isCaseFlagsEnabled()).thenReturn(true); + when(featureToggleService.isCaseFlagsV2Enabled(anyString())).thenReturn(true); mockMvc.perform(post(ABOUT_TO_SUBMIT_URL) .content(jsonMapper.toJson(ccdRequest)) @@ -179,7 +181,7 @@ void testAmendClaimantRepSubmitted() { @SneakyThrows void testAmendClaimantRepSubmittedDoesNotSetUpCaseFlagsWhenEnabled() { when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); - when(featureToggleService.isCaseFlagsEnabled()).thenReturn(true); + when(featureToggleService.isCaseFlagsV2Enabled(anyString())).thenReturn(true); mockMvc.perform(post(SUBMITTED_URL) .content(jsonMapper.toJson(callbackRequest)) diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java index e3f7a481ec..90c540a658 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.SneakyThrows; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -65,6 +66,7 @@ import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; import static org.mockito.ArgumentMatchers.anyList; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyString; @@ -72,6 +74,7 @@ import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.never; +import static org.mockito.Mockito.same; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -309,6 +312,28 @@ void postDefaultValues() { .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); } + @Test + @SneakyThrows + void postDefaultValuesSetsUpLegacyFlagsOnPrepopulatedCaseData() { + CaseData prepopulatedCaseData = new CaseData(); + ((ObjectNode) requestContent2).put("event_id", "initiateCase"); + when(defaultValuesReaderService.getDefaultValues(anyString())).thenReturn(defaultValues); + when(singleReferenceService.createReference(anyString())).thenReturn("5100001/2019"); + when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); + when(featureToggleService.isCaseFlagsEnabled()).thenReturn(true); + when(caseFlagsService.legacyCaseFlagsSetupRequired(any(CaseData.class))).thenReturn(true); + when(nocRespondentRepresentativeService.prepopulateOrgPolicyAndNoc(any(CaseData.class))) + .thenReturn(prepopulatedCaseData); + + mvc.perform(post(POST_DEFAULT_VALUES_URL) + .content(requestContent2.toString()) + .header(AUTHORIZATION, AUTH_TOKEN) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + + verify(caseFlagsService).setupLegacyCaseFlags(same(prepopulatedCaseData)); + } + @Test @SneakyThrows void amendCaseDetails() { @@ -361,7 +386,7 @@ void amendCaseDetailsWithErrors() { @Test @SneakyThrows - void amendClaimantDetails() { + void amendClaimantDetailsUsesLegacyCaseFlagsWhenV2IsDisabled() { when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); mvc.perform(post(AMEND_CLAIMANT_DETAILS_URL) .content(requestContent2.toString()) @@ -373,13 +398,14 @@ void amendClaimantDetails() { .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); verify(caseFlagsService, times(0)).setupCaseFlags(any(CaseData.class)); + verify(caseFlagsService).setupLegacyCaseFlags(any(CaseData.class)); } @Test @SneakyThrows void amendClaimantDetailsSetsUpCaseFlagsWhenEnabled() { when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); - when(featureToggleService.isCaseFlagsEnabled()).thenReturn(true); + when(featureToggleService.isCaseFlagsV2Enabled(anyString())).thenReturn(true); mvc.perform(post(AMEND_CLAIMANT_DETAILS_URL) .content(requestContent2.toString()) @@ -391,11 +417,12 @@ void amendClaimantDetailsSetsUpCaseFlagsWhenEnabled() { .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); verify(caseFlagsService, times(1)).setupCaseFlags(any(CaseData.class)); + verify(caseFlagsService, times(0)).setupLegacyCaseFlags(any(CaseData.class)); } @Test @SneakyThrows - void amendRespondentDetails() { + void amendRespondentDetailsUsesLegacyCaseFlagsWhenV2IsDisabled() { when(caseManagementForCaseWorkerService.struckOutRespondents(any(CCDRequest.class))) .thenReturn(submitEvent.getCaseData()); when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); @@ -410,6 +437,7 @@ void amendRespondentDetails() { .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); verify(caseFlagsService, times(0)).setupCaseFlags(any(CaseData.class)); + verify(caseFlagsService).setupLegacyCaseFlags(any(CaseData.class)); verify(nocRespondentHelper, times(1)).amendRespondentNameRepresentativeNames(any(CaseData.class)); verify(nocRespondentRepresentativeService, times(1)) .prepopulateOrgPolicyAndNoc(any(CaseData.class)); @@ -421,7 +449,7 @@ void amendRespondentDetailsSetsUpCaseFlagsWhenEnabled() { when(caseManagementForCaseWorkerService.struckOutRespondents(any(CCDRequest.class))) .thenReturn(submitEvent.getCaseData()); when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); - when(featureToggleService.isCaseFlagsEnabled()).thenReturn(true); + when(featureToggleService.isCaseFlagsV2Enabled(anyString())).thenReturn(true); doNothing().when(nocRespondentHelper).amendRespondentNameRepresentativeNames(any(CaseData.class)); mvc.perform(post(AMEND_RESPONDENT_DETAILS_URL) @@ -434,6 +462,7 @@ void amendRespondentDetailsSetsUpCaseFlagsWhenEnabled() { .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); verify(caseFlagsService, times(1)).setupCaseFlags(any(CaseData.class)); + verify(caseFlagsService, times(0)).setupLegacyCaseFlags(any(CaseData.class)); } @Test diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsControllerTest.java index f05155be3e..a0ace66e45 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsControllerTest.java @@ -53,6 +53,7 @@ protected void setUp() throws IOException, URISyntaxException { ccdRequest = CCDRequestBuilder.builder() .withCaseData(caseDetails.getCaseData()) + .withCaseTypeId(ENGLANDWALES_CASE_TYPE_ID) .build(); } diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsDataMigrationControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsDataMigrationControllerTest.java index df4e473fdf..13868d82f3 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsDataMigrationControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseFlagsDataMigrationControllerTest.java @@ -20,6 +20,7 @@ import uk.gov.hmcts.ethos.replacement.docmosis.DocmosisApplication; import uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsReferenceDataService; import uk.gov.hmcts.ethos.replacement.docmosis.service.CaseFlagsService; +import uk.gov.hmcts.ethos.replacement.docmosis.service.FeatureToggleService; import uk.gov.hmcts.ethos.replacement.docmosis.service.VerifyTokenService; import uk.gov.hmcts.ethos.replacement.docmosis.utils.JsonMapper; @@ -34,6 +35,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; @@ -58,6 +60,9 @@ class CaseFlagsDataMigrationControllerTest { @MockitoBean private CaseFlagsReferenceDataService caseFlagsReferenceDataService; + @MockitoBean + private FeatureToggleService featureToggleService; + @Autowired private WebApplicationContext applicationContext; private JsonNode requestContent; @@ -76,6 +81,7 @@ void setUp() throws URISyntaxException, IOException { @SneakyThrows void shouldMigrateCaseFlags() { when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); + when(featureToggleService.isCaseFlagsV2Enabled("ET_EnglandWales")).thenReturn(true); Map partyFlagVisibilities = Map.of("ra0010", "External"); when(caseFlagsReferenceDataService.getPartyFlagVisibilities(AUTH_TOKEN)).thenReturn(partyFlagVisibilities); @@ -110,10 +116,70 @@ void shouldMigrateCaseFlags_tokenFail() { .andExpect(status().isForbidden()); } + @Test + @SneakyThrows + void shouldUseLegacyMigrationWhenV2IsDisabledForCaseType() { + when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); + when(featureToggleService.isCaseFlagsV2Enabled("ET_EnglandWales")).thenReturn(false); + when(featureToggleService.isCaseFlagsV2Enabled("ET_Scotland")).thenReturn(true); + + mvc.perform(post(CASE_FLAGS_DATA_MIGRATION) + .content(requestContent.toString()) + .header(AUTHORIZATION, AUTH_TOKEN) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + + verify(caseFlagsReferenceDataService, never()).getPartyFlagVisibilities(any()); + verify(caseFlagsService, never()).migrateExistingClaimantAndRespondentCaseFlags(any(), any()); + verify(caseFlagsService).setupLegacyCaseFlags(any(CaseData.class)); + } + + @Test + @SneakyThrows + void shouldMigrateScotlandCaseFlagsIndependentlyOfEnglandWales() { + requestContent.withObject("/case_details").put("case_type_id", "ET_Scotland"); + when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); + when(featureToggleService.isCaseFlagsV2Enabled("ET_EnglandWales")).thenReturn(false); + when(featureToggleService.isCaseFlagsV2Enabled("ET_Scotland")).thenReturn(true); + Map partyFlagVisibilities = Map.of("ra0010", "External"); + when(caseFlagsReferenceDataService.getPartyFlagVisibilities(AUTH_TOKEN)).thenReturn(partyFlagVisibilities); + + mvc.perform(post(CASE_FLAGS_DATA_MIGRATION) + .content(requestContent.toString()) + .header(AUTHORIZATION, AUTH_TOKEN) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + + verify(caseFlagsService).migrateExistingClaimantAndRespondentCaseFlags( + any(CaseData.class), + eq(partyFlagVisibilities) + ); + verify(caseFlagsService, never()).setupLegacyCaseFlags(any(CaseData.class)); + } + + @Test + @SneakyThrows + void shouldKeepScotlandMigrationOnV1WhenOnlyEnglandWalesV2IsEnabled() { + requestContent.withObject("/case_details").put("case_type_id", "ET_Scotland"); + when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); + when(featureToggleService.isCaseFlagsV2Enabled("ET_EnglandWales")).thenReturn(true); + when(featureToggleService.isCaseFlagsV2Enabled("ET_Scotland")).thenReturn(false); + + mvc.perform(post(CASE_FLAGS_DATA_MIGRATION) + .content(requestContent.toString()) + .header(AUTHORIZATION, AUTH_TOKEN) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + + verify(caseFlagsService).setupLegacyCaseFlags(any(CaseData.class)); + verify(caseFlagsService, never()).migrateExistingClaimantAndRespondentCaseFlags(any(), any()); + } + @Test @SneakyThrows void shouldRollbackCaseFlags() { when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); + when(featureToggleService.isCaseFlagsV2Enabled("ET_EnglandWales")).thenReturn(true); mvc.perform(post(CASE_FLAGS_DATA_ROLLBACK) .content(requestContent.toString()) .header(AUTHORIZATION, AUTH_TOKEN) @@ -126,6 +192,57 @@ void shouldRollbackCaseFlags() { verify(caseFlagsService).rollbackCaseFlags(any(CaseData.class)); } + @Test + @SneakyThrows + void shouldRollbackLegacyCaseFlagsWhenV2IsDisabledForCaseType() { + when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); + + mvc.perform(post(CASE_FLAGS_DATA_ROLLBACK) + .content(requestContent.toString()) + .header(AUTHORIZATION, AUTH_TOKEN) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + + verify(caseFlagsService).rollbackLegacyCaseFlags(any(CaseData.class)); + verify(caseFlagsService, never()).rollbackCaseFlags(any(CaseData.class)); + } + + @Test + @SneakyThrows + void shouldRollbackScotlandV2CaseFlagsIndependentlyOfEnglandWales() { + requestContent.withObject("/case_details").put("case_type_id", "ET_Scotland"); + when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); + when(featureToggleService.isCaseFlagsV2Enabled("ET_EnglandWales")).thenReturn(false); + when(featureToggleService.isCaseFlagsV2Enabled("ET_Scotland")).thenReturn(true); + + mvc.perform(post(CASE_FLAGS_DATA_ROLLBACK) + .content(requestContent.toString()) + .header(AUTHORIZATION, AUTH_TOKEN) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + + verify(caseFlagsService).rollbackCaseFlags(any(CaseData.class)); + verify(caseFlagsService, never()).rollbackLegacyCaseFlags(any(CaseData.class)); + } + + @Test + @SneakyThrows + void shouldKeepScotlandRollbackOnV1WhenOnlyEnglandWalesV2IsEnabled() { + requestContent.withObject("/case_details").put("case_type_id", "ET_Scotland"); + when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); + when(featureToggleService.isCaseFlagsV2Enabled("ET_EnglandWales")).thenReturn(true); + when(featureToggleService.isCaseFlagsV2Enabled("ET_Scotland")).thenReturn(false); + + mvc.perform(post(CASE_FLAGS_DATA_ROLLBACK) + .content(requestContent.toString()) + .header(AUTHORIZATION, AUTH_TOKEN) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + + verify(caseFlagsService).rollbackLegacyCaseFlags(any(CaseData.class)); + verify(caseFlagsService, never()).rollbackCaseFlags(any(CaseData.class)); + } + @Test @SneakyThrows void shouldRollbackCaseFlags_tokenFail() { diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1ReppedControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1ReppedControllerTest.java index a9756c29ac..042b2e0bf6 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1ReppedControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1ReppedControllerTest.java @@ -947,7 +947,7 @@ void submitClaim_toggleOn() { void submitClaim_caseFlagToggleOn() { when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); when(featureToggleService.isEt1DocGenEnabled()).thenReturn(true); - when(featureToggleService.isCaseFlagsEnabled()).thenReturn(true); + when(featureToggleService.isCaseFlagsV2Enabled(anyString())).thenReturn(true); when(caseFlagsService.caseFlagsSetupRequired(any())).thenReturn(false); mockMvc.perform(post(SUBMIT_CLAIM) @@ -968,7 +968,7 @@ void submitClaim_caseFlagToggleOn() { void submitClaim_caseFlagSetupToggleOn() { when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); when(featureToggleService.isEt1DocGenEnabled()).thenReturn(true); - when(featureToggleService.isCaseFlagsEnabled()).thenReturn(true); + when(featureToggleService.isCaseFlagsV2Enabled(anyString())).thenReturn(true); when(caseFlagsService.caseFlagsSetupRequired(any())).thenReturn(true); mockMvc.perform(post(SUBMIT_CLAIM) diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/NoticeOfChangeControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/NoticeOfChangeControllerTest.java index 67e4fb0eea..c344c9e063 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/NoticeOfChangeControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/NoticeOfChangeControllerTest.java @@ -35,6 +35,7 @@ import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.times; @@ -119,7 +120,7 @@ void handleAboutToSubmit_RespondentRep() throws Exception { @Test void handleAboutToSubmitSetsUpCaseFlagsWhenEnabled() throws Exception { when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); - when(featureToggleService.isCaseFlagsEnabled()).thenReturn(true); + when(featureToggleService.isCaseFlagsV2Enabled(anyString())).thenReturn(true); when(nocRepresentativeService.updateRepresentation(any(), any())).thenReturn(caseData); when(ccdCaseAssignment.applyNoc(any(), any())).thenReturn(CCDCallbackResponse.builder() .data(caseData) diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/RespondentRepresentativeControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/RespondentRepresentativeControllerTest.java index f5af010acd..cfdd7e4e26 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/RespondentRepresentativeControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/RespondentRepresentativeControllerTest.java @@ -48,6 +48,7 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static uk.gov.hmcts.ecm.common.model.helper.Constants.ENGLANDWALES_CASE_TYPE_ID; @ExtendWith(SpringExtension.class) @WebMvcTest({RespondentRepresentativeController.class, JsonMapper.class}) @@ -57,6 +58,7 @@ class RespondentRepresentativeControllerTest { private static final String DUMMY_SUBMISSION_REFERENCE = "1234567890123456"; private static final String HEADER_AUTHORIZATION = "Authorization"; private static final String ID_RESPONDENT_1 = "12345acc-be68-4614-b6ad-0ca1cfa9e1d5"; + private static final String ID_RESPONDENT_2 = "22345acc-be68-4614-b6ad-0ca1cfa9e1d5"; private static final String ID_REPRESENTATIVE_1 = "71240acc-be68-4614-b6ad-0ca1cfa9e1d5"; private static final String ID_REPRESENTATIVE_2 = "3130e246-5fee-4b35-b805-41d58099625c"; private static final String RESPONDENT_NAME_1 = "Respondent Name 1"; @@ -176,8 +178,11 @@ void testRemoveOwnRepresentativeSetsUpCaseFlagsWhenRequired() throws Exception { RepresentedTypeRItem representedTypeRItem = RepresentedTypeRItem.builder().id(ID_REPRESENTATIVE_1).build(); caseData.setRepCollection(List.of(representedTypeRItem)); caseData.setRepCollectionToRemove(List.of(representedTypeRItem)); - CCDRequest ccdRequest = CCDRequestBuilder.builder().withCaseData(caseData).build(); - when(featureToggleService.isCaseFlagsEnabled()).thenReturn(true); + CCDRequest ccdRequest = CCDRequestBuilder.builder() + .withCaseData(caseData) + .withCaseTypeId(ENGLANDWALES_CASE_TYPE_ID) + .build(); + when(featureToggleService.isCaseFlagsV2Enabled(anyString())).thenReturn(true); when(caseFlagsService.caseFlagsSetupRequired(any(CaseData.class))).thenReturn(true); mockMvc.perform(post(URL_REMOVE_OWN_REPRESENTATIVE) @@ -266,6 +271,7 @@ void amendRespondentRepresentativeAboutToSubmitSetsUpCaseFlagsWhenNameChanges() .nameOfRepresentative(REPRESENTATIVE_NAME).build()).build())); CaseDetails caseDetails = new CaseDetails(); caseDetails.setCaseId(DUMMY_SUBMISSION_REFERENCE); + caseDetails.setCaseTypeId(ENGLANDWALES_CASE_TYPE_ID); caseDetails.setCaseData(caseData); CaseDetails caseDetailsBefore = new CaseDetails(); caseDetailsBefore.setCaseId(DUMMY_SUBMISSION_REFERENCE); @@ -274,7 +280,7 @@ void amendRespondentRepresentativeAboutToSubmitSetsUpCaseFlagsWhenNameChanges() .caseDetails(caseDetails) .caseDetailsBefore(caseDetailsBefore) .build(); - when(featureToggleService.isCaseFlagsEnabled()).thenReturn(true); + when(featureToggleService.isCaseFlagsV2Enabled(anyString())).thenReturn(true); mockMvc.perform(post(URL_AMEND_RESPONDENT_REPRESENTATIVE_ABOUT_TO_SUBMIT) .content(jsonMapper.toJson(callbackRequest)) @@ -318,6 +324,7 @@ void amendRespondentRepresentativeAboutToSubmitClearsAndSetsUpCaseFlagsWhenOnlyE .build()).build())); CaseDetails caseDetails = new CaseDetails(); caseDetails.setCaseId(DUMMY_SUBMISSION_REFERENCE); + caseDetails.setCaseTypeId(ENGLANDWALES_CASE_TYPE_ID); caseDetails.setCaseData(caseData); CaseDetails caseDetailsBefore = new CaseDetails(); caseDetailsBefore.setCaseId(DUMMY_SUBMISSION_REFERENCE); @@ -326,7 +333,7 @@ void amendRespondentRepresentativeAboutToSubmitClearsAndSetsUpCaseFlagsWhenOnlyE .caseDetails(caseDetails) .caseDetailsBefore(caseDetailsBefore) .build(); - when(featureToggleService.isCaseFlagsEnabled()).thenReturn(true); + when(featureToggleService.isCaseFlagsV2Enabled(anyString())).thenReturn(true); mockMvc.perform(post(URL_AMEND_RESPONDENT_REPRESENTATIVE_ABOUT_TO_SUBMIT) .content(jsonMapper.toJson(callbackRequest)) @@ -342,6 +349,83 @@ void amendRespondentRepresentativeAboutToSubmitClearsAndSetsUpCaseFlagsWhenOnlyE verify(caseFlagsService, times(1)).setupCaseFlags(any(CaseData.class)); } + @Test + @SneakyThrows + void amendRespondentRepresentativeAboutToSubmitReconcilesFlagsWhenOneRepresentationIsRemoved() { + DynamicValueType respondent2Selection = new DynamicValueType(); + respondent2Selection.setLabel(RESPONDENT_NAME_2); + DynamicFixedListType respondent2DynamicList = new DynamicFixedListType(); + respondent2DynamicList.setValue(respondent2Selection); + RepresentedTypeRItem respondent1Representative = RepresentedTypeRItem.builder() + .id(ID_REPRESENTATIVE_1) + .value(RepresentedTypeR.builder() + .respondentId(ID_RESPONDENT_1) + .respRepName(RESPONDENT_NAME_1) + .nameOfRepresentative(REPRESENTATIVE_NAME) + .representativeEmailAddress("representative@example.com") + .role(ROLE_SOLICITOR_A) + .build()) + .build(); + RepresentedTypeRItem respondent2Representative = RepresentedTypeRItem.builder() + .id(ID_REPRESENTATIVE_2) + .value(RepresentedTypeR.builder() + .respondentId(ID_RESPONDENT_2) + .dynamicRespRepName(respondent2DynamicList) + .respRepName(RESPONDENT_NAME_2) + .nameOfRepresentative(REPRESENTATIVE_NAME) + .representativeEmailAddress("representative@example.com") + .role(ROLE_SOLICITOR_B) + .build()) + .build(); + CaseData previousCaseData = new CaseData(); + previousCaseData.setRepCollection(List.of(respondent1Representative, respondent2Representative)); + CaseData currentCaseData = new CaseData(); + currentCaseData.setRepCollection(List.of(respondent2Representative)); + + CallbackRequest callbackRequest = respondentRepresentativeCallback(previousCaseData, currentCaseData); + when(featureToggleService.isCaseFlagsV2Enabled(ENGLANDWALES_CASE_TYPE_ID)).thenReturn(true); + + mockMvc.perform(post(URL_AMEND_RESPONDENT_REPRESENTATIVE_ABOUT_TO_SUBMIT) + .content(jsonMapper.toJson(callbackRequest)) + .header(HEADER_AUTHORIZATION, DUMMY_TOKEN) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + + verify(caseFlagsService, never()).clearRespondentRepresentativeFlags(any(CaseData.class), any()); + verify(caseFlagsService).setupCaseFlags(any(CaseData.class)); + } + + @Test + @SneakyThrows + void amendRespondentRepresentativeAboutToSubmitDeletesFlagsWhenFinalRepresentationIsRemoved() { + RepresentedTypeRItem representative = RepresentedTypeRItem.builder() + .id(ID_REPRESENTATIVE_1) + .value(RepresentedTypeR.builder() + .respondentId(ID_RESPONDENT_1) + .respRepName(RESPONDENT_NAME_1) + .nameOfRepresentative(REPRESENTATIVE_NAME) + .representativeEmailAddress("representative@example.com") + .role(ROLE_SOLICITOR_A) + .build()) + .build(); + CaseData previousCaseData = new CaseData(); + previousCaseData.setRepCollection(List.of(representative)); + CaseData currentCaseData = new CaseData(); + currentCaseData.setRepCollection(List.of()); + + CallbackRequest callbackRequest = respondentRepresentativeCallback(previousCaseData, currentCaseData); + when(featureToggleService.isCaseFlagsV2Enabled(ENGLANDWALES_CASE_TYPE_ID)).thenReturn(true); + + mockMvc.perform(post(URL_AMEND_RESPONDENT_REPRESENTATIVE_ABOUT_TO_SUBMIT) + .content(jsonMapper.toJson(callbackRequest)) + .header(HEADER_AUTHORIZATION, DUMMY_TOKEN) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + + verify(caseFlagsService, never()).clearRespondentRepresentativeFlags(any(CaseData.class), any()); + verify(caseFlagsService).setupCaseFlags(any(CaseData.class)); + } + @Test @SneakyThrows void amendRespondentRepresentativeAboutToSubmitWithError() { @@ -591,4 +675,27 @@ void testUpdateRespOrgPolicyAboutToSubmit_RepCollectionToRemoveAndAddAreNotEmpty .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()); } + + private static CallbackRequest respondentRepresentativeCallback( + CaseData previousCaseData, CaseData currentCaseData) { + RespondentSumTypeItem respondent1 = new RespondentSumTypeItem(); + respondent1.setId(ID_RESPONDENT_1); + respondent1.setValue(RespondentSumType.builder().respondentName(RESPONDENT_NAME_1).build()); + RespondentSumTypeItem respondent2 = new RespondentSumTypeItem(); + respondent2.setId(ID_RESPONDENT_2); + respondent2.setValue(RespondentSumType.builder().respondentName(RESPONDENT_NAME_2).build()); + currentCaseData.setRespondentCollection(List.of(respondent1, respondent2)); + + CaseDetails previousCaseDetails = new CaseDetails(); + previousCaseDetails.setCaseId(DUMMY_SUBMISSION_REFERENCE); + previousCaseDetails.setCaseData(previousCaseData); + CaseDetails currentCaseDetails = new CaseDetails(); + currentCaseDetails.setCaseId(DUMMY_SUBMISSION_REFERENCE); + currentCaseDetails.setCaseTypeId(ENGLANDWALES_CASE_TYPE_ID); + currentCaseDetails.setCaseData(currentCaseData); + return CallbackRequest.builder() + .caseDetailsBefore(previousCaseDetails) + .caseDetails(currentCaseDetails) + .build(); + } } diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java index 10d80dc30e..1e52115234 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java @@ -10,6 +10,7 @@ import uk.gov.hmcts.et.common.model.ccd.items.FlagDetailType; import uk.gov.hmcts.et.common.model.ccd.items.GenericTseApplicationType; import uk.gov.hmcts.et.common.model.ccd.items.GenericTseApplicationTypeItem; +import uk.gov.hmcts.et.common.model.ccd.items.GenericTypeItem; import uk.gov.hmcts.et.common.model.ccd.items.ListTypeItem; import uk.gov.hmcts.et.common.model.ccd.items.RepresentedTypeRItem; import uk.gov.hmcts.et.common.model.ccd.items.RespondentSumTypeItem; @@ -204,6 +205,38 @@ void setupCaseFlags_shouldCreateAllPartyFlagsHolderWhenAbsent() { assertNotNull(allPartyFlags(caseData).getClaimantExternalFlags()); } + @Test + void setupLegacyCaseFlags_shouldOnlyCreateV1CaseClaimantAndRespondentFlags() { + caseFlagsService.setupLegacyCaseFlags(caseData); + + AllPartyFlags flags = allPartyFlags(caseData); + assertNotNull(flags.getCaseFlags()); + assertThat(flags.getClaimantFlags().getPartyName(), is(CLAIMANT_NAME)); + assertThat(flags.getClaimantFlags().getRoleOnCase(), is(CLAIMANT)); + assertThat(flags.getRespondentFlags().getPartyName(), is(RESPONDENT_NAME)); + assertThat(flags.getRespondentFlags().getRoleOnCase(), is("respondent")); + assertNull(flags.getClaimantExternalFlags()); + assertNull(flags.getRespondentExternalFlags()); + assertNull(flags.getClaimantRepresentativeFlags()); + assertNull(flags.getRepresentativeFlags()); + assertFalse(caseFlagsService.legacyCaseFlagsSetupRequired(caseData)); + } + + @Test + void rollbackLegacyCaseFlags_shouldLeaveV2OnlyFieldsUnchanged() { + caseFlagsService.setupCaseFlags(caseData); + final CaseFlagsType claimantExternalFlags = allPartyFlags(caseData).getClaimantExternalFlags(); + final CaseFlagsType representativeFlags = allPartyFlags(caseData).getRepresentativeFlags(); + + caseFlagsService.rollbackLegacyCaseFlags(caseData); + + assertNull(allPartyFlags(caseData).getCaseFlags()); + assertNull(allPartyFlags(caseData).getClaimantFlags()); + assertNull(allPartyFlags(caseData).getRespondentFlags()); + assertSame(claimantExternalFlags, allPartyFlags(caseData).getClaimantExternalFlags()); + assertSame(representativeFlags, allPartyFlags(caseData).getRepresentativeFlags()); + } + @Test void migrateExistingClaimantAndRespondentCaseFlags_shouldMoveFlagsToInternalAndExternalSections() { caseData.setRespondentCollection(respondentCollection(2)); @@ -441,6 +474,43 @@ void setupCaseFlags_shouldReuseRespondentRepresentativeFlagsForTheSameRepresenta ); } + @Test + void setupCaseFlags_shouldRetainSharedRepresentativeDetailsUntilFinalRepresentationIsRemoved() { + caseData.setRespondentCollection(respondentCollection(2)); + List respondents = caseData.getRespondentCollection(); + RepresentedTypeRItem respondent1Representative = representativeItemForRespondent( + "1", "Shared Representative", "shared@example.com", respondents.get(0), "[SOLICITORA]"); + RepresentedTypeRItem respondent2Representative = representativeItemForRespondent( + "2", "Shared Representative", "shared@example.com", respondents.get(1), "[SOLICITORB]"); + caseData.setRepCollection(List.of(respondent1Representative, respondent2Representative)); + + caseFlagsService.setupCaseFlags(caseData); + AllPartyFlags allPartyFlags = allPartyFlags(caseData); + allPartyFlags.getRepresentativeFlags().setDetails( + ListTypeItem.from(activeFlag("Representative internal flag"))); + allPartyFlags.getRepresentativeExternalFlags().setDetails( + ListTypeItem.from(activeFlag("Representative external flag"))); + + caseData.setRepCollection(List.of(respondent2Representative)); + caseFlagsService.setupCaseFlags(caseData); + + assertAll( + () -> assertNull(allPartyFlags.getRepresentativeFlags()), + () -> assertEquals("Representative internal flag", + allPartyFlags.getRepresentative1Flags().getDetails().getFirst().getValue().getName()), + () -> assertEquals("Representative external flag", + allPartyFlags.getRepresentative1ExternalFlags().getDetails().getFirst().getValue().getName()) + ); + + caseData.setRepCollection(List.of()); + caseFlagsService.setupCaseFlags(caseData); + + assertAll( + () -> assertNull(allPartyFlags.getRepresentative1Flags()), + () -> assertNull(allPartyFlags.getRepresentative1ExternalFlags()) + ); + } + @Test void setupCaseFlags_shouldCreateSeparateRespondentRepresentativeFlagsForSameNameWithDifferentEmails() { String sharedRepresentativeName = "Shared Representative"; @@ -633,16 +703,57 @@ void setupCaseFlags_shouldRecreatePartyFlagsWhenRoleIsMissing(FlagSlot slot) { } @Test - void rollbackCaseFlags_shouldSetToNull() { + void rollbackCaseFlags_shouldConsolidateV2PartyFlagsAndKeepCaseFlags() { caseFlagsService.setupCaseFlags(caseData); + AllPartyFlags flags = allPartyFlags(caseData); + CaseFlagsType caseFlags = flags.getCaseFlags(); + caseFlags.setDetails(ListTypeItem.from(activeFlag("Case flag"))); + + flags.getClaimantFlags().setDetails(ListTypeItem.from(activeFlag("Claimant internal flag"))); + flags.getClaimantExternalFlags().setDetails(ListTypeItem.from(activeFlag("Claimant external flag"))); + + flags.getRespondentFlags().setDetails(ListTypeItem.from(activeFlag("Respondent 1 internal flag"))); + flags.getRespondentExternalFlags().setDetails(ListTypeItem.from(activeFlag("Respondent 1 external flag"))); + flags.getRespondent1Flags().setDetails(ListTypeItem.from(activeFlag("Respondent 2 internal flag"))); + flags.getRespondent1ExternalFlags().setDetails(ListTypeItem.from(activeFlag("Respondent 2 external flag"))); + flags.getRespondent2Flags().setDetails(ListTypeItem.from(activeFlag("Respondent 3 internal flag"))); + flags.getRespondent2ExternalFlags().setDetails(ListTypeItem.from(activeFlag("Respondent 3 external flag"))); + + flags.getClaimantRepresentativeFlags().setDetails( + ListTypeItem.from(activeFlag("Claimant representative flag"))); + flags.getRepresentativeFlags().setDetails(ListTypeItem.from(activeFlag("Respondent representative flag"))); + caseFlagsService.rollbackCaseFlags(caseData); - assertThat(allPartyFlags(caseData).getCaseFlags(), is(nullValue())); - assertThat(allPartyFlags(caseData).getClaimantFlags(), is(nullValue())); - assertThat(allPartyFlags(caseData).getRespondentFlags(), is(nullValue())); - assertThat(allPartyFlags(caseData).getClaimantExternalFlags(), is(nullValue())); - assertThat(allPartyFlags(caseData).getRespondentExternalFlags(), is(nullValue())); - allPartyFlagSlots().forEach(slot -> assertNull(slot.get(caseData), slot + " should be cleared")); + assertSame(caseFlags, flags.getCaseFlags()); + assertEquals(List.of("Case flag"), flagNames(flags.getCaseFlags())); + assertEquals(List.of("Claimant internal flag", "Claimant external flag"), + flagNames(flags.getClaimantFlags())); + assertEquals(CLAIMANT_NAME, flags.getClaimantFlags().getPartyName()); + assertEquals(CLAIMANT, flags.getClaimantFlags().getRoleOnCase()); + assertNull(flags.getClaimantFlags().getGroupId()); + assertNull(flags.getClaimantFlags().getVisibility()); + assertNull(flags.getClaimantExternalFlags()); + assertEquals(List.of( + "Respondent 1 internal flag", + "Respondent 1 external flag", + "Respondent 2 internal flag", + "Respondent 2 external flag", + "Respondent 3 internal flag", + "Respondent 3 external flag"), flagNames(flags.getRespondentFlags())); + assertEquals(RESPONDENT_NAME, flags.getRespondentFlags().getPartyName()); + assertEquals("respondent", flags.getRespondentFlags().getRoleOnCase()); + assertNull(flags.getRespondentFlags().getGroupId()); + assertNull(flags.getRespondentFlags().getVisibility()); + assertNull(flags.getRespondentExternalFlags()); + + respondentPartyFlagSlots() + .filter(slot -> slot.respondentIndex > 0) + .forEach(slot -> assertNull(slot.get(caseData), slot + " should be cleared")); + assertNull(flags.getClaimantRepresentativeFlags()); + assertNull(flags.getClaimantRepresentativeExternalFlags()); + respondentRepresentativePartyFlagSlots() + .forEach(slot -> assertNull(slot.get(caseData), slot + " should be cleared")); } @Test @@ -652,6 +763,34 @@ void rollbackCaseFlags_shouldNotCreateAllPartyFlagsWhenAbsent() { assertNull(caseData.getAllPartyFlags()); } + @Test + void rollbackCaseFlags_shouldCreateMissingConsolidationSectionsWithoutLosingFlags() { + AllPartyFlags flags = AllPartyFlags.builder() + .claimantExternalFlags(legacyCaseFlags(activeFlag("Claimant external flag"))) + .respondent1Flags(legacyCaseFlags(activeFlag("Respondent 2 internal flag"))) + .respondent1ExternalFlags(legacyCaseFlags(activeFlag("Respondent 2 external flag"))) + .build(); + caseData.setAllPartyFlags(flags); + + caseFlagsService.rollbackCaseFlags(caseData); + + assertEquals(List.of("Claimant external flag"), flagNames(flags.getClaimantFlags())); + assertEquals(CLAIMANT_NAME, flags.getClaimantFlags().getPartyName()); + assertEquals(CLAIMANT, flags.getClaimantFlags().getRoleOnCase()); + assertNull(flags.getClaimantFlags().getGroupId()); + assertNull(flags.getClaimantFlags().getVisibility()); + assertEquals(List.of("Respondent 2 internal flag", "Respondent 2 external flag"), + flagNames(flags.getRespondentFlags())); + assertEquals(RESPONDENT_NAME, flags.getRespondentFlags().getPartyName()); + assertEquals("respondent", flags.getRespondentFlags().getRoleOnCase()); + assertNull(flags.getRespondentFlags().getGroupId()); + assertNull(flags.getRespondentFlags().getVisibility()); + assertNull(flags.getRespondentExternalFlags()); + assertNull(flags.getClaimantExternalFlags()); + assertNull(flags.getRespondent1Flags()); + assertNull(flags.getRespondent1ExternalFlags()); + } + @Test void inactivateRespondentCaseFlags_shouldSetAllMatchingRespondentFlagDetailsInactive() { caseFlagsService.setupCaseFlags(caseData); @@ -1640,6 +1779,13 @@ private static String firstFlagStatus(CaseFlagsType flags) { return flags.getDetails().getFirst().getValue().getStatus(); } + private static List flagNames(CaseFlagsType flags) { + return flags.getDetails().stream() + .map(GenericTypeItem::getValue) + .map(FlagDetailType::getName) + .toList(); + } + private static String firstFlagComment(CaseFlagsType flags) { return flags.getDetails().getFirst().getValue().getFlagComment(); } diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseManagementForCaseWorkerServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseManagementForCaseWorkerServiceTest.java index 7a38797f91..2f98f2b807 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseManagementForCaseWorkerServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseManagementForCaseWorkerServiceTest.java @@ -159,6 +159,7 @@ void setUp() throws URISyntaxException, IOException { when(featureToggleService.isGlobalSearchEnabled()).thenReturn(true); when(featureToggleService.isWorkAllocationEnabled()).thenReturn(true); when(featureToggleService.isHmcEnabled()).thenReturn(true); + when(featureToggleService.isCaseFlagsV2Enabled(anyString())).thenReturn(true); when(featureToggleService.isWorkAllocationEnabled()).thenReturn(true); when(adminUserService.getAdminUserToken()).thenReturn(AUTH_TOKEN); caseManagementForCaseWorkerService = new CaseManagementForCaseWorkerService( @@ -503,6 +504,16 @@ void struckOutRespondentFirstToLast() { ); } + @Test + void struckOutRespondentDoesNotInactivateCaseFlagsWhenDisabledForScotland() { + when(featureToggleService.isCaseFlagsV2Enabled(SCOTLAND_CASE_TYPE_ID)).thenReturn(false); + + caseManagementForCaseWorkerService.struckOutRespondents(scotlandCcdRequest1); + + verify(caseFlagsService, never()).inactivateRespondentCaseFlags(any(), anyString()); + verify(caseFlagsService, never()).inactivateRespondentRepresentativeCaseFlags(any(), any()); + } + @Test void struckOutRespondentRespAddressLinesEmpty() { scotlandCcdRequest1.getCaseDetails().getCaseData().getRespondentCollection().getFirst().getValue() diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/FeatureToggleServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/FeatureToggleServiceTest.java index 4fad19c0e2..48188f6ac2 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/FeatureToggleServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/FeatureToggleServiceTest.java @@ -1,6 +1,7 @@ package uk.gov.hmcts.ethos.replacement.docmosis.service; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; @@ -10,6 +11,8 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.when; +import static uk.gov.hmcts.ecm.common.model.helper.Constants.ENGLANDWALES_CASE_TYPE_ID; +import static uk.gov.hmcts.ecm.common.model.helper.Constants.SCOTLAND_CASE_TYPE_ID; @ExtendWith(MockitoExtension.class) class FeatureToggleServiceTest { @@ -44,12 +47,33 @@ void shouldReturnCorrectValue_whenAnyFeatureIsEnabled(Boolean toggleStat) { @ParameterizedTest @ValueSource(booleans = {true, false}) - void shouldReturnCorrectValue_whenCaseFlagsLinkingIsEnabled(Boolean toggleStat) { + void shouldReturnCorrectValue_whenLegacyCaseFlagsLinkingIsEnabled(Boolean toggleStat) { givenToggle("case-flags-linking-enabled", toggleStat); assertThat(featureToggleService.isCaseFlagsEnabled()).isEqualTo(toggleStat); } + @ParameterizedTest + @ValueSource(booleans = {true, false}) + void shouldReturnCorrectValue_whenEnglandWalesCaseFlagsLinkingIsEnabled(Boolean toggleStat) { + givenToggle("case-flags-v2-enabled-england-wales", toggleStat); + + assertThat(featureToggleService.isCaseFlagsV2Enabled(ENGLANDWALES_CASE_TYPE_ID)).isEqualTo(toggleStat); + } + + @ParameterizedTest + @ValueSource(booleans = {true, false}) + void shouldReturnCorrectValue_whenScotlandCaseFlagsLinkingIsEnabled(Boolean toggleStat) { + givenToggle("case-flags-v2-enabled-scotland", toggleStat); + + assertThat(featureToggleService.isCaseFlagsV2Enabled(SCOTLAND_CASE_TYPE_ID)).isEqualTo(toggleStat); + } + + @Test + void shouldDisableCaseFlagsForUnknownCaseType() { + assertThat(featureToggleService.isCaseFlagsV2Enabled("unknown")).isFalse(); + } + @ParameterizedTest @ValueSource(booleans = {true, false}) void shouldReturnCorrectValue_whenBundlesIsEnabled(Boolean toggleStat) { diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocRespondentRepresentativeServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocRespondentRepresentativeServiceTest.java index b6708fc4c9..8596a0c90e 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocRespondentRepresentativeServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocRespondentRepresentativeServiceTest.java @@ -781,6 +781,51 @@ void revokeOldRespondentRepresentativeAccessOnlyRevokesRemovedRepresentativeAssi .containsExactlyInAnyOrder(removedPrimaryAssignment, removedAdditionalAssignment); } + @Test + @SneakyThrows + void revokeOldRespondentRepresentativeAccessRetainsRoleForAnotherRespondentRepresentedBySameUser() { + RepresentedTypeRItem removedRespondentOneRepresentative = removableRepresentativeForRespondent( + "rep-item-1", RESPONDENT_ID_ONE, RESPONDENT_NAME_ONE, ROLE_SOLICITORA, + REPRESENTATIVE_ID_ONE, REPRESENTATIVE_EMAIL_1, ORGANISATION_ID_ONE); + RepresentedTypeRItem remainingRespondentTwoRepresentative = removableRepresentativeForRespondent( + "rep-item-2", RESPONDENT_ID_TWO, RESPONDENT_NAME_TWO, ROLE_SOLICITORB, + REPRESENTATIVE_ID_ONE, REPRESENTATIVE_EMAIL_1, ORGANISATION_ID_ONE); + CaseData previousCaseData = new CaseData(); + previousCaseData.setRepCollection(List.of( + removedRespondentOneRepresentative, remainingRespondentTwoRepresentative)); + CaseData currentCaseData = new CaseData(); + currentCaseData.setRepCollection(List.of(remainingRespondentTwoRepresentative)); + CaseDetails previousCaseDetails = new CaseDetails(); + previousCaseDetails.setCaseId(CASE_ID_1); + previousCaseDetails.setCaseData(previousCaseData); + CaseDetails currentCaseDetails = new CaseDetails(); + currentCaseDetails.setCaseId(CASE_ID_1); + currentCaseDetails.setCaseData(currentCaseData); + CallbackRequest callbackRequest = CallbackRequest.builder() + .caseDetailsBefore(previousCaseDetails) + .caseDetails(currentCaseDetails) + .build(); + + CaseUserAssignment removedRespondentAssignment = assignment(REPRESENTATIVE_ID_ONE, ROLE_SOLICITORA); + CaseUserAssignment remainingRespondentAssignment = assignment(REPRESENTATIVE_ID_ONE, ROLE_SOLICITORB); + when(adminUserService.getAdminUserToken()).thenReturn(ADMIN_USER_TOKEN); + when(nocCcdService.retrieveCaseUserAssignments(ADMIN_USER_TOKEN, CASE_ID_1)) + .thenReturn(CaseUserAssignmentData.builder() + .caseUserAssignments(List.of(removedRespondentAssignment, remainingRespondentAssignment)) + .build()); + + List revokedRepresentatives = nocRespondentRepresentativeService + .revokeOldRespondentRepresentativeAccess( + callbackRequest, USER_TOKEN, List.of(removedRespondentOneRepresentative)); + + assertThat(revokedRepresentatives).containsExactly(removedRespondentOneRepresentative); + ArgumentCaptor revokedAssignments = + ArgumentCaptor.forClass(CaseUserAssignmentData.class); + verify(ccdClient).revokeCaseAssignments(eq(USER_TOKEN), revokedAssignments.capture()); + assertThat(revokedAssignments.getValue().getCaseUserAssignments()) + .containsExactly(removedRespondentAssignment); + } + @Test @SneakyThrows void revokeOldRespondentRepresentativeAccessOnlyRevokesDeletedMiddleRepresentativeAssignments() { diff --git a/src/test/java/uk/gov/hmcts/reform/et/syaapi/service/FeatureToggleServiceTest.java b/src/test/java/uk/gov/hmcts/reform/et/syaapi/service/FeatureToggleServiceTest.java index 25b451d016..3219b3de3e 100644 --- a/src/test/java/uk/gov/hmcts/reform/et/syaapi/service/FeatureToggleServiceTest.java +++ b/src/test/java/uk/gov/hmcts/reform/et/syaapi/service/FeatureToggleServiceTest.java @@ -1,6 +1,7 @@ package uk.gov.hmcts.reform.et.syaapi.service; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; @@ -10,6 +11,8 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.when; +import static uk.gov.hmcts.ecm.common.model.helper.Constants.ENGLANDWALES_CASE_TYPE_ID; +import static uk.gov.hmcts.ecm.common.model.helper.Constants.SCOTLAND_CASE_TYPE_ID; @ExtendWith(MockitoExtension.class) class FeatureToggleServiceTest { @@ -35,12 +38,33 @@ void shouldReturnCorrectValueWhenAnyFeatureIsEnabled(boolean toggleStat) { @ParameterizedTest @ValueSource(booleans = {true, false}) - void shouldReturnCorrectValueWhenCaseFlagsLinkingIsEnabled(boolean toggleStat) { + void shouldReturnCorrectValueWhenEnglandWalesCaseFlagsLinkingIsEnabled(boolean toggleStat) { + givenToggle("case-flags-v2-enabled-england-wales", toggleStat); + + assertThat(featureToggleService.isCaseFlagsV2Enabled(ENGLANDWALES_CASE_TYPE_ID)).isEqualTo(toggleStat); + } + + @ParameterizedTest + @ValueSource(booleans = {true, false}) + void shouldReturnCorrectValueWhenLegacyCaseFlagsLinkingIsEnabled(boolean toggleStat) { givenToggle("case-flags-linking-enabled", toggleStat); assertThat(featureToggleService.isCaseFlagsEnabled()).isEqualTo(toggleStat); } + @ParameterizedTest + @ValueSource(booleans = {true, false}) + void shouldReturnCorrectValueWhenScotlandCaseFlagsLinkingIsEnabled(boolean toggleStat) { + givenToggle("case-flags-v2-enabled-scotland", toggleStat); + + assertThat(featureToggleService.isCaseFlagsV2Enabled(SCOTLAND_CASE_TYPE_ID)).isEqualTo(toggleStat); + } + + @Test + void shouldDisableCaseFlagsForUnknownCaseType() { + assertThat(featureToggleService.isCaseFlagsV2Enabled("unknown")).isFalse(); + } + @ParameterizedTest @ValueSource(booleans = {true, false}) void shouldReturnCorrectValueWhenWorkAllocationIsEnabled(boolean toggleStat) { From 94ef6056d5f38c1e3a0a9117495d3811c9cafc80 Mon Sep 17 00:00:00 2001 From: rajaram Date: Sun, 30 Aug 2026 15:15:29 +0100 Subject: [PATCH 037/100] Claimant rep flags to be removed while claimant removes their rep and other issues --- ...AmendClaimantRepresentativeController.java | 9 +- .../CaseActionsForCaseWorkerController.java | 11 +- .../ClaimantRepresentativeController.java | 12 +- .../RespondentRepresentativeController.java | 4 + .../docmosis/helpers/NocRespondentHelper.java | 21 +++- .../docmosis/service/CaseFlagsService.java | 104 ++++++++++++++++++ .../noc/NocClaimantRepresentativeService.java | 12 +- .../NocRespondentRepresentativeService.java | 5 +- .../noc/ClaimantRepresentativeUtils.java | 13 ++- .../syaapi/service/ManageCaseRoleService.java | 12 +- ...dClaimantRepresentativeControllerTest.java | 5 +- ...aseActionsForCaseWorkerControllerTest.java | 43 ++++++-- .../ClaimantRepresentativeControllerTest.java | 55 ++++++++- ...espondentRepresentativeControllerTest.java | 4 + .../helpers/NocRespondentHelperTest.java | 21 +++- .../service/CaseFlagsServiceTest.java | 51 +++++++++ .../NocClaimantRepresentativeServiceTest.java | 40 +++++-- ...ocRespondentRepresentativeServiceTest.java | 19 +++- .../noc/ClaimantRepresentativeUtilsTest.java | 40 ++++++- .../service/ManageCaseRoleServiceTest.java | 33 ++++++ 20 files changed, 459 insertions(+), 55 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeController.java index b535c83119..ae62206a2b 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeController.java @@ -114,13 +114,15 @@ public ResponseEntity aboutToSubmit( errors.add(error); } CaseData caseData = callbackRequest.getCaseDetails().getCaseData(); + boolean caseFlagsV2Enabled = featureToggleService.isCaseFlagsV2Enabled( + callbackRequest.getCaseDetails().getCaseTypeId()); if (errors.isEmpty()) { - ClaimantRepresentativeUtils.addAmendClaimantRepresentative(caseData); + ClaimantRepresentativeUtils.addAmendClaimantRepresentative(caseData, caseFlagsV2Enabled); nocRespondentRepresentativeService.revokeRespondentRepresentativesWithSameOrganisationAsClaimant( callbackRequest.getCaseDetails()); } - if (featureToggleService.isCaseFlagsV2Enabled(callbackRequest.getCaseDetails().getCaseTypeId())) { + if (caseFlagsV2Enabled) { caseFlagsService.clearClaimantRepresentativeFlagsIfRepresentativeChanged(caseData, callbackRequest.getCaseDetailsBefore() == null ? null @@ -144,7 +146,8 @@ public ResponseEntity amendClaimantRepSubmitted( log.info("AMEND CLAIMANT REPRESENTATIVE SUBMITTED ---> " + LOG_MESSAGE + "{}", callbackRequest.getCaseDetails().getCaseId()); try { - nocClaimantRepresentativeService.updateClaimantRepAccess(callbackRequest); + nocClaimantRepresentativeService.updateClaimantRepAccess(callbackRequest, + featureToggleService.isCaseFlagsV2Enabled(callbackRequest.getCaseDetails().getCaseTypeId())); } catch (IOException e) { throw new CcdInputOutputException("Failed to update claimant representatives access", e); } diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java index 86e91a41fc..db7cc87f49 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java @@ -381,8 +381,12 @@ public ResponseEntity amendRespondentDetails( eventValidationService.validateMaximumSize(caseData).ifPresent(errors::add); if (errors.isEmpty() && isNotEmpty(caseData.getRepCollection())) { //Needed to keep the respondent names in the rep collection sync - nocRespondentHelper.amendRespondentNameRepresentativeNames(caseData); - caseData = nocRespondentRepresentativeService.prepopulateOrgPolicyAndNoc(caseData); + boolean caseFlagsV2Enabled = featureToggleService.isCaseFlagsV2Enabled( + ccdRequest.getCaseDetails().getCaseTypeId()); + nocRespondentHelper.amendRespondentNameRepresentativeNames(caseData, caseFlagsV2Enabled); + if (caseFlagsV2Enabled) { + caseData = nocRespondentRepresentativeService.prepopulateOrgPolicyAndNoc(caseData); + } } if (errors.isEmpty() && isNotEmpty(caseData.getRespondentCollection())) { @@ -410,6 +414,9 @@ public ResponseEntity amendRespondentDetails( public void amendRespondentDetailsSubmitted( @RequestBody CallbackRequest callbackRequest, @RequestHeader(AUTHORIZATION) String userToken) { + if (!featureToggleService.isCaseFlagsV2Enabled(callbackRequest.getCaseDetails().getCaseTypeId())) { + return; + } try { nocRespondentRepresentativeService.realignRespondentRepresentativeAccess(callbackRequest); } catch (RuntimeException exception) { diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/ClaimantRepresentativeController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/ClaimantRepresentativeController.java index 232d629f66..8ea7daffeb 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/ClaimantRepresentativeController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/ClaimantRepresentativeController.java @@ -18,7 +18,7 @@ import uk.gov.hmcts.et.common.model.ccd.CCDRequest; import uk.gov.hmcts.et.common.model.ccd.CaseData; import uk.gov.hmcts.et.common.model.ccd.CaseDetails; -import uk.gov.hmcts.et.common.model.ccd.types.OrganisationPolicy; +import uk.gov.hmcts.ethos.replacement.docmosis.service.FeatureToggleService; import static org.springframework.http.HttpHeaders.AUTHORIZATION; import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; @@ -39,8 +39,8 @@ import static uk.gov.hmcts.ethos.replacement.docmosis.constants.HttpConstants.HTTP_MESSAGE_FOUR_ZERO_ONE; import static uk.gov.hmcts.ethos.replacement.docmosis.constants.HttpConstants.HTTP_MESSAGE_FOUR_ZERO_THREE; import static uk.gov.hmcts.ethos.replacement.docmosis.constants.HttpConstants.HTTP_MESSAGE_TWO_HUNDRED; -import static uk.gov.hmcts.ethos.replacement.docmosis.domain.ClaimantSolicitorRole.CLAIMANTSOLICITOR; import static uk.gov.hmcts.ethos.replacement.docmosis.helpers.CallbackRespHelper.getCallbackRespEntityNoErrors; +import static uk.gov.hmcts.ethos.replacement.docmosis.utils.noc.ClaimantRepresentativeUtils.markClaimantAsUnrepresented; @Slf4j @RequestMapping("/claimantRepresentative") @@ -51,6 +51,8 @@ public class ClaimantRepresentativeController { private static final String LOG_MESSAGE = "received claimant's remove own representative request for case reference : "; + private final FeatureToggleService featureToggleService; + /** * Handles the removal of a claimant's own representative from the case data. *

@@ -105,10 +107,8 @@ public ResponseEntity removeOwnRepresentative( CaseData caseData = caseDetails.getCaseData(); if (StringUtils.isNotBlank(caseData.getClaimantRepresentedQuestion()) && NO.equals(caseData.getClaimantRepresentedQuestion())) { - caseData.setRepresentativeClaimantType(null); - caseData.setClaimantRepresentativeOrganisationPolicy( - OrganisationPolicy.builder().orgPolicyCaseAssignedRole(CLAIMANTSOLICITOR.getCaseRoleLabel()).build() - ); + markClaimantAsUnrepresented(caseData, + featureToggleService.isCaseFlagsV2Enabled(caseDetails.getCaseTypeId())); } return getCallbackRespEntityNoErrors(ccdRequest.getCaseDetails().getCaseData()); } diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/RespondentRepresentativeController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/RespondentRepresentativeController.java index 4ac5bbfb99..1abfa03d2e 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/RespondentRepresentativeController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/RespondentRepresentativeController.java @@ -284,6 +284,10 @@ public ResponseEntity removeOwnRepresentative( CaseData caseData = caseDetails.getCaseData(); if (CollectionUtils.isNotEmpty(caseData.getRepCollection()) && CollectionUtils.isNotEmpty(caseData.getRepCollectionToRemove())) { + if (featureToggleService.isCaseFlagsV2Enabled(caseDetails.getCaseTypeId())) { + caseFlagsService.removeRespondentRepresentativeFlags( + caseData, caseData.getRepCollectionToRemove()); + } caseData.getRepCollection().removeAll(caseData.getRepCollectionToRemove()); caseData.setRepCollectionToRemove(null); } diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/helpers/NocRespondentHelper.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/helpers/NocRespondentHelper.java index d1a382edae..0b3af98e2f 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/helpers/NocRespondentHelper.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/helpers/NocRespondentHelper.java @@ -179,7 +179,12 @@ public static void resetRepresentation(RespondentSumTypeItem respondent) { respondent.getValue().setRepresentativeId(null); } - public void amendRespondentNameRepresentativeNames(CaseData caseData) { + public void amendRespondentNameRepresentativeNames(CaseData caseData, boolean caseFlagsV2Enabled) { + if (!caseFlagsV2Enabled) { + amendRespondentNameRepresentativeNamesLegacy(caseData); + return; + } + List representatives = emptyIfNull(caseData.getRepCollection()); List respondents = emptyIfNull(caseData.getRespondentCollection()); List alignedRepCollection = new ArrayList<>(); @@ -204,6 +209,20 @@ public void amendRespondentNameRepresentativeNames(CaseData caseData) { caseData.setRepCollection(alignedRepCollection); } + private void amendRespondentNameRepresentativeNamesLegacy(CaseData caseData) { + List repCollection = new ArrayList<>(); + for (RepresentedTypeRItem respondentRep : emptyIfNull(caseData.getRepCollection())) { + Optional matchedRespondent = emptyIfNull(caseData.getRespondentCollection()).stream() + .filter(respondent -> respondent.getId().equals(respondentRep.getValue().getRespondentId())) + .findFirst(); + + matchedRespondent.ifPresent(respondent -> updateRepWithRespondentDetails( + respondent, respondentRep, caseData.getRespondentCollection())); + repCollection.add(respondentRep); + } + caseData.setRepCollection(repCollection); + } + private Optional findRepresentativeByRespondentId( RespondentSumTypeItem respondent, List representatives) { if (respondent == null || StringUtils.isBlank(respondent.getId())) { diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java index f428a56697..cfaa98a679 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java @@ -1,6 +1,7 @@ package uk.gov.hmcts.ethos.replacement.docmosis.service; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import uk.gov.hmcts.et.common.model.ccd.CaseData; @@ -29,6 +30,7 @@ import java.util.Objects; import java.util.function.BiConsumer; import java.util.function.Function; +import java.util.stream.IntStream; import javax.annotation.Nullable; import static uk.gov.hmcts.ecm.common.model.helper.CaseFlagConstants.ACTIVE; @@ -465,6 +467,108 @@ public void clearRespondentRepresentativeFlags(CaseData caseData, List .forEach(flags -> flags.setDetails(null)); } + /** + * Removes Case Flags for respondent representatives being removed through the respondent self-service flow. + * If the same representative still represents another respondent, their flags are moved to that remaining + * representative role instead. + * + * @param caseData case data before the representative collection entries are removed + * @param representativesToRemove representative collection entries selected for removal + */ + public void removeRespondentRepresentativeFlags( + CaseData caseData, List representativesToRemove) { + if (caseData == null || CollectionUtils.isEmpty(caseData.getRepCollection()) + || CollectionUtils.isEmpty(representativesToRemove)) { + return; + } + + List currentRepresentatives = caseData.getRepCollection(); + List remainingRepresentatives = currentRepresentatives.stream() + .filter(representative -> representativesToRemove.stream() + .noneMatch(removed -> sameRepresentativeCollectionItem(removed, representative))) + .toList(); + + for (RepresentedTypeRItem removedRepresentative : representativesToRemove) { + int collectionIndex = representativeCollectionIndex(currentRepresentatives, removedRepresentative); + if (collectionIndex < 0) { + continue; + } + + int sourceSlot = representativeFlagSlotIndex(removedRepresentative, collectionIndex); + RepresentativeIdentity removedIdentity = representativeIdentity(removedRepresentative.getValue()); + int targetSlot = remainingRepresentativeFlagSlot(remainingRepresentatives, removedIdentity); + moveOrClearRepresentativeFlag(caseData, sourceSlot, targetSlot, INTERNAL); + moveOrClearRepresentativeFlag(caseData, sourceSlot, targetSlot, EXTERNAL); + } + } + + private static int representativeCollectionIndex( + List representatives, RepresentedTypeRItem representative) { + return IntStream.range(0, representatives.size()) + .filter(index -> sameRepresentativeCollectionItem(representatives.get(index), representative)) + .findFirst() + .orElse(-1); + } + + private static boolean sameRepresentativeCollectionItem( + RepresentedTypeRItem first, RepresentedTypeRItem second) { + if (first == null || second == null) { + return false; + } + if (StringUtils.isNotBlank(first.getId()) && StringUtils.isNotBlank(second.getId())) { + return Objects.equals(first.getId(), second.getId()); + } + return first == second || Objects.equals(first, second); + } + + private static int remainingRepresentativeFlagSlot( + List remainingRepresentatives, RepresentativeIdentity removedIdentity) { + if (removedIdentity == null) { + return -1; + } + return IntStream.range(0, remainingRepresentatives.size()) + .filter(index -> Objects.equals(removedIdentity, + representativeIdentity(remainingRepresentatives.get(index).getValue()))) + .map(index -> representativeFlagSlotIndex(remainingRepresentatives.get(index), index)) + .findFirst() + .orElse(-1); + } + + private static void moveOrClearRepresentativeFlag( + CaseData caseData, int sourceSlot, int targetSlot, String visibility) { + PartyFlag sourceFlag = respondentRepresentativeFlag(sourceSlot, visibility); + if (sourceFlag == null) { + return; + } + + CaseFlagsType source = sourceFlag.get(caseData); + if (source == null || sourceSlot == targetSlot) { + return; + } + if (targetSlot >= 0) { + PartyFlag targetFlag = respondentRepresentativeFlag(targetSlot, visibility); + if (targetFlag != null) { + CaseFlagsType target = targetFlag.get(caseData); + if (target == null) { + targetFlag.set(caseData, source); + } else if (!Objects.equals(target.getDetails(), source.getDetails())) { + target.setDetails(concatFlagDetails(target.getDetails(), source.getDetails())); + } + } + } + sourceFlag.clear(caseData); + } + + @Nullable + private static PartyFlag respondentRepresentativeFlag(int slot, String visibility) { + return PARTY_FLAGS.stream() + .filter(flag -> PartyType.RESPONDENT_REPRESENTATIVE.equals(flag.partyType())) + .filter(flag -> flag.index() == slot) + .filter(flag -> visibility.equals(flag.visibility())) + .findFirst() + .orElse(null); + } + public void clearClaimantRepresentativeFlagsIfRepresentativeChanged(CaseData caseData, CaseData caseDataBefore) { if (caseData == null || caseDataBefore == null || !claimantRepresentativeChanged(caseData.getRepresentativeClaimantType(), diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocClaimantRepresentativeService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocClaimantRepresentativeService.java index 7c5eab2871..bf821d6923 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocClaimantRepresentativeService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocClaimantRepresentativeService.java @@ -227,14 +227,14 @@ private void prepopulateOrgAddress(CaseData caseData, String userToken) { } } - public void updateClaimantRepAccess(CallbackRequest callbackRequest) + public void updateClaimantRepAccess(CallbackRequest callbackRequest, boolean caseFlagsV2Enabled) throws IOException { CaseDetails caseDetails = callbackRequest.getCaseDetails(); CaseDetails caseDetailsBefore = callbackRequest.getCaseDetailsBefore(); CaseData caseDataBefore = caseDetailsBefore.getCaseData(); CaseData caseData = caseDetails.getCaseData(); - ChangeOrganisationRequest changeRequest = identifyRepresentationChanges(caseData, - caseDataBefore); + ChangeOrganisationRequest changeRequest = identifyRepresentationChanges( + caseData, caseDataBefore, caseFlagsV2Enabled); try { nocNotificationService.sendNotificationOfChangeEmails(caseDetailsBefore, caseDetails, changeRequest, true); } catch (Exception exception) { @@ -265,14 +265,16 @@ public void updateClaimantRepAccess(CallbackRequest callbackRequest) } } - public ChangeOrganisationRequest identifyRepresentationChanges(CaseData after, CaseData before) { + public ChangeOrganisationRequest identifyRepresentationChanges( + CaseData after, CaseData before, boolean caseFlagsV2Enabled) { RepresentedTypeC newRep = after.getRepresentativeClaimantType(); RepresentedTypeC oldRep = before.getRepresentativeClaimantType(); Organisation newRepOrg = newRep != null ? newRep.getMyHmctsOrganisation() : null; Organisation oldRepOrg = oldRep != null ? oldRep.getMyHmctsOrganisation() : null; ChangeOrganisationRequest changeRequests; - if (!Objects.equals(newRepOrg, oldRepOrg) || claimantRepresentativeChanged(newRep, oldRep)) { + if (!Objects.equals(newRepOrg, oldRepOrg) + || (caseFlagsV2Enabled && claimantRepresentativeChanged(newRep, oldRep))) { changeRequests = NocUtils.buildApprovedChangeOrganisationRequest(newRepOrg, oldRepOrg, ClaimantSolicitorRole.CLAIMANTSOLICITOR.getCaseRoleLabel()); } else { diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocRespondentRepresentativeService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocRespondentRepresentativeService.java index b6c7632f7e..4e59edf063 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocRespondentRepresentativeService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocRespondentRepresentativeService.java @@ -38,6 +38,7 @@ import uk.gov.hmcts.ethos.replacement.docmosis.helpers.NoticeOfChangeFieldPopulator; import uk.gov.hmcts.ethos.replacement.docmosis.rdprofessional.OrganisationClient; import uk.gov.hmcts.ethos.replacement.docmosis.service.AdminUserService; +import uk.gov.hmcts.ethos.replacement.docmosis.service.FeatureToggleService; import uk.gov.hmcts.ethos.replacement.docmosis.service.MyHmctsService; import uk.gov.hmcts.ethos.replacement.docmosis.service.OrganisationService; import uk.gov.hmcts.ethos.replacement.docmosis.service.UserIdamService; @@ -106,6 +107,7 @@ public class NocRespondentRepresentativeService { private final UserIdamService userIdamService; private final OrganisationService organisationService; private final MyHmctsService myHmctsService; + private final FeatureToggleService featureToggleService; private static final String CLASS_NAME = NocRespondentRepresentativeService.class.getSimpleName(); @@ -1202,7 +1204,8 @@ public CaseData removeConflictingClaimantRepresentation(CaseDetails caseDetails) } final String adminUserToken = adminUserService.getAdminUserToken(); nocCcdService.revokeClaimantRepresentation(adminUserToken, caseDetails); - ClaimantRepresentativeUtils.markClaimantAsUnrepresented(caseDetails.getCaseData()); + ClaimantRepresentativeUtils.markClaimantAsUnrepresented( + caseDetails.getCaseData(), featureToggleService.isCaseFlagsV2Enabled(caseDetails.getCaseTypeId())); return caseDetails.getCaseData(); } diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/utils/noc/ClaimantRepresentativeUtils.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/utils/noc/ClaimantRepresentativeUtils.java index 8409751b29..6e0a6e41ac 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/utils/noc/ClaimantRepresentativeUtils.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/utils/noc/ClaimantRepresentativeUtils.java @@ -181,11 +181,15 @@ public static boolean isClaimantRepresentativeEmailMatchedWithRespondents(CaseDa * * @param caseData the case data to update to an unrepresented claimant state; * must not be {@code null} + * @param caseFlagsV2Enabled whether claimant representative v2.1 Case Flags should be removed */ - public static void markClaimantAsUnrepresented(CaseData caseData) { + public static void markClaimantAsUnrepresented(CaseData caseData, boolean caseFlagsV2Enabled) { caseData.setRepresentativeClaimantType(null); caseData.setClaimantRepresentativeRemoved(YES); caseData.setClaimantRepresentedQuestion(NO); + if (caseFlagsV2Enabled) { + clearClaimantRepresentativeFlags(caseData); + } caseData.setClaimantRepresentativeOrganisationPolicy(OrganisationPolicy.builder() .orgPolicyCaseAssignedRole(ClaimantSolicitorRole.CLAIMANTSOLICITOR.getCaseRoleLabel()).build()); } @@ -260,15 +264,18 @@ public static boolean hasRepresentativeEmail(RepresentedTypeC claimantRepresenta *

Assumption: The provided {@code caseData} is not {@code null}.

* * @param caseData the case data containing claimant representative information to update + * @param caseFlagsV2Enabled whether claimant representative v2.1 Case Flags should be removed */ - public static void addAmendClaimantRepresentative(CaseData caseData) { + public static void addAmendClaimantRepresentative(CaseData caseData, boolean caseFlagsV2Enabled) { if (NO.equals(caseData.getClaimantRepresentedQuestion()) || caseData.getRepresentativeClaimantType() == null) { if (caseData.getRepresentativeClaimantType() != null) { caseData.setClaimantRepresentativeRemoved(YES); } caseData.setRepresentativeClaimantType(null); caseData.setClaimantRepresentedQuestion(NO); - clearClaimantRepresentativeFlags(caseData); + if (caseFlagsV2Enabled) { + clearClaimantRepresentativeFlags(caseData); + } caseData.setClaimantRepresentativeOrganisationPolicy(OrganisationPolicy.builder().organisation(null) .orgPolicyCaseAssignedRole(ClaimantSolicitorRole.CLAIMANTSOLICITOR.getCaseRoleLabel()).build()); diff --git a/src/main/java/uk/gov/hmcts/reform/et/syaapi/service/ManageCaseRoleService.java b/src/main/java/uk/gov/hmcts/reform/et/syaapi/service/ManageCaseRoleService.java index ac615e0885..91e13912df 100644 --- a/src/main/java/uk/gov/hmcts/reform/et/syaapi/service/ManageCaseRoleService.java +++ b/src/main/java/uk/gov/hmcts/reform/et/syaapi/service/ManageCaseRoleService.java @@ -795,12 +795,10 @@ public CaseDetails revokeRespondentSolicitorRole(String authorisation, if (StringUtils.isNotBlank(caseUserRole)) { try { revokeCaseUserRole(caseDetails, caseUserRole); - } catch (IOException | ManageCaseRoleException e) { - log.info( - "No case user role revoked for respondent index: {}, in case with submission reference: {}. " - + "This maybe because respondent representative does not have any organisation defined in " - + "ref data.", - respondentIndex, caseSubmissionReference + } catch (IOException e) { + throw new ManageCaseRoleException( + "Unable to revoke respondent representative access for respondent index " + respondentIndex, + e ); } } @@ -966,6 +964,8 @@ public CaseDetails removeRespondentRepresentativeFromCaseData(String authorisati startedCaseDetails.getId().toString()); } respondentSumTypeItem.getValue().setRepresentativeRemoved(YES); + respondentSumTypeItem.getValue().setRepresented(NO); + respondentSumTypeItem.getValue().setRepresentativeId(null); RepresentedTypeRItem representativeRItem = RespondentUtil.findRespondentRepresentative(respondentSumTypeItem, caseData.getRepCollection(), diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeControllerTest.java index 1069b8085d..37c99e22b6 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/AddAmendClaimantRepresentativeControllerTest.java @@ -35,6 +35,7 @@ import static org.hamcrest.Matchers.nullValue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; @@ -173,7 +174,7 @@ void testAmendClaimantRepSubmitted() { .andExpect(jsonPath("$.warnings", nullValue())); verify(nocClaimantRepresentativeService, times(1)) - .updateClaimantRepAccess(any()); + .updateClaimantRepAccess(any(), eq(false)); verify(caseFlagsService, never()).setupCaseFlags(any()); } @@ -193,7 +194,7 @@ void testAmendClaimantRepSubmittedDoesNotSetUpCaseFlagsWhenEnabled() { .andExpect(jsonPath("$.warnings", nullValue())); verify(nocClaimantRepresentativeService, times(1)) - .updateClaimantRepAccess(any()); + .updateClaimantRepAccess(any(), eq(true)); verify(caseFlagsService, never()).setupCaseFlags(any()); } diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java index 90c540a658..8dc172a16b 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java @@ -65,6 +65,7 @@ import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; +import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyList; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; @@ -426,7 +427,8 @@ void amendRespondentDetailsUsesLegacyCaseFlagsWhenV2IsDisabled() { when(caseManagementForCaseWorkerService.struckOutRespondents(any(CCDRequest.class))) .thenReturn(submitEvent.getCaseData()); when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); - doNothing().when(nocRespondentHelper).amendRespondentNameRepresentativeNames(any(CaseData.class)); + doNothing().when(nocRespondentHelper) + .amendRespondentNameRepresentativeNames(any(CaseData.class), eq(false)); mvc.perform(post(AMEND_RESPONDENT_DETAILS_URL) .content(requestContent2.toString()) .header(AUTHORIZATION, AUTH_TOKEN) @@ -438,8 +440,9 @@ void amendRespondentDetailsUsesLegacyCaseFlagsWhenV2IsDisabled() { verify(caseFlagsService, times(0)).setupCaseFlags(any(CaseData.class)); verify(caseFlagsService).setupLegacyCaseFlags(any(CaseData.class)); - verify(nocRespondentHelper, times(1)).amendRespondentNameRepresentativeNames(any(CaseData.class)); - verify(nocRespondentRepresentativeService, times(1)) + verify(nocRespondentHelper, times(1)) + .amendRespondentNameRepresentativeNames(any(CaseData.class), eq(false)); + verify(nocRespondentRepresentativeService, never()) .prepopulateOrgPolicyAndNoc(any(CaseData.class)); } @@ -450,7 +453,8 @@ void amendRespondentDetailsSetsUpCaseFlagsWhenEnabled() { .thenReturn(submitEvent.getCaseData()); when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); when(featureToggleService.isCaseFlagsV2Enabled(anyString())).thenReturn(true); - doNothing().when(nocRespondentHelper).amendRespondentNameRepresentativeNames(any(CaseData.class)); + doNothing().when(nocRespondentHelper) + .amendRespondentNameRepresentativeNames(any(CaseData.class), eq(true)); mvc.perform(post(AMEND_RESPONDENT_DETAILS_URL) .content(requestContent2.toString()) @@ -483,7 +487,8 @@ void amendRespondentDetails_moreThan10Respondents() { .andExpect(jsonPath(JsonMapper.ERRORS, notNullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(nocRespondentHelper, times(0)).amendRespondentNameRepresentativeNames(any(CaseData.class)); + verify(nocRespondentHelper, times(0)) + .amendRespondentNameRepresentativeNames(any(CaseData.class), anyBoolean()); verify(nocRespondentRepresentativeService, never()).prepopulateOrgPolicyAndNoc(any(CaseData.class)); } @@ -505,7 +510,8 @@ void amendRespondentDetails_noRepCollection() { .andExpect(jsonPath(JsonMapper.ERRORS, notNullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); - verify(nocRespondentHelper, times(0)).amendRespondentNameRepresentativeNames(any(CaseData.class)); + verify(nocRespondentHelper, times(0)) + .amendRespondentNameRepresentativeNames(any(CaseData.class), anyBoolean()); verify(nocRespondentRepresentativeService, never()).prepopulateOrgPolicyAndNoc(any(CaseData.class)); } @@ -515,7 +521,8 @@ void amendRespondentDetails_UpdateCounter() { when(caseManagementForCaseWorkerService.struckOutRespondents(any(CCDRequest.class))) .thenReturn(submitEvent.getCaseData()); when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); - doNothing().when(nocRespondentHelper).amendRespondentNameRepresentativeNames(any(CaseData.class)); + doNothing().when(nocRespondentHelper) + .amendRespondentNameRepresentativeNames(any(CaseData.class), anyBoolean()); when(featureToggleService.isWorkAllocationEnabled()).thenReturn(true); @@ -540,7 +547,8 @@ void amendRespondentDetailsContinuingClaim() { when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); when(nocRespondentRepresentativeService.prepopulateOrgPolicyAndNoc(any(CaseData.class))) .thenReturn(ccdRequest.getCaseDetails().getCaseData()); - doNothing().when(nocRespondentHelper).amendRespondentNameRepresentativeNames(any(CaseData.class)); + doNothing().when(nocRespondentHelper) + .amendRespondentNameRepresentativeNames(any(CaseData.class), anyBoolean()); mvc.perform(post(AMEND_RESPONDENT_DETAILS_URL) .content(requestContent2.toString()) .header(AUTHORIZATION, AUTH_TOKEN) @@ -562,6 +570,7 @@ void amendRespondentDetailsSubmittedRealignsRepresentativeAccess() { .caseDetails(ccdRequest.getCaseDetails()) .build(); when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); + when(featureToggleService.isCaseFlagsV2Enabled(anyString())).thenReturn(true); mvc.perform(post(AMEND_RESPONDENT_DETAILS_SUBMITTED_URL) .content(jsonMapper.toJson(callbackRequest)) @@ -573,6 +582,24 @@ void amendRespondentDetailsSubmittedRealignsRepresentativeAccess() { .realignRespondentRepresentativeAccess(any(CallbackRequest.class)); } + @Test + @SneakyThrows + void amendRespondentDetailsSubmittedDoesNotRealignRepresentativeAccessWhenV2IsDisabled() { + CallbackRequest callbackRequest = CallbackRequest.builder() + .caseDetails(ccdRequest.getCaseDetails()) + .build(); + when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); + + mvc.perform(post(AMEND_RESPONDENT_DETAILS_SUBMITTED_URL) + .content(jsonMapper.toJson(callbackRequest)) + .header(AUTHORIZATION, AUTH_TOKEN) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + + verify(nocRespondentRepresentativeService, never()) + .realignRespondentRepresentativeAccess(any(CallbackRequest.class)); + } + @Test @SneakyThrows void updateHearing() { diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/ClaimantRepresentativeControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/ClaimantRepresentativeControllerTest.java index 53c8a7c725..99a967cade 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/ClaimantRepresentativeControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/ClaimantRepresentativeControllerTest.java @@ -9,6 +9,11 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.web.servlet.MockMvc; import uk.gov.hmcts.et.common.model.ccd.CCDRequest; +import uk.gov.hmcts.et.common.model.ccd.CaseData; +import uk.gov.hmcts.et.common.model.ccd.types.AllPartyFlags; +import uk.gov.hmcts.et.common.model.ccd.types.CaseFlagsType; +import uk.gov.hmcts.et.common.model.ccd.types.RepresentedTypeC; +import uk.gov.hmcts.ethos.replacement.docmosis.service.FeatureToggleService; import uk.gov.hmcts.ethos.replacement.docmosis.service.VerifyTokenService; import uk.gov.hmcts.ethos.replacement.docmosis.utils.JsonMapper; import uk.gov.hmcts.ethos.utils.CCDRequestBuilder; @@ -16,10 +21,12 @@ import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.when; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static uk.gov.hmcts.ecm.common.model.helper.Constants.ENGLANDWALES_CASE_TYPE_ID; import static uk.gov.hmcts.ecm.common.model.helper.Constants.NO; import static uk.gov.hmcts.ecm.common.model.helper.Constants.YES; @@ -29,6 +36,8 @@ class ClaimantRepresentativeControllerTest { @MockitoBean private VerifyTokenService verifyTokenService; + @MockitoBean + private FeatureToggleService featureToggleService; @Autowired private MockMvc mockMvc; @@ -54,10 +63,21 @@ void testRemoveOwnRepresentative_ClaimantRepresentedQuestionEmpty() throws Excep @Test void testRemoveOwnRepresentative_ClaimantRepresentedQuestionNo() throws Exception { - CCDRequest ccdRequest = CCDRequestBuilder.builder().withCaseData( - CaseDataBuilder.builder().withClaimantRepresentedQuestion(NO).build()).build(); + CaseData caseData = CaseDataBuilder.builder().withClaimantRepresentedQuestion(NO).build(); + caseData.setRepresentativeClaimantType(RepresentedTypeC.builder().build()); + caseData.setAllPartyFlags(AllPartyFlags.builder() + .claimantFlags(CaseFlagsType.builder().build()) + .claimantExternalFlags(CaseFlagsType.builder().build()) + .claimantRepresentativeFlags(CaseFlagsType.builder().build()) + .claimantRepresentativeExternalFlags(CaseFlagsType.builder().build()) + .build()); + CCDRequest ccdRequest = CCDRequestBuilder.builder() + .withCaseData(caseData) + .withCaseTypeId(ENGLANDWALES_CASE_TYPE_ID) + .build(); String token = "some-token"; when(verifyTokenService.verifyTokenSignature(token)).thenReturn(true); + when(featureToggleService.isCaseFlagsV2Enabled(anyString())).thenReturn(true); mockMvc.perform(post("/claimantRepresentative/removeOwnRepresentative") .contentType(MediaType.APPLICATION_JSON) @@ -66,10 +86,41 @@ void testRemoveOwnRepresentative_ClaimantRepresentedQuestionNo() throws Exceptio .andExpect(status().isOk()) .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) + .andExpect(jsonPath("$.data.representativeClaimantType", nullValue())) + .andExpect(jsonPath("$.data.claimantRepresentativeFlags", nullValue())) + .andExpect(jsonPath("$.data.claimantRepresentativeExternalFlags", nullValue())) + .andExpect(jsonPath("$.data.claimantFlags", notNullValue())) + .andExpect(jsonPath("$.data.claimantExternalFlags", notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); } + @Test + void testRemoveOwnRepresentative_PreservesCaseFlagsWhenV2Disabled() throws Exception { + CaseData caseData = CaseDataBuilder.builder().withClaimantRepresentedQuestion(NO).build(); + caseData.setRepresentativeClaimantType(RepresentedTypeC.builder().build()); + caseData.setAllPartyFlags(AllPartyFlags.builder() + .claimantRepresentativeFlags(CaseFlagsType.builder().build()) + .claimantRepresentativeExternalFlags(CaseFlagsType.builder().build()) + .build()); + CCDRequest ccdRequest = CCDRequestBuilder.builder() + .withCaseData(caseData) + .withCaseTypeId(ENGLANDWALES_CASE_TYPE_ID) + .build(); + String token = "some-token"; + when(verifyTokenService.verifyTokenSignature(token)).thenReturn(true); + when(featureToggleService.isCaseFlagsV2Enabled(ENGLANDWALES_CASE_TYPE_ID)).thenReturn(false); + + mockMvc.perform(post("/claimantRepresentative/removeOwnRepresentative") + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", token) + .content(jsonMapper.toJson(ccdRequest))) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.data.representativeClaimantType", nullValue())) + .andExpect(jsonPath("$.data.claimantRepresentativeFlags", notNullValue())) + .andExpect(jsonPath("$.data.claimantRepresentativeExternalFlags", notNullValue())); + } + @Test void testRemoveOwnRepresentative_ClaimantRepresentedQuestionYes() throws Exception { CCDRequest ccdRequest = CCDRequestBuilder.builder().withCaseData( diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/RespondentRepresentativeControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/RespondentRepresentativeControllerTest.java index cfdd7e4e26..7e168a7b1d 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/RespondentRepresentativeControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/RespondentRepresentativeControllerTest.java @@ -118,6 +118,8 @@ void testRemoveOwnRepresentative_withoutRepCollection() throws Exception { .andExpect(jsonPath(JsonMapper.DATA, notNullValue())) .andExpect(jsonPath(JsonMapper.ERRORS, nullValue())) .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); + + verify(caseFlagsService, never()).removeRespondentRepresentativeFlags(any(), any()); } @Test @@ -195,6 +197,8 @@ void testRemoveOwnRepresentativeSetsUpCaseFlagsWhenRequired() throws Exception { .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); verify(caseFlagsService, times(1)).setupCaseFlags(any(CaseData.class)); + verify(caseFlagsService).removeRespondentRepresentativeFlags( + any(CaseData.class), eq(List.of(representedTypeRItem))); } @Test diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/helpers/NocRespondentHelperTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/helpers/NocRespondentHelperTest.java index 45aca5e891..7905138d15 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/helpers/NocRespondentHelperTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/helpers/NocRespondentHelperTest.java @@ -247,7 +247,7 @@ void shouldReturnRespondent() { void amendRespondentNameRepresentativeNamesReordersRepresentativesAndRolesWithRespondents() { RespondentSumTypeItem amendedRespondent = caseData.getRespondentCollection().get(2); amendedRespondent.getValue().setRespondentName(AMENDED_RESP_NAME); - nocRespondentHelper.amendRespondentNameRepresentativeNames(caseData); + nocRespondentHelper.amendRespondentNameRepresentativeNames(caseData, true); RepresentedTypeR rep = caseData.getRepCollection().getFirst().getValue(); assertThat(caseData.getRepCollection().getFirst().getId()).isEqualTo(RESPONDENT_REP_ID_THREE); @@ -271,12 +271,29 @@ void amendRespondentNameRepresentativeNamesReordersRepresentativesAndRolesWithRe assertThat(rep.getRespRepName()).isEqualTo(AMENDED_RESP_NAME); } + @Test + void amendRespondentNameRepresentativeNamesRetainsLegacyOrderWhenV2IsDisabled() { + List representativeIds = caseData.getRepCollection().stream() + .map(RepresentedTypeRItem::getId) + .toList(); + List representativeRoles = caseData.getRepCollection().stream() + .map(item -> item.getValue().getRole()) + .toList(); + + nocRespondentHelper.amendRespondentNameRepresentativeNames(caseData, false); + + Assertions.assertThat(caseData.getRepCollection()).extracting(RepresentedTypeRItem::getId) + .containsExactlyElementsOf(representativeIds); + Assertions.assertThat(caseData.getRepCollection()).extracting(item -> item.getValue().getRole()) + .containsExactlyElementsOf(representativeRoles); + } + @Test void amendRespondentNameRepresentativeNamesIgnoresRepresentativesWithoutRespondentId() { caseData.getRespondentCollection().getFirst().setId(null); caseData.getRepCollection().getFirst().getValue().setRespondentId(null); - assertDoesNotThrow(() -> nocRespondentHelper.amendRespondentNameRepresentativeNames(caseData)); + assertDoesNotThrow(() -> nocRespondentHelper.amendRespondentNameRepresentativeNames(caseData, true)); } @Test diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java index 1e52115234..5fb5c35e63 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java @@ -539,6 +539,57 @@ void setupCaseFlags_shouldCreateSeparateRespondentRepresentativeFlagsForSameName ); } + @Test + void removeRespondentRepresentativeFlags_shouldDeleteOnlyRemovedRepresentativeWithSameName() { + caseData.setRespondentCollection(respondentCollection(2)); + List respondents = caseData.getRespondentCollection(); + RepresentedTypeRItem firstRepresentative = representativeItemForRespondent( + "1", "Shared Name", "first@example.com", respondents.get(0), "[SOLICITORA]"); + RepresentedTypeRItem secondRepresentative = representativeItemForRespondent( + "2", "Shared Name", "second@example.com", respondents.get(1), "[SOLICITORB]"); + caseData.setRepCollection(new ArrayList<>(List.of(firstRepresentative, secondRepresentative))); + caseFlagsService.setupCaseFlags(caseData); + AllPartyFlags allPartyFlags = allPartyFlags(caseData); + allPartyFlags.getRepresentativeFlags().setDetails(ListTypeItem.from(activeFlag("First flag"))); + allPartyFlags.getRepresentative1Flags().setDetails(ListTypeItem.from(activeFlag("Second flag"))); + + caseFlagsService.removeRespondentRepresentativeFlags(caseData, List.of(firstRepresentative)); + caseData.getRepCollection().remove(firstRepresentative); + caseFlagsService.setupCaseFlags(caseData); + + assertAll( + () -> assertNull(allPartyFlags.getRepresentativeFlags()), + () -> assertEquals("second@example.com", + caseData.getRepCollection().getFirst().getValue().getRepresentativeEmailAddress()), + () -> assertEquals("Second flag", + allPartyFlags.getRepresentative1Flags().getDetails().getFirst().getValue().getName()) + ); + } + + @Test + void removeRespondentRepresentativeFlags_shouldRetainFlagsWhenRepresentativeStillRepresentsAnotherRespondent() { + caseData.setRespondentCollection(respondentCollection(2)); + List respondents = caseData.getRespondentCollection(); + RepresentedTypeRItem firstRepresentation = representativeItemForRespondent( + "1", "Shared Representative", "shared@example.com", respondents.get(0), "[SOLICITORA]"); + RepresentedTypeRItem secondRepresentation = representativeItemForRespondent( + "2", "Shared Representative", "shared@example.com", respondents.get(1), "[SOLICITORB]"); + caseData.setRepCollection(new ArrayList<>(List.of(firstRepresentation, secondRepresentation))); + caseFlagsService.setupCaseFlags(caseData); + AllPartyFlags allPartyFlags = allPartyFlags(caseData); + allPartyFlags.getRepresentativeFlags().setDetails(ListTypeItem.from(activeFlag("Shared flag"))); + + caseFlagsService.removeRespondentRepresentativeFlags(caseData, List.of(firstRepresentation)); + caseData.getRepCollection().remove(firstRepresentation); + caseFlagsService.setupCaseFlags(caseData); + + assertAll( + () -> assertNull(allPartyFlags.getRepresentativeFlags()), + () -> assertEquals("Shared flag", + allPartyFlags.getRepresentative1Flags().getDetails().getFirst().getValue().getName()) + ); + } + @Test void caseFlagsSetupRequired_shouldBeTrueWhenCompactedRepresentativeNeedsMovingToRoleAlignedSlot() { String representative1Name = "Representative 1"; diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocClaimantRepresentativeServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocClaimantRepresentativeServiceTest.java index e3b9b90d44..94635d3598 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocClaimantRepresentativeServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocClaimantRepresentativeServiceTest.java @@ -183,7 +183,7 @@ void updateRepresentativesAccess() throws IOException { .build()); when(NocUtils.buildApprovedChangeOrganisationRequest(any(), any(), any())) .thenReturn(createChangeOrganisationRequest()); - nocClaimantRepresentativeService.updateClaimantRepAccess(getCallBackCallbackRequest()); + nocClaimantRepresentativeService.updateClaimantRepAccess(getCallBackCallbackRequest(), true); verify(nocNotificationService, times(1)) .sendNotificationOfChangeEmails(any(), any(), any(), eq(true)); } @@ -206,7 +206,7 @@ void updateClaimantRepAccess_shouldGrantAndRemoveAccessAndSendNotification() thr doReturn(ResponseEntity.ok(organisationsResponse)).when(organisationClient) .retrieveOrganisationDetailsByUserId(DUMMY_ADMIN_USER_TOKEN, S2S_TOKEN, DUMMY_ORGANISATION_USER_ID); // Act - nocClaimantRepresentativeService.updateClaimantRepAccess(callbackRequest); + nocClaimantRepresentativeService.updateClaimantRepAccess(callbackRequest, true); // Assert verify(nocNotificationService, times(NumberUtils.INTEGER_ONE)).sendNotificationOfChangeEmails( any(), any(), any(), eq(true)); @@ -230,7 +230,7 @@ void shouldReturnChangeRequestWhenOrganisationChanged() { ClaimantSolicitorRole.CLAIMANTSOLICITOR.getCaseRoleLabel())).thenReturn(expected); ChangeOrganisationRequest result = - nocClaimantRepresentativeService.identifyRepresentationChanges(after, before); + nocClaimantRepresentativeService.identifyRepresentationChanges(after, before, true); assertThat(result).isSameAs(expected); } @@ -250,7 +250,7 @@ void shouldReturnChangeRequestWhenOrganisationUnchanged() { ClaimantSolicitorRole.CLAIMANTSOLICITOR.getCaseRoleLabel())).thenReturn(expected); ChangeOrganisationRequest result = - nocClaimantRepresentativeService.identifyRepresentationChanges(after, before); + nocClaimantRepresentativeService.identifyRepresentationChanges(after, before, true); assertThat(result).isSameAs(expected); } @@ -276,7 +276,33 @@ void shouldReturnChangeRequestWithOrganisationToRemoveWhenNameChanges() { ClaimantSolicitorRole.CLAIMANTSOLICITOR.getCaseRoleLabel())).thenReturn(expected); ChangeOrganisationRequest result = - nocClaimantRepresentativeService.identifyRepresentationChanges(after, before); + nocClaimantRepresentativeService.identifyRepresentationChanges(after, before, true); + + assertThat(result).isSameAs(expected); + } + + @Test + void shouldUseLegacyChangeRequestWhenNameChangesAndV2IsDisabled() { + Organisation org = Organisation.builder().organisationID("SAME").build(); + CaseData after = new CaseData(); + CaseData before = new CaseData(); + after.setRepresentativeClaimantType(RepresentedTypeC.builder() + .nameOfRepresentative("New Representative") + .representativeEmailAddress("claimant.rep@example.com") + .myHmctsOrganisation(org) + .build()); + before.setRepresentativeClaimantType(RepresentedTypeC.builder() + .nameOfRepresentative("Old Representative") + .representativeEmailAddress("claimant.rep@example.com") + .myHmctsOrganisation(org) + .build()); + + ChangeOrganisationRequest expected = ChangeOrganisationRequest.builder().build(); + when(NocUtils.buildApprovedChangeOrganisationRequest(org, null, + ClaimantSolicitorRole.CLAIMANTSOLICITOR.getCaseRoleLabel())).thenReturn(expected); + + ChangeOrganisationRequest result = + nocClaimantRepresentativeService.identifyRepresentationChanges(after, before, false); assertThat(result).isSameAs(expected); } @@ -302,7 +328,7 @@ void shouldReturnChangeRequestWithOrganisationToRemoveWhenEmailChanges() { ClaimantSolicitorRole.CLAIMANTSOLICITOR.getCaseRoleLabel())).thenReturn(expected); ChangeOrganisationRequest result = - nocClaimantRepresentativeService.identifyRepresentationChanges(after, before); + nocClaimantRepresentativeService.identifyRepresentationChanges(after, before, true); assertThat(result).isSameAs(expected); } @@ -314,7 +340,7 @@ void shouldHandleNullRepresentativeClaimantType() { ChangeOrganisationRequest expected = ChangeOrganisationRequest.builder().build(); ChangeOrganisationRequest result = - nocClaimantRepresentativeService.identifyRepresentationChanges(after, before); + nocClaimantRepresentativeService.identifyRepresentationChanges(after, before, true); assertThat(result).isEqualTo(expected); } diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocRespondentRepresentativeServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocRespondentRepresentativeServiceTest.java index 8596a0c90e..7a83a37dbb 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocRespondentRepresentativeServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocRespondentRepresentativeServiceTest.java @@ -31,6 +31,8 @@ import uk.gov.hmcts.et.common.model.ccd.SubmitEvent; import uk.gov.hmcts.et.common.model.ccd.items.RepresentedTypeRItem; import uk.gov.hmcts.et.common.model.ccd.items.RespondentSumTypeItem; +import uk.gov.hmcts.et.common.model.ccd.types.AllPartyFlags; +import uk.gov.hmcts.et.common.model.ccd.types.CaseFlagsType; import uk.gov.hmcts.et.common.model.ccd.types.ChangeOrganisationRequest; import uk.gov.hmcts.et.common.model.ccd.types.NoticeOfChangeAnswers; import uk.gov.hmcts.et.common.model.ccd.types.Organisation; @@ -49,6 +51,7 @@ import uk.gov.hmcts.ethos.replacement.docmosis.helpers.NoticeOfChangeFieldPopulator; import uk.gov.hmcts.ethos.replacement.docmosis.rdprofessional.OrganisationClient; import uk.gov.hmcts.ethos.replacement.docmosis.service.AdminUserService; +import uk.gov.hmcts.ethos.replacement.docmosis.service.FeatureToggleService; import uk.gov.hmcts.ethos.replacement.docmosis.service.OrganisationService; import uk.gov.hmcts.ethos.replacement.docmosis.service.UserIdamService; import uk.gov.hmcts.ethos.replacement.docmosis.test.utils.LoggerTestUtils; @@ -185,6 +188,8 @@ class NocRespondentRepresentativeServiceTest { @MockitoBean private AdminUserService adminUserService; @MockitoBean + private FeatureToggleService featureToggleService; + @MockitoBean private NocCcdService nocCcdService; @MockitoBean private NocNotificationService nocNotificationService; @@ -219,7 +224,8 @@ void setUp() { nocRespondentRepresentativeService = new NocRespondentRepresentativeService(noticeOfChangeFieldPopulator, converter, nocCcdService, adminUserService, nocRespondentHelper, nocNotificationService, ccdClient, organisationClient, - authTokenGenerator, nocService, userIdamService, organisationService, myHmctsService); + authTokenGenerator, nocService, userIdamService, organisationService, myHmctsService, + featureToggleService); // Respondent caseData.setRespondentCollection(new ArrayList<>()); @@ -1498,6 +1504,13 @@ void theRemoveConflictingClaimantRepresentation() { // representative case assignment and return case data. tmpCaseData.getRepresentativeClaimantType().setRepresentativeEmailAddress(REPRESENTATIVE_EMAIL_1); tmpCaseData.getRepCollection().getFirst().getValue().setRepresentativeEmailAddress(REPRESENTATIVE_EMAIL_1); + tmpCaseData.setAllPartyFlags(AllPartyFlags.builder() + .claimantFlags(CaseFlagsType.builder().build()) + .claimantExternalFlags(CaseFlagsType.builder().build()) + .claimantRepresentativeFlags(CaseFlagsType.builder().build()) + .claimantRepresentativeExternalFlags(CaseFlagsType.builder().build()) + .build()); + when(featureToggleService.isCaseFlagsV2Enabled(CASE_TYPE_ID_ENGLAND_WALES)).thenReturn(true); when(adminUserService.getAdminUserToken()).thenReturn(ADMIN_USER_TOKEN); doNothing().when(nocCcdService).revokeClaimantRepresentation(ADMIN_USER_TOKEN, caseDetails); assertThat(nocRespondentRepresentativeService.removeConflictingClaimantRepresentation(caseDetails)) @@ -1507,6 +1520,10 @@ void theRemoveConflictingClaimantRepresentation() { assertThat(tmpCaseData.getClaimantRepresentedQuestion()).isEqualTo(NO); assertThat(tmpCaseData.getClaimantRepresentativeRemoved()).isEqualTo(YES); assertThat(tmpCaseData.getRepresentativeClaimantType()).isNull(); + assertThat(tmpCaseData.getAllPartyFlags().getClaimantRepresentativeFlags()).isNull(); + assertThat(tmpCaseData.getAllPartyFlags().getClaimantRepresentativeExternalFlags()).isNull(); + assertThat(tmpCaseData.getAllPartyFlags().getClaimantFlags()).isNotNull(); + assertThat(tmpCaseData.getAllPartyFlags().getClaimantExternalFlags()).isNotNull(); OrganisationPolicy tmpClaimantOrganisationPolicy = OrganisationPolicy.builder().orgPolicyCaseAssignedRole( ROLE_CLAIMANT_SOLICITOR).build(); assertThat(tmpCaseData.getClaimantRepresentativeOrganisationPolicy()).isEqualTo(tmpClaimantOrganisationPolicy); diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/utils/noc/ClaimantRepresentativeUtilsTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/utils/noc/ClaimantRepresentativeUtilsTest.java index 0e5f8e8412..297c1366c5 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/utils/noc/ClaimantRepresentativeUtilsTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/utils/noc/ClaimantRepresentativeUtilsTest.java @@ -162,14 +162,24 @@ void theMarkClaimantAsUnrepresented() { ClaimantSolicitorRole.CLAIMANTSOLICITOR.getCaseRoleLabel()).build()); caseData.setRepresentativeClaimantType(RepresentedTypeC.builder().representativeId(CLAIMANT_REPRESENTATIVE_ID) .myHmctsOrganisation(Organisation.builder().organisationID(ORGANISATION_ID_1).build()).build()); + caseData.setAllPartyFlags(AllPartyFlags.builder() + .claimantFlags(CaseFlagsType.builder().build()) + .claimantExternalFlags(CaseFlagsType.builder().build()) + .claimantRepresentativeFlags(CaseFlagsType.builder().build()) + .claimantRepresentativeExternalFlags(CaseFlagsType.builder().build()) + .build()); caseData.setClaimantRepresentativeRemoved(NO); caseData.setClaimantRepresentedQuestion(YES); - ClaimantRepresentativeUtils.markClaimantAsUnrepresented(caseData); + ClaimantRepresentativeUtils.markClaimantAsUnrepresented(caseData, true); assertThat(caseData.getRepresentativeClaimantType()).isNull(); assertThat(caseData.getClaimantRepresentativeRemoved()).isEqualTo(YES); assertThat(caseData.getClaimantRepresentedQuestion()).isEqualTo(NO); assertThat(caseData.getClaimantRepresentativeOrganisationPolicy()).isEqualTo(OrganisationPolicy.builder() .orgPolicyCaseAssignedRole(ClaimantSolicitorRole.CLAIMANTSOLICITOR.getCaseRoleLabel()).build()); + assertThat(caseData.getAllPartyFlags().getClaimantRepresentativeFlags()).isNull(); + assertThat(caseData.getAllPartyFlags().getClaimantRepresentativeExternalFlags()).isNull(); + assertThat(caseData.getAllPartyFlags().getClaimantFlags()).isNotNull(); + assertThat(caseData.getAllPartyFlags().getClaimantExternalFlags()).isNotNull(); } @@ -221,7 +231,7 @@ void theHasRepresentativeEmail() { void theAddAmendClaimantRepresentative() { // when claimant representative empty should not assign any claimant representative CaseData caseData = new CaseData(); - ClaimantRepresentativeUtils.addAmendClaimantRepresentative(caseData); + ClaimantRepresentativeUtils.addAmendClaimantRepresentative(caseData, true); assertThat(caseData.getRepresentativeClaimantType()).isNull(); assertThat(caseData.getClaimantRepresentativeRemoved()).isNull(); assertThat(caseData.getAllPartyFlags()).isNull(); @@ -242,7 +252,7 @@ void theAddAmendClaimantRepresentative() { .claimantRepresentativeFlags(claimantRepresentativeFlags) .claimantRepresentativeExternalFlags(claimantRepresentativeExternalFlags) .build()); - ClaimantRepresentativeUtils.addAmendClaimantRepresentative(caseData); + ClaimantRepresentativeUtils.addAmendClaimantRepresentative(caseData, true); assertThat(caseData.getRepresentativeClaimantType()).isNull(); assertThat(caseData.getClaimantRepresentativeRemoved()).isEqualTo(YES); assertThat(caseData.getAllPartyFlags().getClaimantFlags()).isSameAs(claimantFlags); @@ -258,7 +268,7 @@ void theAddAmendClaimantRepresentative() { .claimantRepresentativeFlags(claimantRepresentativeFlags) .claimantRepresentativeExternalFlags(claimantRepresentativeExternalFlags) .build()); - ClaimantRepresentativeUtils.addAmendClaimantRepresentative(caseData); + ClaimantRepresentativeUtils.addAmendClaimantRepresentative(caseData, true); assertThat(caseData.getClaimantRepresentativeRemoved()).isEqualTo(NO); assertThat(caseData.getRepresentativeClaimantType().getRepresentativeId()).isNotNull(); assertThat(caseData.getRepresentativeClaimantType().getOrganisationId()).isNotNull(); @@ -273,7 +283,7 @@ void theAddAmendClaimantRepresentative() { // those ids claimantRepresentative.setRepresentativeId(CLAIMANT_REPRESENTATIVE_ID); claimantRepresentative.setOrganisationId(ORGANISATION_ID_1); - ClaimantRepresentativeUtils.addAmendClaimantRepresentative(caseData); + ClaimantRepresentativeUtils.addAmendClaimantRepresentative(caseData, true); assertThat(caseData.getClaimantRepresentativeRemoved()).isEqualTo(NO); assertThat(caseData.getRepresentativeClaimantType().getRepresentativeId()).isNotNull() .isEqualTo(CLAIMANT_REPRESENTATIVE_ID); @@ -285,7 +295,7 @@ void theAddAmendClaimantRepresentative() { // when claimant representative exists and has my hmcts organisation with id should set organisation id to // my hmcts organisation id claimantRepresentative.setMyHmctsOrganisation(Organisation.builder().organisationID(ORGANISATION_ID_2).build()); - ClaimantRepresentativeUtils.addAmendClaimantRepresentative(caseData); + ClaimantRepresentativeUtils.addAmendClaimantRepresentative(caseData, true); assertThat(caseData.getClaimantRepresentativeRemoved()).isEqualTo(NO); assertThat(caseData.getRepresentativeClaimantType().getRepresentativeId()).isNotNull() .isEqualTo(CLAIMANT_REPRESENTATIVE_ID); @@ -296,6 +306,24 @@ void theAddAmendClaimantRepresentative() { .isEqualTo(ORGANISATION_ID_2); } + @Test + void addAmendClaimantRepresentativeRetainsV2FlagsWhenV2IsDisabled() { + CaseFlagsType internalFlags = CaseFlagsType.builder().build(); + CaseFlagsType externalFlags = CaseFlagsType.builder().build(); + CaseData caseData = new CaseData(); + caseData.setClaimantRepresentedQuestion(NO); + caseData.setRepresentativeClaimantType(RepresentedTypeC.builder().build()); + caseData.setAllPartyFlags(AllPartyFlags.builder() + .claimantRepresentativeFlags(internalFlags) + .claimantRepresentativeExternalFlags(externalFlags) + .build()); + + ClaimantRepresentativeUtils.addAmendClaimantRepresentative(caseData, false); + + assertThat(caseData.getAllPartyFlags().getClaimantRepresentativeFlags()).isSameAs(internalFlags); + assertThat(caseData.getAllPartyFlags().getClaimantRepresentativeExternalFlags()).isSameAs(externalFlags); + } + @Test void theRemoveClaimantRepresentativeAssignment() { List caseUserAssignments = new ArrayList<>(); diff --git a/src/test/java/uk/gov/hmcts/reform/et/syaapi/service/ManageCaseRoleServiceTest.java b/src/test/java/uk/gov/hmcts/reform/et/syaapi/service/ManageCaseRoleServiceTest.java index 456f357c45..b2b9ec7bf1 100644 --- a/src/test/java/uk/gov/hmcts/reform/et/syaapi/service/ManageCaseRoleServiceTest.java +++ b/src/test/java/uk/gov/hmcts/reform/et/syaapi/service/ManageCaseRoleServiceTest.java @@ -65,7 +65,12 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.lenient; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static uk.gov.hmcts.ecm.common.model.helper.Constants.EMPLOYMENT; import static uk.gov.hmcts.reform.et.syaapi.constants.ManageCaseRoleConstants.CASE_USER_ROLE_CCD_API_POST_METHOD_NAME; @@ -77,6 +82,7 @@ import static uk.gov.hmcts.reform.et.syaapi.enums.CaseEvent.UPDATE_CASE_SUBMITTED; import static uk.gov.hmcts.reform.et.syaapi.enums.CaseEvent.UPDATE_ET3_FORM; import static uk.gov.hmcts.reform.et.syaapi.service.utils.TestConstants.DUMMY_AUTHORISATION_TOKEN; +import static uk.gov.hmcts.reform.et.syaapi.service.utils.TestConstants.NO; import static uk.gov.hmcts.reform.et.syaapi.service.utils.TestConstants.TEST_APPLICATION_NAME; import static uk.gov.hmcts.reform.et.syaapi.service.utils.TestConstants.TEST_CASE_ID_LONG; import static uk.gov.hmcts.reform.et.syaapi.service.utils.TestConstants.TEST_CASE_ID_STRING; @@ -1081,6 +1087,8 @@ void theRemoveRespondentRepresentativeFromCaseData() { CaseDetails caseDetails = new CaseTestData().getCaseDetailsWithCaseData(); CaseData caseData = EmployeeObjectMapper.convertCaseDataMapToCaseDataObject(caseDetails.getData()); caseData.getRespondentCollection().getFirst().setId(USER_ID); + caseData.getRespondentCollection().getFirst().getValue().setRepresented(YES); + caseData.getRespondentCollection().getFirst().getValue().setRepresentativeId("representative-id"); caseData.setRepCollection(List.of(RepresentedTypeRItem.builder().value( RepresentedTypeR.builder().respondentId(USER_ID).build()).build())); caseDetails.setData(EmployeeObjectMapper.mapCaseDataToLinkedHashMap(caseData)); @@ -1113,6 +1121,31 @@ void theRemoveRespondentRepresentativeFromCaseData() { CaseDetails updatedCaseDetails = manageCaseRoleService.removeRespondentRepresentativeFromCaseData( DUMMY_AUTHORISATION_TOKEN, caseDetails, "0", "[SOLICITORA]"); assertThat(updatedCaseDetails).isNotNull(); + CaseData updatedCaseData = EmployeeObjectMapper.convertCaseDataMapToCaseDataObject(caseDetails.getData()); + assertThat(updatedCaseData.getRespondentCollection().getFirst().getValue().getRepresentativeRemoved()) + .isEqualTo(YES); + assertThat(updatedCaseData.getRespondentCollection().getFirst().getValue().getRepresented()).isEqualTo(NO); + assertThat(updatedCaseData.getRespondentCollection().getFirst().getValue().getRepresentativeId()).isNull(); + } + + @Test + void revokeRespondentSolicitorRoleDoesNotRemoveRepresentativeWhenAccessRevocationFails() throws IOException { + CaseDetails caseDetails = new CaseTestData().getCaseDetailsWithCaseData(); + caseDetails.setId(TEST_CASE_ID_LONG); + CaseData caseData = EmployeeObjectMapper.convertCaseDataMapToCaseDataObject(caseDetails.getData()); + caseData.setNoticeOfChangeAnswers0( + NoticeOfChangeAnswers.builder().respondentName(TEST_RESPONDENT_ORGANISATION_NAME).build()); + caseDetails.setData(EmployeeObjectMapper.mapCaseDataToLinkedHashMap(caseData)); + ManageCaseRoleService service = spy(manageCaseRoleService); + doReturn(caseDetails).when(service).getUserCaseByCaseUserRole( + DUMMY_AUTHORISATION_TOKEN, TEST_CASE_ID_STRING, CASE_USER_ROLE_DEFENDANT); + doThrow(new IOException("CCD unavailable")).when(service) + .revokeCaseUserRole(eq(caseDetails), anyString()); + + assertThrows(ManageCaseRoleException.class, () -> service.revokeRespondentSolicitorRole( + DUMMY_AUTHORISATION_TOKEN, TEST_CASE_ID_STRING, NumberUtils.INTEGER_ZERO.toString())); + + verify(service, never()).removeRespondentRepresentativeFromCaseData(anyString(), any(), anyString(), any()); } @Test From 563080863051ced3f6679ab8219274081d4e430a Mon Sep 17 00:00:00 2001 From: rajaram Date: Mon, 31 Aug 2026 10:53:40 +0100 Subject: [PATCH 038/100] Fixed build issue --- .../ethos/replacement/docmosis/service/CaseFlagsService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java index cfaa98a679..9c59de7a0d 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java @@ -518,7 +518,7 @@ private static boolean sameRepresentativeCollectionItem( if (StringUtils.isNotBlank(first.getId()) && StringUtils.isNotBlank(second.getId())) { return Objects.equals(first.getId(), second.getId()); } - return first == second || Objects.equals(first, second); + return Objects.equals(first, second); } private static int remainingRepresentativeFlagSlot( From 3f93141bea6914d451c879ca0fda7a295083d529 Mon Sep 17 00:00:00 2001 From: rajaram Date: Mon, 31 Aug 2026 10:57:31 +0100 Subject: [PATCH 039/100] Fixed build issue and warnings --- .../docmosis/service/CaseFlagsService.java | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java index 9c59de7a0d..2db2368a0f 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java @@ -227,16 +227,6 @@ public void setupLegacyCaseFlags(CaseData caseData) { "respondent")); } - /** - * Migrates existing claimant and respondent case flags from the v1.0 fields into - * the v2.1 internal and external sections. - * - * @param caseData Data about the current case - */ - public void migrateExistingClaimantAndRespondentCaseFlags(CaseData caseData) { - migrateExistingClaimantAndRespondentCaseFlags(caseData, Map.of()); - } - /** * Migrates existing claimant and respondent case flags from the v1.0 fields into * the v2.1 internal and external sections. @@ -269,11 +259,11 @@ public void rollbackCaseFlags(CaseData caseData) { } PartyFlag claimantInternal = partyFlag(PartyType.CLAIMANT, INTERNAL, NOT_INDEXED); - consolidateFlagDetails(caseData, claimantInternal, partyFlags(PartyType.CLAIMANT, null)); + consolidateFlagDetails(caseData, claimantInternal, partyFlags(PartyType.CLAIMANT)); partyFlag(PartyType.CLAIMANT, EXTERNAL, NOT_INDEXED).clear(caseData); PartyFlag firstRespondentInternal = partyFlag(PartyType.RESPONDENT, INTERNAL, 0); - consolidateFlagDetails(caseData, firstRespondentInternal, partyFlags(PartyType.RESPONDENT, null)); + consolidateFlagDetails(caseData, firstRespondentInternal, partyFlags(PartyType.RESPONDENT)); PARTY_FLAGS.stream() .filter(flag -> PartyType.RESPONDENT.equals(flag.partyType())) @@ -322,10 +312,9 @@ private static String rollbackDestinationPartyName( .orElse(null)); } - private static List partyFlags(PartyType partyType, @Nullable String visibility) { + private static List partyFlags(PartyType partyType) { return PARTY_FLAGS.stream() .filter(flag -> partyType.equals(flag.partyType())) - .filter(flag -> visibility == null || visibility.equals(flag.visibility())) .toList(); } @@ -832,7 +821,6 @@ private static PartyFlag matchingExternalPartyFlag(PartyFlag internalFlag) { .orElseThrow(); } - @SafeVarargs private static List> existingDetails(CaseFlagsType...flags) { List> details = new ArrayList<>(); for (CaseFlagsType flagsType : flags) { From fc75b2cc804fffec910d44515f1563dc1f515c98 Mon Sep 17 00:00:00 2001 From: rajaram Date: Mon, 31 Aug 2026 12:07:40 +0100 Subject: [PATCH 040/100] Recalculate dependent interpreter/security indicators during migration --- .../docmosis/service/CaseFlagsService.java | 1 + .../service/CaseFlagsServiceTest.java | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java index 2db2368a0f..4ea9c5a247 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsService.java @@ -246,6 +246,7 @@ public void migrateExistingClaimantAndRespondentCaseFlags( List existingFlagDetails = currentClaimantAndRespondentFlagDetails(caseData); setupCaseFlags(caseData); existingFlagDetails.forEach(details -> migrateExistingFlagDetails(caseData, details, referenceDataVisibility)); + processNewlySetCaseFlags(caseData); } /** diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java index 5fb5c35e63..23d365d3ce 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java @@ -278,6 +278,26 @@ void migrateExistingClaimantAndRespondentCaseFlags_shouldMoveFlagsToInternalAndE respondent2External); } + @Test + void migrateExistingClaimantAndRespondentCaseFlags_shouldRecalculateDependentIndicators() { + FlagDetailType interpreterFlag = flagDetail(LANGUAGE_INTERPRETER, ACTIVE, NO); + FlagDetailType securityFlag = flagDetail(DISRUPTIVE_CUSTOMER, ACTIVE, YES); + AllPartyFlags allPartyFlags = getOrCreateAllPartyFlags(caseData); + allPartyFlags.setClaimantFlags(legacyCaseFlags(interpreterFlag)); + allPartyFlags.setRespondentFlags(legacyCaseFlags(securityFlag)); + + caseFlagsService.migrateExistingClaimantAndRespondentCaseFlags( + caseData, + Map.of( + LANGUAGE_INTERPRETER, INTERNAL, + DISRUPTIVE_CUSTOMER, EXTERNAL + ) + ); + + assertEquals(YES, caseData.getCaseInterpreterRequiredFlag()); + assertEquals(YES, caseData.getCaseAdditionalSecurityFlag()); + } + @Test void migrateExistingClaimantAndRespondentCaseFlags_shouldKeepFlagsMissingFromReferenceDataInternal() { FlagDetailType claimantFlagMissingFromReferenceData = flagDetail("Missing claimant flag", ACTIVE, YES); From c192268850d05778996974d9a91f607de93a660b Mon Sep 17 00:00:00 2001 From: sonny-hmcts Date: Tue, 1 Sep 2026 14:06:58 +0100 Subject: [PATCH 041/100] Update AuthorisationCaseField-CaseFlagsCaseLinking.json --- .../AuthorisationCaseField-CaseFlagsCaseLinking.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json index 848ee5027a..c9edd821a5 100644 --- a/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json @@ -986,7 +986,7 @@ { "CaseTypeId": "ET_Scotland", "CaseFieldID": "claimantExternalFlags", - "UserRole": "citizen", - "CRUD": "R" + "UserRole": "[CREATOR]", + "CRUD": "CRU" } ] From 41969bec33f762148341985f5c29e4c0413e03b5 Mon Sep 17 00:00:00 2001 From: rajaram Date: Tue, 1 Sep 2026 14:35:45 +0100 Subject: [PATCH 042/100] CVEs suppressed --- config/owasp/suppressions.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/config/owasp/suppressions.xml b/config/owasp/suppressions.xml index 993d14e8f5..dd38be1a86 100644 --- a/config/owasp/suppressions.xml +++ b/config/owasp/suppressions.xml @@ -170,4 +170,10 @@ ^pkg:maven/com\.azure\.spring/spring-cloud-azure-service@.*$ cpe:/a:service_project:service + + CVE-2026-59313 + + + CVE-2026-59314 + From 4b7a3f21ab18146e2c13308c31cabe5411bf040f Mon Sep 17 00:00:00 2001 From: rajaram Date: Tue, 1 Sep 2026 15:24:55 +0100 Subject: [PATCH 043/100] Used refdata common api for case flags searches --- build.gradle | 1 + charts/et-cos/values.preview.template.yaml | 7 ++--- charts/et-cos/values.yaml | 1 + .../rdcommondata/OrganisationClient.java | 29 +++++++++++++++++++ .../rdprofessional/OrganisationClient.java | 17 +---------- .../CaseFlagsReferenceDataService.java | 8 ++--- src/main/resources/application.yaml | 1 + src/test/apiTest/resources/application.yaml | 1 + .../integration/resources/application.yaml | 1 + .../CaseFlagsReferenceDataServiceTest.java | 9 +++--- 10 files changed, 45 insertions(+), 30 deletions(-) create mode 100644 src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/rdcommondata/OrganisationClient.java diff --git a/build.gradle b/build.gradle index c7a3fab531..ce354733ef 100644 --- a/build.gradle +++ b/build.gradle @@ -813,6 +813,7 @@ bootWithCCD { environment 'IDAM_SECURITY_ALLOWED_ISSUER_2', 'http://localhost:5062/o' // xui-manage-org environment 'RD_PROFESSIONAL_API_URL', 'http://localhost:8765' + environment 'RD_COMMONDATA_API_URL', 'http://localhost:8765' environment 'RD_PROFESSIONAL_API_SERVICE', 'http://localhost:8765' environment 'PRD_HOST', 'http://localhost:8765' environment 'XUI_MANAGE_ORGANISATIONS_CASETYPES', 'ET_EnglandWales,ET_Scotland' diff --git a/charts/et-cos/values.preview.template.yaml b/charts/et-cos/values.preview.template.yaml index 8d2b8bcd96..e3db5648bd 100644 --- a/charts/et-cos/values.preview.template.yaml +++ b/charts/et-cos/values.preview.template.yaml @@ -44,6 +44,7 @@ java: ET_COS_DB_POOL_NAME: et-cos-db-pool CASE_DOCUMENT_AM_URL: http://ccd-case-document-am-api-aat.service.core-compute-aat.internal RD_PROFESSIONAL_API_URL: http://rd-professional-api-aat.service.core-compute-aat.internal + RD_COMMONDATA_API_URL: http://rd-commondata-api-aat.service.core-compute-aat.internal SECURE_DOC_STORE_FEATURE: true EM_CCD_ORCHESTRATOR_URL: http://em-ccd-orchestrator-{{ .Values.global.environment }}.service.core-compute-{{ .Values.global.environment }}.internal ACAS_BASE_URL: "https://api-dev-acas-01.azure-api.net/ECCLUAT" @@ -194,15 +195,13 @@ ccd: environment: USER_PROFILE_HOST: http://${SERVICE_NAME}-ccd-user-profile-api USER_PROFILE_S2S_AUTHORISED_SERVICES: ccd_data,ccd_definition,ccd_admin + # Start small in preview but allow the pool to grow to the service default under load. + SPRING_DATASOURCE_HIKARI_MINIMUM_IDLE: 1 keyVaults: [] devcpuRequests: 10m devcpuLimits: 1000m devmemoryRequests: 768Mi devmemoryLimits: 1536Mi - environment: - USER_PROFILE_S2S_AUTHORISED_SERVICES: ccd_data,ccd_definition,ccd_admin - # Start small in preview but allow the pool to grow to the service default under load. - SPRING_DATASOURCE_HIKARI_MINIMUM_IDLE: 1 ingressHost: ccd-user-profile-api-${SERVICE_FQDN} ccd-data-store-api: diff --git a/charts/et-cos/values.yaml b/charts/et-cos/values.yaml index 095d317682..9cb07f6407 100644 --- a/charts/et-cos/values.yaml +++ b/charts/et-cos/values.yaml @@ -75,6 +75,7 @@ java: ET_COS_DB_POOL_NAME: et-cos-db-pool CASE_DOCUMENT_AM_URL: http://ccd-case-document-am-api-{{ .Values.global.environment }}.service.core-compute-{{ .Values.global.environment }}.internal RD_PROFESSIONAL_API_URL: http://rd-professional-api-{{ .Values.global.environment }}.service.core-compute-{{ .Values.global.environment }}.internal + RD_COMMONDATA_API_URL: http://rd-commondata-api-{{ .Values.global.environment }}.service.core-compute-{{ .Values.global.environment }}.internal SECURE_DOC_STORE_FEATURE: true EXUI_CASE_DETAILS_URL: "https://manage-case.{{ .Values.global.environment }}.platform.hmcts.net/cases/case-details/" CITIZEN_CASE_DETAILS_URL: "https://et-sya.{{ .Values.global.environment }}.platform.hmcts.net/citizen-hub/" diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/rdcommondata/OrganisationClient.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/rdcommondata/OrganisationClient.java new file mode 100644 index 0000000000..8e82fdbf44 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/rdcommondata/OrganisationClient.java @@ -0,0 +1,29 @@ +package uk.gov.hmcts.ethos.replacement.docmosis.rdcommondata; + +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestParam; +import uk.gov.hmcts.ethos.replacement.docmosis.domain.caseflags.CaseFlagReferenceDataResponse; + +import static org.springframework.http.HttpHeaders.AUTHORIZATION; +import static uk.gov.hmcts.reform.ccd.document.am.feign.CaseDocumentClientApi.SERVICE_AUTHORIZATION; + +@FeignClient(name = "commondata-organisation-client", url = "${rd_commondata-api-url}") +public interface OrganisationClient { + + @GetMapping( + value = "/refdata/commondata/caseflags/service-id={serviceId}", + consumes = MediaType.APPLICATION_JSON_VALUE, + produces = MediaType.APPLICATION_JSON_VALUE + ) + CaseFlagReferenceDataResponse getCaseFlags( + @RequestHeader(AUTHORIZATION) String authorisation, + @RequestHeader(SERVICE_AUTHORIZATION) String serviceAuthorisation, + @PathVariable("serviceId") String serviceId, + @RequestParam("flag-type") String flagType + ); + +} diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/rdprofessional/OrganisationClient.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/rdprofessional/OrganisationClient.java index ccd473b05e..339c9b3d25 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/rdprofessional/OrganisationClient.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/rdprofessional/OrganisationClient.java @@ -11,13 +11,12 @@ import uk.gov.hmcts.et.common.model.ccd.types.OrganisationUsersResponse; import uk.gov.hmcts.et.common.model.ccd.types.OrganisationsResponse; import uk.gov.hmcts.ethos.replacement.docmosis.domain.AccountIdByEmailResponse; -import uk.gov.hmcts.ethos.replacement.docmosis.domain.caseflags.CaseFlagReferenceDataResponse; import java.util.List; import static org.springframework.http.HttpHeaders.AUTHORIZATION; import static uk.gov.hmcts.reform.ccd.document.am.feign.CaseDocumentClientApi.SERVICE_AUTHORIZATION; -@FeignClient(name = "organisation-client", url = "${rd_professional-api-url}") +@FeignClient(name = "professional-organisation-client", url = "${rd_professional-api-url}") public interface OrganisationClient { @GetMapping( @@ -73,18 +72,4 @@ ResponseEntity getAccountIdByEmail( @RequestParam("email") String email ); - @GetMapping( - value = "/refdata/commondata/caseflags/service-id={serviceId}", - consumes = MediaType.APPLICATION_JSON_VALUE, - produces = MediaType.APPLICATION_JSON_VALUE - ) - CaseFlagReferenceDataResponse getCaseFlags( - @RequestHeader(AUTHORIZATION) String authorisation, - @RequestHeader(SERVICE_AUTHORIZATION) String serviceAuthorisation, - @PathVariable("serviceId") String serviceId, - @RequestParam("flag-type") String flagType, - @RequestParam("welsh-required") String welshRequired, - @RequestParam("available-external-flag") String availableExternalFlag - ); - } diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsReferenceDataService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsReferenceDataService.java index 9c5d77922f..4ea735ff6e 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsReferenceDataService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsReferenceDataService.java @@ -6,7 +6,7 @@ import uk.gov.hmcts.ethos.replacement.docmosis.domain.caseflags.CaseFlagReferenceDataDetail; import uk.gov.hmcts.ethos.replacement.docmosis.domain.caseflags.CaseFlagReferenceDataGroup; import uk.gov.hmcts.ethos.replacement.docmosis.domain.caseflags.CaseFlagReferenceDataResponse; -import uk.gov.hmcts.ethos.replacement.docmosis.rdprofessional.OrganisationClient; +import uk.gov.hmcts.ethos.replacement.docmosis.rdcommondata.OrganisationClient; import uk.gov.hmcts.reform.authorisation.generators.AuthTokenGenerator; import java.util.HashMap; @@ -21,8 +21,6 @@ @Service public class CaseFlagsReferenceDataService { private static final String PARTY_FLAG_TYPE = "PARTY"; - private static final String WELSH_REQUIRED = "Y"; - private static final String AVAILABLE_EXTERNAL_FLAG = "N"; private final OrganisationClient organisationClient; private final AuthTokenGenerator authTokenGenerator; @@ -42,9 +40,7 @@ public Map getPartyFlagVisibilities(String userToken) { userToken, authTokenGenerator.generate(), hmctsServiceId, - PARTY_FLAG_TYPE, - WELSH_REQUIRED, - AVAILABLE_EXTERNAL_FLAG + PARTY_FLAG_TYPE ); return visibilityByFlagCodeOrName(response); diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index b45744bd46..88b35c9475 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -131,6 +131,7 @@ case_document_am: max_retries: ${CASE_DOCUMENT_AM_MAX_RETRIES:3} rd_professional-api-url: ${RD_PROFESSIONAL_API_URL:http://localhost:4507} +rd_commondata-api-url: ${RD_COMMONDATA_API_URL:http://localhost:4507} feature: secure-doc-store: diff --git a/src/test/apiTest/resources/application.yaml b/src/test/apiTest/resources/application.yaml index 46482437af..5a960dd0de 100644 --- a/src/test/apiTest/resources/application.yaml +++ b/src/test/apiTest/resources/application.yaml @@ -195,6 +195,7 @@ assign_case_access_api_url: ${AAC_URL:http://localhost:4454} apply_noc_access_api_assignments_path: /noc/apply-decision rd_professional-api-url: ${RD_PROFESSIONAL_API_URL:http://localhost:4507} +rd_commondata-api-url: ${RD_COMMONDATA_API_URL:http://localhost:4507} case-details-url: citizen: ${CITIZEN_CASE_DETAILS_URL:http://localhost:3001/citizen-hub/} diff --git a/src/test/integration/resources/application.yaml b/src/test/integration/resources/application.yaml index c0a57eaede..19fabfdb00 100644 --- a/src/test/integration/resources/application.yaml +++ b/src/test/integration/resources/application.yaml @@ -43,6 +43,7 @@ case_document_am: url: http://localhost:4455 rd_professional-api-url: http://localhost:4507 +rd_commondata-api-url: http://localhost:4507 feature: secure-doc-store: diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsReferenceDataServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsReferenceDataServiceTest.java index 62219cd820..092e3f8207 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsReferenceDataServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsReferenceDataServiceTest.java @@ -4,7 +4,7 @@ import uk.gov.hmcts.ethos.replacement.docmosis.domain.caseflags.CaseFlagReferenceDataDetail; import uk.gov.hmcts.ethos.replacement.docmosis.domain.caseflags.CaseFlagReferenceDataGroup; import uk.gov.hmcts.ethos.replacement.docmosis.domain.caseflags.CaseFlagReferenceDataResponse; -import uk.gov.hmcts.ethos.replacement.docmosis.rdprofessional.OrganisationClient; +import uk.gov.hmcts.ethos.replacement.docmosis.rdcommondata.OrganisationClient; import uk.gov.hmcts.reform.authorisation.generators.AuthTokenGenerator; import java.util.List; @@ -21,6 +21,7 @@ class CaseFlagsReferenceDataServiceTest { private static final String USER_TOKEN = "user-token"; private static final String SERVICE_TOKEN = "service-token"; private static final String HMCTS_SERVICE_ID = "BHA1"; + private static final String PARTY_FLAG_TYPE = "PARTY"; @Test void getPartyFlagVisibilities_shouldFlattenReferenceDataByCodeNativeCodeAndName() { @@ -29,7 +30,7 @@ void getPartyFlagVisibilities_shouldFlattenReferenceDataByCodeNativeCodeAndName( CaseFlagsReferenceDataService service = new CaseFlagsReferenceDataService(client, authTokenGenerator, HMCTS_SERVICE_ID); when(authTokenGenerator.generate()).thenReturn(SERVICE_TOKEN); - when(client.getCaseFlags(USER_TOKEN, SERVICE_TOKEN, HMCTS_SERVICE_ID, "PARTY", "Y", "N")) + when(client.getCaseFlags(USER_TOKEN, SERVICE_TOKEN, HMCTS_SERVICE_ID, PARTY_FLAG_TYPE)) .thenReturn(new CaseFlagReferenceDataResponse(List.of(new CaseFlagReferenceDataGroup(List.of( flag("Reasonable adjustment", false, "CATGRY", "RA0001", List.of( flag("Documents in a specified colour", true, "RA0010", "RA0010", List.of()), @@ -44,7 +45,7 @@ void getPartyFlagVisibilities_shouldFlattenReferenceDataByCodeNativeCodeAndName( assertEquals(EXTERNAL, actual.get("documents in a specified colour")); assertEquals(INTERNAL, actual.get("ra0017")); assertEquals(INTERNAL, actual.get("guidance on how to complete forms")); - verify(client).getCaseFlags(USER_TOKEN, SERVICE_TOKEN, HMCTS_SERVICE_ID, "PARTY", "Y", "N"); + verify(client).getCaseFlags(USER_TOKEN, SERVICE_TOKEN, HMCTS_SERVICE_ID, PARTY_FLAG_TYPE); } @Test @@ -54,7 +55,7 @@ void getPartyFlagVisibilities_shouldIgnoreAmbiguousNames() { CaseFlagsReferenceDataService service = new CaseFlagsReferenceDataService(client, authTokenGenerator, HMCTS_SERVICE_ID); when(authTokenGenerator.generate()).thenReturn(SERVICE_TOKEN); - when(client.getCaseFlags(USER_TOKEN, SERVICE_TOKEN, HMCTS_SERVICE_ID, "PARTY", "Y", "N")) + when(client.getCaseFlags(USER_TOKEN, SERVICE_TOKEN, HMCTS_SERVICE_ID, PARTY_FLAG_TYPE)) .thenReturn(new CaseFlagReferenceDataResponse(List.of(new CaseFlagReferenceDataGroup(List.of( flag("Other", true, "OT0001", "OT0001", List.of()), flag("Other", false, "OT0002", "OT0002", List.of()) From bbe2febb8552af2823a72292722bc8c9e17fd078 Mon Sep 17 00:00:00 2001 From: hmcts-jenkins-d-to-i <62423932+hmcts-jenkins-d-to-i[bot]@users.noreply.github.com> Date: Tue, 1 Sep 2026 14:28:22 +0000 Subject: [PATCH 044/100] Bumping chart version/ fixing aliases --- charts/et-cos/Chart.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/et-cos/Chart.yaml b/charts/et-cos/Chart.yaml index 1ac11669fa..32ae870eeb 100644 --- a/charts/et-cos/Chart.yaml +++ b/charts/et-cos/Chart.yaml @@ -1,7 +1,7 @@ apiVersion: v2 name: et-cos home: https://github.com/hmcts/et-ccd-callbacks -version: 0.0.71 +version: 0.0.72 description: HMCTS Employment Tribunals CCD Callbacks service maintainers: - name: HMCTS Employment Tribunals Team From 17540e7a7916c547cdab0aad6709d119635fc193 Mon Sep 17 00:00:00 2001 From: rajaram Date: Tue, 1 Sep 2026 15:38:25 +0100 Subject: [PATCH 045/100] Added rd-commondata-api in chart --- charts/et-cos/Chart.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/charts/et-cos/Chart.yaml b/charts/et-cos/Chart.yaml index 32ae870eeb..f932db0adb 100644 --- a/charts/et-cos/Chart.yaml +++ b/charts/et-cos/Chart.yaml @@ -77,6 +77,10 @@ dependencies: version: ~0.0.25 repository: 'oci://hmctsprod.azurecr.io/helm' condition: rd-professional-api.enabled + - name: rd-commondata-api + version: ~0.0.21 + repository: 'oci://hmctsprod.azurecr.io/helm' + condition: rd-commondata-api.enabled - name: rd-user-profile-api version: ~0.0.28 repository: 'oci://hmctsprod.azurecr.io/helm' From e7f97721e35d65460d89a11940bd9ae4bf6ac1b1 Mon Sep 17 00:00:00 2001 From: rajaram Date: Tue, 1 Sep 2026 16:17:50 +0100 Subject: [PATCH 046/100] Updated lombok config --- lombok.config | 1 + 1 file changed, 1 insertion(+) diff --git a/lombok.config b/lombok.config index 9e81b73fd4..467f6343dd 100644 --- a/lombok.config +++ b/lombok.config @@ -2,3 +2,4 @@ config.stopBubbling = true lombok.addLombokGeneratedAnnotation = true lombok.copyableAnnotations += org.springframework.beans.factory.annotation.Qualifier +lombok.jacksonized.jacksonVersion += 2 From f3f5613d4b1fe85646abca82217ce05a4edf6bda Mon Sep 17 00:00:00 2001 From: rajaram Date: Tue, 1 Sep 2026 17:15:41 +0100 Subject: [PATCH 047/100] Updated rd commondata config --- charts/et-cos/values.aat.template.yaml | 2 ++ charts/et-cos/values.preview.template.yaml | 33 ++++++++++++++++++++++ charts/et-cos/values.yaml | 2 ++ 3 files changed, 37 insertions(+) diff --git a/charts/et-cos/values.aat.template.yaml b/charts/et-cos/values.aat.template.yaml index 7001fc2eec..b27b6e917f 100644 --- a/charts/et-cos/values.aat.template.yaml +++ b/charts/et-cos/values.aat.template.yaml @@ -33,6 +33,8 @@ rd-judicial-api: enabled: false rd-professional-api: enabled: false +rd-commondata-api: + enabled: false rd-user-profile-api: enabled: false rd-caseworker-ref-api: diff --git a/charts/et-cos/values.preview.template.yaml b/charts/et-cos/values.preview.template.yaml index e3db5648bd..c568d0cdf8 100644 --- a/charts/et-cos/values.preview.template.yaml +++ b/charts/et-cos/values.preview.template.yaml @@ -1036,6 +1036,39 @@ rd-professional-api: CCD_URL: https://ccd-data-store-api-${SERVICE_FQDN} POSTGRES_CONNECTION_OPTIONS: "?stringtype=unspecified&reWriteBatchedInserts=true&sslmode=require" +rd-commondata-api: + enabled: false + java: + image: 'hmctsprod.azurecr.io/rd/commondata-api:latest' + ingressHost: rd-commondata-api-${SERVICE_FQDN} + releaseNameOverride: ${SERVICE_NAME}-rd-commondata-api + keyVaults: + rd: + secrets: + - name: app-insights-connection-string + alias: app-insights-connection-string + - name: LD-SDK-KEY + alias: LD_SDK_KEY + - name: common-data-api-s2s-secret + alias: COMMONDATA_API_S2S_SECRET + secrets: + POSTGRES_PASSWORD: + secretRef: postgres + key: PASSWORD + disabled: false + devcpuRequests: 10m + devcpuLimits: 1000m + devmemoryRequests: 1024Mi + devmemoryLimits: 2048Mi + environment: + POSTGRES_HOST: et-preview.postgres.database.azure.com + POSTGRES_USERNAME: hmcts + POSTGRES_PORT: 5432 + POSTGRES_NAME: "pr-${CHANGE_ID}-dbcommondata" + USER_PROFILE_URL: https://rd-user-profile-api-${SERVICE_FQDN} + CCD_URL: https://ccd-data-store-api-${SERVICE_FQDN} + POSTGRES_CONNECTION_OPTIONS: "?stringtype=unspecified&reWriteBatchedInserts=true&sslmode=require" + rd-user-profile-api: enabled: false java: diff --git a/charts/et-cos/values.yaml b/charts/et-cos/values.yaml index 9cb07f6407..42168dfbb3 100644 --- a/charts/et-cos/values.yaml +++ b/charts/et-cos/values.yaml @@ -115,6 +115,8 @@ rd-judicial-api: enabled: false rd-professional-api: enabled: false +rd-commondata-api: + enabled: false rd-user-profile-api: enabled: false rd-caseworker-ref-api: From aabf43ec3d96af0ff44869b5fc018f0846f20b56 Mon Sep 17 00:00:00 2001 From: rajaram Date: Tue, 1 Sep 2026 17:38:34 +0100 Subject: [PATCH 048/100] Updated lombok config --- lombok.config | 1 - 1 file changed, 1 deletion(-) diff --git a/lombok.config b/lombok.config index 467f6343dd..9e81b73fd4 100644 --- a/lombok.config +++ b/lombok.config @@ -2,4 +2,3 @@ config.stopBubbling = true lombok.addLombokGeneratedAnnotation = true lombok.copyableAnnotations += org.springframework.beans.factory.annotation.Qualifier -lombok.jacksonized.jacksonVersion += 2 From d04e2adcb7ef7b1d5031b07b2aa631ebdab2d8ae Mon Sep 17 00:00:00 2001 From: rajaram Date: Wed, 2 Sep 2026 10:37:38 +0100 Subject: [PATCH 049/100] Removed rd-commondata-api config from preview --- charts/et-cos/values.preview.template.yaml | 33 ---------------------- 1 file changed, 33 deletions(-) diff --git a/charts/et-cos/values.preview.template.yaml b/charts/et-cos/values.preview.template.yaml index c568d0cdf8..e3db5648bd 100644 --- a/charts/et-cos/values.preview.template.yaml +++ b/charts/et-cos/values.preview.template.yaml @@ -1036,39 +1036,6 @@ rd-professional-api: CCD_URL: https://ccd-data-store-api-${SERVICE_FQDN} POSTGRES_CONNECTION_OPTIONS: "?stringtype=unspecified&reWriteBatchedInserts=true&sslmode=require" -rd-commondata-api: - enabled: false - java: - image: 'hmctsprod.azurecr.io/rd/commondata-api:latest' - ingressHost: rd-commondata-api-${SERVICE_FQDN} - releaseNameOverride: ${SERVICE_NAME}-rd-commondata-api - keyVaults: - rd: - secrets: - - name: app-insights-connection-string - alias: app-insights-connection-string - - name: LD-SDK-KEY - alias: LD_SDK_KEY - - name: common-data-api-s2s-secret - alias: COMMONDATA_API_S2S_SECRET - secrets: - POSTGRES_PASSWORD: - secretRef: postgres - key: PASSWORD - disabled: false - devcpuRequests: 10m - devcpuLimits: 1000m - devmemoryRequests: 1024Mi - devmemoryLimits: 2048Mi - environment: - POSTGRES_HOST: et-preview.postgres.database.azure.com - POSTGRES_USERNAME: hmcts - POSTGRES_PORT: 5432 - POSTGRES_NAME: "pr-${CHANGE_ID}-dbcommondata" - USER_PROFILE_URL: https://rd-user-profile-api-${SERVICE_FQDN} - CCD_URL: https://ccd-data-store-api-${SERVICE_FQDN} - POSTGRES_CONNECTION_OPTIONS: "?stringtype=unspecified&reWriteBatchedInserts=true&sslmode=require" - rd-user-profile-api: enabled: false java: From c07c6adeb9d67784444b50204df8ebab21ad11f1 Mon Sep 17 00:00:00 2001 From: rajaram Date: Thu, 3 Sep 2026 16:09:13 +0100 Subject: [PATCH 050/100] Moved Event and tab config for EngWales to nonprod --- ...horisationCaseEvent-CaseFlags-nonprod.json | 26 ++ ...isationCaseEvent-CaseFlagsCaseLinking.json | 24 -- .../CaseTypeTab-CaseFlags-nonprod.json | 233 ++++++++++++++++++ .../CaseTypeTab-CaseFlagsCaseLinking.json | 231 ----------------- 4 files changed, 259 insertions(+), 255 deletions(-) create mode 100644 ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseEvent/AuthorisationCaseEvent-CaseFlags-nonprod.json create mode 100644 ccd-definitions/jurisdictions/england-wales/json/CaseTypeTab/CaseTypeTab-CaseFlags-nonprod.json diff --git a/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseEvent/AuthorisationCaseEvent-CaseFlags-nonprod.json b/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseEvent/AuthorisationCaseEvent-CaseFlags-nonprod.json new file mode 100644 index 0000000000..a4222220fd --- /dev/null +++ b/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseEvent/AuthorisationCaseEvent-CaseFlags-nonprod.json @@ -0,0 +1,26 @@ +[ + { + "CaseTypeId": "ET_EnglandWales", + "CaseEventID": "requestSupport", + "UserRole": "caseworker-employment-legalrep-solicitor", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseEventID": "manageSupport", + "UserRole": "caseworker-employment-legalrep-solicitor", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseEventID": "requestSupport", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseEventID": "manageSupport", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + } +] \ No newline at end of file diff --git a/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseEvent/AuthorisationCaseEvent-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseEvent/AuthorisationCaseEvent-CaseFlagsCaseLinking.json index b8bcefa9a7..82511ffeac 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseEvent/AuthorisationCaseEvent-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseEvent/AuthorisationCaseEvent-CaseFlagsCaseLinking.json @@ -23,30 +23,6 @@ "UserRole": "caseworker-employment-englandwales", "CRUD": "CRU" }, - { - "CaseTypeId": "ET_EnglandWales", - "CaseEventID": "requestSupport", - "UserRole": "caseworker-employment-legalrep-solicitor", - "CRUD": "CRU" - }, - { - "CaseTypeId": "ET_EnglandWales", - "CaseEventID": "manageSupport", - "UserRole": "caseworker-employment-legalrep-solicitor", - "CRUD": "CRU" - }, - { - "CaseTypeId": "ET_EnglandWales", - "CaseEventID": "requestSupport", - "UserRole": "caseworker-employment-api", - "CRUD": "CRUD" - }, - { - "CaseTypeId": "ET_EnglandWales", - "CaseEventID": "manageSupport", - "UserRole": "caseworker-employment-api", - "CRUD": "CRUD" - }, { "CaseTypeId": "ET_EnglandWales", "CaseEventID": "migrateCaseFlags", diff --git a/ccd-definitions/jurisdictions/england-wales/json/CaseTypeTab/CaseTypeTab-CaseFlags-nonprod.json b/ccd-definitions/jurisdictions/england-wales/json/CaseTypeTab/CaseTypeTab-CaseFlags-nonprod.json new file mode 100644 index 0000000000..3adcdfd5bc --- /dev/null +++ b/ccd-definitions/jurisdictions/england-wales/json/CaseTypeTab/CaseTypeTab-CaseFlags-nonprod.json @@ -0,0 +1,233 @@ +[ + { + "CaseFieldID": "flagLauncherExternal", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "TabDisplayOrder": 69, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 12, + "UserRole": "caseworker-employment-support", + "DisplayContextParameter": "#ARGUMENT(READ,EXTERNAL)" + }, + { + "CaseFieldID": "claimantExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 69, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 1 + }, + { + "CaseFieldID": "claimantRepresentativeExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 69, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 1 + }, + { + "CaseFieldID": "respondentExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 2 + }, + { + "CaseFieldID": "respondent1ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 3 + }, + { + "CaseFieldID": "respondent2ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 4 + }, + { + "CaseFieldID": "respondent3ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 5 + }, + { + "CaseFieldID": "respondent4ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 6 + }, + { + "CaseFieldID": "respondent5ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 7 + }, + { + "CaseFieldID": "respondent6ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 8 + }, + { + "CaseFieldID": "respondent7ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 9 + }, + { + "CaseFieldID": "respondent8ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 10 + }, + { + "CaseFieldID": "respondent9ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 11 + }, + { + "CaseFieldID": "representativeExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 2 + }, + { + "CaseFieldID": "representative1ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 3 + }, + { + "CaseFieldID": "representative2ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 4 + }, + { + "CaseFieldID": "representative3ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 5 + }, + { + "CaseFieldID": "representative4ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 6 + }, + { + "CaseFieldID": "representative5ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 7 + }, + { + "CaseFieldID": "representative6ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 8 + }, + { + "CaseFieldID": "representative7ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 9 + }, + { + "CaseFieldID": "representative8ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 10 + }, + { + "CaseFieldID": "representative9ExternalFlags", + "CaseTypeID": "ET_EnglandWales", + "Channel": "CaseWorker", + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "TabDisplayOrder": 1, + "TabID": "support", + "TabLabel": "Support", + "TabFieldDisplayOrder": 11 + } +] diff --git a/ccd-definitions/jurisdictions/england-wales/json/CaseTypeTab/CaseTypeTab-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/england-wales/json/CaseTypeTab/CaseTypeTab-CaseFlagsCaseLinking.json index ddebf94923..56182e901f 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/CaseTypeTab/CaseTypeTab-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/england-wales/json/CaseTypeTab/CaseTypeTab-CaseFlagsCaseLinking.json @@ -486,236 +486,5 @@ "TabID": "caseFlags", "TabLabel": "Case Flags", "TabFieldDisplayOrder": 11 - }, - { - "CaseFieldID": "flagLauncherExternal", - "CaseTypeID": "ET_EnglandWales", - "Channel": "CaseWorker", - "TabDisplayOrder": 69, - "TabID": "support", - "TabLabel": "Support", - "TabFieldDisplayOrder": 12, - "UserRole": "caseworker-employment-support", - "DisplayContextParameter": "#ARGUMENT(READ,EXTERNAL)" - }, - { - "CaseFieldID": "claimantExternalFlags", - "CaseTypeID": "ET_EnglandWales", - "Channel": "CaseWorker", - "FieldShowCondition": "flagLauncherExternal=\"hidden\"", - "TabDisplayOrder": 69, - "TabID": "support", - "TabLabel": "Support", - "TabFieldDisplayOrder": 1 - }, - { - "CaseFieldID": "claimantRepresentativeExternalFlags", - "CaseTypeID": "ET_EnglandWales", - "Channel": "CaseWorker", - "FieldShowCondition": "flagLauncherExternal=\"hidden\"", - "TabDisplayOrder": 69, - "TabID": "support", - "TabLabel": "Support", - "TabFieldDisplayOrder": 1 - }, - { - "CaseFieldID": "respondentExternalFlags", - "CaseTypeID": "ET_EnglandWales", - "Channel": "CaseWorker", - "FieldShowCondition": "flagLauncherExternal=\"hidden\"", - "TabDisplayOrder": 1, - "TabID": "support", - "TabLabel": "Support", - "TabFieldDisplayOrder": 2 - }, - { - "CaseFieldID": "respondent1ExternalFlags", - "CaseTypeID": "ET_EnglandWales", - "Channel": "CaseWorker", - "FieldShowCondition": "flagLauncherExternal=\"hidden\"", - "TabDisplayOrder": 1, - "TabID": "support", - "TabLabel": "Support", - "TabFieldDisplayOrder": 3 - }, - { - "CaseFieldID": "respondent2ExternalFlags", - "CaseTypeID": "ET_EnglandWales", - "Channel": "CaseWorker", - "FieldShowCondition": "flagLauncherExternal=\"hidden\"", - "TabDisplayOrder": 1, - "TabID": "support", - "TabLabel": "Support", - "TabFieldDisplayOrder": 4 - }, - { - "CaseFieldID": "respondent3ExternalFlags", - "CaseTypeID": "ET_EnglandWales", - "Channel": "CaseWorker", - "FieldShowCondition": "flagLauncherExternal=\"hidden\"", - "TabDisplayOrder": 1, - "TabID": "support", - "TabLabel": "Support", - "TabFieldDisplayOrder": 5 - }, - { - "CaseFieldID": "respondent4ExternalFlags", - "CaseTypeID": "ET_EnglandWales", - "Channel": "CaseWorker", - "FieldShowCondition": "flagLauncherExternal=\"hidden\"", - "TabDisplayOrder": 1, - "TabID": "support", - "TabLabel": "Support", - "TabFieldDisplayOrder": 6 - }, - { - "CaseFieldID": "respondent5ExternalFlags", - "CaseTypeID": "ET_EnglandWales", - "Channel": "CaseWorker", - "FieldShowCondition": "flagLauncherExternal=\"hidden\"", - "TabDisplayOrder": 1, - "TabID": "support", - "TabLabel": "Support", - "TabFieldDisplayOrder": 7 - }, - { - "CaseFieldID": "respondent6ExternalFlags", - "CaseTypeID": "ET_EnglandWales", - "Channel": "CaseWorker", - "FieldShowCondition": "flagLauncherExternal=\"hidden\"", - "TabDisplayOrder": 1, - "TabID": "support", - "TabLabel": "Support", - "TabFieldDisplayOrder": 8 - }, - { - "CaseFieldID": "respondent7ExternalFlags", - "CaseTypeID": "ET_EnglandWales", - "Channel": "CaseWorker", - "FieldShowCondition": "flagLauncherExternal=\"hidden\"", - "TabDisplayOrder": 1, - "TabID": "support", - "TabLabel": "Support", - "TabFieldDisplayOrder": 9 - }, - { - "CaseFieldID": "respondent8ExternalFlags", - "CaseTypeID": "ET_EnglandWales", - "Channel": "CaseWorker", - "FieldShowCondition": "flagLauncherExternal=\"hidden\"", - "TabDisplayOrder": 1, - "TabID": "support", - "TabLabel": "Support", - "TabFieldDisplayOrder": 10 - }, - { - "CaseFieldID": "respondent9ExternalFlags", - "CaseTypeID": "ET_EnglandWales", - "Channel": "CaseWorker", - "FieldShowCondition": "flagLauncherExternal=\"hidden\"", - "TabDisplayOrder": 1, - "TabID": "support", - "TabLabel": "Support", - "TabFieldDisplayOrder": 11 - }, - { - "CaseFieldID": "representativeExternalFlags", - "CaseTypeID": "ET_EnglandWales", - "Channel": "CaseWorker", - "FieldShowCondition": "flagLauncherExternal=\"hidden\"", - "TabDisplayOrder": 1, - "TabID": "support", - "TabLabel": "Support", - "TabFieldDisplayOrder": 2 - }, - { - "CaseFieldID": "representative1ExternalFlags", - "CaseTypeID": "ET_EnglandWales", - "Channel": "CaseWorker", - "FieldShowCondition": "flagLauncherExternal=\"hidden\"", - "TabDisplayOrder": 1, - "TabID": "support", - "TabLabel": "Support", - "TabFieldDisplayOrder": 3 - }, - { - "CaseFieldID": "representative2ExternalFlags", - "CaseTypeID": "ET_EnglandWales", - "Channel": "CaseWorker", - "FieldShowCondition": "flagLauncherExternal=\"hidden\"", - "TabDisplayOrder": 1, - "TabID": "support", - "TabLabel": "Support", - "TabFieldDisplayOrder": 4 - }, - { - "CaseFieldID": "representative3ExternalFlags", - "CaseTypeID": "ET_EnglandWales", - "Channel": "CaseWorker", - "FieldShowCondition": "flagLauncherExternal=\"hidden\"", - "TabDisplayOrder": 1, - "TabID": "support", - "TabLabel": "Support", - "TabFieldDisplayOrder": 5 - }, - { - "CaseFieldID": "representative4ExternalFlags", - "CaseTypeID": "ET_EnglandWales", - "Channel": "CaseWorker", - "FieldShowCondition": "flagLauncherExternal=\"hidden\"", - "TabDisplayOrder": 1, - "TabID": "support", - "TabLabel": "Support", - "TabFieldDisplayOrder": 6 - }, - { - "CaseFieldID": "representative5ExternalFlags", - "CaseTypeID": "ET_EnglandWales", - "Channel": "CaseWorker", - "FieldShowCondition": "flagLauncherExternal=\"hidden\"", - "TabDisplayOrder": 1, - "TabID": "support", - "TabLabel": "Support", - "TabFieldDisplayOrder": 7 - }, - { - "CaseFieldID": "representative6ExternalFlags", - "CaseTypeID": "ET_EnglandWales", - "Channel": "CaseWorker", - "FieldShowCondition": "flagLauncherExternal=\"hidden\"", - "TabDisplayOrder": 1, - "TabID": "support", - "TabLabel": "Support", - "TabFieldDisplayOrder": 8 - }, - { - "CaseFieldID": "representative7ExternalFlags", - "CaseTypeID": "ET_EnglandWales", - "Channel": "CaseWorker", - "FieldShowCondition": "flagLauncherExternal=\"hidden\"", - "TabDisplayOrder": 1, - "TabID": "support", - "TabLabel": "Support", - "TabFieldDisplayOrder": 9 - }, - { - "CaseFieldID": "representative8ExternalFlags", - "CaseTypeID": "ET_EnglandWales", - "Channel": "CaseWorker", - "FieldShowCondition": "flagLauncherExternal=\"hidden\"", - "TabDisplayOrder": 1, - "TabID": "support", - "TabLabel": "Support", - "TabFieldDisplayOrder": 10 - }, - { - "CaseFieldID": "representative9ExternalFlags", - "CaseTypeID": "ET_EnglandWales", - "Channel": "CaseWorker", - "FieldShowCondition": "flagLauncherExternal=\"hidden\"", - "TabDisplayOrder": 1, - "TabID": "support", - "TabLabel": "Support", - "TabFieldDisplayOrder": 11 } ] From 928ae9abd5a04829198429c20d44a399caa501b0 Mon Sep 17 00:00:00 2001 From: rajaram Date: Thu, 3 Sep 2026 17:11:27 +0100 Subject: [PATCH 051/100] RET-6745 - Name only changes --- .../RespondentRepresentativeController.java | 39 +++- .../NocRespondentRepresentativeService.java | 33 ++-- .../noc/RespondentRepresentativeUtils.java | 18 +- ...espondentRepresentativeControllerTest.java | 77 ++++++++ .../service/CaseFlagsServiceTest.java | 178 ++++++++++++++++++ ...ocRespondentRepresentativeServiceTest.java | 120 ++++++++++++ .../RespondentRepresentativeUtilsTest.java | 23 +++ 7 files changed, 471 insertions(+), 17 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/RespondentRepresentativeController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/RespondentRepresentativeController.java index 1abfa03d2e..fb823a19a9 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/RespondentRepresentativeController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/RespondentRepresentativeController.java @@ -309,13 +309,48 @@ private void setupCaseFlagsIfRespondentRepresentativeChanged(CallbackRequest cal boolean representativeRemoved = respondentRepresentativeRemoved(callbackRequest); if (featureToggleService.isCaseFlagsV2Enabled(callbackRequest.getCaseDetails().getCaseTypeId()) && (CollectionUtils.isNotEmpty(changedRepresentativeIndexes) || representativeRemoved)) { - if (CollectionUtils.isNotEmpty(changedRepresentativeIndexes)) { - caseFlagsService.clearRespondentRepresentativeFlags(caseData, changedRepresentativeIndexes); + List representativeIndexesToClear = changedRepresentativeIndexes.stream() + .filter(index -> shouldClearChangedRepresentativeFlags(callbackRequest, index)) + .toList(); + if (CollectionUtils.isNotEmpty(representativeIndexesToClear)) { + caseFlagsService.clearRespondentRepresentativeFlags(caseData, representativeIndexesToClear); } caseFlagsService.setupCaseFlags(caseData); } } + private static boolean shouldClearChangedRepresentativeFlags( + CallbackRequest callbackRequest, int currentRepresentativeIndex) { + List previousRepresentatives = + callbackRequest.getCaseDetailsBefore().getCaseData().getRepCollection(); + List currentRepresentatives = + callbackRequest.getCaseDetails().getCaseData().getRepCollection(); + RepresentedTypeRItem currentRepresentative = currentRepresentatives.get(currentRepresentativeIndex); + RepresentedTypeRItem previousRepresentative = previousRepresentatives.stream() + .filter(previous -> sameRepresentative(previous, currentRepresentative)) + .findFirst() + .orElse(null); + + if (previousRepresentative == null) { + return true; + } + + return IntStream.range(0, currentRepresentatives.size()) + .filter(index -> index != currentRepresentativeIndex) + .mapToObj(currentRepresentatives::get) + .noneMatch(representative -> sameRepresentativeIdentity(previousRepresentative, representative)); + } + + private static boolean sameRepresentativeIdentity( + RepresentedTypeRItem firstRepresentative, RepresentedTypeRItem secondRepresentative) { + return Strings.CI.equals( + StringUtils.trimToEmpty(representativeName(firstRepresentative)), + StringUtils.trimToEmpty(representativeName(secondRepresentative))) + && Strings.CI.equals( + StringUtils.trimToEmpty(representativeEmail(firstRepresentative)), + StringUtils.trimToEmpty(representativeEmail(secondRepresentative))); + } + private static boolean respondentRepresentativeRemoved(CallbackRequest callbackRequest) { if (callbackRequest.getCaseDetailsBefore() == null || callbackRequest.getCaseDetailsBefore().getCaseData() == null diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocRespondentRepresentativeService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocRespondentRepresentativeService.java index 4e59edf063..f216f14eac 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocRespondentRepresentativeService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocRespondentRepresentativeService.java @@ -462,7 +462,7 @@ public void revokeOldRepresentatives(CallbackRequest callbackRequest, *
    *
  • it is a valid representative, and
  • *
  • no matching representative exists in {@code newRepresentatives} for the same respondent, or
  • - *
  • a matching representative exists but the organisation or email address has changed
  • + *
  • a matching representative exists but the name, organisation or email address has changed
  • *
*

* Only valid representatives are considered during the comparison. If @@ -471,7 +471,7 @@ public void revokeOldRepresentatives(CallbackRequest callbackRequest, * @param oldRepresentatives the existing representatives to compare against * @param newRepresentatives the updated representatives to compare with * @return a list of representatives from {@code oldRepresentatives} that are either - * no longer present or have updated organisation or email details + * no longer present or have updated name, organisation or email details */ public List findRepresentativesToRemove( List oldRepresentatives, List newRepresentatives) { @@ -486,17 +486,19 @@ public List findRepresentativesToRemove( if (!RespondentRepresentativeUtils.isValidRepresentative(oldRepresentative)) { continue; } - // to check if representative exists but its organisation or email is changed or not - boolean hasRespondentRepresentativeOrganisationChanged = false; + // to check if representative exists but its name, organisation or email is changed or not + boolean hasRespondentRepresentativeDetailsChanged = false; // to check if representative exists or not boolean isMatchingValidRepresentative = false; boolean hmctsRepresentativeEmailChanged = false; for (RepresentedTypeRItem newRepresentative : newRepresentatives) { if (RespondentRepresentativeUtils.isMatchingValidRepresentative(oldRepresentative, newRepresentative)) { isMatchingValidRepresentative = true; - // representative already exists but its organisation or email is changed - hasRespondentRepresentativeOrganisationChanged = + // representative already exists but its name or organisation is changed + hasRespondentRepresentativeDetailsChanged = RespondentRepresentativeUtils.hasRespondentRepresentativeOrganisationChanged( + oldRepresentative.getValue(), newRepresentative.getValue()) + || RespondentRepresentativeUtils.isRepresentativeNameChanged( oldRepresentative.getValue(), newRepresentative.getValue()); // when representative email changed and new representative has account on HMCTS should // remove old representative and assign new representative access with new email address. @@ -505,7 +507,7 @@ public List findRepresentativesToRemove( } } if (RespondentRepresentativeUtils.canRemoveRepresentative(isMatchingValidRepresentative, - hasRespondentRepresentativeOrganisationChanged, + hasRespondentRepresentativeDetailsChanged, hmctsRepresentativeEmailChanged)) { representativesToRemove.add(oldRepresentative); } @@ -664,22 +666,27 @@ private static Set currentRespondentRepresentativeRoles( return caseData.getRepCollection().stream() .filter(RespondentRepresentativeUtils::isValidRepresentative) .map(RepresentedTypeRItem::getValue) - .filter(currentRepresentative -> sameRepresentativeUser( + .filter(currentRepresentative -> sameRepresentativeIdentity( removedRepresentativeValue, currentRepresentative)) .map(RepresentedTypeR::getRole) .filter(RoleUtils::isRespondentRepresentativeRole) .collect(Collectors.toSet()); } - private static boolean sameRepresentativeUser( + private static boolean sameRepresentativeIdentity( RepresentedTypeR firstRepresentative, RepresentedTypeR secondRepresentative) { + boolean sameUser; if (StringUtils.isNotBlank(firstRepresentative.getIdamId()) && StringUtils.isNotBlank(secondRepresentative.getIdamId())) { - return Strings.CS.equals(firstRepresentative.getIdamId(), secondRepresentative.getIdamId()); + sameUser = Strings.CS.equals(firstRepresentative.getIdamId(), secondRepresentative.getIdamId()); + } else { + sameUser = StringUtils.isNotBlank(firstRepresentative.getRepresentativeEmailAddress()) + && Strings.CI.equals(firstRepresentative.getRepresentativeEmailAddress(), + secondRepresentative.getRepresentativeEmailAddress()); } - return StringUtils.isNotBlank(firstRepresentative.getRepresentativeEmailAddress()) - && Strings.CI.equals(firstRepresentative.getRepresentativeEmailAddress(), - secondRepresentative.getRepresentativeEmailAddress()); + return sameUser && Strings.CI.equals( + StringUtils.trimToEmpty(firstRepresentative.getNameOfRepresentative()), + StringUtils.trimToEmpty(secondRepresentative.getNameOfRepresentative())); } /** diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/utils/noc/RespondentRepresentativeUtils.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/utils/noc/RespondentRepresentativeUtils.java index 7eeb119034..2e462e9913 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/utils/noc/RespondentRepresentativeUtils.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/utils/noc/RespondentRepresentativeUtils.java @@ -353,6 +353,19 @@ public static boolean isRepresentativeEmailChanged(RepresentedTypeR oldRepresent .getRepresentativeEmailAddress()); } + /** + * Checks whether a representative's name has changed. + * + * @param oldRepresentative representative before the update + * @param newRepresentative representative after the update + * @return {@code true} when the names differ + */ + public static boolean isRepresentativeNameChanged(RepresentedTypeR oldRepresentative, + RepresentedTypeR newRepresentative) { + return !Strings.CS.equals(oldRepresentative.getNameOfRepresentative(), + newRepresentative.getNameOfRepresentative()); + } + /** * Determines whether the provided new representative is both valid and * represents the same respondent as the old representative. @@ -400,7 +413,7 @@ public static boolean canRemoveRepresentative(boolean isMatchingValidRepresenta *

*

* Representatives are considered unchanged only when they represent the same respondent - * and both the organisation and email address remain the same. + * and the name, organisation and email address remain the same. *

*

* Any invalid representatives are ignored during the comparison. @@ -409,7 +422,7 @@ public static boolean canRemoveRepresentative(boolean isMatchingValidRepresenta * @param newRepresentatives the list of representatives from the updated case data * @param oldRepresentatives the list of representatives from the previous case data * @return a list of representatives that are either new or have been updated due to - * a change in organisation or email address + * a change in name, organisation or email address */ public static List findNewOrUpdatedRepresentatives( List newRepresentatives, List oldRepresentatives) { @@ -430,6 +443,7 @@ public static List findNewOrUpdatedRepresentatives( && representsSameRespondent(oldRepresentative, newRepresentative) && !hasRespondentRepresentativeOrganisationChanged(oldRepresentative.getValue(), newRepresentative.getValue()) + && !isRepresentativeNameChanged(oldRepresentative.getValue(), newRepresentative.getValue()) && !isRepresentativeEmailChanged(oldRepresentative.getValue(), newRepresentative.getValue())) { representsSameRespondent = true; break; diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/RespondentRepresentativeControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/RespondentRepresentativeControllerTest.java index 7e168a7b1d..b99c4ef434 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/RespondentRepresentativeControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/RespondentRepresentativeControllerTest.java @@ -4,6 +4,9 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.NullSource; +import org.junit.jupiter.params.provider.ValueSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.http.MediaType; @@ -300,6 +303,62 @@ void amendRespondentRepresentativeAboutToSubmitSetsUpCaseFlagsWhenNameChanges() verify(caseFlagsService, times(1)).setupCaseFlags(any(CaseData.class)); } + @ParameterizedTest + @NullSource + @ValueSource(strings = "representative@example.com") + @SneakyThrows + void amendRespondentRepresentativePreservesSharedFlagsWhenNameChangesForOneRespondent(String email) { + CaseData previousCaseData = new CaseData(); + previousCaseData.setRepCollection(List.of( + respondentRepresentative(ID_REPRESENTATIVE_1, "Representative X", email, ID_RESPONDENT_1), + respondentRepresentative(ID_REPRESENTATIVE_2, "Representative X", email, ID_RESPONDENT_2) + )); + CaseData currentCaseData = new CaseData(); + currentCaseData.setRepCollection(List.of( + respondentRepresentative(ID_REPRESENTATIVE_1, "Representative Y", email, ID_RESPONDENT_1), + respondentRepresentative(ID_REPRESENTATIVE_2, "Representative X", email, ID_RESPONDENT_2) + )); + CallbackRequest callbackRequest = respondentRepresentativeCallback(previousCaseData, currentCaseData); + when(featureToggleService.isCaseFlagsV2Enabled(ENGLANDWALES_CASE_TYPE_ID)).thenReturn(true); + + mockMvc.perform(post(URL_AMEND_RESPONDENT_REPRESENTATIVE_ABOUT_TO_SUBMIT) + .content(jsonMapper.toJson(callbackRequest)) + .header(HEADER_AUTHORIZATION, DUMMY_TOKEN) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + + verify(caseFlagsService, never()).clearRespondentRepresentativeFlags(any(CaseData.class), any()); + verify(caseFlagsService).setupCaseFlags(any(CaseData.class)); + } + + @ParameterizedTest + @NullSource + @ValueSource(strings = "representative@example.com") + @SneakyThrows + void amendRespondentRepresentativeClearsSharedFlagsAfterFinalNameChange(String email) { + CaseData previousCaseData = new CaseData(); + previousCaseData.setRepCollection(List.of( + respondentRepresentative(ID_REPRESENTATIVE_1, "Representative Y", email, ID_RESPONDENT_1), + respondentRepresentative(ID_REPRESENTATIVE_2, "Representative X", email, ID_RESPONDENT_2) + )); + CaseData currentCaseData = new CaseData(); + currentCaseData.setRepCollection(List.of( + respondentRepresentative(ID_REPRESENTATIVE_1, "Representative Y", email, ID_RESPONDENT_1), + respondentRepresentative(ID_REPRESENTATIVE_2, "Representative Y", email, ID_RESPONDENT_2) + )); + CallbackRequest callbackRequest = respondentRepresentativeCallback(previousCaseData, currentCaseData); + when(featureToggleService.isCaseFlagsV2Enabled(ENGLANDWALES_CASE_TYPE_ID)).thenReturn(true); + + mockMvc.perform(post(URL_AMEND_RESPONDENT_REPRESENTATIVE_ABOUT_TO_SUBMIT) + .content(jsonMapper.toJson(callbackRequest)) + .header(HEADER_AUTHORIZATION, DUMMY_TOKEN) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + + verify(caseFlagsService).clearRespondentRepresentativeFlags(any(CaseData.class), eq(List.of(1))); + verify(caseFlagsService).setupCaseFlags(any(CaseData.class)); + } + @Test @SneakyThrows void amendRespondentRepresentativeAboutToSubmitClearsAndSetsUpCaseFlagsWhenOnlyEmailChanges() { @@ -702,4 +761,22 @@ private static CallbackRequest respondentRepresentativeCallback( .caseDetails(currentCaseDetails) .build(); } + + private static RepresentedTypeRItem respondentRepresentative( + String id, String name, String email, String respondentId) { + DynamicValueType respondentSelection = new DynamicValueType(); + respondentSelection.setLabel(ID_RESPONDENT_1.equals(respondentId) ? RESPONDENT_NAME_1 : RESPONDENT_NAME_2); + DynamicFixedListType respondentList = new DynamicFixedListType(); + respondentList.setValue(respondentSelection); + return RepresentedTypeRItem.builder() + .id(id) + .value(RepresentedTypeR.builder() + .nameOfRepresentative(name) + .representativeEmailAddress(email) + .respondentId(respondentId) + .respRepName(ID_RESPONDENT_1.equals(respondentId) ? RESPONDENT_NAME_1 : RESPONDENT_NAME_2) + .dynamicRespRepName(respondentList) + .build()) + .build(); + } } diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java index 23d365d3ce..252c91d426 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/CaseFlagsServiceTest.java @@ -6,6 +6,8 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; +import org.junit.jupiter.params.provider.NullSource; +import org.junit.jupiter.params.provider.ValueSource; import uk.gov.hmcts.et.common.model.ccd.CaseData; import uk.gov.hmcts.et.common.model.ccd.items.FlagDetailType; import uk.gov.hmcts.et.common.model.ccd.items.GenericTseApplicationType; @@ -531,6 +533,182 @@ void setupCaseFlags_shouldRetainSharedRepresentativeDetailsUntilFinalRepresentat ); } + @ParameterizedTest + @NullSource + @ValueSource(strings = "representative@example.com") + void setupCaseFlags_shouldPreserveRepresentativeFlagsUntilFinalNameChange(String email) { + caseData.setRespondentCollection(respondentCollection(2)); + List respondents = caseData.getRespondentCollection(); + RepresentedTypeRItem respondent1Representative = representativeItemForRespondent( + "1", "Representative X", email, respondents.get(0), "[SOLICITORA]"); + RepresentedTypeRItem respondent2Representative = representativeItemForRespondent( + "2", "Representative X", email, respondents.get(1), "[SOLICITORB]"); + caseData.setRepCollection(List.of(respondent1Representative, respondent2Representative)); + + caseFlagsService.setupCaseFlags(caseData); + AllPartyFlags allPartyFlags = allPartyFlags(caseData); + allPartyFlags.getRepresentativeFlags().setDetails( + ListTypeItem.from(activeFlag("Representative internal flag"))); + allPartyFlags.getRepresentativeExternalFlags().setDetails( + ListTypeItem.from(activeFlag("Representative external flag"))); + + respondent1Representative.getValue().setNameOfRepresentative("Representative Y"); + caseFlagsService.setupCaseFlags(caseData); + + assertAll( + () -> assertEquals("Representative Y", allPartyFlags.getRepresentativeFlags().getPartyName()), + () -> assertNull(allPartyFlags.getRepresentativeFlags().getDetails()), + () -> assertEquals("Representative Y", + allPartyFlags.getRepresentativeExternalFlags().getPartyName()), + () -> assertNull(allPartyFlags.getRepresentativeExternalFlags().getDetails()), + () -> assertEquals("Representative X", allPartyFlags.getRepresentative1Flags().getPartyName()), + () -> assertEquals("Representative internal flag", + allPartyFlags.getRepresentative1Flags().getDetails().getFirst().getValue().getName()), + () -> assertEquals("Representative external flag", + allPartyFlags.getRepresentative1ExternalFlags().getDetails().getFirst().getValue().getName()) + ); + + respondent2Representative.getValue().setNameOfRepresentative("Representative Y"); + caseFlagsService.clearRespondentRepresentativeFlags(caseData, List.of(1)); + caseFlagsService.setupCaseFlags(caseData); + + assertAll( + () -> assertEquals("Representative Y", allPartyFlags.getRepresentativeFlags().getPartyName()), + () -> assertNull(allPartyFlags.getRepresentativeFlags().getDetails()), + () -> assertEquals("Representative Y", + allPartyFlags.getRepresentativeExternalFlags().getPartyName()), + () -> assertNull(allPartyFlags.getRepresentativeExternalFlags().getDetails()), + () -> assertNull(allPartyFlags.getRepresentative1Flags()), + () -> assertNull(allPartyFlags.getRepresentative1ExternalFlags()) + ); + } + + @Test + void setupCaseFlags_shouldHandleStagedNoEmailRepresentativeNameChangeAcrossFourRespondents() { + caseData.setRespondentCollection(respondentCollection(4)); + List respondents = caseData.getRespondentCollection(); + RepresentedTypeRItem representative1 = representativeItemForRespondent( + "1", "Representative 1", null, respondents.get(0), "[SOLICITORA]"); + RepresentedTypeRItem representative2Respondent2 = representativeItemForRespondent( + "2", "Representative 2", null, respondents.get(1), "[SOLICITORB]"); + RepresentedTypeRItem representative2Respondent3 = representativeItemForRespondent( + "3", "Representative 2", null, respondents.get(2), "[SOLICITORC]"); + RepresentedTypeRItem representative3 = representativeItemForRespondent( + "4", "Representative 3", null, respondents.get(3), "[SOLICITORD]"); + caseData.setRepCollection(List.of( + representative1, representative2Respondent2, representative2Respondent3, representative3)); + + caseFlagsService.setupCaseFlags(caseData); + AllPartyFlags allPartyFlags = allPartyFlags(caseData); + allPartyFlags.getRepresentativeFlags().setDetails( + ListTypeItem.from(activeFlag("Representative 1 internal flag"))); + allPartyFlags.getRepresentativeExternalFlags().setDetails( + ListTypeItem.from(activeFlag("Representative 1 external flag"))); + allPartyFlags.getRepresentative1Flags().setDetails( + ListTypeItem.from(activeFlag("Representative 2 internal flag"))); + allPartyFlags.getRepresentative1ExternalFlags().setDetails( + ListTypeItem.from(activeFlag("Representative 2 external flag"))); + allPartyFlags.getRepresentative3Flags().setDetails( + ListTypeItem.from(activeFlag("Representative 3 internal flag"))); + allPartyFlags.getRepresentative3ExternalFlags().setDetails( + ListTypeItem.from(activeFlag("Representative 3 external flag"))); + + representative2Respondent2.getValue().setNameOfRepresentative("Representative 4"); + caseFlagsService.setupCaseFlags(caseData); + + assertAll( + () -> assertRepresentativeFlags(allPartyFlags.getRepresentativeFlags(), + "Representative 1", REPRESENTATIVE1, ACTIVE, "Representative 1 internal flag"), + () -> assertRepresentativeFlags(allPartyFlags.getRepresentativeExternalFlags(), + "Representative 1", REPRESENTATIVE1, ACTIVE, "Representative 1 external flag"), + () -> assertEquals("Representative 4", allPartyFlags.getRepresentative1Flags().getPartyName()), + () -> assertNull(allPartyFlags.getRepresentative1Flags().getDetails()), + () -> assertEquals("Representative 4", + allPartyFlags.getRepresentative1ExternalFlags().getPartyName()), + () -> assertNull(allPartyFlags.getRepresentative1ExternalFlags().getDetails()), + () -> assertRepresentativeFlags(allPartyFlags.getRepresentative2Flags(), + "Representative 2", REPRESENTATIVE3, ACTIVE, "Representative 2 internal flag"), + () -> assertRepresentativeFlags(allPartyFlags.getRepresentative2ExternalFlags(), + "Representative 2", REPRESENTATIVE3, ACTIVE, "Representative 2 external flag"), + () -> assertRepresentativeFlags(allPartyFlags.getRepresentative3Flags(), + "Representative 3", REPRESENTATIVE4, ACTIVE, "Representative 3 internal flag"), + () -> assertRepresentativeFlags(allPartyFlags.getRepresentative3ExternalFlags(), + "Representative 3", REPRESENTATIVE4, ACTIVE, "Representative 3 external flag") + ); + + representative2Respondent3.getValue().setNameOfRepresentative("Representative 4"); + caseFlagsService.clearRespondentRepresentativeFlags(caseData, List.of(2)); + caseFlagsService.setupCaseFlags(caseData); + + assertAll( + () -> assertRepresentativeFlags(allPartyFlags.getRepresentativeFlags(), + "Representative 1", REPRESENTATIVE1, ACTIVE, "Representative 1 internal flag"), + () -> assertRepresentativeFlags(allPartyFlags.getRepresentativeExternalFlags(), + "Representative 1", REPRESENTATIVE1, ACTIVE, "Representative 1 external flag"), + () -> assertEquals("Representative 4", allPartyFlags.getRepresentative1Flags().getPartyName()), + () -> assertNull(allPartyFlags.getRepresentative1Flags().getDetails()), + () -> assertEquals("Representative 4", + allPartyFlags.getRepresentative1ExternalFlags().getPartyName()), + () -> assertNull(allPartyFlags.getRepresentative1ExternalFlags().getDetails()), + () -> assertNull(allPartyFlags.getRepresentative2Flags()), + () -> assertNull(allPartyFlags.getRepresentative2ExternalFlags()), + () -> assertRepresentativeFlags(allPartyFlags.getRepresentative3Flags(), + "Representative 3", REPRESENTATIVE4, ACTIVE, "Representative 3 internal flag"), + () -> assertRepresentativeFlags(allPartyFlags.getRepresentative3ExternalFlags(), + "Representative 3", REPRESENTATIVE4, ACTIVE, "Representative 3 external flag") + ); + } + + @Test + void setupCaseFlags_shouldReplaceOnlyChangedSingleRespondentRepresentativeSections() { + caseData.setRespondentCollection(respondentCollection(3)); + List respondents = caseData.getRespondentCollection(); + RepresentedTypeRItem representative1 = representativeItemForRespondent( + "1", "Representative 1", "rep1@example.com", respondents.get(0), "[SOLICITORA]"); + RepresentedTypeRItem representative2 = representativeItemForRespondent( + "2", "Representative 2", "rep2@example.com", respondents.get(1), "[SOLICITORB]"); + RepresentedTypeRItem representative3 = representativeItemForRespondent( + "3", "Representative 3", "rep3@example.com", respondents.get(2), "[SOLICITORC]"); + caseData.setRepCollection(List.of(representative1, representative2, representative3)); + + caseFlagsService.setupCaseFlags(caseData); + AllPartyFlags allPartyFlags = allPartyFlags(caseData); + allPartyFlags.getRepresentativeFlags().setDetails( + ListTypeItem.from(activeFlag("Representative 1 internal flag"))); + allPartyFlags.getRepresentativeExternalFlags().setDetails( + ListTypeItem.from(activeFlag("Representative 1 external flag"))); + allPartyFlags.getRepresentative1Flags().setDetails( + ListTypeItem.from(activeFlag("Representative 2 internal flag"))); + allPartyFlags.getRepresentative1ExternalFlags().setDetails( + ListTypeItem.from(activeFlag("Representative 2 external flag"))); + allPartyFlags.getRepresentative2Flags().setDetails( + ListTypeItem.from(activeFlag("Representative 3 internal flag"))); + allPartyFlags.getRepresentative2ExternalFlags().setDetails( + ListTypeItem.from(activeFlag("Representative 3 external flag"))); + + representative2.getValue().setNameOfRepresentative("Representative 4"); + caseFlagsService.clearRespondentRepresentativeFlags(caseData, List.of(1)); + caseFlagsService.setupCaseFlags(caseData); + + assertAll( + () -> assertRepresentativeFlags(allPartyFlags.getRepresentativeFlags(), + "Representative 1", REPRESENTATIVE1, ACTIVE, "Representative 1 internal flag"), + () -> assertRepresentativeFlags(allPartyFlags.getRepresentativeExternalFlags(), + "Representative 1", REPRESENTATIVE1, ACTIVE, "Representative 1 external flag"), + () -> assertEquals("Representative 4", allPartyFlags.getRepresentative1Flags().getPartyName()), + () -> assertEquals(INTERNAL, allPartyFlags.getRepresentative1Flags().getVisibility()), + () -> assertNull(allPartyFlags.getRepresentative1Flags().getDetails()), + () -> assertEquals("Representative 4", + allPartyFlags.getRepresentative1ExternalFlags().getPartyName()), + () -> assertEquals(EXTERNAL, allPartyFlags.getRepresentative1ExternalFlags().getVisibility()), + () -> assertNull(allPartyFlags.getRepresentative1ExternalFlags().getDetails()), + () -> assertRepresentativeFlags(allPartyFlags.getRepresentative2Flags(), + "Representative 3", REPRESENTATIVE3, ACTIVE, "Representative 3 internal flag"), + () -> assertRepresentativeFlags(allPartyFlags.getRepresentative2ExternalFlags(), + "Representative 3", REPRESENTATIVE3, ACTIVE, "Representative 3 external flag") + ); + } + @Test void setupCaseFlags_shouldCreateSeparateRespondentRepresentativeFlagsForSameNameWithDifferentEmails() { String sharedRepresentativeName = "Shared Representative"; diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocRespondentRepresentativeServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocRespondentRepresentativeServiceTest.java index 7a83a37dbb..70ac2d9224 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocRespondentRepresentativeServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocRespondentRepresentativeServiceTest.java @@ -787,6 +787,62 @@ void revokeOldRespondentRepresentativeAccessOnlyRevokesRemovedRepresentativeAssi .containsExactlyInAnyOrder(removedPrimaryAssignment, removedAdditionalAssignment); } + @Test + @SneakyThrows + void revokeOldRespondentRepresentativeAccessOnlyRevokesRoleForChangedRepresentativeName() { + RepresentedTypeRItem representative1 = removableRepresentativeForRespondent( + "rep-item-1", RESPONDENT_ID_ONE, RESPONDENT_NAME_ONE, ROLE_SOLICITORA, + REPRESENTATIVE_ID_ONE, REPRESENTATIVE_EMAIL_1, ORGANISATION_ID_ONE); + representative1.getValue().setNameOfRepresentative(RESPONDENT_REP_NAME); + RepresentedTypeRItem representative2 = removableRepresentativeForRespondent( + "rep-item-2", RESPONDENT_ID_TWO, RESPONDENT_NAME_TWO, ROLE_SOLICITORB, + REPRESENTATIVE_ID_TWO, REPRESENTATIVE_EMAIL_2, ORGANISATION_ID_TWO); + representative2.getValue().setNameOfRepresentative(RESPONDENT_REP_NAME_TWO); + RepresentedTypeRItem representative3 = removableRepresentativeForRespondent( + "rep-item-3", RESPONDENT_ID_THREE, RESPONDENT_NAME_THREE, ROLE_SOLICITORC, + REPRESENTATIVE_ID_THREE, RESPONDENT_REPRESENTATIVE_EMAIL, ORGANISATION_ID_THREE); + representative3.getValue().setNameOfRepresentative(RESPONDENT_REP_NAME_THREE); + + RepresentedTypeRItem representative4 = removableRepresentativeForRespondent( + "rep-item-2", RESPONDENT_ID_TWO, RESPONDENT_NAME_TWO, ROLE_SOLICITORB, + REPRESENTATIVE_ID_TWO, REPRESENTATIVE_EMAIL_2, ORGANISATION_ID_TWO); + representative4.getValue().setNameOfRepresentative("Legal Four"); + CaseData previousCaseData = new CaseData(); + previousCaseData.setRepCollection(List.of(representative1, representative2, representative3)); + CaseData currentCaseData = new CaseData(); + currentCaseData.setRepCollection(List.of(representative1, representative4, representative3)); + CaseDetails previousCaseDetails = new CaseDetails(); + previousCaseDetails.setCaseId(CASE_ID_1); + previousCaseDetails.setCaseData(previousCaseData); + CaseDetails currentCaseDetails = new CaseDetails(); + currentCaseDetails.setCaseId(CASE_ID_1); + currentCaseDetails.setCaseData(currentCaseData); + CallbackRequest callbackRequest = CallbackRequest.builder() + .caseDetailsBefore(previousCaseDetails) + .caseDetails(currentCaseDetails) + .build(); + + CaseUserAssignment representative1Assignment = assignment(REPRESENTATIVE_ID_ONE, ROLE_SOLICITORA); + CaseUserAssignment representative2Assignment = assignment(REPRESENTATIVE_ID_TWO, ROLE_SOLICITORB); + CaseUserAssignment representative3Assignment = assignment(REPRESENTATIVE_ID_THREE, ROLE_SOLICITORC); + when(adminUserService.getAdminUserToken()).thenReturn(ADMIN_USER_TOKEN); + when(nocCcdService.retrieveCaseUserAssignments(ADMIN_USER_TOKEN, CASE_ID_1)) + .thenReturn(CaseUserAssignmentData.builder() + .caseUserAssignments(List.of( + representative1Assignment, representative2Assignment, representative3Assignment)) + .build()); + + List revokedRepresentatives = nocRespondentRepresentativeService + .revokeOldRespondentRepresentativeAccess(callbackRequest, USER_TOKEN, List.of(representative2)); + + assertThat(revokedRepresentatives).containsExactly(representative2); + ArgumentCaptor revokedAssignments = + ArgumentCaptor.forClass(CaseUserAssignmentData.class); + verify(ccdClient).revokeCaseAssignments(eq(USER_TOKEN), revokedAssignments.capture()); + assertThat(revokedAssignments.getValue().getCaseUserAssignments()) + .containsExactly(representative2Assignment); + } + @Test @SneakyThrows void revokeOldRespondentRepresentativeAccessRetainsRoleForAnotherRespondentRepresentedBySameUser() { @@ -1651,6 +1707,54 @@ void theAddNewRepresentatives() { RESPONDENT_EMAIL, CASE_ID_1, organisation, ROLE_SOLICITORA); } + @Test + @SneakyThrows + void addNewRepresentativesGrantsRespondentAccessWhenRepresentativeNameChanges() { + final Organisation organisation = Organisation.builder().organisationID(ORGANISATION_ID_TWO).build(); + RepresentedTypeRItem oldRepresentative = removableRepresentativeForRespondent( + "rep-item-2", RESPONDENT_ID_TWO, RESPONDENT_NAME_TWO, ROLE_SOLICITORB, + REPRESENTATIVE_ID_TWO, REPRESENTATIVE_EMAIL_2, ORGANISATION_ID_TWO); + oldRepresentative.getValue().setNameOfRepresentative(RESPONDENT_REP_NAME_TWO); + RepresentedTypeRItem newRepresentative = removableRepresentativeForRespondent( + "rep-item-2", RESPONDENT_ID_TWO, RESPONDENT_NAME_TWO, ROLE_SOLICITORB, + REPRESENTATIVE_ID_TWO, REPRESENTATIVE_EMAIL_2, ORGANISATION_ID_TWO); + newRepresentative.getValue().setNameOfRepresentative("Legal Four"); + + CaseData previousCaseData = new CaseData(); + previousCaseData.setRepCollection(List.of(oldRepresentative)); + final CaseData currentCaseData = new CaseData(); + RespondentSumTypeItem respondent1 = new RespondentSumTypeItem(); + respondent1.setId(RESPONDENT_ID_ONE); + respondent1.setValue(RespondentSumType.builder().respondentName(RESPONDENT_NAME_ONE).build()); + RespondentSumTypeItem respondent2 = new RespondentSumTypeItem(); + respondent2.setId(RESPONDENT_ID_TWO); + respondent2.setValue(RespondentSumType.builder().respondentName(RESPONDENT_NAME_TWO).build()); + currentCaseData.setRespondentCollection(List.of(respondent1, respondent2)); + currentCaseData.setRepCollection(List.of(newRepresentative)); + CaseDetails previousCaseDetails = new CaseDetails(); + previousCaseDetails.setCaseData(previousCaseData); + CaseDetails currentCaseDetails = new CaseDetails(); + currentCaseDetails.setCaseId(CASE_ID_1); + currentCaseDetails.setCaseData(currentCaseData); + final CallbackRequest callbackRequest = CallbackRequest.builder() + .caseDetailsBefore(previousCaseDetails) + .caseDetails(currentCaseDetails) + .build(); + + when(adminUserService.getAdminUserToken()).thenReturn(ADMIN_USER_TOKEN); + when(nocCcdService.retrieveCaseUserAssignments(ADMIN_USER_TOKEN, CASE_ID_1)) + .thenReturn(new CaseUserAssignmentData()); + when(nocService.grantRepresentativeAccess( + ADMIN_USER_TOKEN, REPRESENTATIVE_EMAIL_2, CASE_ID_1, organisation, ROLE_SOLICITORB)) + .thenReturn(REPRESENTATIVE_ID_TWO); + + nocRespondentRepresentativeService.addNewRepresentatives(callbackRequest); + + verify(nocService).grantRepresentativeAccess( + ADMIN_USER_TOKEN, REPRESENTATIVE_EMAIL_2, CASE_ID_1, organisation, ROLE_SOLICITORB); + assertThat(currentCaseData.getRepCollectionToAdd()).containsExactly(newRepresentative); + } + @Test void theFindRepresentativesToRemove() { List oldRepresentatives = new ArrayList<>(); @@ -1730,6 +1834,22 @@ void theFindRepresentativesToRemove() { assertThat(newRepresentatives).hasSize(NumberUtils.INTEGER_ONE); } + @Test + void findRepresentativesToRemoveReturnsPreviousRepresentativeWhenNameChanges() { + RepresentedTypeRItem oldRepresentative = removableRepresentativeForRespondent( + "rep-item-2", RESPONDENT_ID_TWO, RESPONDENT_NAME_TWO, ROLE_SOLICITORB, + REPRESENTATIVE_ID_TWO, REPRESENTATIVE_EMAIL_2, ORGANISATION_ID_TWO); + oldRepresentative.getValue().setNameOfRepresentative(RESPONDENT_REP_NAME_TWO); + RepresentedTypeRItem newRepresentative = removableRepresentativeForRespondent( + "rep-item-2", RESPONDENT_ID_TWO, RESPONDENT_NAME_TWO, ROLE_SOLICITORB, + REPRESENTATIVE_ID_TWO, REPRESENTATIVE_EMAIL_2, ORGANISATION_ID_TWO); + newRepresentative.getValue().setNameOfRepresentative("Legal Four"); + + assertThat(nocRespondentRepresentativeService.findRepresentativesToRemove( + List.of(oldRepresentative), List.of(newRepresentative))) + .containsExactly(oldRepresentative); + } + @Test void theIsHmctsOrganisationUser() { // when email is blank should return false diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/utils/noc/RespondentRepresentativeUtilsTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/utils/noc/RespondentRepresentativeUtilsTest.java index c4292a183b..262a052267 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/utils/noc/RespondentRepresentativeUtilsTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/utils/noc/RespondentRepresentativeUtilsTest.java @@ -317,6 +317,24 @@ void theIsRepresentativeEmailChanged() { .isFalse(); } + @Test + void theIsRepresentativeNameChanged() { + RepresentedTypeR oldRepresentative = RepresentedTypeR.builder() + .nameOfRepresentative(REPRESENTATIVE_NAME_1) + .build(); + RepresentedTypeR newRepresentative = RepresentedTypeR.builder() + .nameOfRepresentative(REPRESENTATIVE_NAME_1) + .build(); + + assertThat(RespondentRepresentativeUtils.isRepresentativeNameChanged( + oldRepresentative, newRepresentative)).isFalse(); + + newRepresentative.setNameOfRepresentative(REPRESENTATIVE_NAME_2); + + assertThat(RespondentRepresentativeUtils.isRepresentativeNameChanged( + oldRepresentative, newRepresentative)).isTrue(); + } + @Test void theFindNewOrUpdatedRepresentatives() { List newRepresentatives = new ArrayList<>(); @@ -368,6 +386,11 @@ void theFindNewOrUpdatedRepresentatives() { oldRepresentative.getValue().setRepresentativeEmailAddress(REPRESENTATIVE_EMAIL_1); assertThat(RespondentRepresentativeUtils.findNewOrUpdatedRepresentatives(newRepresentatives, oldRepresentatives)).isEmpty(); + // when the representative name changes, the updated representative should be returned + oldRepresentative.getValue().setNameOfRepresentative(REPRESENTATIVE_NAME_1); + newRepresentative.getValue().setNameOfRepresentative(REPRESENTATIVE_NAME_2); + assertThat(RespondentRepresentativeUtils.findNewOrUpdatedRepresentatives(newRepresentatives, + oldRepresentatives)).containsExactly(newRepresentative); } @Test From 746c4d60e704d46a43dd98051f7c837066c668a6 Mon Sep 17 00:00:00 2001 From: Rajaram Date: Thu, 10 Sep 2026 17:08:59 +0100 Subject: [PATCH 052/100] Case Flags v2.1 WA changes (#3442) --- .../AuthorisationCaseEvent-WA-nonprod.json | 26 ++ ...isationCaseField-CaseFlagsCaseLinking.json | 12 + ...AuthorisationComplexType-CaseFlags-WA.json | 79 ++++ .../CaseEvent-CaseFlagsCaseLinking.json | 22 +- .../json/CaseEvent/CaseEvent-ET3.json | 5 +- .../json/CaseEvent/CaseEvent.json | 3 +- .../CaseField-CaseFlagsCaseLinking.json | 7 + .../ComplexTypes-CaseFlagsCaseLinking.json | 51 +++ .../AuthorisationCaseEvent-WA.json | 24 + ...isationCaseField-CaseFlagsCaseLinking.json | 12 + ...AuthorisationComplexType-CaseFlags-WA.json | 79 ++++ .../CaseEvent-CaseFlagsCaseLinking.json | 22 +- .../json/CaseEvent/CaseEvent-ET3.json | 5 +- .../scotland/json/CaseEvent/CaseEvent.json | 3 +- .../CaseField-CaseFlagsCaseLinking.json | 7 + .../ComplexTypes-CaseFlagsCaseLinking.json | 51 +++ .../hmcts/et/common/model/ccd/CaseData.java | 4 + .../model/ccd/types/SupportTaskState.java | 24 + .../config/SupportTaskConfiguration.java | 32 ++ .../constants/SupportTaskConstants.java | 18 + .../CaseActionsForCaseWorkerController.java | 58 ++- .../docmosis/service/PartyCaseFlagUtils.java | 79 ++++ .../docmosis/service/SupportTaskService.java | 175 +++++++ .../messagehandler/SingleCreationService.java | 15 +- src/main/resources/support-tasks.yml | 43 ++ .../config/SupportTaskConfigurationTest.java | 49 ++ ...aseActionsForCaseWorkerControllerTest.java | 121 ++++- .../service/SupportTaskServiceTest.java | 431 ++++++++++++++++++ .../SingleCreationServiceTest.java | 91 +++- 29 files changed, 1518 insertions(+), 30 deletions(-) create mode 100644 ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseEvent/AuthorisationCaseEvent-WA-nonprod.json create mode 100644 ccd-definitions/jurisdictions/england-wales/json/AuthorisationComplexType/AuthorisationComplexType-CaseFlags-WA.json create mode 100644 ccd-definitions/jurisdictions/england-wales/json/ComplexTypes/ComplexTypes-CaseFlagsCaseLinking.json create mode 100644 ccd-definitions/jurisdictions/scotland/json/AuthorisationComplexType/AuthorisationComplexType-CaseFlags-WA.json create mode 100644 ccd-definitions/jurisdictions/scotland/json/ComplexTypes/ComplexTypes-CaseFlagsCaseLinking.json create mode 100644 et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/types/SupportTaskState.java create mode 100644 src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/config/SupportTaskConfiguration.java create mode 100644 src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/constants/SupportTaskConstants.java create mode 100644 src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/PartyCaseFlagUtils.java create mode 100644 src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java create mode 100644 src/main/resources/support-tasks.yml create mode 100644 src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/config/SupportTaskConfigurationTest.java create mode 100644 src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java diff --git a/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseEvent/AuthorisationCaseEvent-WA-nonprod.json b/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseEvent/AuthorisationCaseEvent-WA-nonprod.json new file mode 100644 index 0000000000..9076676c3a --- /dev/null +++ b/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseEvent/AuthorisationCaseEvent-WA-nonprod.json @@ -0,0 +1,26 @@ +[ + { + "CaseTypeId": "ET_EnglandWales", + "CaseEventID": "createFlag", + "UserRole": "caseworker-wa-task-configuration", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseEventID": "manageFlags", + "UserRole": "caseworker-wa-task-configuration", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseEventID": "requestSupport", + "UserRole": "caseworker-wa-task-configuration", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseEventID": "manageSupport", + "UserRole": "caseworker-wa-task-configuration", + "CRUD": "R" + } +] diff --git a/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json index 354efa0409..8285374d62 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json @@ -994,5 +994,17 @@ "CaseFieldID": "respondentExternalFlags", "UserRole": "[DEFENDANT]", "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "supportTaskState", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "supportTaskState", + "UserRole": "caseworker-wa-task-configuration", + "CRUD": "R" } ] diff --git a/ccd-definitions/jurisdictions/england-wales/json/AuthorisationComplexType/AuthorisationComplexType-CaseFlags-WA.json b/ccd-definitions/jurisdictions/england-wales/json/AuthorisationComplexType/AuthorisationComplexType-CaseFlags-WA.json new file mode 100644 index 0000000000..e2a0b3b178 --- /dev/null +++ b/ccd-definitions/jurisdictions/england-wales/json/AuthorisationComplexType/AuthorisationComplexType-CaseFlags-WA.json @@ -0,0 +1,79 @@ +[ + { + "CaseTypeID": "ET_EnglandWales", + "CaseFieldID": "supportTaskState", + "ListElementCode": "adminTaskCreated", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseFieldID": "supportTaskState", + "ListElementCode": "adminTaskRequired", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseFieldID": "supportTaskState", + "ListElementCode": "legalOfficerTaskCreated", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseFieldID": "supportTaskState", + "ListElementCode": "legalOfficerTaskRequired", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseFieldID": "supportTaskState", + "ListElementCode": "judgeTaskCreated", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseFieldID": "supportTaskState", + "ListElementCode": "judgeTaskRequired", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseFieldID": "supportTaskState", + "ListElementCode": "adminTaskRequired", + "UserRole": "caseworker-wa-task-configuration", + "CRUD": "R" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseFieldID": "supportTaskState", + "ListElementCode": "legalOfficerTaskRequired", + "UserRole": "caseworker-wa-task-configuration", + "CRUD": "R" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseFieldID": "supportTaskState", + "ListElementCode": "judgeTaskRequired", + "UserRole": "caseworker-wa-task-configuration", + "CRUD": "R" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseFieldID": "supportTaskState", + "ListElementCode": "arrangeSupportTaskName", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseFieldID": "supportTaskState", + "ListElementCode": "arrangeSupportTaskName", + "UserRole": "caseworker-wa-task-configuration", + "CRUD": "R" + } +] diff --git a/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json index 73efde5a32..26d59d29d6 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json @@ -11,8 +11,9 @@ "ShowSummary": "Y", "EventEnablingCondition": "", "CallBackURLAboutToStartEvent": "", - "CallBackURLAboutToSubmitEvent": "", - "CallBackURLSubmittedEvent": "" + "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/supportTasks/aboutToSubmit", + "CallBackURLSubmittedEvent": "", + "Publish": "Y" }, { "CaseTypeID": "ET_EnglandWales", @@ -26,8 +27,9 @@ "ShowSummary": "Y", "EventEnablingCondition": "", "CallBackURLAboutToStartEvent": "", - "CallBackURLAboutToSubmitEvent": "", - "CallBackURLSubmittedEvent": "" + "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/supportTasks/aboutToSubmit", + "CallBackURLSubmittedEvent": "", + "Publish": "Y" }, { "CaseTypeID": "ET_EnglandWales", @@ -41,8 +43,9 @@ "ShowSummary": "Y", "EventEnablingCondition": "", "CallBackURLAboutToStartEvent": "", - "CallBackURLAboutToSubmitEvent": "", - "CallBackURLSubmittedEvent": "" + "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/supportTasks/aboutToSubmit", + "CallBackURLSubmittedEvent": "", + "Publish": "Y" }, { "CaseTypeID": "ET_EnglandWales", @@ -56,8 +59,9 @@ "ShowSummary": "Y", "EventEnablingCondition": "", "CallBackURLAboutToStartEvent": "", - "CallBackURLAboutToSubmitEvent": "", - "CallBackURLSubmittedEvent": "" + "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/supportTasks/aboutToSubmit", + "CallBackURLSubmittedEvent": "", + "Publish": "Y" }, { "CaseTypeID": "ET_EnglandWales", @@ -132,4 +136,4 @@ "CallBackURLAboutToSubmitEvent": "", "CallBackURLSubmittedEvent": "" } -] \ No newline at end of file +] diff --git a/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent-ET3.json b/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent-ET3.json index f55864140b..9d9d454fda 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent-ET3.json +++ b/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent-ET3.json @@ -6,6 +6,7 @@ "Description": "Submit ET3 Form", "PreConditionState(s)": "Accepted", "PostConditionState": "Accepted", + "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/supportTasks/aboutToSubmit", "SecurityClassification": "Public", "ShowEventNotes": "N", "ShowSummary": "N", @@ -18,8 +19,10 @@ "Description": "Update ET3 Form", "PreConditionState(s)": "Accepted", "PostConditionState": "Accepted", + "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/supportTasks/aboutToSubmit", "SecurityClassification": "Public", "ShowEventNotes": "N", - "ShowSummary": "N" + "ShowSummary": "N", + "Publish": "Y" } ] diff --git a/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent.json b/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent.json index 162a018a9c..871aa1cc2d 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent.json +++ b/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent.json @@ -132,7 +132,8 @@ "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/postDefaultValues", "SecurityClassification": "Public", "ShowEventNotes": "N", - "ShowSummary": "N" + "ShowSummary": "N", + "Publish": "Y" }, { "CaseTypeID": "ET_EnglandWales", diff --git a/ccd-definitions/jurisdictions/england-wales/json/CaseField/CaseField-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/england-wales/json/CaseField/CaseField-CaseFlagsCaseLinking.json index 58c6240020..b2de1ec693 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/CaseField/CaseField-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/england-wales/json/CaseField/CaseField-CaseFlagsCaseLinking.json @@ -328,6 +328,13 @@ "FieldType": "Flags", "SecurityClassification": "Public" }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "supportTaskState", + "Label": "Support task state", + "FieldType": "SupportTaskState", + "SecurityClassification": "Public" + }, { "LiveFrom": "03/11/2022", "CaseTypeID": "ET_EnglandWales", diff --git a/ccd-definitions/jurisdictions/england-wales/json/ComplexTypes/ComplexTypes-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/england-wales/json/ComplexTypes/ComplexTypes-CaseFlagsCaseLinking.json new file mode 100644 index 0000000000..d1ca30e961 --- /dev/null +++ b/ccd-definitions/jurisdictions/england-wales/json/ComplexTypes/ComplexTypes-CaseFlagsCaseLinking.json @@ -0,0 +1,51 @@ +[ + { + "ID": "SupportTaskState", + "ListElementCode": "adminTaskCreated", + "FieldType": "YesOrNo", + "ElementLabel": "Admin task created", + "SecurityClassification": "Public" + }, + { + "ID": "SupportTaskState", + "ListElementCode": "adminTaskRequired", + "FieldType": "YesOrNo", + "ElementLabel": "Admin task required", + "SecurityClassification": "Public" + }, + { + "ID": "SupportTaskState", + "ListElementCode": "legalOfficerTaskCreated", + "FieldType": "YesOrNo", + "ElementLabel": "Legal Officer task created", + "SecurityClassification": "Public" + }, + { + "ID": "SupportTaskState", + "ListElementCode": "legalOfficerTaskRequired", + "FieldType": "YesOrNo", + "ElementLabel": "Legal Officer task required", + "SecurityClassification": "Public" + }, + { + "ID": "SupportTaskState", + "ListElementCode": "judgeTaskCreated", + "FieldType": "YesOrNo", + "ElementLabel": "Judge task created", + "SecurityClassification": "Public" + }, + { + "ID": "SupportTaskState", + "ListElementCode": "judgeTaskRequired", + "FieldType": "YesOrNo", + "ElementLabel": "Judge task required", + "SecurityClassification": "Public" + }, + { + "ID": "SupportTaskState", + "ListElementCode": "arrangeSupportTaskName", + "FieldType": "Text", + "ElementLabel": "Arrange support task name", + "SecurityClassification": "Public" + } +] diff --git a/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseEvent/AuthorisationCaseEvent-WA.json b/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseEvent/AuthorisationCaseEvent-WA.json index c1f1914ee8..10a151d2d9 100644 --- a/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseEvent/AuthorisationCaseEvent-WA.json +++ b/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseEvent/AuthorisationCaseEvent-WA.json @@ -173,5 +173,29 @@ "CaseEventID": "sendNotification", "UserRole": "caseworker-wa-task-configuration", "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseEventID": "createFlag", + "UserRole": "caseworker-wa-task-configuration", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseEventID": "manageFlags", + "UserRole": "caseworker-wa-task-configuration", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseEventID": "requestSupport", + "UserRole": "caseworker-wa-task-configuration", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseEventID": "manageSupport", + "UserRole": "caseworker-wa-task-configuration", + "CRUD": "R" } ] diff --git a/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json index c9edd821a5..81c8570aaf 100644 --- a/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json @@ -988,5 +988,17 @@ "CaseFieldID": "claimantExternalFlags", "UserRole": "[CREATOR]", "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "supportTaskState", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "supportTaskState", + "UserRole": "caseworker-wa-task-configuration", + "CRUD": "R" } ] diff --git a/ccd-definitions/jurisdictions/scotland/json/AuthorisationComplexType/AuthorisationComplexType-CaseFlags-WA.json b/ccd-definitions/jurisdictions/scotland/json/AuthorisationComplexType/AuthorisationComplexType-CaseFlags-WA.json new file mode 100644 index 0000000000..01ccf71348 --- /dev/null +++ b/ccd-definitions/jurisdictions/scotland/json/AuthorisationComplexType/AuthorisationComplexType-CaseFlags-WA.json @@ -0,0 +1,79 @@ +[ + { + "CaseTypeID": "ET_Scotland", + "CaseFieldID": "supportTaskState", + "ListElementCode": "adminTaskCreated", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseFieldID": "supportTaskState", + "ListElementCode": "adminTaskRequired", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseFieldID": "supportTaskState", + "ListElementCode": "legalOfficerTaskCreated", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseFieldID": "supportTaskState", + "ListElementCode": "legalOfficerTaskRequired", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseFieldID": "supportTaskState", + "ListElementCode": "judgeTaskCreated", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseFieldID": "supportTaskState", + "ListElementCode": "judgeTaskRequired", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseFieldID": "supportTaskState", + "ListElementCode": "adminTaskRequired", + "UserRole": "caseworker-wa-task-configuration", + "CRUD": "R" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseFieldID": "supportTaskState", + "ListElementCode": "legalOfficerTaskRequired", + "UserRole": "caseworker-wa-task-configuration", + "CRUD": "R" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseFieldID": "supportTaskState", + "ListElementCode": "judgeTaskRequired", + "UserRole": "caseworker-wa-task-configuration", + "CRUD": "R" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseFieldID": "supportTaskState", + "ListElementCode": "arrangeSupportTaskName", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseFieldID": "supportTaskState", + "ListElementCode": "arrangeSupportTaskName", + "UserRole": "caseworker-wa-task-configuration", + "CRUD": "R" + } +] diff --git a/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json index 5e7c0aada9..2cb223fb9c 100644 --- a/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json @@ -11,8 +11,9 @@ "ShowSummary": "Y", "EventEnablingCondition": "", "CallBackURLAboutToStartEvent": "", - "CallBackURLAboutToSubmitEvent": "", - "CallBackURLSubmittedEvent": "" + "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/supportTasks/aboutToSubmit", + "CallBackURLSubmittedEvent": "", + "Publish": "Y" }, { "CaseTypeID": "ET_Scotland", @@ -26,8 +27,9 @@ "ShowSummary": "Y", "EventEnablingCondition": "", "CallBackURLAboutToStartEvent": "", - "CallBackURLAboutToSubmitEvent": "", - "CallBackURLSubmittedEvent": "" + "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/supportTasks/aboutToSubmit", + "CallBackURLSubmittedEvent": "", + "Publish": "Y" }, { "CaseTypeID": "ET_Scotland", @@ -41,8 +43,9 @@ "ShowSummary": "Y", "EventEnablingCondition": "", "CallBackURLAboutToStartEvent": "", - "CallBackURLAboutToSubmitEvent": "", - "CallBackURLSubmittedEvent": "" + "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/supportTasks/aboutToSubmit", + "CallBackURLSubmittedEvent": "", + "Publish": "Y" }, { "CaseTypeID": "ET_Scotland", @@ -56,8 +59,9 @@ "ShowSummary": "Y", "EventEnablingCondition": "", "CallBackURLAboutToStartEvent": "", - "CallBackURLAboutToSubmitEvent": "", - "CallBackURLSubmittedEvent": "" + "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/supportTasks/aboutToSubmit", + "CallBackURLSubmittedEvent": "", + "Publish": "Y" }, { "CaseTypeID": "ET_Scotland", @@ -132,4 +136,4 @@ "ShowEventNotes": "N", "ShowSummary": "N" } -] \ No newline at end of file +] diff --git a/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent-ET3.json b/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent-ET3.json index 6796a70483..b2e7db6762 100644 --- a/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent-ET3.json +++ b/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent-ET3.json @@ -6,6 +6,7 @@ "Description": "Submit ET3 Form", "PreConditionState(s)": "Accepted", "PostConditionState": "Accepted", + "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/supportTasks/aboutToSubmit", "SecurityClassification": "Public", "ShowEventNotes": "N", "ShowSummary": "N", @@ -18,8 +19,10 @@ "Description": "Update ET3 Form", "PreConditionState(s)": "Accepted", "PostConditionState": "Accepted", + "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/supportTasks/aboutToSubmit", "SecurityClassification": "Public", "ShowEventNotes": "N", - "ShowSummary": "N" + "ShowSummary": "N", + "Publish": "Y" } ] diff --git a/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent.json b/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent.json index b1cb6e7f92..01537b66bc 100644 --- a/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent.json +++ b/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent.json @@ -100,7 +100,8 @@ "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/postDefaultValues", "SecurityClassification": "Public", "ShowEventNotes": "N", - "ShowSummary": "N" + "ShowSummary": "N", + "Publish": "Y" }, { "CaseTypeID": "ET_Scotland", diff --git a/ccd-definitions/jurisdictions/scotland/json/CaseField/CaseField-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/scotland/json/CaseField/CaseField-CaseFlagsCaseLinking.json index dfb21555fb..2c82538696 100644 --- a/ccd-definitions/jurisdictions/scotland/json/CaseField/CaseField-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/scotland/json/CaseField/CaseField-CaseFlagsCaseLinking.json @@ -329,6 +329,13 @@ "FieldType": "Flags", "SecurityClassification": "Public" }, + { + "CaseTypeID": "ET_Scotland", + "ID": "supportTaskState", + "Label": "Support task state", + "FieldType": "SupportTaskState", + "SecurityClassification": "Public" + }, { "LiveFrom": "10/02/2023", "CaseTypeID": "ET_Scotland", diff --git a/ccd-definitions/jurisdictions/scotland/json/ComplexTypes/ComplexTypes-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/scotland/json/ComplexTypes/ComplexTypes-CaseFlagsCaseLinking.json new file mode 100644 index 0000000000..d1ca30e961 --- /dev/null +++ b/ccd-definitions/jurisdictions/scotland/json/ComplexTypes/ComplexTypes-CaseFlagsCaseLinking.json @@ -0,0 +1,51 @@ +[ + { + "ID": "SupportTaskState", + "ListElementCode": "adminTaskCreated", + "FieldType": "YesOrNo", + "ElementLabel": "Admin task created", + "SecurityClassification": "Public" + }, + { + "ID": "SupportTaskState", + "ListElementCode": "adminTaskRequired", + "FieldType": "YesOrNo", + "ElementLabel": "Admin task required", + "SecurityClassification": "Public" + }, + { + "ID": "SupportTaskState", + "ListElementCode": "legalOfficerTaskCreated", + "FieldType": "YesOrNo", + "ElementLabel": "Legal Officer task created", + "SecurityClassification": "Public" + }, + { + "ID": "SupportTaskState", + "ListElementCode": "legalOfficerTaskRequired", + "FieldType": "YesOrNo", + "ElementLabel": "Legal Officer task required", + "SecurityClassification": "Public" + }, + { + "ID": "SupportTaskState", + "ListElementCode": "judgeTaskCreated", + "FieldType": "YesOrNo", + "ElementLabel": "Judge task created", + "SecurityClassification": "Public" + }, + { + "ID": "SupportTaskState", + "ListElementCode": "judgeTaskRequired", + "FieldType": "YesOrNo", + "ElementLabel": "Judge task required", + "SecurityClassification": "Public" + }, + { + "ID": "SupportTaskState", + "ListElementCode": "arrangeSupportTaskName", + "FieldType": "Text", + "ElementLabel": "Arrange support task name", + "SecurityClassification": "Public" + } +] diff --git a/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/CaseData.java b/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/CaseData.java index c33156f65e..d1be96c811 100644 --- a/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/CaseData.java +++ b/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/CaseData.java @@ -45,6 +45,7 @@ import uk.gov.hmcts.et.common.model.ccd.types.RepresentedTypeR; import uk.gov.hmcts.et.common.model.ccd.types.RespondentTse; import uk.gov.hmcts.et.common.model.ccd.types.RestrictedReportingType; +import uk.gov.hmcts.et.common.model.ccd.types.SupportTaskState; import uk.gov.hmcts.et.common.model.ccd.types.SendNotificationTypeItem; import uk.gov.hmcts.et.common.model.ccd.types.UploadHearingDocumentType; import uk.gov.hmcts.et.common.model.ccd.types.UploadedDocumentType; @@ -1591,6 +1592,9 @@ public class CaseData extends Et1CaseData { @JsonUnwrapped private AllPartyFlags allPartyFlags; + @JsonProperty("supportTaskState") + private SupportTaskState supportTaskState; + //et-hearings-api @JsonProperty("autoListFlag") private String autoListFlag; diff --git a/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/types/SupportTaskState.java b/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/types/SupportTaskState.java new file mode 100644 index 0000000000..231f37a560 --- /dev/null +++ b/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/types/SupportTaskState.java @@ -0,0 +1,24 @@ +package uk.gov.hmcts.et.common.model.ccd.types; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.extern.jackson.Jacksonized; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +@Jacksonized +@JsonIgnoreProperties(ignoreUnknown = true) +public class SupportTaskState { + private String adminTaskCreated; + private String adminTaskRequired; + private String legalOfficerTaskCreated; + private String legalOfficerTaskRequired; + private String judgeTaskCreated; + private String judgeTaskRequired; + private String arrangeSupportTaskName; +} diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/config/SupportTaskConfiguration.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/config/SupportTaskConfiguration.java new file mode 100644 index 0000000000..ed4d843bc9 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/config/SupportTaskConfiguration.java @@ -0,0 +1,32 @@ +package uk.gov.hmcts.ethos.replacement.docmosis.config; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; + +import java.util.Map; +import java.util.Set; + +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.CONFIGURATION_PREFIX; + +@Configuration +@ConfigurationProperties(CONFIGURATION_PREFIX) +@PropertySource(value = "classpath:support-tasks.yml", factory = YamlPropertySourceFactory.class) +@Data +public class SupportTaskConfiguration { + private Review review = new Review(); + private Arrange arrange = new Arrange(); + + @Data + public static class Review { + private Set adminFlagCodes = Set.of(); + private Set legalOfficerFlagCodes = Set.of(); + private Set judgeFlagCodes = Set.of(); + } + + @Data + public static class Arrange { + private Map flagTitles = Map.of(); + } +} diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/constants/SupportTaskConstants.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/constants/SupportTaskConstants.java new file mode 100644 index 0000000000..4a9ce2b0ca --- /dev/null +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/constants/SupportTaskConstants.java @@ -0,0 +1,18 @@ +package uk.gov.hmcts.ethos.replacement.docmosis.constants; + +public final class SupportTaskConstants { + public static final String CONFIGURATION_PREFIX = "support-tasks"; + public static final String EVENT_CREATE_FLAG = "createFlag"; + public static final String EVENT_MANAGE_FLAGS = "manageFlags"; + public static final String EVENT_SUBMIT_CASE_DRAFT = "SUBMIT_CASE_DRAFT"; + public static final String EVENT_UPDATE_CASE_SUBMITTED = "UPDATE_CASE_SUBMITTED"; + public static final String EVENT_SUBMIT_ET3_FORM = "SUBMIT_ET3_FORM"; + public static final String EVENT_UPDATE_ET3_FORM = "UPDATE_ET3_FORM"; + public static final String EVENT_REQUEST_SUPPORT = "requestSupport"; + public static final String EVENT_MANAGE_SUPPORT = "manageSupport"; + public static final String FLAG_STATUS_ACTIVE = "Active"; + public static final String FLAG_STATUS_REQUESTED = "Requested"; + + private SupportTaskConstants() { + } +} diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java index 51c5d26fe6..a7cc8cb499 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java @@ -50,6 +50,7 @@ import uk.gov.hmcts.ethos.replacement.docmosis.service.ScotlandFileLocationSelectionService; import uk.gov.hmcts.ethos.replacement.docmosis.service.SingleCaseMultipleMidEventValidationService; import uk.gov.hmcts.ethos.replacement.docmosis.service.SingleReferenceService; +import uk.gov.hmcts.ethos.replacement.docmosis.service.SupportTaskService; import uk.gov.hmcts.ethos.replacement.docmosis.service.noc.NocRespondentRepresentativeService; import uk.gov.hmcts.ethos.replacement.docmosis.utils.LoggingUtils; import uk.gov.hmcts.ethos.replacement.docmosis.utils.noc.NocUtils; @@ -63,6 +64,14 @@ import static org.apache.commons.lang3.StringUtils.defaultIfEmpty; import static org.springframework.http.HttpHeaders.AUTHORIZATION; import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.EVENT_CREATE_FLAG; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.EVENT_MANAGE_FLAGS; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.EVENT_MANAGE_SUPPORT; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.EVENT_REQUEST_SUPPORT; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.EVENT_SUBMIT_CASE_DRAFT; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.EVENT_SUBMIT_ET3_FORM; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.EVENT_UPDATE_CASE_SUBMITTED; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.EVENT_UPDATE_ET3_FORM; import static uk.gov.hmcts.ethos.replacement.docmosis.helpers.CallbackRespHelper.getCallbackRespEntity; import static uk.gov.hmcts.ethos.replacement.docmosis.helpers.CallbackRespHelper.getCallbackRespEntityErrors; import static uk.gov.hmcts.ethos.replacement.docmosis.helpers.CallbackRespHelper.getCallbackRespEntityNoErrors; @@ -79,11 +88,17 @@ public class CaseActionsForCaseWorkerController { private static final String TWO_HUNDRED = "200"; private static final String FOUR_HUNDRED = "400"; private static final String FIVE_HUNDRED = "500"; - private static final String SUBMIT_CASE_DRAFT = "SUBMIT_CASE_DRAFT"; public static final String ACCESSED_SUCCESSFULLY = "Accessed successfully"; public static final String BAD_REQUEST = "Bad Request"; public static final String INTERNAL_SERVER_ERROR = "Internal Server Error"; - private static final List SUBMISSION_EVENTS = List.of(SUBMIT_CASE_DRAFT, "initiateCase", "submitEt1Draft"); + private static final List SUBMISSION_EVENTS = + List.of(EVENT_SUBMIT_CASE_DRAFT, "initiateCase", "submitEt1Draft"); + private static final List REVIEW_SUPPORT_TASK_EVENTS = + List.of(EVENT_SUBMIT_CASE_DRAFT, EVENT_UPDATE_CASE_SUBMITTED); + private static final List RESPONDENT_REVIEW_SUPPORT_TASK_EVENTS = + List.of(EVENT_SUBMIT_ET3_FORM, EVENT_UPDATE_ET3_FORM); + private static final List NEW_FLAG_REVIEW_SUPPORT_TASK_EVENTS = + List.of(EVENT_REQUEST_SUPPORT, EVENT_CREATE_FLAG); public static final String CREATE_ECM_CASE = "createEcmCase"; private final CaseCloseValidator caseCloseValidator; @@ -104,6 +119,7 @@ public class CaseActionsForCaseWorkerController { private final NocRespondentRepresentativeService nocRespondentRepresentativeService; private final FeatureToggleService featureToggleService; private final CaseFlagsService caseFlagsService; + private final SupportTaskService supportTaskService; private final CaseManagementLocationService caseManagementLocationService; private final Et1SubmissionService et1SubmissionService; private final NocRespondentHelper nocRespondentHelper; @@ -174,6 +190,11 @@ public ResponseEntity postDefaultValues( setupCaseFlags(caseDetails.getCaseTypeId(), caseData); } + if (featureToggleService.isCaseFlagsV2Enabled(caseDetails.getCaseTypeId()) + && REVIEW_SUPPORT_TASK_EVENTS.contains(ccdRequest.getEventId())) { + supportTaskService.prepareReviewSupportTasks(caseData); + } + boolean hmcToggle = featureToggleService.isHmcEnabled(); log.info("HMC feature flag is {}", hmcToggle); if (hmcToggle) { @@ -181,7 +202,8 @@ public ResponseEntity postDefaultValues( caseManagementLocationService.setCaseManagementLocationCode(caseData); } - if (featureToggleService.citizenEt1Generation() && SUBMIT_CASE_DRAFT.equals(ccdRequest.getEventId())) { + if (featureToggleService.citizenEt1Generation() + && EVENT_SUBMIT_CASE_DRAFT.equals(ccdRequest.getEventId())) { caseDetails.setCaseData(caseData); et1SubmissionService.createAndUploadEt1Docs(caseDetails, userToken); et1SubmissionService.vexationCheck(caseDetails, userToken); @@ -193,6 +215,36 @@ public ResponseEntity postDefaultValues( return getCallbackRespEntityErrors(errors, caseData); } + @PostMapping(value = {"/supportTasks/aboutToSubmit", "/reviewSupportTasks/aboutToSubmit"}, + consumes = APPLICATION_JSON_VALUE) + @Operation(summary = "Prepare Review Support and Arrange Support tasks for eligible Case Flags.") + public ResponseEntity prepareSupportTasks( + @RequestBody CallbackRequest callbackRequest) { + CaseDetails caseDetails = callbackRequest.getCaseDetails(); + CaseData caseData = caseDetails.getCaseData(); + + if (featureToggleService.isCaseFlagsV2Enabled(caseDetails.getCaseTypeId())) { + CaseData caseDataBefore = callbackRequest.getCaseDetailsBefore() == null + ? null + : callbackRequest.getCaseDetailsBefore().getCaseData(); + if (RESPONDENT_REVIEW_SUPPORT_TASK_EVENTS.contains(callbackRequest.getEventId())) { + supportTaskService.prepareRespondentReviewSupportTasks(caseData); + } else if (NEW_FLAG_REVIEW_SUPPORT_TASK_EVENTS.contains(callbackRequest.getEventId())) { + supportTaskService.prepareNewFlagReviewSupportTasks(caseData, caseDataBefore); + } else if (EVENT_MANAGE_FLAGS.equals(callbackRequest.getEventId()) + || EVENT_MANAGE_SUPPORT.equals(callbackRequest.getEventId())) { + supportTaskService.prepareManagedReviewSupportTasks(caseData); + } + + if (EVENT_CREATE_FLAG.equals(callbackRequest.getEventId()) + || EVENT_MANAGE_FLAGS.equals(callbackRequest.getEventId())) { + supportTaskService.prepareArrangeSupportTask(caseData, caseDataBefore); + } + } + + return getCallbackRespEntityNoErrors(caseData); + } + private List getValidationDate(String eventId, CaseDetails caseDetails) { if (!CREATE_ECM_CASE.equals(eventId)) { return eventValidationService.validateReceiptDate(caseDetails); diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/PartyCaseFlagUtils.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/PartyCaseFlagUtils.java new file mode 100644 index 0000000000..44f9b1272c --- /dev/null +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/PartyCaseFlagUtils.java @@ -0,0 +1,79 @@ +package uk.gov.hmcts.ethos.replacement.docmosis.service; + +import uk.gov.hmcts.et.common.model.ccd.items.FlagDetailType; +import uk.gov.hmcts.et.common.model.ccd.items.GenericTypeItem; +import uk.gov.hmcts.et.common.model.ccd.types.AllPartyFlags; +import uk.gov.hmcts.et.common.model.ccd.types.CaseFlagsType; + +import java.util.stream.Stream; + +final class PartyCaseFlagUtils { + private PartyCaseFlagUtils() { + } + + static Stream respondentFlagDetails(AllPartyFlags flags) { + if (flags == null) { + return Stream.empty(); + } + return flagDetails( + flags.getRespondentFlags(), flags.getRespondentExternalFlags(), + flags.getRespondent1Flags(), flags.getRespondent1ExternalFlags(), + flags.getRespondent2Flags(), flags.getRespondent2ExternalFlags(), + flags.getRespondent3Flags(), flags.getRespondent3ExternalFlags(), + flags.getRespondent4Flags(), flags.getRespondent4ExternalFlags(), + flags.getRespondent5Flags(), flags.getRespondent5ExternalFlags(), + flags.getRespondent6Flags(), flags.getRespondent6ExternalFlags(), + flags.getRespondent7Flags(), flags.getRespondent7ExternalFlags(), + flags.getRespondent8Flags(), flags.getRespondent8ExternalFlags(), + flags.getRespondent9Flags(), flags.getRespondent9ExternalFlags()); + } + + static Stream> allFlagItems(AllPartyFlags flags) { + if (flags == null) { + return Stream.empty(); + } + return Stream.concat( + flagItems(flags.getClaimantFlags(), flags.getClaimantExternalFlags()), + Stream.concat(respondentFlagItems(flags), representativeFlagItems(flags))); + } + + static Stream flagDetails(CaseFlagsType... flags) { + return flagItems(flags).map(GenericTypeItem::getValue); + } + + private static Stream> respondentFlagItems(AllPartyFlags flags) { + return flagItems( + flags.getRespondentFlags(), flags.getRespondentExternalFlags(), + flags.getRespondent1Flags(), flags.getRespondent1ExternalFlags(), + flags.getRespondent2Flags(), flags.getRespondent2ExternalFlags(), + flags.getRespondent3Flags(), flags.getRespondent3ExternalFlags(), + flags.getRespondent4Flags(), flags.getRespondent4ExternalFlags(), + flags.getRespondent5Flags(), flags.getRespondent5ExternalFlags(), + flags.getRespondent6Flags(), flags.getRespondent6ExternalFlags(), + flags.getRespondent7Flags(), flags.getRespondent7ExternalFlags(), + flags.getRespondent8Flags(), flags.getRespondent8ExternalFlags(), + flags.getRespondent9Flags(), flags.getRespondent9ExternalFlags()); + } + + private static Stream> representativeFlagItems(AllPartyFlags flags) { + return flagItems( + flags.getClaimantRepresentativeFlags(), flags.getClaimantRepresentativeExternalFlags(), + flags.getRepresentativeFlags(), flags.getRepresentativeExternalFlags(), + flags.getRepresentative1Flags(), flags.getRepresentative1ExternalFlags(), + flags.getRepresentative2Flags(), flags.getRepresentative2ExternalFlags(), + flags.getRepresentative3Flags(), flags.getRepresentative3ExternalFlags(), + flags.getRepresentative4Flags(), flags.getRepresentative4ExternalFlags(), + flags.getRepresentative5Flags(), flags.getRepresentative5ExternalFlags(), + flags.getRepresentative6Flags(), flags.getRepresentative6ExternalFlags(), + flags.getRepresentative7Flags(), flags.getRepresentative7ExternalFlags(), + flags.getRepresentative8Flags(), flags.getRepresentative8ExternalFlags(), + flags.getRepresentative9Flags(), flags.getRepresentative9ExternalFlags()); + } + + private static Stream> flagItems(CaseFlagsType... flags) { + return Stream.of(flags) + .filter(flag -> flag != null && flag.getDetails() != null) + .flatMap(flag -> flag.getDetails().stream()) + .filter(item -> item != null && item.getValue() != null); + } +} diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java new file mode 100644 index 0000000000..c6943a5241 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java @@ -0,0 +1,175 @@ +package uk.gov.hmcts.ethos.replacement.docmosis.service; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import uk.gov.hmcts.et.common.model.ccd.CaseData; +import uk.gov.hmcts.et.common.model.ccd.items.FlagDetailType; +import uk.gov.hmcts.et.common.model.ccd.items.GenericTypeItem; +import uk.gov.hmcts.et.common.model.ccd.types.AllPartyFlags; +import uk.gov.hmcts.et.common.model.ccd.types.SupportTaskState; +import uk.gov.hmcts.ethos.replacement.docmosis.config.SupportTaskConfiguration; + +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.function.Consumer; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +import static uk.gov.hmcts.ecm.common.model.helper.Constants.NO; +import static uk.gov.hmcts.ecm.common.model.helper.Constants.YES; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.FLAG_STATUS_ACTIVE; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.FLAG_STATUS_REQUESTED; +import static uk.gov.hmcts.ethos.replacement.docmosis.service.PartyCaseFlagUtils.allFlagItems; +import static uk.gov.hmcts.ethos.replacement.docmosis.service.PartyCaseFlagUtils.flagDetails; +import static uk.gov.hmcts.ethos.replacement.docmosis.service.PartyCaseFlagUtils.respondentFlagDetails; + +@Service +@RequiredArgsConstructor +public class SupportTaskService { + private final SupportTaskConfiguration configuration; + + public void prepareReviewSupportTasks(CaseData caseData) { + AllPartyFlags allPartyFlags = caseData.getAllPartyFlags(); + prepareTasks(caseData, allPartyFlags == null + ? List.of() + : flagDetails(allPartyFlags.getClaimantFlags(), allPartyFlags.getClaimantExternalFlags()).toList()); + } + + public void prepareRespondentReviewSupportTasks(CaseData caseData) { + prepareTasks(caseData, respondentFlagDetails(caseData.getAllPartyFlags()).toList()); + } + + public void prepareNewFlagReviewSupportTasks(CaseData caseData, CaseData caseDataBefore) { + List> previousFlags = allFlagItems( + caseDataBefore == null ? null : caseDataBefore.getAllPartyFlags()).toList(); + Set previousFlagIds = previousFlags.stream() + .map(GenericTypeItem::getId) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + Predicate> isNewFlag = item -> item.getId() == null + ? previousFlags.stream().noneMatch(previous -> previous.getValue().equals(item.getValue())) + : !previousFlagIds.contains(item.getId()); + List newFlags = allFlagItems(caseData.getAllPartyFlags()) + .filter(isNewFlag) + .map(GenericTypeItem::getValue) + .toList(); + + prepareTasks(caseData, newFlags); + } + + public void prepareManagedReviewSupportTasks(CaseData caseData) { + SupportTaskState taskState = taskState(caseData); + List flags = allFlagItems(caseData.getAllPartyFlags()) + .map(GenericTypeItem::getValue) + .toList(); + + updateTaskState(flags, configuration.getReview().getAdminFlagCodes(), + taskState.getAdminTaskCreated(), + taskState::setAdminTaskCreated, + taskState::setAdminTaskRequired); + updateTaskState(flags, configuration.getReview().getLegalOfficerFlagCodes(), + taskState.getLegalOfficerTaskCreated(), + taskState::setLegalOfficerTaskCreated, + taskState::setLegalOfficerTaskRequired); + updateTaskState(flags, configuration.getReview().getJudgeFlagCodes(), + taskState.getJudgeTaskCreated(), + taskState::setJudgeTaskCreated, + taskState::setJudgeTaskRequired); + } + + private void prepareTasks(CaseData caseData, List flags) { + SupportTaskState taskState = taskState(caseData); + taskState.setAdminTaskRequired(null); + taskState.setLegalOfficerTaskRequired(null); + taskState.setJudgeTaskRequired(null); + + if (!YES.equals(taskState.getAdminTaskCreated()) + && hasRequestedFlag(flags, configuration.getReview().getAdminFlagCodes())) { + taskState.setAdminTaskCreated(YES); + taskState.setAdminTaskRequired(YES); + } + if (!YES.equals(taskState.getLegalOfficerTaskCreated()) + && hasRequestedFlag(flags, configuration.getReview().getLegalOfficerFlagCodes())) { + taskState.setLegalOfficerTaskCreated(YES); + taskState.setLegalOfficerTaskRequired(YES); + } + if (!YES.equals(taskState.getJudgeTaskCreated()) + && hasRequestedFlag(flags, configuration.getReview().getJudgeFlagCodes())) { + taskState.setJudgeTaskCreated(YES); + taskState.setJudgeTaskRequired(YES); + } + } + + private static SupportTaskState taskState(CaseData caseData) { + if (caseData.getSupportTaskState() == null) { + caseData.setSupportTaskState(new SupportTaskState()); + } + return caseData.getSupportTaskState(); + } + + private static boolean hasRequestedFlag(List flags, Set eligibleFlagCodes) { + return flags.stream().anyMatch(flag -> isRequested(flag) && eligibleFlagCodes.contains(flag.getFlagCode())); + } + + private static void updateTaskState(List flags, + Set eligibleFlagCodes, + String taskCreated, + Consumer taskCreatedSetter, + Consumer taskRequiredSetter) { + taskRequiredSetter.accept(null); + if (YES.equals(taskCreated) && !hasRequestedFlag(flags, eligibleFlagCodes)) { + taskCreatedSetter.accept(null); + taskRequiredSetter.accept(NO); + } + } + + private static boolean isRequested(FlagDetailType flag) { + return FLAG_STATUS_REQUESTED.equals(flag.getStatus()); + } + + public void prepareArrangeSupportTask(CaseData caseData, CaseData caseDataBefore) { + SupportTaskState taskState = taskState(caseData); + taskState.setArrangeSupportTaskName(null); + + Map flagTitles = configuration.getArrange().getFlagTitles(); + if (flagTitles.isEmpty()) { + return; + } + + List> previousFlags = allFlagItems( + caseDataBefore == null ? null : caseDataBefore.getAllPartyFlags()).toList(); + allFlagItems(caseData.getAllPartyFlags()) + .filter(item -> FLAG_STATUS_ACTIVE.equals(item.getValue().getStatus())) + .filter(item -> flagTitles.containsKey(item.getValue().getFlagCode())) + .filter(item -> wasNotPreviouslyActive(item, previousFlags)) + .findFirst() + .map(item -> flagTitles.get(item.getValue().getFlagCode())) + .ifPresent(taskState::setArrangeSupportTaskName); + } + + private static boolean wasNotPreviouslyActive(GenericTypeItem current, + List> previousFlags) { + return previousFlags.stream() + .filter(previous -> isSameFlag(current, previous)) + .noneMatch(previous -> FLAG_STATUS_ACTIVE.equals(previous.getValue().getStatus())); + } + + private static boolean isSameFlag(GenericTypeItem first, + GenericTypeItem second) { + if (first.getId() != null || second.getId() != null) { + return Objects.equals(first.getId(), second.getId()); + } + + FlagDetailType firstValue = first.getValue(); + FlagDetailType secondValue = second.getValue(); + return Objects.equals(firstValue.getFlagCode(), secondValue.getFlagCode()) + && Objects.equals(firstValue.getName(), secondValue.getName()) + && Objects.equals(firstValue.getSubTypeKey(), secondValue.getSubTypeKey()) + && Objects.equals(firstValue.getSubTypeValue(), secondValue.getSubTypeValue()) + && Objects.equals(firstValue.getDateTimeCreated(), secondValue.getDateTimeCreated()) + && Objects.equals(firstValue.getPath(), secondValue.getPath()); + } + +} diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/messagehandler/SingleCreationService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/messagehandler/SingleCreationService.java index 5909c9c6e7..ed2374d78e 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/messagehandler/SingleCreationService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/messagehandler/SingleCreationService.java @@ -11,6 +11,7 @@ import uk.gov.hmcts.et.common.model.ccd.CaseData; import uk.gov.hmcts.et.common.model.ccd.CaseDetails; import uk.gov.hmcts.et.common.model.ccd.SubmitEvent; +import uk.gov.hmcts.ethos.replacement.docmosis.service.FeatureToggleService; import java.io.IOException; import java.util.ArrayList; @@ -31,10 +32,12 @@ public class SingleCreationService { public static final String CREATE_CASE_EVENT_SUMMARY_TEMPLATE = "Case created by transfer from %s"; private final CcdClient ccdClient; + private final FeatureToggleService featureToggleService; private String ccdGatewayBaseUrl; private static class CaseTransferContext { private final String caseId; + private final String caseTypeId; private final String ccdGatewayBaseUrl; private final String positionTypeCT; private final String jurisdiction; @@ -42,9 +45,10 @@ private static class CaseTransferContext { private final String owningOfficeCT; private final String reasonForCT; - CaseTransferContext(String caseId, String ccdGatewayBaseUrl, String positionTypeCT, + CaseTransferContext(String caseId, String caseTypeId, String ccdGatewayBaseUrl, String positionTypeCT, String jurisdiction, String state, String owningOfficeCT, String reasonForCT) { this.caseId = caseId; + this.caseTypeId = caseTypeId; this.ccdGatewayBaseUrl = ccdGatewayBaseUrl; this.positionTypeCT = positionTypeCT; this.jurisdiction = jurisdiction; @@ -55,8 +59,9 @@ private static class CaseTransferContext { } @Autowired - public SingleCreationService(CcdClient ccdClient) { + public SingleCreationService(CcdClient ccdClient, FeatureToggleService featureToggleService) { this.ccdClient = ccdClient; + this.featureToggleService = featureToggleService; } public void sendCreation(SubmitEvent oldSubmitEvent, String accessToken, UpdateCaseMsg updateCaseMsg) @@ -90,6 +95,7 @@ private void updateExistingCase(SubmitEvent caseDestinationOffice, SubmitEvent o CaseTransferContext context = new CaseTransferContext( caseId, + caseTypeId, ccdGatewayBaseUrl, creationSingleDataModel.getPositionTypeCT(), jurisdiction, @@ -120,6 +126,7 @@ private void transferNewCase(SubmitEvent oldSubmitEvent, String jurisdiction, St CaseTransferContext context = new CaseTransferContext( caseId, + caseTypeId, ccdGatewayBaseUrl, creationSingleDataModel.getPositionTypeCT(), jurisdiction, @@ -268,6 +275,10 @@ private CaseData copyCaseData(CaseData oldCaseData, CaseData newCaseData, CaseTr newCaseData.setRespondentOrganisationPolicy8(oldCaseData.getRespondentOrganisationPolicy8()); newCaseData.setRespondentOrganisationPolicy9(oldCaseData.getRespondentOrganisationPolicy9()); + if (featureToggleService.isCaseFlagsV2Enabled(context.caseTypeId)) { + newCaseData.setAllPartyFlags(oldCaseData.getAllPartyFlags()); + } + return newCaseData; } } diff --git a/src/main/resources/support-tasks.yml b/src/main/resources/support-tasks.yml new file mode 100644 index 0000000000..da310f51fd --- /dev/null +++ b/src/main/resources/support-tasks.yml @@ -0,0 +1,43 @@ +support-tasks: + review: + admin-flag-codes: + - RA0002 + - RA0003 + - RA0004 + - RA0005 + - RA0006 + - RA0008 + - RA0009 + - RA0021 + - RA0033 + - RA0039 + - RA0041 + judge-flag-codes: + - RA0029 + - RA0031 + - RA0032 + - RA0037 + - RA0038 + legal-officer-flag-codes: + - RA0034 + - RA0035 + - RA0036 + arrange: + flag-titles: + RA0003: I need help with forms + RA0017: Guidance on how to complete forms + RA0018: Support filling in forms + RA0019: Step free / wheelchair access + RA0020: Use of venue wheelchair + RA0021: Parking space close to the venue + RA0022: Accessible toilet + RA0024: A different type of chair + RA0030: Appropriate lighting + RA0038: Intermediary + RA0039: Speech to text reporter (palantypist) + RA0041: Lip speaker + RA0042: Sign language interpreter + RA0043: Hearing loop (hearing enhancement system) + RA0044: Infrared receiver (hearing enhancement system) + RA0045: Induction loop (hearing enhancement system) + RA0046: Visit to court or tribunal before the hearing diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/config/SupportTaskConfigurationTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/config/SupportTaskConfigurationTest.java new file mode 100644 index 0000000000..f9c1e5682e --- /dev/null +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/config/SupportTaskConfigurationTest.java @@ -0,0 +1,49 @@ +package uk.gov.hmcts.ethos.replacement.docmosis.config; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest(classes = { + SupportTaskConfiguration.class, + ConfigurationPropertiesAutoConfiguration.class +}) +class SupportTaskConfigurationTest { + @Autowired + private SupportTaskConfiguration configuration; + + @Test + void loadsFlagCodesFromYaml() { + assertThat(configuration.getReview().getAdminFlagCodes()) + .containsExactlyInAnyOrder( + "RA0002", "RA0003", "RA0004", "RA0005", "RA0006", "RA0008", "RA0009", "RA0021", + "RA0033", "RA0039", "RA0041"); + assertThat(configuration.getReview().getJudgeFlagCodes()) + .containsExactlyInAnyOrder("RA0029", "RA0031", "RA0032", "RA0037", "RA0038"); + assertThat(configuration.getReview().getLegalOfficerFlagCodes()) + .containsExactlyInAnyOrder("RA0034", "RA0035", "RA0036"); + + assertThat(configuration.getArrange().getFlagTitles()) + .containsEntry("RA0003", "I need help with forms") + .containsEntry("RA0017", "Guidance on how to complete forms") + .containsEntry("RA0018", "Support filling in forms") + .containsEntry("RA0019", "Step free / wheelchair access") + .containsEntry("RA0020", "Use of venue wheelchair") + .containsEntry("RA0021", "Parking space close to the venue") + .containsEntry("RA0022", "Accessible toilet") + .containsEntry("RA0024", "A different type of chair") + .containsEntry("RA0030", "Appropriate lighting") + .containsEntry("RA0038", "Intermediary") + .containsEntry("RA0039", "Speech to text reporter (palantypist)") + .containsEntry("RA0041", "Lip speaker") + .containsEntry("RA0042", "Sign language interpreter") + .containsEntry("RA0043", "Hearing loop (hearing enhancement system)") + .containsEntry("RA0044", "Infrared receiver (hearing enhancement system)") + .containsEntry("RA0045", "Induction loop (hearing enhancement system)") + .containsEntry("RA0046", "Visit to court or tribunal before the hearing") + .hasSize(17); + } +} diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java index 112c88ce5f..4649567b71 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java @@ -49,6 +49,7 @@ import uk.gov.hmcts.ethos.replacement.docmosis.service.ScotlandFileLocationSelectionService; import uk.gov.hmcts.ethos.replacement.docmosis.service.SingleCaseMultipleMidEventValidationService; import uk.gov.hmcts.ethos.replacement.docmosis.service.SingleReferenceService; +import uk.gov.hmcts.ethos.replacement.docmosis.service.SupportTaskService; import uk.gov.hmcts.ethos.replacement.docmosis.service.noc.NocRespondentRepresentativeService; import uk.gov.hmcts.ethos.replacement.docmosis.utils.InternalException; import uk.gov.hmcts.ethos.replacement.docmosis.utils.JsonMapper; @@ -70,11 +71,12 @@ import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.any; -import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.doCallRealMethod; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.isNull; import static org.mockito.Mockito.never; +import static org.mockito.Mockito.nullable; import static org.mockito.Mockito.same; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -95,6 +97,7 @@ class CaseActionsForCaseWorkerControllerTest extends BaseControllerTest { private static final String PRE_DEFAULT_VALUES_URL = "/preDefaultValues"; private static final String POST_DEFAULT_VALUES_URL = "/postDefaultValues"; + private static final String SUPPORT_TASKS_URL = "/supportTasks/aboutToSubmit"; private static final String AMEND_CASE_DETAILS_URL = "/amendCaseDetails"; private static final String AMEND_CLAIMANT_DETAILS_URL = "/amendClaimantDetails"; private static final String UPDATE_CLAIMANT_EMAIL_ABOUT_TO_START_URL = @@ -186,6 +189,9 @@ class CaseActionsForCaseWorkerControllerTest extends BaseControllerTest { @MockitoBean private CaseFlagsService caseFlagsService; + @MockitoBean + private SupportTaskService supportTaskService; + @MockitoBean private FeatureToggleService featureToggleService; @@ -318,6 +324,119 @@ void postDefaultValues() { .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); } + @ParameterizedTest + @ValueSource(strings = {"SUBMIT_CASE_DRAFT", "UPDATE_CASE_SUBMITTED"}) + @SneakyThrows + void postDefaultValuesPreparesReviewSupportTasksForCaseFlagsV2Events(String eventId) { + ((ObjectNode) requestContent2).put("event_id", eventId); + when(defaultValuesReaderService.getDefaultValues(anyString())).thenReturn(defaultValues); + when(singleReferenceService.createReference(anyString())).thenReturn("5100001/2019"); + when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); + when(featureToggleService.isCaseFlagsV2Enabled(anyString())).thenReturn(true); + + mvc.perform(post(POST_DEFAULT_VALUES_URL) + .content(requestContent2.toString()) + .header(AUTHORIZATION, AUTH_TOKEN) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + + verify(supportTaskService).prepareReviewSupportTasks(any(CaseData.class)); + } + + @Test + @SneakyThrows + void postDefaultValuesDoesNotPrepareReviewSupportTasksWhenCaseFlagsV2IsDisabled() { + ((ObjectNode) requestContent2).put("event_id", "UPDATE_CASE_SUBMITTED"); + when(defaultValuesReaderService.getDefaultValues(anyString())).thenReturn(defaultValues); + when(singleReferenceService.createReference(anyString())).thenReturn("5100001/2019"); + when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); + + mvc.perform(post(POST_DEFAULT_VALUES_URL) + .content(requestContent2.toString()) + .header(AUTHORIZATION, AUTH_TOKEN) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + + verify(supportTaskService, never()).prepareReviewSupportTasks(any(CaseData.class)); + } + + @ParameterizedTest + @ValueSource(strings = {"SUBMIT_ET3_FORM", "UPDATE_ET3_FORM"}) + @SneakyThrows + void preparesRespondentReviewSupportTasksForEt3Events(String eventId) { + ((ObjectNode) requestContent2).put("event_id", eventId); + when(featureToggleService.isCaseFlagsV2Enabled(anyString())).thenReturn(true); + + mvc.perform(post(SUPPORT_TASKS_URL) + .content(requestContent2.toString()) + .header(AUTHORIZATION, AUTH_TOKEN) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + + verify(supportTaskService).prepareRespondentReviewSupportTasks(any(CaseData.class)); + } + + @ParameterizedTest + @ValueSource(strings = {"requestSupport", "createFlag"}) + @SneakyThrows + void preparesReviewSupportTasksForNewCaseFlags(String eventId) { + ((ObjectNode) requestContent2).put("event_id", eventId); + ((ObjectNode) requestContent2).set("case_details_before", + requestContent2.get("case_details").deepCopy()); + when(featureToggleService.isCaseFlagsV2Enabled(anyString())).thenReturn(true); + + mvc.perform(post(SUPPORT_TASKS_URL) + .content(requestContent2.toString()) + .header(AUTHORIZATION, AUTH_TOKEN) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + + verify(supportTaskService).prepareNewFlagReviewSupportTasks( + any(CaseData.class), any(CaseData.class)); + if ("createFlag".equals(eventId)) { + verify(supportTaskService).prepareArrangeSupportTask( + any(CaseData.class), any(CaseData.class)); + } + } + + @ParameterizedTest + @ValueSource(strings = {"manageFlags", "manageSupport"}) + @SneakyThrows + void preparesReviewSupportTaskCompletionForManagedCaseFlags(String eventId) { + ((ObjectNode) requestContent2).put("event_id", eventId); + when(featureToggleService.isCaseFlagsV2Enabled(anyString())).thenReturn(true); + + mvc.perform(post(SUPPORT_TASKS_URL) + .content(requestContent2.toString()) + .header(AUTHORIZATION, AUTH_TOKEN) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + + verify(supportTaskService).prepareManagedReviewSupportTasks(any(CaseData.class)); + if ("manageFlags".equals(eventId)) { + verify(supportTaskService).prepareArrangeSupportTask(any(CaseData.class), isNull()); + } + } + + @Test + @SneakyThrows + void doesNotPrepareReviewSupportTasksWhenCaseFlagsV2IsDisabled() { + ((ObjectNode) requestContent2).put("event_id", "SUBMIT_ET3_FORM"); + + mvc.perform(post(SUPPORT_TASKS_URL) + .content(requestContent2.toString()) + .header(AUTHORIZATION, AUTH_TOKEN) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + + verify(supportTaskService, never()).prepareRespondentReviewSupportTasks(any(CaseData.class)); + verify(supportTaskService, never()).prepareNewFlagReviewSupportTasks( + any(CaseData.class), any(CaseData.class)); + verify(supportTaskService, never()).prepareManagedReviewSupportTasks(any(CaseData.class)); + verify(supportTaskService, never()).prepareArrangeSupportTask( + any(CaseData.class), nullable(CaseData.class)); + } + @Test @SneakyThrows void postDefaultValuesSetsUpLegacyFlagsOnPrepopulatedCaseData() { diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java new file mode 100644 index 0000000000..6e832bdc50 --- /dev/null +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java @@ -0,0 +1,431 @@ +package uk.gov.hmcts.ethos.replacement.docmosis.service; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import uk.gov.hmcts.et.common.model.ccd.CaseData; +import uk.gov.hmcts.et.common.model.ccd.items.FlagDetailType; +import uk.gov.hmcts.et.common.model.ccd.items.GenericTypeItem; +import uk.gov.hmcts.et.common.model.ccd.items.ListTypeItem; +import uk.gov.hmcts.et.common.model.ccd.types.AllPartyFlags; +import uk.gov.hmcts.et.common.model.ccd.types.CaseFlagsType; +import uk.gov.hmcts.et.common.model.ccd.types.SupportTaskState; +import uk.gov.hmcts.ethos.replacement.docmosis.config.SupportTaskConfiguration; + +import java.util.Map; +import java.util.Set; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static uk.gov.hmcts.ecm.common.model.helper.Constants.NO; +import static uk.gov.hmcts.ecm.common.model.helper.Constants.YES; + +class SupportTaskServiceTest { + private final SupportTaskService service = new SupportTaskService(configuration()); + + private static SupportTaskConfiguration configuration() { + SupportTaskConfiguration configuration = new SupportTaskConfiguration(); + configuration.getReview().setAdminFlagCodes(Set.of( + "RA0002", "RA0003", "RA0004", "RA0005", "RA0006", "RA0008", "RA0009", "RA0021", "RA0033", + "RA0039", "RA0041")); + configuration.getReview().setLegalOfficerFlagCodes(Set.of("RA0034", "RA0035", "RA0036")); + configuration.getReview().setJudgeFlagCodes(Set.of("RA0029", "RA0031", "RA0032", "RA0037", "RA0038")); + configuration.getArrange().setFlagTitles(Map.ofEntries( + Map.entry("RA0003", "I need help with forms"), + Map.entry("RA0017", "Guidance on how to complete forms"), + Map.entry("RA0018", "Support filling in forms"), + Map.entry("RA0019", "Step free / wheelchair access"), + Map.entry("RA0020", "Use of venue wheelchair"), + Map.entry("RA0021", "Parking space close to the venue"), + Map.entry("RA0022", "Accessible toilet"), + Map.entry("RA0024", "A different type of chair"), + Map.entry("RA0030", "Appropriate lighting"), + Map.entry("RA0038", "Intermediary"), + Map.entry("RA0039", "Speech to text reporter (palantypist)"), + Map.entry("RA0041", "Lip speaker"), + Map.entry("RA0042", "Sign language interpreter"), + Map.entry("RA0043", "Hearing loop (hearing enhancement system)"), + Map.entry("RA0044", "Infrared receiver (hearing enhancement system)"), + Map.entry("RA0045", "Induction loop (hearing enhancement system)"), + Map.entry("RA0046", "Visit to court or tribunal before the hearing") + )); + return configuration; + } + + static Stream eligibleFlagScenarios() { + return Stream.of( + Stream.of("RA0002", "RA0003", "RA0004", "RA0005", "RA0006", "RA0008", "RA0009", "RA0021", + "RA0033", "RA0039", "RA0041") + .map(code -> Arguments.of(code, "Admin")), + Stream.of("RA0034", "RA0035", "RA0036") + .map(code -> Arguments.of(code, "LegalOfficer")), + Stream.of("RA0029", "RA0031", "RA0032", "RA0037", "RA0038") + .map(code -> Arguments.of(code, "Judge")) + ).flatMap(stream -> stream); + } + + @ParameterizedTest + @MethodSource("eligibleFlagScenarios") + void prepares_each_eligible_task_type_once_per_case(String flagCode, String taskType) { + CaseData caseData = caseDataWithClaimantFlag(flagCode, "Requested", false); + + service.prepareReviewSupportTasks(caseData); + + assertEquals("Admin".equals(taskType) ? YES : null, + taskState(caseData).getAdminTaskRequired()); + assertEquals("LegalOfficer".equals(taskType) ? YES : null, + taskState(caseData).getLegalOfficerTaskRequired()); + assertEquals("Judge".equals(taskType) ? YES : null, + taskState(caseData).getJudgeTaskRequired()); + + service.prepareReviewSupportTasks(caseData); + + assertNull(taskState(caseData).getAdminTaskRequired()); + assertNull(taskState(caseData).getLegalOfficerTaskRequired()); + assertNull(taskState(caseData).getJudgeTaskRequired()); + } + + @Test + void prepares_task_for_requested_external_claimant_flag() { + CaseData caseData = caseDataWithClaimantFlag("RA0029", "Requested", true); + + service.prepareReviewSupportTasks(caseData); + + assertEquals(YES, taskState(caseData).getJudgeTaskCreated()); + assertEquals(YES, taskState(caseData).getJudgeTaskRequired()); + } + + @Test + void prepares_task_for_requested_flag_from_any_respondent() { + CaseData caseData = new CaseData(); + caseData.setAllPartyFlags(AllPartyFlags.builder() + .respondent3ExternalFlags(caseFlags("respondent-3-flag", "RA0034", "Requested")) + .build()); + + service.prepareRespondentReviewSupportTasks(caseData); + + assertEquals(YES, taskState(caseData).getLegalOfficerTaskCreated()); + assertEquals(YES, taskState(caseData).getLegalOfficerTaskRequired()); + } + + @Test + void respondent_event_does_not_use_a_claimant_flag() { + CaseData caseData = caseDataWithClaimantFlag("RA0002", "Requested", false); + + service.prepareRespondentReviewSupportTasks(caseData); + + assertNull(taskState(caseData).getAdminTaskCreated()); + } + + @Test + void prepares_task_only_for_a_newly_created_flag() { + CaseData caseDataBefore = new CaseData(); + caseDataBefore.setAllPartyFlags(AllPartyFlags.builder() + .claimantFlags(caseFlags("existing-flag", "RA0002", "Requested")) + .build()); + CaseData caseData = new CaseData(); + caseData.setAllPartyFlags(AllPartyFlags.builder() + .claimantFlags(caseFlags("existing-flag", "RA0002", "Requested")) + .respondent2Flags(caseFlags("new-flag", "RA0029", "Requested")) + .build()); + + service.prepareNewFlagReviewSupportTasks(caseData, caseDataBefore); + + assertNull(taskState(caseData).getAdminTaskCreated()); + assertEquals(YES, taskState(caseData).getJudgeTaskCreated()); + assertEquals(YES, taskState(caseData).getJudgeTaskRequired()); + } + + @Test + void prepares_task_for_a_new_requested_flag() { + CaseData caseData = new CaseData(); + caseData.setAllPartyFlags(AllPartyFlags.builder() + .representative2ExternalFlags(caseFlags("new-flag", "RA0002", "Requested")) + .build()); + + service.prepareNewFlagReviewSupportTasks(caseData, new CaseData()); + + assertEquals(YES, taskState(caseData).getAdminTaskCreated()); + assertEquals(YES, taskState(caseData).getAdminTaskRequired()); + } + + @Test + void does_not_treat_an_unchanged_flag_without_an_id_as_new() { + CaseData caseDataBefore = new CaseData(); + caseDataBefore.setAllPartyFlags(AllPartyFlags.builder() + .claimantFlags(caseFlags(null, "RA0002", "Requested")) + .build()); + CaseData caseData = new CaseData(); + caseData.setAllPartyFlags(AllPartyFlags.builder() + .claimantFlags(caseFlags(null, "RA0002", "Requested")) + .build()); + + service.prepareNewFlagReviewSupportTasks(caseData, caseDataBefore); + + assertNull(taskState(caseData).getAdminTaskCreated()); + assertNull(taskState(caseData).getAdminTaskRequired()); + } + + @Test + void does_not_treat_an_updated_existing_flag_as_new() { + CaseData caseDataBefore = new CaseData(); + caseDataBefore.setAllPartyFlags(AllPartyFlags.builder() + .claimantFlags(caseFlags("existing-flag", "RA0002", "Active")) + .build()); + CaseData caseData = new CaseData(); + caseData.setAllPartyFlags(AllPartyFlags.builder() + .claimantFlags(caseFlags("existing-flag", "RA0002", "Requested")) + .build()); + + service.prepareNewFlagReviewSupportTasks(caseData, caseDataBefore); + + assertNull(taskState(caseData).getAdminTaskCreated()); + assertNull(taskState(caseData).getAdminTaskRequired()); + } + + @Test + void does_not_prepare_task_for_a_new_case_level_flag() { + CaseData caseData = new CaseData(); + caseData.setAllPartyFlags(AllPartyFlags.builder() + .caseFlags(caseFlags("new-case-flag", "RA0002", "Requested")) + .build()); + + service.prepareNewFlagReviewSupportTasks(caseData, new CaseData()); + + assertNull(taskState(caseData).getAdminTaskCreated()); + } + + @Test + void prepares_tasks_for_new_claimant_and_representative_flags() { + CaseData caseData = new CaseData(); + caseData.setAllPartyFlags(AllPartyFlags.builder() + .claimantExternalFlags(caseFlags("claimant-flag", "RA0002", "Requested")) + .claimantRepresentativeFlags(caseFlags("claimant-rep-flag", "RA0034", "Requested")) + .representative4ExternalFlags(caseFlags("respondent-rep-flag", "RA0029", "Requested")) + .build()); + + service.prepareNewFlagReviewSupportTasks(caseData, new CaseData()); + + assertEquals(YES, taskState(caseData).getAdminTaskRequired()); + assertEquals(YES, taskState(caseData).getLegalOfficerTaskRequired()); + assertEquals(YES, taskState(caseData).getJudgeTaskRequired()); + } + + @Test + void completes_only_task_type_without_an_eligible_requested_flag() { + CaseData caseData = new CaseData(); + caseData.setAllPartyFlags(AllPartyFlags.builder() + .claimantFlags(caseFlags("admin-flag", "RA0002", "Active")) + .respondent2Flags(caseFlags("judge-flag", "RA0029", "Requested")) + .build()); + caseData.setSupportTaskState(SupportTaskState.builder() + .adminTaskCreated(YES) + .judgeTaskCreated(YES) + .build()); + + service.prepareManagedReviewSupportTasks(caseData); + + assertNull(taskState(caseData).getAdminTaskCreated()); + assertEquals(NO, taskState(caseData).getAdminTaskRequired()); + assertEquals(YES, taskState(caseData).getJudgeTaskCreated()); + assertNull(taskState(caseData).getJudgeTaskRequired()); + assertNull(taskState(caseData).getLegalOfficerTaskRequired()); + } + + @Test + void keeps_task_active_when_another_party_has_an_eligible_requested_flag() { + CaseData caseData = new CaseData(); + caseData.setAllPartyFlags(AllPartyFlags.builder() + .claimantFlags(caseFlags("managed-flag", "RA0002", "Active")) + .representative2ExternalFlags(caseFlags("requested-flag", "RA0003", "Requested")) + .build()); + caseData.setSupportTaskState(SupportTaskState.builder().adminTaskCreated(YES).build()); + + service.prepareManagedReviewSupportTasks(caseData); + + assertEquals(YES, taskState(caseData).getAdminTaskCreated()); + assertNull(taskState(caseData).getAdminTaskRequired()); + } + + @Test + void keeps_task_active_when_an_eligible_requested_flag_remains() { + CaseData caseData = caseDataWithClaimantFlag("RA0002", "Requested", false); + caseData.setSupportTaskState(SupportTaskState.builder().adminTaskCreated(YES).build()); + + service.prepareManagedReviewSupportTasks(caseData); + + assertEquals(YES, taskState(caseData).getAdminTaskCreated()); + assertNull(taskState(caseData).getAdminTaskRequired()); + } + + @Test + void completes_created_tasks_when_party_flags_are_missing() { + CaseData caseData = new CaseData(); + caseData.setSupportTaskState(SupportTaskState.builder() + .adminTaskCreated(YES) + .legalOfficerTaskCreated(YES) + .judgeTaskCreated(YES) + .build()); + + service.prepareManagedReviewSupportTasks(caseData); + + assertNull(taskState(caseData).getAdminTaskCreated()); + assertNull(taskState(caseData).getLegalOfficerTaskCreated()); + assertNull(taskState(caseData).getJudgeTaskCreated()); + assertEquals(NO, taskState(caseData).getAdminTaskRequired()); + assertEquals(NO, taskState(caseData).getLegalOfficerTaskRequired()); + assertEquals(NO, taskState(caseData).getJudgeTaskRequired()); + } + + @Test + void creates_a_new_task_after_the_previous_task_was_completed() { + CaseData caseDataBefore = caseDataWithClaimantFlag("RA0002", "Active", false); + caseDataBefore.setSupportTaskState(SupportTaskState.builder().adminTaskCreated(YES).build()); + service.prepareManagedReviewSupportTasks(caseDataBefore); + + CaseData caseData = caseDataWithClaimantFlag("RA0002", "Active", false); + caseData.getAllPartyFlags().setRespondent1Flags( + caseFlags("new-requested-flag", "RA0003", "Requested")); + + service.prepareNewFlagReviewSupportTasks(caseData, caseDataBefore); + + assertEquals(YES, taskState(caseData).getAdminTaskCreated()); + assertEquals(YES, taskState(caseData).getAdminTaskRequired()); + } + + static Stream ineligibleFlagScenarios() { + return Stream.of( + Arguments.of("RA0002", "Active"), + Arguments.of("RA0002", null), + Arguments.of("RA9999", "Requested") + ); + } + + @ParameterizedTest + @MethodSource("ineligibleFlagScenarios") + void does_not_prepare_tasks_for_ineligible_flags(String flagCode, String status) { + CaseData caseData = caseDataWithClaimantFlag(flagCode, status, false); + + service.prepareReviewSupportTasks(caseData); + + assertNull(taskState(caseData).getAdminTaskCreated()); + assertNull(taskState(caseData).getLegalOfficerTaskCreated()); + assertNull(taskState(caseData).getJudgeTaskCreated()); + } + + static Stream arrangeSupportFlagScenarios() { + return configuration().getArrange().getFlagTitles().entrySet().stream() + .map(entry -> Arguments.of(entry.getKey(), entry.getValue())); + } + + @ParameterizedTest + @MethodSource("arrangeSupportFlagScenarios") + void prepares_arrange_support_task_for_each_new_active_flag(String flagCode, String taskName) { + CaseData caseData = new CaseData(); + caseData.setAllPartyFlags(AllPartyFlags.builder() + .representative4ExternalFlags(caseFlags("new-flag", flagCode, "Active")) + .build()); + + service.prepareArrangeSupportTask(caseData, new CaseData()); + + assertEquals(taskName, taskState(caseData).getArrangeSupportTaskName()); + } + + @Test + void prepares_separate_arrange_support_tasks_for_the_same_code_on_separate_events() { + CaseData firstEvent = new CaseData(); + firstEvent.setAllPartyFlags(AllPartyFlags.builder() + .claimantFlags(caseFlags("claimant-flag", "RA0017", "Active")) + .build()); + service.prepareArrangeSupportTask(firstEvent, new CaseData()); + + CaseData secondEvent = new CaseData(); + secondEvent.setAllPartyFlags(AllPartyFlags.builder() + .claimantFlags(caseFlags("claimant-flag", "RA0017", "Active")) + .respondent2Flags(caseFlags("respondent-flag", "RA0017", "Active")) + .build()); + service.prepareArrangeSupportTask(secondEvent, firstEvent); + + assertEquals("Guidance on how to complete forms", taskState(firstEvent).getArrangeSupportTaskName()); + assertEquals("Guidance on how to complete forms", taskState(secondEvent).getArrangeSupportTaskName()); + } + + @Test + void prepares_arrange_support_task_when_existing_flag_becomes_active() { + CaseData caseDataBefore = new CaseData(); + caseDataBefore.setAllPartyFlags(AllPartyFlags.builder() + .claimantRepresentativeFlags(caseFlags("managed-flag", "RA0042", "Requested")) + .build()); + CaseData caseData = new CaseData(); + caseData.setAllPartyFlags(AllPartyFlags.builder() + .claimantRepresentativeFlags(caseFlags("managed-flag", "RA0042", "Active")) + .build()); + + service.prepareArrangeSupportTask(caseData, caseDataBefore); + + assertEquals("Sign language interpreter", taskState(caseData).getArrangeSupportTaskName()); + } + + @Test + void does_not_prepare_arrange_support_task_for_unchanged_active_flag() { + CaseData caseDataBefore = new CaseData(); + caseDataBefore.setAllPartyFlags(AllPartyFlags.builder() + .claimantFlags(caseFlags("unchanged-flag", "RA0003", "Active")) + .build()); + CaseData caseData = new CaseData(); + caseData.setAllPartyFlags(AllPartyFlags.builder() + .claimantFlags(caseFlags("unchanged-flag", "RA0003", "Active")) + .build()); + + service.prepareArrangeSupportTask(caseData, caseDataBefore); + + assertNull(taskState(caseData).getArrangeSupportTaskName()); + } + + @Test + void does_not_prepare_arrange_support_task_for_ineligible_or_non_active_flag() { + CaseData caseData = new CaseData(); + caseData.setAllPartyFlags(AllPartyFlags.builder() + .claimantFlags(caseFlags("requested-flag", "RA0003", "Requested")) + .respondentFlags(caseFlags("ineligible-flag", "RA9999", "Active")) + .build()); + caseData.setSupportTaskState(SupportTaskState.builder() + .arrangeSupportTaskName("Previous task") + .build()); + + service.prepareArrangeSupportTask(caseData, new CaseData()); + + assertNull(taskState(caseData).getArrangeSupportTaskName()); + } + + private static CaseData caseDataWithClaimantFlag(String flagCode, + String status, + boolean external) { + FlagDetailType detail = FlagDetailType.builder() + .flagCode(flagCode) + .status(status) + .build(); + CaseFlagsType flags = CaseFlagsType.builder().details(ListTypeItem.from(detail)).build(); + AllPartyFlags allPartyFlags = external + ? AllPartyFlags.builder().claimantExternalFlags(flags).build() + : AllPartyFlags.builder().claimantFlags(flags).build(); + CaseData caseData = new CaseData(); + caseData.setAllPartyFlags(allPartyFlags); + return caseData; + } + + private static CaseFlagsType caseFlags(String id, String flagCode, String status) { + FlagDetailType detail = FlagDetailType.builder() + .flagCode(flagCode) + .status(status) + .build(); + ListTypeItem details = ListTypeItem.from(GenericTypeItem.from(id, detail)); + return CaseFlagsType.builder().details(details).build(); + } + + private static SupportTaskState taskState(CaseData caseData) { + return caseData.getSupportTaskState(); + } +} diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/messagehandler/SingleCreationServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/messagehandler/SingleCreationServiceTest.java index b406d2b350..7a6d78b152 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/messagehandler/SingleCreationServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/messagehandler/SingleCreationServiceTest.java @@ -17,7 +17,12 @@ import uk.gov.hmcts.et.common.model.ccd.CaseData; import uk.gov.hmcts.et.common.model.ccd.CaseDetails; import uk.gov.hmcts.et.common.model.ccd.SubmitEvent; +import uk.gov.hmcts.et.common.model.ccd.items.FlagDetailType; +import uk.gov.hmcts.et.common.model.ccd.items.ListTypeItem; +import uk.gov.hmcts.et.common.model.ccd.types.AllPartyFlags; +import uk.gov.hmcts.et.common.model.ccd.types.CaseFlagsType; import uk.gov.hmcts.ethos.replacement.docmosis.helpers.MessageHandlerTestHelper; +import uk.gov.hmcts.ethos.replacement.docmosis.service.FeatureToggleService; import java.io.IOException; import java.util.ArrayList; @@ -25,6 +30,7 @@ import java.util.List; import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.times; @@ -42,8 +48,12 @@ class SingleCreationServiceTest { private SingleCreationService singleCreationService; @Mock private CcdClient ccdClient; + @Mock + private FeatureToggleService featureToggleService; @Captor ArgumentCaptor caseDetailsArgumentCaptor; + @Captor + ArgumentCaptor caseDataArgumentCaptor; private static final String USER_TOKEN = "accessToken"; @Test @@ -54,6 +64,7 @@ void caseTransferToScotlandCreateCase() throws IOException { var caseData = new CaseData(); caseData.setEthosCaseReference(ethosCaseReference); caseData.setManagingOffice(managingOffice); + caseData.setAllPartyFlags(createAllPartyFlags()); var submitEvent = new SubmitEvent(); submitEvent.setCaseData(caseData); CaseData newCaseData = new CaseData(); @@ -82,12 +93,14 @@ void caseTransferToScotlandCreateCase() throws IOException { .thenReturn(new ArrayList<>()); when(ccdClient.startCaseCreationTransfer(eq(USER_TOKEN), any())) .thenReturn(updateCCDRequest); + when(featureToggleService.isCaseFlagsV2Enabled(SCOTLAND_CASE_TYPE_ID)).thenReturn(false); singleCreationService.sendCreation(submitEvent, USER_TOKEN, updateCaseMsg); verify(ccdClient, times(1)) .retrieveCasesElasticSearch(USER_TOKEN, SCOTLAND_CASE_TYPE_ID, List.of(ethosCaseReference)); - verify(ccdClient, times(1)).startCaseCreationTransfer(eq(USER_TOKEN), any()); + verify(ccdClient, times(1)).startCaseCreationTransfer(eq(USER_TOKEN), caseDetailsArgumentCaptor.capture()); + assertNull(caseDetailsArgumentCaptor.getValue().getCaseData().getAllPartyFlags()); var expectedEventSummary = String.format(CREATE_CASE_EVENT_SUMMARY_TEMPLATE, managingOffice); verify(ccdClient, times(1)).submitCaseCreation(eq(USER_TOKEN), any(), any(), eq(expectedEventSummary)); @@ -111,12 +124,15 @@ void caseTransferToEnglandCreateCase() throws IOException { caseData.setEthosCaseReference(ethosCaseReference); caseData.setManagingOffice(managingOffice); caseData.setFeeGroupReference("1234123412341234"); + AllPartyFlags allPartyFlags = createAllPartyFlags(); + caseData.setAllPartyFlags(allPartyFlags); SubmitEvent submitEvent = new SubmitEvent(); submitEvent.setCaseData(caseData); UpdateCaseMsg updateCaseMsg = MessageHandlerTestHelper.generateCreationSingleCaseMsg(); ((CreationSingleDataModel)updateCaseMsg.getDataModelParent()).setOfficeCT( TribunalOffice.NEWCASTLE.getOfficeName()); + when(featureToggleService.isCaseFlagsV2Enabled(ENGLANDWALES_CASE_TYPE_ID)).thenReturn(true); singleCreationService.sendCreation(submitEvent, USER_TOKEN, updateCaseMsg); @@ -124,6 +140,7 @@ void caseTransferToEnglandCreateCase() throws IOException { List.of(ethosCaseReference)); verify(ccdClient).startCaseCreationTransfer(eq(USER_TOKEN), caseDetailsArgumentCaptor.capture()); assertNull(caseDetailsArgumentCaptor.getValue().getCaseData().getFeeGroupReference()); + assertSame(allPartyFlags, caseDetailsArgumentCaptor.getValue().getCaseData().getAllPartyFlags()); var expectedEventSummary = String.format(CREATE_CASE_EVENT_SUMMARY_TEMPLATE, managingOffice); verify(ccdClient).submitCaseCreation(eq(USER_TOKEN), any(), any(), eq(expectedEventSummary)); verify(ccdClient, times(0)).returnCaseCreationTransfer(eq(USER_TOKEN), any(), any(), @@ -139,6 +156,8 @@ void caseTransferToScotlandUpdateExisting() throws IOException { var caseData = new CaseData(); caseData.setEthosCaseReference(ethosCaseReference); caseData.setManagingOffice(managingOffice); + AllPartyFlags allPartyFlags = createAllPartyFlags(); + caseData.setAllPartyFlags(allPartyFlags); var submitEvent = new SubmitEvent(); submitEvent.setCaseData(caseData); var caseId = 100; @@ -147,6 +166,7 @@ void caseTransferToScotlandUpdateExisting() throws IOException { var updateCaseMsg = MessageHandlerTestHelper.generateCreationSingleCaseMsg(); ((CreationSingleDataModel)updateCaseMsg.getDataModelParent()).setOfficeCT( TribunalOffice.GLASGOW.getOfficeName()); + when(featureToggleService.isCaseFlagsV2Enabled(SCOTLAND_CASE_TYPE_ID)).thenReturn(true); when(ccdClient.retrieveCasesElasticSearch(USER_TOKEN, SCOTLAND_CASE_TYPE_ID, List.of(ethosCaseReference))) .thenReturn(new ArrayList<>(Collections.singletonList(submitEvent))); @@ -156,10 +176,77 @@ void caseTransferToScotlandUpdateExisting() throws IOException { verify(ccdClient).retrieveCasesElasticSearch(USER_TOKEN, SCOTLAND_CASE_TYPE_ID, List.of(ethosCaseReference)); verify(ccdClient).returnCaseCreationTransfer(USER_TOKEN, SCOTLAND_CASE_TYPE_ID, "EMPLOYMENT", String.valueOf(caseId)); - verify(ccdClient).submitEventForCase(eq(USER_TOKEN), any(), eq(SCOTLAND_CASE_TYPE_ID), eq("EMPLOYMENT"), any(), + verify(ccdClient).submitEventForCase(eq(USER_TOKEN), caseDataArgumentCaptor.capture(), + eq(SCOTLAND_CASE_TYPE_ID), eq("EMPLOYMENT"), any(), eq(String.valueOf(caseId))); + assertSame(allPartyFlags, caseDataArgumentCaptor.getValue().getAllPartyFlags()); verify(ccdClient, times(0)).startCaseCreationTransfer(eq(USER_TOKEN), any()); verifyNoMoreInteractions(ccdClient); } + private AllPartyFlags createAllPartyFlags() { + return AllPartyFlags.builder() + .caseFlags(createCaseFlags("Case flags")) + .claimantFlags(createCaseFlags("Claimant flags")) + .claimantExternalFlags(createCaseFlags("Claimant external flags")) + .respondentFlags(createCaseFlags("Respondent flags")) + .respondentExternalFlags(createCaseFlags("Respondent external flags")) + .respondent1Flags(createCaseFlags("Respondent 1 flags")) + .respondent1ExternalFlags(createCaseFlags("Respondent 1 external flags")) + .respondent2Flags(createCaseFlags("Respondent 2 flags")) + .respondent2ExternalFlags(createCaseFlags("Respondent 2 external flags")) + .respondent3Flags(createCaseFlags("Respondent 3 flags")) + .respondent3ExternalFlags(createCaseFlags("Respondent 3 external flags")) + .respondent4Flags(createCaseFlags("Respondent 4 flags")) + .respondent4ExternalFlags(createCaseFlags("Respondent 4 external flags")) + .respondent5Flags(createCaseFlags("Respondent 5 flags")) + .respondent5ExternalFlags(createCaseFlags("Respondent 5 external flags")) + .respondent6Flags(createCaseFlags("Respondent 6 flags")) + .respondent6ExternalFlags(createCaseFlags("Respondent 6 external flags")) + .respondent7Flags(createCaseFlags("Respondent 7 flags")) + .respondent7ExternalFlags(createCaseFlags("Respondent 7 external flags")) + .respondent8Flags(createCaseFlags("Respondent 8 flags")) + .respondent8ExternalFlags(createCaseFlags("Respondent 8 external flags")) + .respondent9Flags(createCaseFlags("Respondent 9 flags")) + .respondent9ExternalFlags(createCaseFlags("Respondent 9 external flags")) + .claimantRepresentativeFlags(createCaseFlags("Claimant representative flags")) + .claimantRepresentativeExternalFlags(createCaseFlags("Claimant representative external flags")) + .representativeFlags(createCaseFlags("Representative flags")) + .representativeExternalFlags(createCaseFlags("Representative external flags")) + .representative1Flags(createCaseFlags("Representative 1 flags")) + .representative1ExternalFlags(createCaseFlags("Representative 1 external flags")) + .representative2Flags(createCaseFlags("Representative 2 flags")) + .representative2ExternalFlags(createCaseFlags("Representative 2 external flags")) + .representative3Flags(createCaseFlags("Representative 3 flags")) + .representative3ExternalFlags(createCaseFlags("Representative 3 external flags")) + .representative4Flags(createCaseFlags("Representative 4 flags")) + .representative4ExternalFlags(createCaseFlags("Representative 4 external flags")) + .representative5Flags(createCaseFlags("Representative 5 flags")) + .representative5ExternalFlags(createCaseFlags("Representative 5 external flags")) + .representative6Flags(createCaseFlags("Representative 6 flags")) + .representative6ExternalFlags(createCaseFlags("Representative 6 external flags")) + .representative7Flags(createCaseFlags("Representative 7 flags")) + .representative7ExternalFlags(createCaseFlags("Representative 7 external flags")) + .representative8Flags(createCaseFlags("Representative 8 flags")) + .representative8ExternalFlags(createCaseFlags("Representative 8 external flags")) + .representative9Flags(createCaseFlags("Representative 9 flags")) + .representative9ExternalFlags(createCaseFlags("Representative 9 external flags")) + .build(); + } + + private CaseFlagsType createCaseFlags(String sectionName) { + FlagDetailType flagDetail = FlagDetailType.builder() + .name(sectionName + " detail") + .flagCode("CF-001") + .status("Active") + .build(); + return CaseFlagsType.builder() + .partyName(sectionName + " party") + .roleOnCase(sectionName + " role") + .groupId(sectionName + " group") + .visibility(sectionName.contains("external") ? "External" : "Internal") + .details(ListTypeItem.from(flagDetail)) + .build(); + } + } From 7d0f915c02812d9c7b67232a1c4db8c1c671da95 Mon Sep 17 00:00:00 2001 From: rajaram Date: Fri, 11 Sep 2026 13:16:02 +0100 Subject: [PATCH 053/100] Fixed issue with WA task creation --- .../CaseEventToFields-SupportTasks.json | 94 +++++++ .../EventToComplexTypes-SupportTasks.json | 236 ++++++++++++++++++ .../CaseEventToFields-SupportTasks.json | 94 +++++++ .../EventToComplexTypes-SupportTasks.json | 236 ++++++++++++++++++ .../CaseActionsForCaseWorkerController.java | 5 +- .../docmosis/service/SupportTaskService.java | 27 ++ ...aseActionsForCaseWorkerControllerTest.java | 4 +- .../service/SupportTaskServiceTest.java | 45 ++++ 8 files changed, 738 insertions(+), 3 deletions(-) create mode 100644 ccd-definitions/jurisdictions/england-wales/json/CaseEventToFields/CaseEventToFields-SupportTasks.json create mode 100644 ccd-definitions/jurisdictions/england-wales/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json create mode 100644 ccd-definitions/jurisdictions/scotland/json/CaseEventToFields/CaseEventToFields-SupportTasks.json create mode 100644 ccd-definitions/jurisdictions/scotland/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json diff --git a/ccd-definitions/jurisdictions/england-wales/json/CaseEventToFields/CaseEventToFields-SupportTasks.json b/ccd-definitions/jurisdictions/england-wales/json/CaseEventToFields/CaseEventToFields-SupportTasks.json new file mode 100644 index 0000000000..cc59bb565e --- /dev/null +++ b/ccd-definitions/jurisdictions/england-wales/json/CaseEventToFields/CaseEventToFields-SupportTasks.json @@ -0,0 +1,94 @@ +[ + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "SUBMIT_CASE_DRAFT", + "CaseFieldID": "supportTaskState", + "DisplayContext": "COMPLEX", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 99, + "FieldShowCondition": "horizontalLine=\"dummy\"", + "ShowSummaryChangeOption": "N", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "UPDATE_CASE_SUBMITTED", + "CaseFieldID": "supportTaskState", + "DisplayContext": "COMPLEX", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 99, + "FieldShowCondition": "et1OnlineSubmission=\"DUMMY_VALUE_TO_HIDE_FIELD\"", + "ShowSummaryChangeOption": "N", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "SUBMIT_ET3_FORM", + "CaseFieldID": "supportTaskState", + "DisplayContext": "COMPLEX", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 99, + "ShowSummaryChangeOption": "N" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "UPDATE_ET3_FORM", + "CaseFieldID": "supportTaskState", + "DisplayContext": "COMPLEX", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 99, + "ShowSummaryChangeOption": "N" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "requestSupport", + "CaseFieldID": "supportTaskState", + "DisplayContext": "COMPLEX", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 99, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "N", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "createFlag", + "CaseFieldID": "supportTaskState", + "DisplayContext": "COMPLEX", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 99, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "N", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageFlags", + "CaseFieldID": "supportTaskState", + "DisplayContext": "COMPLEX", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 99, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "N", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "manageSupport", + "CaseFieldID": "supportTaskState", + "DisplayContext": "COMPLEX", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 99, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "N", + "RetainHiddenValue": "Yes" + } +] diff --git a/ccd-definitions/jurisdictions/england-wales/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json b/ccd-definitions/jurisdictions/england-wales/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json new file mode 100644 index 0000000000..0305335c4f --- /dev/null +++ b/ccd-definitions/jurisdictions/england-wales/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json @@ -0,0 +1,236 @@ +[ + { + "ID": "SupportTaskState", + "CaseEventID": "SUBMIT_CASE_DRAFT", + "CaseFieldID": "supportTaskState", + "ListElementCode": "adminTaskRequired", + "FieldDisplayOrder": 1, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "SUBMIT_CASE_DRAFT", + "CaseFieldID": "supportTaskState", + "ListElementCode": "legalOfficerTaskRequired", + "FieldDisplayOrder": 2, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "SUBMIT_CASE_DRAFT", + "CaseFieldID": "supportTaskState", + "ListElementCode": "judgeTaskRequired", + "FieldDisplayOrder": 3, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "UPDATE_CASE_SUBMITTED", + "CaseFieldID": "supportTaskState", + "ListElementCode": "adminTaskRequired", + "FieldDisplayOrder": 1, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "UPDATE_CASE_SUBMITTED", + "CaseFieldID": "supportTaskState", + "ListElementCode": "legalOfficerTaskRequired", + "FieldDisplayOrder": 2, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "UPDATE_CASE_SUBMITTED", + "CaseFieldID": "supportTaskState", + "ListElementCode": "judgeTaskRequired", + "FieldDisplayOrder": 3, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "SUBMIT_ET3_FORM", + "CaseFieldID": "supportTaskState", + "ListElementCode": "adminTaskRequired", + "FieldDisplayOrder": 1, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "SUBMIT_ET3_FORM", + "CaseFieldID": "supportTaskState", + "ListElementCode": "legalOfficerTaskRequired", + "FieldDisplayOrder": 2, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "SUBMIT_ET3_FORM", + "CaseFieldID": "supportTaskState", + "ListElementCode": "judgeTaskRequired", + "FieldDisplayOrder": 3, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "UPDATE_ET3_FORM", + "CaseFieldID": "supportTaskState", + "ListElementCode": "adminTaskRequired", + "FieldDisplayOrder": 1, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "UPDATE_ET3_FORM", + "CaseFieldID": "supportTaskState", + "ListElementCode": "legalOfficerTaskRequired", + "FieldDisplayOrder": 2, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "UPDATE_ET3_FORM", + "CaseFieldID": "supportTaskState", + "ListElementCode": "judgeTaskRequired", + "FieldDisplayOrder": 3, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "requestSupport", + "CaseFieldID": "supportTaskState", + "ListElementCode": "adminTaskRequired", + "FieldDisplayOrder": 1, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "requestSupport", + "CaseFieldID": "supportTaskState", + "ListElementCode": "legalOfficerTaskRequired", + "FieldDisplayOrder": 2, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "requestSupport", + "CaseFieldID": "supportTaskState", + "ListElementCode": "judgeTaskRequired", + "FieldDisplayOrder": 3, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "createFlag", + "CaseFieldID": "supportTaskState", + "ListElementCode": "adminTaskRequired", + "FieldDisplayOrder": 1, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "createFlag", + "CaseFieldID": "supportTaskState", + "ListElementCode": "legalOfficerTaskRequired", + "FieldDisplayOrder": 2, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "createFlag", + "CaseFieldID": "supportTaskState", + "ListElementCode": "judgeTaskRequired", + "FieldDisplayOrder": 3, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "createFlag", + "CaseFieldID": "supportTaskState", + "ListElementCode": "arrangeSupportTaskName", + "FieldDisplayOrder": 4, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "manageFlags", + "CaseFieldID": "supportTaskState", + "ListElementCode": "adminTaskRequired", + "FieldDisplayOrder": 1, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "manageFlags", + "CaseFieldID": "supportTaskState", + "ListElementCode": "legalOfficerTaskRequired", + "FieldDisplayOrder": 2, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "manageFlags", + "CaseFieldID": "supportTaskState", + "ListElementCode": "judgeTaskRequired", + "FieldDisplayOrder": 3, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "manageFlags", + "CaseFieldID": "supportTaskState", + "ListElementCode": "arrangeSupportTaskName", + "FieldDisplayOrder": 4, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "manageSupport", + "CaseFieldID": "supportTaskState", + "ListElementCode": "adminTaskRequired", + "FieldDisplayOrder": 1, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "manageSupport", + "CaseFieldID": "supportTaskState", + "ListElementCode": "legalOfficerTaskRequired", + "FieldDisplayOrder": 2, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "manageSupport", + "CaseFieldID": "supportTaskState", + "ListElementCode": "judgeTaskRequired", + "FieldDisplayOrder": 3, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + } +] diff --git a/ccd-definitions/jurisdictions/scotland/json/CaseEventToFields/CaseEventToFields-SupportTasks.json b/ccd-definitions/jurisdictions/scotland/json/CaseEventToFields/CaseEventToFields-SupportTasks.json new file mode 100644 index 0000000000..617ad23ace --- /dev/null +++ b/ccd-definitions/jurisdictions/scotland/json/CaseEventToFields/CaseEventToFields-SupportTasks.json @@ -0,0 +1,94 @@ +[ + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "SUBMIT_CASE_DRAFT", + "CaseFieldID": "supportTaskState", + "DisplayContext": "COMPLEX", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 99, + "FieldShowCondition": "horizontalLine=\"dummy\"", + "ShowSummaryChangeOption": "N", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "UPDATE_CASE_SUBMITTED", + "CaseFieldID": "supportTaskState", + "DisplayContext": "COMPLEX", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 99, + "FieldShowCondition": "et1OnlineSubmission=\"DUMMY_VALUE_TO_HIDE_FIELD\"", + "ShowSummaryChangeOption": "N", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "SUBMIT_ET3_FORM", + "CaseFieldID": "supportTaskState", + "DisplayContext": "COMPLEX", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 99, + "ShowSummaryChangeOption": "N" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "UPDATE_ET3_FORM", + "CaseFieldID": "supportTaskState", + "DisplayContext": "COMPLEX", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 99, + "ShowSummaryChangeOption": "N" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "requestSupport", + "CaseFieldID": "supportTaskState", + "DisplayContext": "COMPLEX", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 99, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "N", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "createFlag", + "CaseFieldID": "supportTaskState", + "DisplayContext": "COMPLEX", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 99, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "N", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageFlags", + "CaseFieldID": "supportTaskState", + "DisplayContext": "COMPLEX", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 99, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "N", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "manageSupport", + "CaseFieldID": "supportTaskState", + "DisplayContext": "COMPLEX", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 99, + "FieldShowCondition": "flagLauncherExternal=\"hidden\"", + "ShowSummaryChangeOption": "N", + "RetainHiddenValue": "Yes" + } +] diff --git a/ccd-definitions/jurisdictions/scotland/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json b/ccd-definitions/jurisdictions/scotland/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json new file mode 100644 index 0000000000..0305335c4f --- /dev/null +++ b/ccd-definitions/jurisdictions/scotland/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json @@ -0,0 +1,236 @@ +[ + { + "ID": "SupportTaskState", + "CaseEventID": "SUBMIT_CASE_DRAFT", + "CaseFieldID": "supportTaskState", + "ListElementCode": "adminTaskRequired", + "FieldDisplayOrder": 1, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "SUBMIT_CASE_DRAFT", + "CaseFieldID": "supportTaskState", + "ListElementCode": "legalOfficerTaskRequired", + "FieldDisplayOrder": 2, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "SUBMIT_CASE_DRAFT", + "CaseFieldID": "supportTaskState", + "ListElementCode": "judgeTaskRequired", + "FieldDisplayOrder": 3, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "UPDATE_CASE_SUBMITTED", + "CaseFieldID": "supportTaskState", + "ListElementCode": "adminTaskRequired", + "FieldDisplayOrder": 1, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "UPDATE_CASE_SUBMITTED", + "CaseFieldID": "supportTaskState", + "ListElementCode": "legalOfficerTaskRequired", + "FieldDisplayOrder": 2, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "UPDATE_CASE_SUBMITTED", + "CaseFieldID": "supportTaskState", + "ListElementCode": "judgeTaskRequired", + "FieldDisplayOrder": 3, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "SUBMIT_ET3_FORM", + "CaseFieldID": "supportTaskState", + "ListElementCode": "adminTaskRequired", + "FieldDisplayOrder": 1, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "SUBMIT_ET3_FORM", + "CaseFieldID": "supportTaskState", + "ListElementCode": "legalOfficerTaskRequired", + "FieldDisplayOrder": 2, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "SUBMIT_ET3_FORM", + "CaseFieldID": "supportTaskState", + "ListElementCode": "judgeTaskRequired", + "FieldDisplayOrder": 3, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "UPDATE_ET3_FORM", + "CaseFieldID": "supportTaskState", + "ListElementCode": "adminTaskRequired", + "FieldDisplayOrder": 1, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "UPDATE_ET3_FORM", + "CaseFieldID": "supportTaskState", + "ListElementCode": "legalOfficerTaskRequired", + "FieldDisplayOrder": 2, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "UPDATE_ET3_FORM", + "CaseFieldID": "supportTaskState", + "ListElementCode": "judgeTaskRequired", + "FieldDisplayOrder": 3, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "requestSupport", + "CaseFieldID": "supportTaskState", + "ListElementCode": "adminTaskRequired", + "FieldDisplayOrder": 1, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "requestSupport", + "CaseFieldID": "supportTaskState", + "ListElementCode": "legalOfficerTaskRequired", + "FieldDisplayOrder": 2, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "requestSupport", + "CaseFieldID": "supportTaskState", + "ListElementCode": "judgeTaskRequired", + "FieldDisplayOrder": 3, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "createFlag", + "CaseFieldID": "supportTaskState", + "ListElementCode": "adminTaskRequired", + "FieldDisplayOrder": 1, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "createFlag", + "CaseFieldID": "supportTaskState", + "ListElementCode": "legalOfficerTaskRequired", + "FieldDisplayOrder": 2, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "createFlag", + "CaseFieldID": "supportTaskState", + "ListElementCode": "judgeTaskRequired", + "FieldDisplayOrder": 3, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "createFlag", + "CaseFieldID": "supportTaskState", + "ListElementCode": "arrangeSupportTaskName", + "FieldDisplayOrder": 4, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "manageFlags", + "CaseFieldID": "supportTaskState", + "ListElementCode": "adminTaskRequired", + "FieldDisplayOrder": 1, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "manageFlags", + "CaseFieldID": "supportTaskState", + "ListElementCode": "legalOfficerTaskRequired", + "FieldDisplayOrder": 2, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "manageFlags", + "CaseFieldID": "supportTaskState", + "ListElementCode": "judgeTaskRequired", + "FieldDisplayOrder": 3, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "manageFlags", + "CaseFieldID": "supportTaskState", + "ListElementCode": "arrangeSupportTaskName", + "FieldDisplayOrder": 4, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "manageSupport", + "CaseFieldID": "supportTaskState", + "ListElementCode": "adminTaskRequired", + "FieldDisplayOrder": 1, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "manageSupport", + "CaseFieldID": "supportTaskState", + "ListElementCode": "legalOfficerTaskRequired", + "FieldDisplayOrder": 2, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "manageSupport", + "CaseFieldID": "supportTaskState", + "ListElementCode": "judgeTaskRequired", + "FieldDisplayOrder": 3, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + } +] diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java index a7cc8cb499..45c402a982 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java @@ -236,8 +236,9 @@ public ResponseEntity prepareSupportTasks( supportTaskService.prepareManagedReviewSupportTasks(caseData); } - if (EVENT_CREATE_FLAG.equals(callbackRequest.getEventId()) - || EVENT_MANAGE_FLAGS.equals(callbackRequest.getEventId())) { + if (EVENT_CREATE_FLAG.equals(callbackRequest.getEventId())) { + supportTaskService.prepareNewFlagArrangeSupportTask(caseData, caseDataBefore); + } else if (EVENT_MANAGE_FLAGS.equals(callbackRequest.getEventId())) { supportTaskService.prepareArrangeSupportTask(caseData, caseDataBefore); } } diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java index c6943a5241..d3f18ff625 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java @@ -9,9 +9,11 @@ import uk.gov.hmcts.et.common.model.ccd.types.SupportTaskState; import uk.gov.hmcts.ethos.replacement.docmosis.config.SupportTaskConfiguration; +import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.Set; import java.util.function.Consumer; import java.util.function.Predicate; @@ -56,6 +58,10 @@ public void prepareNewFlagReviewSupportTasks(CaseData caseData, CaseData caseDat .map(GenericTypeItem::getValue) .toList(); + if (newFlags.isEmpty()) { + newFlags = latestCreatedFlag(caseData).map(List::of).orElseGet(List::of); + } + prepareTasks(caseData, newFlags); } @@ -149,6 +155,27 @@ public void prepareArrangeSupportTask(CaseData caseData, CaseData caseDataBefore .ifPresent(taskState::setArrangeSupportTaskName); } + public void prepareNewFlagArrangeSupportTask(CaseData caseData, CaseData caseDataBefore) { + prepareArrangeSupportTask(caseData, caseDataBefore); + if (caseData.getSupportTaskState().getArrangeSupportTaskName() != null) { + return; + } + + Map flagTitles = configuration.getArrange().getFlagTitles(); + latestCreatedFlag(caseData) + .filter(flag -> FLAG_STATUS_ACTIVE.equals(flag.getStatus())) + .map(FlagDetailType::getFlagCode) + .map(flagTitles::get) + .ifPresent(caseData.getSupportTaskState()::setArrangeSupportTaskName); + } + + private static Optional latestCreatedFlag(CaseData caseData) { + return allFlagItems(caseData.getAllPartyFlags()) + .map(GenericTypeItem::getValue) + .filter(flag -> flag.getDateTimeCreated() != null) + .max(Comparator.comparing(FlagDetailType::getDateTimeCreated)); + } + private static boolean wasNotPreviouslyActive(GenericTypeItem current, List> previousFlags) { return previousFlags.stream() diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java index 4649567b71..ae4c2210db 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java @@ -394,7 +394,7 @@ void preparesReviewSupportTasksForNewCaseFlags(String eventId) { verify(supportTaskService).prepareNewFlagReviewSupportTasks( any(CaseData.class), any(CaseData.class)); if ("createFlag".equals(eventId)) { - verify(supportTaskService).prepareArrangeSupportTask( + verify(supportTaskService).prepareNewFlagArrangeSupportTask( any(CaseData.class), any(CaseData.class)); } } @@ -435,6 +435,8 @@ void doesNotPrepareReviewSupportTasksWhenCaseFlagsV2IsDisabled() { verify(supportTaskService, never()).prepareManagedReviewSupportTasks(any(CaseData.class)); verify(supportTaskService, never()).prepareArrangeSupportTask( any(CaseData.class), nullable(CaseData.class)); + verify(supportTaskService, never()).prepareNewFlagArrangeSupportTask( + any(CaseData.class), nullable(CaseData.class)); } @Test diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java index 6e832bdc50..8a1bcad781 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java @@ -151,6 +151,20 @@ void prepares_task_for_a_new_requested_flag() { assertEquals(YES, taskState(caseData).getAdminTaskRequired()); } + @Test + void prepares_review_task_when_create_flag_before_data_already_contains_the_new_flag() { + CaseFlagsType requestedFlag = caseFlags("new-flag", "RA0038", "Requested", "2026-09-11T10:00:00.000Z"); + CaseData caseDataBefore = new CaseData(); + caseDataBefore.setAllPartyFlags(AllPartyFlags.builder().claimantFlags(requestedFlag).build()); + CaseData caseData = new CaseData(); + caseData.setAllPartyFlags(AllPartyFlags.builder().claimantFlags(requestedFlag).build()); + + service.prepareNewFlagReviewSupportTasks(caseData, caseDataBefore); + + assertEquals(YES, taskState(caseData).getJudgeTaskCreated()); + assertEquals(YES, taskState(caseData).getJudgeTaskRequired()); + } + @Test void does_not_treat_an_unchanged_flag_without_an_id_as_new() { CaseData caseDataBefore = new CaseData(); @@ -368,6 +382,32 @@ void prepares_arrange_support_task_when_existing_flag_becomes_active() { assertEquals("Sign language interpreter", taskState(caseData).getArrangeSupportTaskName()); } + @Test + void prepares_arrange_task_when_create_flag_before_data_already_contains_the_new_active_flag() { + CaseFlagsType activeFlag = caseFlags("new-flag", "RA0038", "Active", "2026-09-11T10:00:00.000Z"); + CaseData caseDataBefore = new CaseData(); + caseDataBefore.setAllPartyFlags(AllPartyFlags.builder().claimantFlags(activeFlag).build()); + CaseData caseData = new CaseData(); + caseData.setAllPartyFlags(AllPartyFlags.builder().claimantFlags(activeFlag).build()); + + service.prepareNewFlagArrangeSupportTask(caseData, caseDataBefore); + + assertEquals("Intermediary", taskState(caseData).getArrangeSupportTaskName()); + } + + @Test + void does_not_fall_back_to_an_older_eligible_flag_when_the_newest_flag_is_ineligible() { + CaseData caseData = new CaseData(); + caseData.setAllPartyFlags(AllPartyFlags.builder() + .claimantFlags(caseFlags("old-flag", "RA0038", "Active", "2026-09-11T09:00:00.000Z")) + .respondentFlags(caseFlags("new-flag", "RA9999", "Active", "2026-09-11T10:00:00.000Z")) + .build()); + + service.prepareNewFlagArrangeSupportTask(caseData, caseData); + + assertNull(taskState(caseData).getArrangeSupportTaskName()); + } + @Test void does_not_prepare_arrange_support_task_for_unchanged_active_flag() { CaseData caseDataBefore = new CaseData(); @@ -417,9 +457,14 @@ private static CaseData caseDataWithClaimantFlag(String flagCode, } private static CaseFlagsType caseFlags(String id, String flagCode, String status) { + return caseFlags(id, flagCode, status, null); + } + + private static CaseFlagsType caseFlags(String id, String flagCode, String status, String dateTimeCreated) { FlagDetailType detail = FlagDetailType.builder() .flagCode(flagCode) .status(status) + .dateTimeCreated(dateTimeCreated) .build(); ListTypeItem details = ListTypeItem.from(GenericTypeItem.from(id, detail)); return CaseFlagsType.builder().details(details).build(); From 044c32f9aad6f4846beaf2b5716e7dd488676fa3 Mon Sep 17 00:00:00 2001 From: rajaram Date: Fri, 11 Sep 2026 16:00:30 +0100 Subject: [PATCH 054/100] Removed unwanted top-level flag code configuration --- src/main/resources/support-tasks.yml | 8 --- .../config/SupportTaskConfigurationTest.java | 6 +-- .../service/SupportTaskServiceTest.java | 51 +++++++++---------- 3 files changed, 26 insertions(+), 39 deletions(-) diff --git a/src/main/resources/support-tasks.yml b/src/main/resources/support-tasks.yml index da310f51fd..be028d8a8b 100644 --- a/src/main/resources/support-tasks.yml +++ b/src/main/resources/support-tasks.yml @@ -1,13 +1,6 @@ support-tasks: review: admin-flag-codes: - - RA0002 - - RA0003 - - RA0004 - - RA0005 - - RA0006 - - RA0008 - - RA0009 - RA0021 - RA0033 - RA0039 @@ -24,7 +17,6 @@ support-tasks: - RA0036 arrange: flag-titles: - RA0003: I need help with forms RA0017: Guidance on how to complete forms RA0018: Support filling in forms RA0019: Step free / wheelchair access diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/config/SupportTaskConfigurationTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/config/SupportTaskConfigurationTest.java index f9c1e5682e..4842797cd6 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/config/SupportTaskConfigurationTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/config/SupportTaskConfigurationTest.java @@ -19,15 +19,13 @@ class SupportTaskConfigurationTest { void loadsFlagCodesFromYaml() { assertThat(configuration.getReview().getAdminFlagCodes()) .containsExactlyInAnyOrder( - "RA0002", "RA0003", "RA0004", "RA0005", "RA0006", "RA0008", "RA0009", "RA0021", - "RA0033", "RA0039", "RA0041"); + "RA0021", "RA0033", "RA0039", "RA0041"); assertThat(configuration.getReview().getJudgeFlagCodes()) .containsExactlyInAnyOrder("RA0029", "RA0031", "RA0032", "RA0037", "RA0038"); assertThat(configuration.getReview().getLegalOfficerFlagCodes()) .containsExactlyInAnyOrder("RA0034", "RA0035", "RA0036"); assertThat(configuration.getArrange().getFlagTitles()) - .containsEntry("RA0003", "I need help with forms") .containsEntry("RA0017", "Guidance on how to complete forms") .containsEntry("RA0018", "Support filling in forms") .containsEntry("RA0019", "Step free / wheelchair access") @@ -44,6 +42,6 @@ void loadsFlagCodesFromYaml() { .containsEntry("RA0044", "Infrared receiver (hearing enhancement system)") .containsEntry("RA0045", "Induction loop (hearing enhancement system)") .containsEntry("RA0046", "Visit to court or tribunal before the hearing") - .hasSize(17); + .hasSize(16); } } diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java index 8a1bcad781..37693d972d 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java @@ -28,12 +28,10 @@ class SupportTaskServiceTest { private static SupportTaskConfiguration configuration() { SupportTaskConfiguration configuration = new SupportTaskConfiguration(); configuration.getReview().setAdminFlagCodes(Set.of( - "RA0002", "RA0003", "RA0004", "RA0005", "RA0006", "RA0008", "RA0009", "RA0021", "RA0033", - "RA0039", "RA0041")); + "RA0021", "RA0033", "RA0039", "RA0041")); configuration.getReview().setLegalOfficerFlagCodes(Set.of("RA0034", "RA0035", "RA0036")); configuration.getReview().setJudgeFlagCodes(Set.of("RA0029", "RA0031", "RA0032", "RA0037", "RA0038")); configuration.getArrange().setFlagTitles(Map.ofEntries( - Map.entry("RA0003", "I need help with forms"), Map.entry("RA0017", "Guidance on how to complete forms"), Map.entry("RA0018", "Support filling in forms"), Map.entry("RA0019", "Step free / wheelchair access"), @@ -56,8 +54,7 @@ private static SupportTaskConfiguration configuration() { static Stream eligibleFlagScenarios() { return Stream.of( - Stream.of("RA0002", "RA0003", "RA0004", "RA0005", "RA0006", "RA0008", "RA0009", "RA0021", - "RA0033", "RA0039", "RA0041") + Stream.of("RA0021", "RA0033", "RA0039", "RA0041") .map(code -> Arguments.of(code, "Admin")), Stream.of("RA0034", "RA0035", "RA0036") .map(code -> Arguments.of(code, "LegalOfficer")), @@ -112,7 +109,7 @@ void prepares_task_for_requested_flag_from_any_respondent() { @Test void respondent_event_does_not_use_a_claimant_flag() { - CaseData caseData = caseDataWithClaimantFlag("RA0002", "Requested", false); + CaseData caseData = caseDataWithClaimantFlag("RA0033", "Requested", false); service.prepareRespondentReviewSupportTasks(caseData); @@ -123,11 +120,11 @@ void respondent_event_does_not_use_a_claimant_flag() { void prepares_task_only_for_a_newly_created_flag() { CaseData caseDataBefore = new CaseData(); caseDataBefore.setAllPartyFlags(AllPartyFlags.builder() - .claimantFlags(caseFlags("existing-flag", "RA0002", "Requested")) + .claimantFlags(caseFlags("existing-flag", "RA0033", "Requested")) .build()); CaseData caseData = new CaseData(); caseData.setAllPartyFlags(AllPartyFlags.builder() - .claimantFlags(caseFlags("existing-flag", "RA0002", "Requested")) + .claimantFlags(caseFlags("existing-flag", "RA0033", "Requested")) .respondent2Flags(caseFlags("new-flag", "RA0029", "Requested")) .build()); @@ -142,7 +139,7 @@ void prepares_task_only_for_a_newly_created_flag() { void prepares_task_for_a_new_requested_flag() { CaseData caseData = new CaseData(); caseData.setAllPartyFlags(AllPartyFlags.builder() - .representative2ExternalFlags(caseFlags("new-flag", "RA0002", "Requested")) + .representative2ExternalFlags(caseFlags("new-flag", "RA0033", "Requested")) .build()); service.prepareNewFlagReviewSupportTasks(caseData, new CaseData()); @@ -169,11 +166,11 @@ void prepares_review_task_when_create_flag_before_data_already_contains_the_new_ void does_not_treat_an_unchanged_flag_without_an_id_as_new() { CaseData caseDataBefore = new CaseData(); caseDataBefore.setAllPartyFlags(AllPartyFlags.builder() - .claimantFlags(caseFlags(null, "RA0002", "Requested")) + .claimantFlags(caseFlags(null, "RA0033", "Requested")) .build()); CaseData caseData = new CaseData(); caseData.setAllPartyFlags(AllPartyFlags.builder() - .claimantFlags(caseFlags(null, "RA0002", "Requested")) + .claimantFlags(caseFlags(null, "RA0033", "Requested")) .build()); service.prepareNewFlagReviewSupportTasks(caseData, caseDataBefore); @@ -186,11 +183,11 @@ void does_not_treat_an_unchanged_flag_without_an_id_as_new() { void does_not_treat_an_updated_existing_flag_as_new() { CaseData caseDataBefore = new CaseData(); caseDataBefore.setAllPartyFlags(AllPartyFlags.builder() - .claimantFlags(caseFlags("existing-flag", "RA0002", "Active")) + .claimantFlags(caseFlags("existing-flag", "RA0033", "Active")) .build()); CaseData caseData = new CaseData(); caseData.setAllPartyFlags(AllPartyFlags.builder() - .claimantFlags(caseFlags("existing-flag", "RA0002", "Requested")) + .claimantFlags(caseFlags("existing-flag", "RA0033", "Requested")) .build()); service.prepareNewFlagReviewSupportTasks(caseData, caseDataBefore); @@ -203,7 +200,7 @@ void does_not_treat_an_updated_existing_flag_as_new() { void does_not_prepare_task_for_a_new_case_level_flag() { CaseData caseData = new CaseData(); caseData.setAllPartyFlags(AllPartyFlags.builder() - .caseFlags(caseFlags("new-case-flag", "RA0002", "Requested")) + .caseFlags(caseFlags("new-case-flag", "RA0033", "Requested")) .build()); service.prepareNewFlagReviewSupportTasks(caseData, new CaseData()); @@ -215,7 +212,7 @@ void does_not_prepare_task_for_a_new_case_level_flag() { void prepares_tasks_for_new_claimant_and_representative_flags() { CaseData caseData = new CaseData(); caseData.setAllPartyFlags(AllPartyFlags.builder() - .claimantExternalFlags(caseFlags("claimant-flag", "RA0002", "Requested")) + .claimantExternalFlags(caseFlags("claimant-flag", "RA0033", "Requested")) .claimantRepresentativeFlags(caseFlags("claimant-rep-flag", "RA0034", "Requested")) .representative4ExternalFlags(caseFlags("respondent-rep-flag", "RA0029", "Requested")) .build()); @@ -231,7 +228,7 @@ void prepares_tasks_for_new_claimant_and_representative_flags() { void completes_only_task_type_without_an_eligible_requested_flag() { CaseData caseData = new CaseData(); caseData.setAllPartyFlags(AllPartyFlags.builder() - .claimantFlags(caseFlags("admin-flag", "RA0002", "Active")) + .claimantFlags(caseFlags("admin-flag", "RA0033", "Active")) .respondent2Flags(caseFlags("judge-flag", "RA0029", "Requested")) .build()); caseData.setSupportTaskState(SupportTaskState.builder() @@ -252,8 +249,8 @@ void completes_only_task_type_without_an_eligible_requested_flag() { void keeps_task_active_when_another_party_has_an_eligible_requested_flag() { CaseData caseData = new CaseData(); caseData.setAllPartyFlags(AllPartyFlags.builder() - .claimantFlags(caseFlags("managed-flag", "RA0002", "Active")) - .representative2ExternalFlags(caseFlags("requested-flag", "RA0003", "Requested")) + .claimantFlags(caseFlags("managed-flag", "RA0033", "Active")) + .representative2ExternalFlags(caseFlags("requested-flag", "RA0033", "Requested")) .build()); caseData.setSupportTaskState(SupportTaskState.builder().adminTaskCreated(YES).build()); @@ -265,7 +262,7 @@ void keeps_task_active_when_another_party_has_an_eligible_requested_flag() { @Test void keeps_task_active_when_an_eligible_requested_flag_remains() { - CaseData caseData = caseDataWithClaimantFlag("RA0002", "Requested", false); + CaseData caseData = caseDataWithClaimantFlag("RA0033", "Requested", false); caseData.setSupportTaskState(SupportTaskState.builder().adminTaskCreated(YES).build()); service.prepareManagedReviewSupportTasks(caseData); @@ -295,13 +292,13 @@ void completes_created_tasks_when_party_flags_are_missing() { @Test void creates_a_new_task_after_the_previous_task_was_completed() { - CaseData caseDataBefore = caseDataWithClaimantFlag("RA0002", "Active", false); + CaseData caseDataBefore = caseDataWithClaimantFlag("RA0033", "Active", false); caseDataBefore.setSupportTaskState(SupportTaskState.builder().adminTaskCreated(YES).build()); service.prepareManagedReviewSupportTasks(caseDataBefore); - CaseData caseData = caseDataWithClaimantFlag("RA0002", "Active", false); + CaseData caseData = caseDataWithClaimantFlag("RA0033", "Active", false); caseData.getAllPartyFlags().setRespondent1Flags( - caseFlags("new-requested-flag", "RA0003", "Requested")); + caseFlags("new-requested-flag", "RA0033", "Requested")); service.prepareNewFlagReviewSupportTasks(caseData, caseDataBefore); @@ -311,8 +308,8 @@ void creates_a_new_task_after_the_previous_task_was_completed() { static Stream ineligibleFlagScenarios() { return Stream.of( - Arguments.of("RA0002", "Active"), - Arguments.of("RA0002", null), + Arguments.of("RA0033", "Active"), + Arguments.of("RA0033", null), Arguments.of("RA9999", "Requested") ); } @@ -412,11 +409,11 @@ void does_not_fall_back_to_an_older_eligible_flag_when_the_newest_flag_is_inelig void does_not_prepare_arrange_support_task_for_unchanged_active_flag() { CaseData caseDataBefore = new CaseData(); caseDataBefore.setAllPartyFlags(AllPartyFlags.builder() - .claimantFlags(caseFlags("unchanged-flag", "RA0003", "Active")) + .claimantFlags(caseFlags("unchanged-flag", "RA0017", "Active")) .build()); CaseData caseData = new CaseData(); caseData.setAllPartyFlags(AllPartyFlags.builder() - .claimantFlags(caseFlags("unchanged-flag", "RA0003", "Active")) + .claimantFlags(caseFlags("unchanged-flag", "RA0017", "Active")) .build()); service.prepareArrangeSupportTask(caseData, caseDataBefore); @@ -428,7 +425,7 @@ void does_not_prepare_arrange_support_task_for_unchanged_active_flag() { void does_not_prepare_arrange_support_task_for_ineligible_or_non_active_flag() { CaseData caseData = new CaseData(); caseData.setAllPartyFlags(AllPartyFlags.builder() - .claimantFlags(caseFlags("requested-flag", "RA0003", "Requested")) + .claimantFlags(caseFlags("requested-flag", "RA0017", "Requested")) .respondentFlags(caseFlags("ineligible-flag", "RA9999", "Active")) .build()); caseData.setSupportTaskState(SupportTaskState.builder() From 602d7cf689b003e43e534dc03bd635b145adacee Mon Sep 17 00:00:00 2001 From: rajaram Date: Fri, 11 Sep 2026 16:20:11 +0100 Subject: [PATCH 055/100] Reverted - Removed unwanted top-level flag code configuration --- src/main/resources/support-tasks.yml | 8 ++++++++ .../docmosis/config/SupportTaskConfigurationTest.java | 4 +++- .../docmosis/service/SupportTaskServiceTest.java | 5 ++++- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/main/resources/support-tasks.yml b/src/main/resources/support-tasks.yml index be028d8a8b..da310f51fd 100644 --- a/src/main/resources/support-tasks.yml +++ b/src/main/resources/support-tasks.yml @@ -1,6 +1,13 @@ support-tasks: review: admin-flag-codes: + - RA0002 + - RA0003 + - RA0004 + - RA0005 + - RA0006 + - RA0008 + - RA0009 - RA0021 - RA0033 - RA0039 @@ -17,6 +24,7 @@ support-tasks: - RA0036 arrange: flag-titles: + RA0003: I need help with forms RA0017: Guidance on how to complete forms RA0018: Support filling in forms RA0019: Step free / wheelchair access diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/config/SupportTaskConfigurationTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/config/SupportTaskConfigurationTest.java index 4842797cd6..8853d5aedb 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/config/SupportTaskConfigurationTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/config/SupportTaskConfigurationTest.java @@ -19,6 +19,7 @@ class SupportTaskConfigurationTest { void loadsFlagCodesFromYaml() { assertThat(configuration.getReview().getAdminFlagCodes()) .containsExactlyInAnyOrder( + "RA0002", "RA0003", "RA0004", "RA0005", "RA0006", "RA0008", "RA0009", "RA0021", "RA0033", "RA0039", "RA0041"); assertThat(configuration.getReview().getJudgeFlagCodes()) .containsExactlyInAnyOrder("RA0029", "RA0031", "RA0032", "RA0037", "RA0038"); @@ -26,6 +27,7 @@ void loadsFlagCodesFromYaml() { .containsExactlyInAnyOrder("RA0034", "RA0035", "RA0036"); assertThat(configuration.getArrange().getFlagTitles()) + .containsEntry("RA0003", "I need help with forms") .containsEntry("RA0017", "Guidance on how to complete forms") .containsEntry("RA0018", "Support filling in forms") .containsEntry("RA0019", "Step free / wheelchair access") @@ -42,6 +44,6 @@ void loadsFlagCodesFromYaml() { .containsEntry("RA0044", "Infrared receiver (hearing enhancement system)") .containsEntry("RA0045", "Induction loop (hearing enhancement system)") .containsEntry("RA0046", "Visit to court or tribunal before the hearing") - .hasSize(16); + .hasSize(17); } } diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java index 37693d972d..ffd353aa43 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java @@ -28,10 +28,12 @@ class SupportTaskServiceTest { private static SupportTaskConfiguration configuration() { SupportTaskConfiguration configuration = new SupportTaskConfiguration(); configuration.getReview().setAdminFlagCodes(Set.of( + "RA0002", "RA0003", "RA0004", "RA0005", "RA0006", "RA0008", "RA0009", "RA0021", "RA0033", "RA0039", "RA0041")); configuration.getReview().setLegalOfficerFlagCodes(Set.of("RA0034", "RA0035", "RA0036")); configuration.getReview().setJudgeFlagCodes(Set.of("RA0029", "RA0031", "RA0032", "RA0037", "RA0038")); configuration.getArrange().setFlagTitles(Map.ofEntries( + Map.entry("RA0003", "I need help with forms"), Map.entry("RA0017", "Guidance on how to complete forms"), Map.entry("RA0018", "Support filling in forms"), Map.entry("RA0019", "Step free / wheelchair access"), @@ -54,7 +56,8 @@ private static SupportTaskConfiguration configuration() { static Stream eligibleFlagScenarios() { return Stream.of( - Stream.of("RA0021", "RA0033", "RA0039", "RA0041") + Stream.of("RA0002", "RA0003", "RA0004", "RA0005", "RA0006", "RA0008", "RA0009", + "RA0021", "RA0033", "RA0039", "RA0041") .map(code -> Arguments.of(code, "Admin")), Stream.of("RA0034", "RA0035", "RA0036") .map(code -> Arguments.of(code, "LegalOfficer")), From dd3eab2ba4c17cbdb30f52bd1b757ca4894bfe7d Mon Sep 17 00:00:00 2001 From: rajaram Date: Sun, 13 Sep 2026 14:25:01 +0100 Subject: [PATCH 056/100] flagUpdateComment has been added --- .../model/ccd/items/FlagDetailType.java | 1 + .../CaseActionsForCaseWorkerController.java | 3 +- ...aseActionsForCaseWorkerControllerTest.java | 28 +++++++++++++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/items/FlagDetailType.java b/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/items/FlagDetailType.java index 12b3b29c1a..9323db5636 100644 --- a/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/items/FlagDetailType.java +++ b/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/items/FlagDetailType.java @@ -22,6 +22,7 @@ public class FlagDetailType { private String otherDescription_cy; private String flagComment; private String flagComment_cy; + private String flagUpdateComment; private String dateTimeModified; private String dateTimeCreated; private ListTypeItem path; diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java index 45c402a982..3a8d1cfaef 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java @@ -215,8 +215,7 @@ public ResponseEntity postDefaultValues( return getCallbackRespEntityErrors(errors, caseData); } - @PostMapping(value = {"/supportTasks/aboutToSubmit", "/reviewSupportTasks/aboutToSubmit"}, - consumes = APPLICATION_JSON_VALUE) + @PostMapping(value = "/supportTasks/aboutToSubmit", consumes = APPLICATION_JSON_VALUE) @Operation(summary = "Prepare Review Support and Arrange Support tasks for eligible Case Flags.") public ResponseEntity prepareSupportTasks( @RequestBody CallbackRequest callbackRequest) { diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java index ae4c2210db..28880b8721 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java @@ -418,6 +418,34 @@ void preparesReviewSupportTaskCompletionForManagedCaseFlags(String eventId) { } } + @ParameterizedTest + @ValueSource(strings = {"manageFlags", "manageSupport"}) + @SneakyThrows + void preservesCaseFlagUpdateCommentWhenSupportRequestIsRejected(String eventId) { + ((ObjectNode) requestContent2).put("event_id", eventId); + ObjectNode caseData = (ObjectNode) requestContent2.at("/case_details/case_data"); + ObjectNode flag = caseData.putObject("claimantExternalFlags") + .putArray("details") + .addObject() + .put("id", "flag-id") + .putObject("value"); + flag.put("flagCode", "RA0038"); + flag.put("status", "Rejected"); + flag.put("flagComment", "Original request comment"); + flag.put("flagUpdateComment", "Rejection comment"); + when(featureToggleService.isCaseFlagsV2Enabled(anyString())).thenReturn(true); + + mvc.perform(post(SUPPORT_TASKS_URL) + .content(requestContent2.toString()) + .header(AUTHORIZATION, AUTH_TOKEN) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.data.claimantExternalFlags.details[0].value.flagComment", + is("Original request comment"))) + .andExpect(jsonPath("$.data.claimantExternalFlags.details[0].value.flagUpdateComment", + is("Rejection comment"))); + } + @Test @SneakyThrows void doesNotPrepareReviewSupportTasksWhenCaseFlagsV2IsDisabled() { From eee52108ea48cfb74bc1ce822707ba45a5bec31e Mon Sep 17 00:00:00 2001 From: rajaram Date: Mon, 14 Sep 2026 12:38:38 +0100 Subject: [PATCH 057/100] Added new events to create approve request tasks --- .../EventToComplexTypes-SupportTasks.json | 45 +++++++++++++++++++ .../EventToComplexTypes-SupportTasks.json | 45 +++++++++++++++++++ .../hmcts/et/common/model/ccd/CCDRequest.java | 7 +++ .../CaseActionsForCaseWorkerController.java | 8 +++- ...aseActionsForCaseWorkerControllerTest.java | 16 ++++--- 5 files changed, 115 insertions(+), 6 deletions(-) diff --git a/ccd-definitions/jurisdictions/england-wales/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json b/ccd-definitions/jurisdictions/england-wales/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json index 0305335c4f..c92557e041 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json +++ b/ccd-definitions/jurisdictions/england-wales/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json @@ -26,6 +26,15 @@ "DisplayContext": "OPTIONAL", "Publish": "Y" }, + { + "ID": "SupportTaskState", + "CaseEventID": "SUBMIT_CASE_DRAFT", + "CaseFieldID": "supportTaskState", + "ListElementCode": "arrangeSupportTaskName", + "FieldDisplayOrder": 4, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, { "ID": "SupportTaskState", "CaseEventID": "UPDATE_CASE_SUBMITTED", @@ -53,6 +62,15 @@ "DisplayContext": "OPTIONAL", "Publish": "Y" }, + { + "ID": "SupportTaskState", + "CaseEventID": "UPDATE_CASE_SUBMITTED", + "CaseFieldID": "supportTaskState", + "ListElementCode": "arrangeSupportTaskName", + "FieldDisplayOrder": 4, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, { "ID": "SupportTaskState", "CaseEventID": "SUBMIT_ET3_FORM", @@ -80,6 +98,15 @@ "DisplayContext": "OPTIONAL", "Publish": "Y" }, + { + "ID": "SupportTaskState", + "CaseEventID": "SUBMIT_ET3_FORM", + "CaseFieldID": "supportTaskState", + "ListElementCode": "arrangeSupportTaskName", + "FieldDisplayOrder": 4, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, { "ID": "SupportTaskState", "CaseEventID": "UPDATE_ET3_FORM", @@ -107,6 +134,15 @@ "DisplayContext": "OPTIONAL", "Publish": "Y" }, + { + "ID": "SupportTaskState", + "CaseEventID": "UPDATE_ET3_FORM", + "CaseFieldID": "supportTaskState", + "ListElementCode": "arrangeSupportTaskName", + "FieldDisplayOrder": 4, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, { "ID": "SupportTaskState", "CaseEventID": "requestSupport", @@ -134,6 +170,15 @@ "DisplayContext": "OPTIONAL", "Publish": "Y" }, + { + "ID": "SupportTaskState", + "CaseEventID": "requestSupport", + "CaseFieldID": "supportTaskState", + "ListElementCode": "arrangeSupportTaskName", + "FieldDisplayOrder": 4, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, { "ID": "SupportTaskState", "CaseEventID": "createFlag", diff --git a/ccd-definitions/jurisdictions/scotland/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json b/ccd-definitions/jurisdictions/scotland/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json index 0305335c4f..c92557e041 100644 --- a/ccd-definitions/jurisdictions/scotland/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json +++ b/ccd-definitions/jurisdictions/scotland/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json @@ -26,6 +26,15 @@ "DisplayContext": "OPTIONAL", "Publish": "Y" }, + { + "ID": "SupportTaskState", + "CaseEventID": "SUBMIT_CASE_DRAFT", + "CaseFieldID": "supportTaskState", + "ListElementCode": "arrangeSupportTaskName", + "FieldDisplayOrder": 4, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, { "ID": "SupportTaskState", "CaseEventID": "UPDATE_CASE_SUBMITTED", @@ -53,6 +62,15 @@ "DisplayContext": "OPTIONAL", "Publish": "Y" }, + { + "ID": "SupportTaskState", + "CaseEventID": "UPDATE_CASE_SUBMITTED", + "CaseFieldID": "supportTaskState", + "ListElementCode": "arrangeSupportTaskName", + "FieldDisplayOrder": 4, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, { "ID": "SupportTaskState", "CaseEventID": "SUBMIT_ET3_FORM", @@ -80,6 +98,15 @@ "DisplayContext": "OPTIONAL", "Publish": "Y" }, + { + "ID": "SupportTaskState", + "CaseEventID": "SUBMIT_ET3_FORM", + "CaseFieldID": "supportTaskState", + "ListElementCode": "arrangeSupportTaskName", + "FieldDisplayOrder": 4, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, { "ID": "SupportTaskState", "CaseEventID": "UPDATE_ET3_FORM", @@ -107,6 +134,15 @@ "DisplayContext": "OPTIONAL", "Publish": "Y" }, + { + "ID": "SupportTaskState", + "CaseEventID": "UPDATE_ET3_FORM", + "CaseFieldID": "supportTaskState", + "ListElementCode": "arrangeSupportTaskName", + "FieldDisplayOrder": 4, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, { "ID": "SupportTaskState", "CaseEventID": "requestSupport", @@ -134,6 +170,15 @@ "DisplayContext": "OPTIONAL", "Publish": "Y" }, + { + "ID": "SupportTaskState", + "CaseEventID": "requestSupport", + "CaseFieldID": "supportTaskState", + "ListElementCode": "arrangeSupportTaskName", + "FieldDisplayOrder": 4, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, { "ID": "SupportTaskState", "CaseEventID": "createFlag", diff --git a/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/CCDRequest.java b/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/CCDRequest.java index 514c265b68..7fccf6f5a7 100644 --- a/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/CCDRequest.java +++ b/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/CCDRequest.java @@ -17,4 +17,11 @@ public class CCDRequest extends GenericRequest { @JsonProperty("case_details") private CaseDetails caseDetails; + + @JsonProperty("case_details_before") + private CaseDetails caseDetailsBefore; + + public CCDRequest(CaseDetails caseDetails) { + this.caseDetails = caseDetails; + } } diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java index 3a8d1cfaef..c700de561e 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java @@ -193,6 +193,10 @@ public ResponseEntity postDefaultValues( if (featureToggleService.isCaseFlagsV2Enabled(caseDetails.getCaseTypeId()) && REVIEW_SUPPORT_TASK_EVENTS.contains(ccdRequest.getEventId())) { supportTaskService.prepareReviewSupportTasks(caseData); + CaseData caseDataBefore = ccdRequest.getCaseDetailsBefore() == null + ? null + : ccdRequest.getCaseDetailsBefore().getCaseData(); + supportTaskService.prepareArrangeSupportTask(caseData, caseDataBefore); } boolean hmcToggle = featureToggleService.isHmcEnabled(); @@ -228,6 +232,7 @@ public ResponseEntity prepareSupportTasks( : callbackRequest.getCaseDetailsBefore().getCaseData(); if (RESPONDENT_REVIEW_SUPPORT_TASK_EVENTS.contains(callbackRequest.getEventId())) { supportTaskService.prepareRespondentReviewSupportTasks(caseData); + supportTaskService.prepareNewFlagArrangeSupportTask(caseData, caseDataBefore); } else if (NEW_FLAG_REVIEW_SUPPORT_TASK_EVENTS.contains(callbackRequest.getEventId())) { supportTaskService.prepareNewFlagReviewSupportTasks(caseData, caseDataBefore); } else if (EVENT_MANAGE_FLAGS.equals(callbackRequest.getEventId()) @@ -235,7 +240,8 @@ public ResponseEntity prepareSupportTasks( supportTaskService.prepareManagedReviewSupportTasks(caseData); } - if (EVENT_CREATE_FLAG.equals(callbackRequest.getEventId())) { + if (EVENT_CREATE_FLAG.equals(callbackRequest.getEventId()) + || EVENT_REQUEST_SUPPORT.equals(callbackRequest.getEventId())) { supportTaskService.prepareNewFlagArrangeSupportTask(caseData, caseDataBefore); } else if (EVENT_MANAGE_FLAGS.equals(callbackRequest.getEventId())) { supportTaskService.prepareArrangeSupportTask(caseData, caseDataBefore); diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java index 28880b8721..754e461c07 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java @@ -327,8 +327,10 @@ void postDefaultValues() { @ParameterizedTest @ValueSource(strings = {"SUBMIT_CASE_DRAFT", "UPDATE_CASE_SUBMITTED"}) @SneakyThrows - void postDefaultValuesPreparesReviewSupportTasksForCaseFlagsV2Events(String eventId) { + void postDefaultValuesPreparesSupportTasksForCaseFlagsV2Events(String eventId) { ((ObjectNode) requestContent2).put("event_id", eventId); + ((ObjectNode) requestContent2).set("case_details_before", + requestContent2.get("case_details").deepCopy()); when(defaultValuesReaderService.getDefaultValues(anyString())).thenReturn(defaultValues); when(singleReferenceService.createReference(anyString())).thenReturn("5100001/2019"); when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); @@ -341,6 +343,8 @@ void postDefaultValuesPreparesReviewSupportTasksForCaseFlagsV2Events(String even .andExpect(status().isOk()); verify(supportTaskService).prepareReviewSupportTasks(any(CaseData.class)); + verify(supportTaskService).prepareArrangeSupportTask( + any(CaseData.class), any(CaseData.class)); } @Test @@ -358,6 +362,8 @@ void postDefaultValuesDoesNotPrepareReviewSupportTasksWhenCaseFlagsV2IsDisabled( .andExpect(status().isOk()); verify(supportTaskService, never()).prepareReviewSupportTasks(any(CaseData.class)); + verify(supportTaskService, never()).prepareArrangeSupportTask( + any(CaseData.class), nullable(CaseData.class)); } @ParameterizedTest @@ -374,6 +380,8 @@ void preparesRespondentReviewSupportTasksForEt3Events(String eventId) { .andExpect(status().isOk()); verify(supportTaskService).prepareRespondentReviewSupportTasks(any(CaseData.class)); + verify(supportTaskService).prepareNewFlagArrangeSupportTask( + any(CaseData.class), nullable(CaseData.class)); } @ParameterizedTest @@ -393,10 +401,8 @@ void preparesReviewSupportTasksForNewCaseFlags(String eventId) { verify(supportTaskService).prepareNewFlagReviewSupportTasks( any(CaseData.class), any(CaseData.class)); - if ("createFlag".equals(eventId)) { - verify(supportTaskService).prepareNewFlagArrangeSupportTask( - any(CaseData.class), any(CaseData.class)); - } + verify(supportTaskService).prepareNewFlagArrangeSupportTask( + any(CaseData.class), any(CaseData.class)); } @ParameterizedTest From 3e75b1754b4d64b566a772dd454611f73d8c0329 Mon Sep 17 00:00:00 2001 From: rajaram Date: Mon, 14 Sep 2026 13:18:30 +0100 Subject: [PATCH 058/100] Fixed duplicate task creation issue --- .../docmosis/service/SupportTaskService.java | 19 +++++++++++++++++++ .../service/SupportTaskServiceTest.java | 15 +++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java index d3f18ff625..38e8dbe3ea 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java @@ -44,6 +44,7 @@ public void prepareRespondentReviewSupportTasks(CaseData caseData) { } public void prepareNewFlagReviewSupportTasks(CaseData caseData, CaseData caseDataBefore) { + retainCreatedTaskState(caseData, caseDataBefore); List> previousFlags = allFlagItems( caseDataBefore == null ? null : caseDataBefore.getAllPartyFlags()).toList(); Set previousFlagIds = previousFlags.stream() @@ -65,6 +66,24 @@ public void prepareNewFlagReviewSupportTasks(CaseData caseData, CaseData caseDat prepareTasks(caseData, newFlags); } + private static void retainCreatedTaskState(CaseData caseData, CaseData caseDataBefore) { + if (caseDataBefore == null || caseDataBefore.getSupportTaskState() == null) { + return; + } + + SupportTaskState currentState = taskState(caseData); + SupportTaskState previousState = caseDataBefore.getSupportTaskState(); + if (currentState.getAdminTaskCreated() == null) { + currentState.setAdminTaskCreated(previousState.getAdminTaskCreated()); + } + if (currentState.getLegalOfficerTaskCreated() == null) { + currentState.setLegalOfficerTaskCreated(previousState.getLegalOfficerTaskCreated()); + } + if (currentState.getJudgeTaskCreated() == null) { + currentState.setJudgeTaskCreated(previousState.getJudgeTaskCreated()); + } + } + public void prepareManagedReviewSupportTasks(CaseData caseData) { SupportTaskState taskState = taskState(caseData); List flags = allFlagItems(caseData.getAllPartyFlags()) diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java index ffd353aa43..da568a3bf7 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java @@ -151,6 +151,21 @@ void prepares_task_for_a_new_requested_flag() { assertEquals(YES, taskState(caseData).getAdminTaskRequired()); } + @Test + void does_not_prepare_duplicate_judge_task_for_requested_flag_on_another_party() { + CaseData caseDataBefore = caseDataWithClaimantFlag("RA0038", "Requested", false); + caseDataBefore.setSupportTaskState(SupportTaskState.builder().judgeTaskCreated(YES).build()); + + CaseData caseData = caseDataWithClaimantFlag("RA0038", "Requested", false); + caseData.getAllPartyFlags().setRespondent1Flags( + caseFlags("respondent-flag", "RA0038", "Requested")); + + service.prepareNewFlagReviewSupportTasks(caseData, caseDataBefore); + + assertEquals(YES, taskState(caseData).getJudgeTaskCreated()); + assertNull(taskState(caseData).getJudgeTaskRequired()); + } + @Test void prepares_review_task_when_create_flag_before_data_already_contains_the_new_flag() { CaseFlagsType requestedFlag = caseFlags("new-flag", "RA0038", "Requested", "2026-09-11T10:00:00.000Z"); From 00fb1253a913493732ac64e1f268081052c8a849 Mon Sep 17 00:00:00 2001 From: rajaram Date: Tue, 15 Sep 2026 16:29:26 +0100 Subject: [PATCH 059/100] Fixed review task auto close issue --- .../CaseActionsForCaseWorkerController.java | 2 +- .../docmosis/service/SupportTaskService.java | 3 ++- ...aseActionsForCaseWorkerControllerTest.java | 12 ++++++---- .../service/SupportTaskServiceTest.java | 22 ++++++++++++++----- 4 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java index c700de561e..550598d015 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java @@ -237,7 +237,7 @@ public ResponseEntity prepareSupportTasks( supportTaskService.prepareNewFlagReviewSupportTasks(caseData, caseDataBefore); } else if (EVENT_MANAGE_FLAGS.equals(callbackRequest.getEventId()) || EVENT_MANAGE_SUPPORT.equals(callbackRequest.getEventId())) { - supportTaskService.prepareManagedReviewSupportTasks(caseData); + supportTaskService.prepareManagedReviewSupportTasks(caseData, caseDataBefore); } if (EVENT_CREATE_FLAG.equals(callbackRequest.getEventId()) diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java index 38e8dbe3ea..51f2e0fb6f 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java @@ -84,7 +84,8 @@ private static void retainCreatedTaskState(CaseData caseData, CaseData caseDataB } } - public void prepareManagedReviewSupportTasks(CaseData caseData) { + public void prepareManagedReviewSupportTasks(CaseData caseData, CaseData caseDataBefore) { + retainCreatedTaskState(caseData, caseDataBefore); SupportTaskState taskState = taskState(caseData); List flags = allFlagItems(caseData.getAllPartyFlags()) .map(GenericTypeItem::getValue) diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java index 754e461c07..3e150d6f6b 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java @@ -74,7 +74,6 @@ import static org.mockito.Mockito.doCallRealMethod; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.isNull; import static org.mockito.Mockito.never; import static org.mockito.Mockito.nullable; import static org.mockito.Mockito.same; @@ -410,6 +409,8 @@ void preparesReviewSupportTasksForNewCaseFlags(String eventId) { @SneakyThrows void preparesReviewSupportTaskCompletionForManagedCaseFlags(String eventId) { ((ObjectNode) requestContent2).put("event_id", eventId); + ((ObjectNode) requestContent2).set("case_details_before", + requestContent2.get("case_details").deepCopy()); when(featureToggleService.isCaseFlagsV2Enabled(anyString())).thenReturn(true); mvc.perform(post(SUPPORT_TASKS_URL) @@ -418,9 +419,11 @@ void preparesReviewSupportTaskCompletionForManagedCaseFlags(String eventId) { .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()); - verify(supportTaskService).prepareManagedReviewSupportTasks(any(CaseData.class)); + verify(supportTaskService).prepareManagedReviewSupportTasks( + any(CaseData.class), any(CaseData.class)); if ("manageFlags".equals(eventId)) { - verify(supportTaskService).prepareArrangeSupportTask(any(CaseData.class), isNull()); + verify(supportTaskService).prepareArrangeSupportTask( + any(CaseData.class), any(CaseData.class)); } } @@ -466,7 +469,8 @@ void doesNotPrepareReviewSupportTasksWhenCaseFlagsV2IsDisabled() { verify(supportTaskService, never()).prepareRespondentReviewSupportTasks(any(CaseData.class)); verify(supportTaskService, never()).prepareNewFlagReviewSupportTasks( any(CaseData.class), any(CaseData.class)); - verify(supportTaskService, never()).prepareManagedReviewSupportTasks(any(CaseData.class)); + verify(supportTaskService, never()).prepareManagedReviewSupportTasks( + any(CaseData.class), nullable(CaseData.class)); verify(supportTaskService, never()).prepareArrangeSupportTask( any(CaseData.class), nullable(CaseData.class)); verify(supportTaskService, never()).prepareNewFlagArrangeSupportTask( diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java index da568a3bf7..fd20ec6699 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java @@ -254,7 +254,7 @@ void completes_only_task_type_without_an_eligible_requested_flag() { .judgeTaskCreated(YES) .build()); - service.prepareManagedReviewSupportTasks(caseData); + service.prepareManagedReviewSupportTasks(caseData, null); assertNull(taskState(caseData).getAdminTaskCreated()); assertEquals(NO, taskState(caseData).getAdminTaskRequired()); @@ -272,7 +272,7 @@ void keeps_task_active_when_another_party_has_an_eligible_requested_flag() { .build()); caseData.setSupportTaskState(SupportTaskState.builder().adminTaskCreated(YES).build()); - service.prepareManagedReviewSupportTasks(caseData); + service.prepareManagedReviewSupportTasks(caseData, null); assertEquals(YES, taskState(caseData).getAdminTaskCreated()); assertNull(taskState(caseData).getAdminTaskRequired()); @@ -283,7 +283,7 @@ void keeps_task_active_when_an_eligible_requested_flag_remains() { CaseData caseData = caseDataWithClaimantFlag("RA0033", "Requested", false); caseData.setSupportTaskState(SupportTaskState.builder().adminTaskCreated(YES).build()); - service.prepareManagedReviewSupportTasks(caseData); + service.prepareManagedReviewSupportTasks(caseData, null); assertEquals(YES, taskState(caseData).getAdminTaskCreated()); assertNull(taskState(caseData).getAdminTaskRequired()); @@ -298,7 +298,7 @@ void completes_created_tasks_when_party_flags_are_missing() { .judgeTaskCreated(YES) .build()); - service.prepareManagedReviewSupportTasks(caseData); + service.prepareManagedReviewSupportTasks(caseData, null); assertNull(taskState(caseData).getAdminTaskCreated()); assertNull(taskState(caseData).getLegalOfficerTaskCreated()); @@ -308,11 +308,23 @@ void completes_created_tasks_when_party_flags_are_missing() { assertEquals(NO, taskState(caseData).getJudgeTaskRequired()); } + @Test + void completes_judge_task_when_last_requested_flag_is_managed_and_current_state_is_missing() { + CaseData caseDataBefore = caseDataWithClaimantFlag("RA0038", "Requested", false); + caseDataBefore.setSupportTaskState(SupportTaskState.builder().judgeTaskCreated(YES).build()); + CaseData caseData = caseDataWithClaimantFlag("RA0038", "Active", false); + + service.prepareManagedReviewSupportTasks(caseData, caseDataBefore); + + assertNull(taskState(caseData).getJudgeTaskCreated()); + assertEquals(NO, taskState(caseData).getJudgeTaskRequired()); + } + @Test void creates_a_new_task_after_the_previous_task_was_completed() { CaseData caseDataBefore = caseDataWithClaimantFlag("RA0033", "Active", false); caseDataBefore.setSupportTaskState(SupportTaskState.builder().adminTaskCreated(YES).build()); - service.prepareManagedReviewSupportTasks(caseDataBefore); + service.prepareManagedReviewSupportTasks(caseDataBefore, null); CaseData caseData = caseDataWithClaimantFlag("RA0033", "Active", false); caseData.getAllPartyFlags().setRespondent1Flags( From 6d6e4a83081d3c88100ae3d3e5c534530cf5f48e Mon Sep 17 00:00:00 2001 From: rajaram Date: Tue, 15 Sep 2026 17:43:46 +0100 Subject: [PATCH 060/100] Resolved merge conflicts --- .../controllers/CaseActionsForCaseWorkerController.java | 3 +-- .../controllers/CaseActionsForCaseWorkerControllerTest.java | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java index d07a365827..627a57c5cd 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java @@ -184,8 +184,7 @@ public ResponseEntity postDefaultValues( } defaultValuesReaderService.setPositionAndOffice(caseDetails.getCaseTypeId(), caseData); - boolean caseFlagsToggle = featureToggleService.isCaseFlagsV2Enabled(caseDetails.getCaseTypeId()); - if (caseFlagsToggle && caseFlagsSetupRequired(caseDetails.getCaseTypeId(), caseData)) { + if (caseFlagsSetupRequired(caseDetails.getCaseTypeId(), caseData)) { setupCaseFlags(caseDetails.getCaseTypeId(), caseData); } diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java index 5d0469c656..2d9bbc56a2 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java @@ -311,6 +311,7 @@ void postDefaultValues() { when(defaultValuesReaderService.getDefaultValues(anyString())).thenReturn(defaultValues); when(singleReferenceService.createReference(anyString())).thenReturn("5100001/2019"); when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); + when(featureToggleService.isCaseFlagsV2Enabled(anyString())).thenReturn(true); when(caseFlagsService.caseFlagsSetupRequired(any(CaseData.class))).thenReturn(true); when(nocRespondentRepresentativeService.prepopulateOrgPolicyAndNoc(any(CaseData.class))) .thenReturn(ccdRequest.getCaseDetails().getCaseData()); @@ -487,7 +488,6 @@ void postDefaultValuesSetsUpLegacyFlagsOnPrepopulatedCaseData() { when(defaultValuesReaderService.getDefaultValues(anyString())).thenReturn(defaultValues); when(singleReferenceService.createReference(anyString())).thenReturn("5100001/2019"); when(verifyTokenService.verifyTokenSignature(AUTH_TOKEN)).thenReturn(true); - when(featureToggleService.isCaseFlagsEnabled()).thenReturn(true); when(caseFlagsService.legacyCaseFlagsSetupRequired(any(CaseData.class))).thenReturn(true); when(nocRespondentRepresentativeService.prepopulateOrgPolicyAndNoc(any(CaseData.class))) .thenReturn(prepopulatedCaseData); From af248b567c6c27b00f951aaea1687c23a69f8839 Mon Sep 17 00:00:00 2001 From: hmcts-jenkins-d-to-i <62423932+hmcts-jenkins-d-to-i[bot]@users.noreply.github.com> Date: Tue, 15 Sep 2026 16:44:48 +0000 Subject: [PATCH 061/100] Bumping chart version/ fixing aliases --- charts/et-cos/Chart.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/et-cos/Chart.yaml b/charts/et-cos/Chart.yaml index b160436189..aa7c51a049 100644 --- a/charts/et-cos/Chart.yaml +++ b/charts/et-cos/Chart.yaml @@ -1,7 +1,7 @@ apiVersion: v2 name: et-cos home: https://github.com/hmcts/et-ccd-callbacks -version: 0.0.73 +version: 0.0.74 description: HMCTS Employment Tribunals CCD Callbacks service maintainers: - name: HMCTS Employment Tribunals Team From ccda5bbc71558659d35ebedcf86c9e6a63d0293b Mon Sep 17 00:00:00 2001 From: rajaram Date: Tue, 15 Sep 2026 20:03:30 +0100 Subject: [PATCH 062/100] Fixed review task auto close issue --- .../docmosis/service/SupportTaskService.java | 12 +- ...aseActionsForCaseWorkerControllerTest.java | 4 +- .../service/SupportTaskServiceTest.java | 295 +++++++++++++++--- 3 files changed, 254 insertions(+), 57 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java index 51f2e0fb6f..5acc4cef7f 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java @@ -111,17 +111,17 @@ private void prepareTasks(CaseData caseData, List flags) { taskState.setLegalOfficerTaskRequired(null); taskState.setJudgeTaskRequired(null); - if (!YES.equals(taskState.getAdminTaskCreated()) + if (!isTaskCreated(taskState.getAdminTaskCreated()) && hasRequestedFlag(flags, configuration.getReview().getAdminFlagCodes())) { taskState.setAdminTaskCreated(YES); taskState.setAdminTaskRequired(YES); } - if (!YES.equals(taskState.getLegalOfficerTaskCreated()) + if (!isTaskCreated(taskState.getLegalOfficerTaskCreated()) && hasRequestedFlag(flags, configuration.getReview().getLegalOfficerFlagCodes())) { taskState.setLegalOfficerTaskCreated(YES); taskState.setLegalOfficerTaskRequired(YES); } - if (!YES.equals(taskState.getJudgeTaskCreated()) + if (!isTaskCreated(taskState.getJudgeTaskCreated()) && hasRequestedFlag(flags, configuration.getReview().getJudgeFlagCodes())) { taskState.setJudgeTaskCreated(YES); taskState.setJudgeTaskRequired(YES); @@ -145,12 +145,16 @@ private static void updateTaskState(List flags, Consumer taskCreatedSetter, Consumer taskRequiredSetter) { taskRequiredSetter.accept(null); - if (YES.equals(taskCreated) && !hasRequestedFlag(flags, eligibleFlagCodes)) { + if (isTaskCreated(taskCreated) && !hasRequestedFlag(flags, eligibleFlagCodes)) { taskCreatedSetter.accept(null); taskRequiredSetter.accept(NO); } } + private static boolean isTaskCreated(String taskCreated) { + return YES.equalsIgnoreCase(taskCreated) || Boolean.parseBoolean(taskCreated); + } + private static boolean isRequested(FlagDetailType flag) { return FLAG_STATUS_REQUESTED.equals(flag.getStatus()); } diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java index 2d9bbc56a2..1c833c8435 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java @@ -433,7 +433,7 @@ void preparesReviewSupportTaskCompletionForManagedCaseFlags(String eventId) { @ParameterizedTest @ValueSource(strings = {"manageFlags", "manageSupport"}) @SneakyThrows - void preservesCaseFlagUpdateCommentWhenSupportRequestIsRejected(String eventId) { + void preservesCaseFlagUpdateCommentWhenSupportRequestIsNotApproved(String eventId) { ((ObjectNode) requestContent2).put("event_id", eventId); ObjectNode caseData = (ObjectNode) requestContent2.at("/case_details/case_data"); ObjectNode flag = caseData.putObject("claimantExternalFlags") @@ -442,7 +442,7 @@ void preservesCaseFlagUpdateCommentWhenSupportRequestIsRejected(String eventId) .put("id", "flag-id") .putObject("value"); flag.put("flagCode", "RA0038"); - flag.put("status", "Rejected"); + flag.put("status", "Not Approved"); flag.put("flagComment", "Original request comment"); flag.put("flagUpdateComment", "Rejection comment"); when(featureToggleService.isCaseFlagsV2Enabled(anyString())).thenReturn(true); diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java index fd20ec6699..33afd84340 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java @@ -1,5 +1,7 @@ package uk.gov.hmcts.ethos.replacement.docmosis.service; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -23,6 +25,16 @@ import static uk.gov.hmcts.ecm.common.model.helper.Constants.YES; class SupportTaskServiceTest { + private static final String TASK_TYPE_ADMIN = "Admin"; + private static final String TASK_TYPE_LEGAL_OFFICER = "LegalOfficer"; + private static final String TASK_TYPE_JUDGE = "Judge"; + private static final String STATUS_REQUESTED = "Requested"; + private static final String STATUS_ACTIVE = "Active"; + private static final String STATUS_NOT_APPROVED = "Not Approved"; + private static final String STATUS_INACTIVE = "Inactive"; + private static final String CCD_TRUE = "true"; + private static final String CCD_FALSE = "false"; + private final SupportTaskService service = new SupportTaskService(configuration()); private static SupportTaskConfiguration configuration() { @@ -58,26 +70,26 @@ static Stream eligibleFlagScenarios() { return Stream.of( Stream.of("RA0002", "RA0003", "RA0004", "RA0005", "RA0006", "RA0008", "RA0009", "RA0021", "RA0033", "RA0039", "RA0041") - .map(code -> Arguments.of(code, "Admin")), + .map(code -> Arguments.of(code, TASK_TYPE_ADMIN)), Stream.of("RA0034", "RA0035", "RA0036") - .map(code -> Arguments.of(code, "LegalOfficer")), + .map(code -> Arguments.of(code, TASK_TYPE_LEGAL_OFFICER)), Stream.of("RA0029", "RA0031", "RA0032", "RA0037", "RA0038") - .map(code -> Arguments.of(code, "Judge")) + .map(code -> Arguments.of(code, TASK_TYPE_JUDGE)) ).flatMap(stream -> stream); } @ParameterizedTest @MethodSource("eligibleFlagScenarios") void prepares_each_eligible_task_type_once_per_case(String flagCode, String taskType) { - CaseData caseData = caseDataWithClaimantFlag(flagCode, "Requested", false); + CaseData caseData = caseDataWithClaimantFlag(flagCode, STATUS_REQUESTED, false); service.prepareReviewSupportTasks(caseData); - assertEquals("Admin".equals(taskType) ? YES : null, + assertEquals(TASK_TYPE_ADMIN.equals(taskType) ? YES : null, taskState(caseData).getAdminTaskRequired()); - assertEquals("LegalOfficer".equals(taskType) ? YES : null, + assertEquals(TASK_TYPE_LEGAL_OFFICER.equals(taskType) ? YES : null, taskState(caseData).getLegalOfficerTaskRequired()); - assertEquals("Judge".equals(taskType) ? YES : null, + assertEquals(TASK_TYPE_JUDGE.equals(taskType) ? YES : null, taskState(caseData).getJudgeTaskRequired()); service.prepareReviewSupportTasks(caseData); @@ -89,7 +101,7 @@ void prepares_each_eligible_task_type_once_per_case(String flagCode, String task @Test void prepares_task_for_requested_external_claimant_flag() { - CaseData caseData = caseDataWithClaimantFlag("RA0029", "Requested", true); + CaseData caseData = caseDataWithClaimantFlag("RA0029", STATUS_REQUESTED, true); service.prepareReviewSupportTasks(caseData); @@ -101,7 +113,7 @@ void prepares_task_for_requested_external_claimant_flag() { void prepares_task_for_requested_flag_from_any_respondent() { CaseData caseData = new CaseData(); caseData.setAllPartyFlags(AllPartyFlags.builder() - .respondent3ExternalFlags(caseFlags("respondent-3-flag", "RA0034", "Requested")) + .respondent3ExternalFlags(caseFlags("respondent-3-flag", "RA0034", STATUS_REQUESTED)) .build()); service.prepareRespondentReviewSupportTasks(caseData); @@ -112,7 +124,7 @@ void prepares_task_for_requested_flag_from_any_respondent() { @Test void respondent_event_does_not_use_a_claimant_flag() { - CaseData caseData = caseDataWithClaimantFlag("RA0033", "Requested", false); + CaseData caseData = caseDataWithClaimantFlag("RA0033", STATUS_REQUESTED, false); service.prepareRespondentReviewSupportTasks(caseData); @@ -123,12 +135,12 @@ void respondent_event_does_not_use_a_claimant_flag() { void prepares_task_only_for_a_newly_created_flag() { CaseData caseDataBefore = new CaseData(); caseDataBefore.setAllPartyFlags(AllPartyFlags.builder() - .claimantFlags(caseFlags("existing-flag", "RA0033", "Requested")) + .claimantFlags(caseFlags("existing-flag", "RA0033", STATUS_REQUESTED)) .build()); CaseData caseData = new CaseData(); caseData.setAllPartyFlags(AllPartyFlags.builder() - .claimantFlags(caseFlags("existing-flag", "RA0033", "Requested")) - .respondent2Flags(caseFlags("new-flag", "RA0029", "Requested")) + .claimantFlags(caseFlags("existing-flag", "RA0033", STATUS_REQUESTED)) + .respondent2Flags(caseFlags("new-flag", "RA0029", STATUS_REQUESTED)) .build()); service.prepareNewFlagReviewSupportTasks(caseData, caseDataBefore); @@ -142,7 +154,7 @@ void prepares_task_only_for_a_newly_created_flag() { void prepares_task_for_a_new_requested_flag() { CaseData caseData = new CaseData(); caseData.setAllPartyFlags(AllPartyFlags.builder() - .representative2ExternalFlags(caseFlags("new-flag", "RA0033", "Requested")) + .representative2ExternalFlags(caseFlags("new-flag", "RA0033", STATUS_REQUESTED)) .build()); service.prepareNewFlagReviewSupportTasks(caseData, new CaseData()); @@ -153,12 +165,12 @@ void prepares_task_for_a_new_requested_flag() { @Test void does_not_prepare_duplicate_judge_task_for_requested_flag_on_another_party() { - CaseData caseDataBefore = caseDataWithClaimantFlag("RA0038", "Requested", false); + CaseData caseDataBefore = caseDataWithClaimantFlag("RA0038", STATUS_REQUESTED, false); caseDataBefore.setSupportTaskState(SupportTaskState.builder().judgeTaskCreated(YES).build()); - CaseData caseData = caseDataWithClaimantFlag("RA0038", "Requested", false); + CaseData caseData = caseDataWithClaimantFlag("RA0038", STATUS_REQUESTED, false); caseData.getAllPartyFlags().setRespondent1Flags( - caseFlags("respondent-flag", "RA0038", "Requested")); + caseFlags("respondent-flag", "RA0038", STATUS_REQUESTED)); service.prepareNewFlagReviewSupportTasks(caseData, caseDataBefore); @@ -168,7 +180,7 @@ void does_not_prepare_duplicate_judge_task_for_requested_flag_on_another_party() @Test void prepares_review_task_when_create_flag_before_data_already_contains_the_new_flag() { - CaseFlagsType requestedFlag = caseFlags("new-flag", "RA0038", "Requested", "2026-09-11T10:00:00.000Z"); + CaseFlagsType requestedFlag = caseFlags("new-flag", "RA0038", STATUS_REQUESTED, "2026-09-11T10:00:00.000Z"); CaseData caseDataBefore = new CaseData(); caseDataBefore.setAllPartyFlags(AllPartyFlags.builder().claimantFlags(requestedFlag).build()); CaseData caseData = new CaseData(); @@ -184,11 +196,11 @@ void prepares_review_task_when_create_flag_before_data_already_contains_the_new_ void does_not_treat_an_unchanged_flag_without_an_id_as_new() { CaseData caseDataBefore = new CaseData(); caseDataBefore.setAllPartyFlags(AllPartyFlags.builder() - .claimantFlags(caseFlags(null, "RA0033", "Requested")) + .claimantFlags(caseFlags(null, "RA0033", STATUS_REQUESTED)) .build()); CaseData caseData = new CaseData(); caseData.setAllPartyFlags(AllPartyFlags.builder() - .claimantFlags(caseFlags(null, "RA0033", "Requested")) + .claimantFlags(caseFlags(null, "RA0033", STATUS_REQUESTED)) .build()); service.prepareNewFlagReviewSupportTasks(caseData, caseDataBefore); @@ -201,11 +213,11 @@ void does_not_treat_an_unchanged_flag_without_an_id_as_new() { void does_not_treat_an_updated_existing_flag_as_new() { CaseData caseDataBefore = new CaseData(); caseDataBefore.setAllPartyFlags(AllPartyFlags.builder() - .claimantFlags(caseFlags("existing-flag", "RA0033", "Active")) + .claimantFlags(caseFlags("existing-flag", "RA0033", STATUS_ACTIVE)) .build()); CaseData caseData = new CaseData(); caseData.setAllPartyFlags(AllPartyFlags.builder() - .claimantFlags(caseFlags("existing-flag", "RA0033", "Requested")) + .claimantFlags(caseFlags("existing-flag", "RA0033", STATUS_REQUESTED)) .build()); service.prepareNewFlagReviewSupportTasks(caseData, caseDataBefore); @@ -218,7 +230,7 @@ void does_not_treat_an_updated_existing_flag_as_new() { void does_not_prepare_task_for_a_new_case_level_flag() { CaseData caseData = new CaseData(); caseData.setAllPartyFlags(AllPartyFlags.builder() - .caseFlags(caseFlags("new-case-flag", "RA0033", "Requested")) + .caseFlags(caseFlags("new-case-flag", "RA0033", STATUS_REQUESTED)) .build()); service.prepareNewFlagReviewSupportTasks(caseData, new CaseData()); @@ -230,9 +242,9 @@ void does_not_prepare_task_for_a_new_case_level_flag() { void prepares_tasks_for_new_claimant_and_representative_flags() { CaseData caseData = new CaseData(); caseData.setAllPartyFlags(AllPartyFlags.builder() - .claimantExternalFlags(caseFlags("claimant-flag", "RA0033", "Requested")) - .claimantRepresentativeFlags(caseFlags("claimant-rep-flag", "RA0034", "Requested")) - .representative4ExternalFlags(caseFlags("respondent-rep-flag", "RA0029", "Requested")) + .claimantExternalFlags(caseFlags("claimant-flag", "RA0033", STATUS_REQUESTED)) + .claimantRepresentativeFlags(caseFlags("claimant-rep-flag", "RA0034", STATUS_REQUESTED)) + .representative4ExternalFlags(caseFlags("respondent-rep-flag", "RA0029", STATUS_REQUESTED)) .build()); service.prepareNewFlagReviewSupportTasks(caseData, new CaseData()); @@ -246,8 +258,8 @@ void prepares_tasks_for_new_claimant_and_representative_flags() { void completes_only_task_type_without_an_eligible_requested_flag() { CaseData caseData = new CaseData(); caseData.setAllPartyFlags(AllPartyFlags.builder() - .claimantFlags(caseFlags("admin-flag", "RA0033", "Active")) - .respondent2Flags(caseFlags("judge-flag", "RA0029", "Requested")) + .claimantFlags(caseFlags("admin-flag", "RA0033", STATUS_ACTIVE)) + .respondent2Flags(caseFlags("judge-flag", "RA0029", STATUS_REQUESTED)) .build()); caseData.setSupportTaskState(SupportTaskState.builder() .adminTaskCreated(YES) @@ -267,8 +279,8 @@ void completes_only_task_type_without_an_eligible_requested_flag() { void keeps_task_active_when_another_party_has_an_eligible_requested_flag() { CaseData caseData = new CaseData(); caseData.setAllPartyFlags(AllPartyFlags.builder() - .claimantFlags(caseFlags("managed-flag", "RA0033", "Active")) - .representative2ExternalFlags(caseFlags("requested-flag", "RA0033", "Requested")) + .claimantFlags(caseFlags("managed-flag", "RA0033", STATUS_ACTIVE)) + .representative2ExternalFlags(caseFlags("requested-flag", "RA0033", STATUS_REQUESTED)) .build()); caseData.setSupportTaskState(SupportTaskState.builder().adminTaskCreated(YES).build()); @@ -278,9 +290,141 @@ void keeps_task_active_when_another_party_has_an_eligible_requested_flag() { assertNull(taskState(caseData).getAdminTaskRequired()); } + static Stream reviewTaskCategoryScenarios() { + return Stream.of( + Arguments.of(TASK_TYPE_ADMIN, "RA0041", "RA0039"), + Arguments.of(TASK_TYPE_LEGAL_OFFICER, "RA0034", "RA0035"), + Arguments.of(TASK_TYPE_JUDGE, "RA0038", "RA0029") + ); + } + + static Stream nonRequestedReviewTaskScenarios() { + return Stream.of(STATUS_NOT_APPROVED, STATUS_INACTIVE) + .flatMap(status -> Stream.of( + Arguments.of(TASK_TYPE_ADMIN, "RA0041", status), + Arguments.of(TASK_TYPE_LEGAL_OFFICER, "RA0034", status), + Arguments.of(TASK_TYPE_JUDGE, "RA0038", status) + )); + } + + @ParameterizedTest + @MethodSource("reviewTaskCategoryScenarios") + void completes_each_task_category_only_after_its_last_requested_flag_is_activated( + String taskType, String activeFlagCode, String requestedFlagCode) { + CaseData caseData = caseDataWithFlags(activeFlagCode, STATUS_ACTIVE, requestedFlagCode, STATUS_REQUESTED); + setTaskCreated(taskState(caseData), taskType, CCD_TRUE); + + service.prepareManagedReviewSupportTasks(caseData, null); + + assertEquals(CCD_TRUE, getTaskCreated(taskState(caseData), taskType)); + assertNull(getTaskRequired(taskState(caseData), taskType)); + + activateRespondentFlag(caseData); + service.prepareManagedReviewSupportTasks(caseData, null); + + assertNull(getTaskCreated(taskState(caseData), taskType)); + assertEquals(NO, getTaskRequired(taskState(caseData), taskType)); + } + + @ParameterizedTest + @MethodSource("reviewTaskCategoryScenarios") + void boolean_created_state_prevents_duplicate_tasks_for_each_category( + String taskType, String existingFlagCode, String newFlagCode) { + CaseData caseDataBefore = caseDataWithClaimantFlag(existingFlagCode, STATUS_REQUESTED, false); + caseDataBefore.setSupportTaskState(new SupportTaskState()); + setTaskCreated(taskState(caseDataBefore), taskType, CCD_TRUE); + CaseData caseData = caseDataWithFlags(existingFlagCode, STATUS_REQUESTED, newFlagCode, STATUS_REQUESTED); + + service.prepareNewFlagReviewSupportTasks(caseData, caseDataBefore); + + assertEquals(CCD_TRUE, getTaskCreated(taskState(caseData), taskType)); + assertNull(getTaskRequired(taskState(caseData), taskType)); + } + + @ParameterizedTest + @MethodSource("reviewTaskCategoryScenarios") + void restores_boolean_created_state_from_before_data_and_completes_each_category( + String taskType, String flagCode, String secondFlagCode) { + CaseData caseDataBefore = caseDataWithClaimantFlag(flagCode, STATUS_REQUESTED, false); + caseDataBefore.setSupportTaskState(new SupportTaskState()); + setTaskCreated(taskState(caseDataBefore), taskType, CCD_TRUE); + CaseData caseData = caseDataWithFlags(flagCode, STATUS_ACTIVE, secondFlagCode, STATUS_ACTIVE); + + service.prepareManagedReviewSupportTasks(caseData, caseDataBefore); + + assertNull(getTaskCreated(taskState(caseData), taskType)); + assertEquals(NO, getTaskRequired(taskState(caseData), taskType)); + } + + @ParameterizedTest + @MethodSource("reviewTaskCategoryScenarios") + void false_created_state_allows_a_new_task_for_each_category( + String taskType, String flagCode, String secondFlagCode) { + CaseData caseData = caseDataWithFlags(flagCode, STATUS_REQUESTED, secondFlagCode, STATUS_ACTIVE); + setTaskCreated(taskState(caseData), taskType, CCD_FALSE); + + service.prepareReviewSupportTasks(caseData); + + assertEquals(YES, getTaskCreated(taskState(caseData), taskType)); + assertEquals(YES, getTaskRequired(taskState(caseData), taskType)); + } + + @ParameterizedTest + @MethodSource("nonRequestedReviewTaskScenarios") + void completes_each_task_category_for_every_non_requested_status( + String taskType, String flagCode, String status) { + CaseData caseData = caseDataWithClaimantFlag(flagCode, status, false); + caseData.setSupportTaskState(new SupportTaskState()); + setTaskCreated(taskState(caseData), taskType, CCD_TRUE); + + service.prepareManagedReviewSupportTasks(caseData, null); + + assertNull(getTaskCreated(taskState(caseData), taskType)); + assertEquals(NO, getTaskRequired(taskState(caseData), taskType)); + } + + @Test + void completes_only_categories_without_requested_flags_when_boolean_state_is_used() { + CaseData caseData = new CaseData(); + caseData.setAllPartyFlags(AllPartyFlags.builder() + .claimantFlags(caseFlags("admin-flag", "RA0041", STATUS_ACTIVE)) + .respondentFlags(caseFlags("legal-flag", "RA0034", STATUS_REQUESTED)) + .respondent1Flags(caseFlags("judge-flag", "RA0038", STATUS_REQUESTED)) + .build()); + caseData.setSupportTaskState(SupportTaskState.builder() + .adminTaskCreated(CCD_TRUE) + .legalOfficerTaskCreated(CCD_TRUE) + .judgeTaskCreated(CCD_TRUE) + .build()); + + service.prepareManagedReviewSupportTasks(caseData, null); + + assertNull(taskState(caseData).getAdminTaskCreated()); + assertEquals(NO, taskState(caseData).getAdminTaskRequired()); + assertEquals(CCD_TRUE, taskState(caseData).getLegalOfficerTaskCreated()); + assertNull(taskState(caseData).getLegalOfficerTaskRequired()); + assertEquals(CCD_TRUE, taskState(caseData).getJudgeTaskCreated()); + assertNull(taskState(caseData).getJudgeTaskRequired()); + } + + @Test + void ccd_boolean_task_state_is_deserialized_to_boolean_strings() throws JsonProcessingException { + SupportTaskState state = new ObjectMapper().readValue(""" + { + "adminTaskCreated": true, + "legalOfficerTaskCreated": false, + "judgeTaskCreated": true + } + """, SupportTaskState.class); + + assertEquals(CCD_TRUE, state.getAdminTaskCreated()); + assertEquals(CCD_FALSE, state.getLegalOfficerTaskCreated()); + assertEquals(CCD_TRUE, state.getJudgeTaskCreated()); + } + @Test void keeps_task_active_when_an_eligible_requested_flag_remains() { - CaseData caseData = caseDataWithClaimantFlag("RA0033", "Requested", false); + CaseData caseData = caseDataWithClaimantFlag("RA0033", STATUS_REQUESTED, false); caseData.setSupportTaskState(SupportTaskState.builder().adminTaskCreated(YES).build()); service.prepareManagedReviewSupportTasks(caseData, null); @@ -310,9 +454,9 @@ void completes_created_tasks_when_party_flags_are_missing() { @Test void completes_judge_task_when_last_requested_flag_is_managed_and_current_state_is_missing() { - CaseData caseDataBefore = caseDataWithClaimantFlag("RA0038", "Requested", false); + CaseData caseDataBefore = caseDataWithClaimantFlag("RA0038", STATUS_REQUESTED, false); caseDataBefore.setSupportTaskState(SupportTaskState.builder().judgeTaskCreated(YES).build()); - CaseData caseData = caseDataWithClaimantFlag("RA0038", "Active", false); + CaseData caseData = caseDataWithClaimantFlag("RA0038", STATUS_ACTIVE, false); service.prepareManagedReviewSupportTasks(caseData, caseDataBefore); @@ -322,13 +466,13 @@ void completes_judge_task_when_last_requested_flag_is_managed_and_current_state_ @Test void creates_a_new_task_after_the_previous_task_was_completed() { - CaseData caseDataBefore = caseDataWithClaimantFlag("RA0033", "Active", false); + CaseData caseDataBefore = caseDataWithClaimantFlag("RA0033", STATUS_ACTIVE, false); caseDataBefore.setSupportTaskState(SupportTaskState.builder().adminTaskCreated(YES).build()); service.prepareManagedReviewSupportTasks(caseDataBefore, null); - CaseData caseData = caseDataWithClaimantFlag("RA0033", "Active", false); + CaseData caseData = caseDataWithClaimantFlag("RA0033", STATUS_ACTIVE, false); caseData.getAllPartyFlags().setRespondent1Flags( - caseFlags("new-requested-flag", "RA0033", "Requested")); + caseFlags("new-requested-flag", "RA0033", STATUS_REQUESTED)); service.prepareNewFlagReviewSupportTasks(caseData, caseDataBefore); @@ -338,9 +482,9 @@ void creates_a_new_task_after_the_previous_task_was_completed() { static Stream ineligibleFlagScenarios() { return Stream.of( - Arguments.of("RA0033", "Active"), + Arguments.of("RA0033", STATUS_ACTIVE), Arguments.of("RA0033", null), - Arguments.of("RA9999", "Requested") + Arguments.of("RA9999", STATUS_REQUESTED) ); } @@ -366,7 +510,7 @@ static Stream arrangeSupportFlagScenarios() { void prepares_arrange_support_task_for_each_new_active_flag(String flagCode, String taskName) { CaseData caseData = new CaseData(); caseData.setAllPartyFlags(AllPartyFlags.builder() - .representative4ExternalFlags(caseFlags("new-flag", flagCode, "Active")) + .representative4ExternalFlags(caseFlags("new-flag", flagCode, STATUS_ACTIVE)) .build()); service.prepareArrangeSupportTask(caseData, new CaseData()); @@ -378,14 +522,14 @@ void prepares_arrange_support_task_for_each_new_active_flag(String flagCode, Str void prepares_separate_arrange_support_tasks_for_the_same_code_on_separate_events() { CaseData firstEvent = new CaseData(); firstEvent.setAllPartyFlags(AllPartyFlags.builder() - .claimantFlags(caseFlags("claimant-flag", "RA0017", "Active")) + .claimantFlags(caseFlags("claimant-flag", "RA0017", STATUS_ACTIVE)) .build()); service.prepareArrangeSupportTask(firstEvent, new CaseData()); CaseData secondEvent = new CaseData(); secondEvent.setAllPartyFlags(AllPartyFlags.builder() - .claimantFlags(caseFlags("claimant-flag", "RA0017", "Active")) - .respondent2Flags(caseFlags("respondent-flag", "RA0017", "Active")) + .claimantFlags(caseFlags("claimant-flag", "RA0017", STATUS_ACTIVE)) + .respondent2Flags(caseFlags("respondent-flag", "RA0017", STATUS_ACTIVE)) .build()); service.prepareArrangeSupportTask(secondEvent, firstEvent); @@ -397,11 +541,11 @@ void prepares_separate_arrange_support_tasks_for_the_same_code_on_separate_event void prepares_arrange_support_task_when_existing_flag_becomes_active() { CaseData caseDataBefore = new CaseData(); caseDataBefore.setAllPartyFlags(AllPartyFlags.builder() - .claimantRepresentativeFlags(caseFlags("managed-flag", "RA0042", "Requested")) + .claimantRepresentativeFlags(caseFlags("managed-flag", "RA0042", STATUS_REQUESTED)) .build()); CaseData caseData = new CaseData(); caseData.setAllPartyFlags(AllPartyFlags.builder() - .claimantRepresentativeFlags(caseFlags("managed-flag", "RA0042", "Active")) + .claimantRepresentativeFlags(caseFlags("managed-flag", "RA0042", STATUS_ACTIVE)) .build()); service.prepareArrangeSupportTask(caseData, caseDataBefore); @@ -411,7 +555,7 @@ void prepares_arrange_support_task_when_existing_flag_becomes_active() { @Test void prepares_arrange_task_when_create_flag_before_data_already_contains_the_new_active_flag() { - CaseFlagsType activeFlag = caseFlags("new-flag", "RA0038", "Active", "2026-09-11T10:00:00.000Z"); + CaseFlagsType activeFlag = caseFlags("new-flag", "RA0038", STATUS_ACTIVE, "2026-09-11T10:00:00.000Z"); CaseData caseDataBefore = new CaseData(); caseDataBefore.setAllPartyFlags(AllPartyFlags.builder().claimantFlags(activeFlag).build()); CaseData caseData = new CaseData(); @@ -426,8 +570,8 @@ void prepares_arrange_task_when_create_flag_before_data_already_contains_the_new void does_not_fall_back_to_an_older_eligible_flag_when_the_newest_flag_is_ineligible() { CaseData caseData = new CaseData(); caseData.setAllPartyFlags(AllPartyFlags.builder() - .claimantFlags(caseFlags("old-flag", "RA0038", "Active", "2026-09-11T09:00:00.000Z")) - .respondentFlags(caseFlags("new-flag", "RA9999", "Active", "2026-09-11T10:00:00.000Z")) + .claimantFlags(caseFlags("old-flag", "RA0038", STATUS_ACTIVE, "2026-09-11T09:00:00.000Z")) + .respondentFlags(caseFlags("new-flag", "RA9999", STATUS_ACTIVE, "2026-09-11T10:00:00.000Z")) .build()); service.prepareNewFlagArrangeSupportTask(caseData, caseData); @@ -439,11 +583,11 @@ void does_not_fall_back_to_an_older_eligible_flag_when_the_newest_flag_is_inelig void does_not_prepare_arrange_support_task_for_unchanged_active_flag() { CaseData caseDataBefore = new CaseData(); caseDataBefore.setAllPartyFlags(AllPartyFlags.builder() - .claimantFlags(caseFlags("unchanged-flag", "RA0017", "Active")) + .claimantFlags(caseFlags("unchanged-flag", "RA0017", STATUS_ACTIVE)) .build()); CaseData caseData = new CaseData(); caseData.setAllPartyFlags(AllPartyFlags.builder() - .claimantFlags(caseFlags("unchanged-flag", "RA0017", "Active")) + .claimantFlags(caseFlags("unchanged-flag", "RA0017", STATUS_ACTIVE)) .build()); service.prepareArrangeSupportTask(caseData, caseDataBefore); @@ -455,8 +599,8 @@ void does_not_prepare_arrange_support_task_for_unchanged_active_flag() { void does_not_prepare_arrange_support_task_for_ineligible_or_non_active_flag() { CaseData caseData = new CaseData(); caseData.setAllPartyFlags(AllPartyFlags.builder() - .claimantFlags(caseFlags("requested-flag", "RA0017", "Requested")) - .respondentFlags(caseFlags("ineligible-flag", "RA9999", "Active")) + .claimantFlags(caseFlags("requested-flag", "RA0017", STATUS_REQUESTED)) + .respondentFlags(caseFlags("ineligible-flag", "RA9999", STATUS_ACTIVE)) .build()); caseData.setSupportTaskState(SupportTaskState.builder() .arrangeSupportTaskName("Previous task") @@ -483,6 +627,55 @@ private static CaseData caseDataWithClaimantFlag(String flagCode, return caseData; } + private static CaseData caseDataWithFlags(String claimantFlagCode, + String claimantFlagStatus, + String respondentFlagCode, + String respondentFlagStatus) { + CaseData caseData = new CaseData(); + caseData.setAllPartyFlags(AllPartyFlags.builder() + .claimantFlags(caseFlags("claimant-flag", claimantFlagCode, claimantFlagStatus)) + .respondentFlags(caseFlags("respondent-flag", respondentFlagCode, respondentFlagStatus)) + .build()); + caseData.setSupportTaskState(new SupportTaskState()); + return caseData; + } + + private static void activateRespondentFlag(CaseData caseData) { + caseData.getAllPartyFlags() + .getRespondentFlags() + .getDetails() + .getFirst() + .getValue() + .setStatus(STATUS_ACTIVE); + } + + private static void setTaskCreated(SupportTaskState state, String taskType, String value) { + switch (taskType) { + case TASK_TYPE_ADMIN -> state.setAdminTaskCreated(value); + case TASK_TYPE_LEGAL_OFFICER -> state.setLegalOfficerTaskCreated(value); + case TASK_TYPE_JUDGE -> state.setJudgeTaskCreated(value); + default -> throw new IllegalArgumentException("Unknown task type: " + taskType); + } + } + + private static String getTaskCreated(SupportTaskState state, String taskType) { + return switch (taskType) { + case TASK_TYPE_ADMIN -> state.getAdminTaskCreated(); + case TASK_TYPE_LEGAL_OFFICER -> state.getLegalOfficerTaskCreated(); + case TASK_TYPE_JUDGE -> state.getJudgeTaskCreated(); + default -> throw new IllegalArgumentException("Unknown task type: " + taskType); + }; + } + + private static String getTaskRequired(SupportTaskState state, String taskType) { + return switch (taskType) { + case TASK_TYPE_ADMIN -> state.getAdminTaskRequired(); + case TASK_TYPE_LEGAL_OFFICER -> state.getLegalOfficerTaskRequired(); + case TASK_TYPE_JUDGE -> state.getJudgeTaskRequired(); + default -> throw new IllegalArgumentException("Unknown task type: " + taskType); + }; + } + private static CaseFlagsType caseFlags(String id, String flagCode, String status) { return caseFlags(id, flagCode, status, null); } From 995227f8a7eade9bbbd36b11e7f8e2a3887aa3ce Mon Sep 17 00:00:00 2001 From: rajaram Date: Tue, 15 Sep 2026 22:26:34 +0100 Subject: [PATCH 063/100] Review tasks to show only requested flags for the respective task category --- ...horisationCaseEvent-CaseFlags-nonprod.json | 36 ++++++ .../AuthorisationCaseEvent-WA-nonprod.json | 18 +++ ...isationCaseField-CaseFlagsCaseLinking.json | 12 ++ .../CaseEvent-CaseFlagsCaseLinking.json | 42 +++++++ .../CaseEventToFields-SupportTasks.json | 105 ++++++++++++++++ .../CaseField-CaseFlagsCaseLinking.json | 9 ++ .../EventToComplexTypes-SupportTasks.json | 54 +++++++++ ...isationCaseEvent-CaseFlagsCaseLinking.json | 38 +++++- .../AuthorisationCaseEvent-WA.json | 18 +++ ...isationCaseField-CaseFlagsCaseLinking.json | 12 ++ .../CaseEvent-CaseFlagsCaseLinking.json | 42 +++++++ .../CaseEventToFields-SupportTasks.json | 105 ++++++++++++++++ .../CaseField-CaseFlagsCaseLinking.json | 9 ++ .../EventToComplexTypes-SupportTasks.json | 54 +++++++++ charts/et-cos/Chart.yaml | 8 +- .../hmcts/et/common/model/ccd/CaseData.java | 4 + .../constants/SupportTaskConstants.java | 3 + .../CaseActionsForCaseWorkerController.java | 36 ++++++ .../docmosis/service/PartyCaseFlagUtils.java | 30 +++++ .../docmosis/service/SupportTaskService.java | 91 ++++++++++++-- ...aseActionsForCaseWorkerControllerTest.java | 72 +++++++++++ .../service/SupportTaskServiceTest.java | 114 ++++++++++++++++-- 22 files changed, 886 insertions(+), 26 deletions(-) diff --git a/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseEvent/AuthorisationCaseEvent-CaseFlags-nonprod.json b/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseEvent/AuthorisationCaseEvent-CaseFlags-nonprod.json index a4222220fd..27458d4467 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseEvent/AuthorisationCaseEvent-CaseFlags-nonprod.json +++ b/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseEvent/AuthorisationCaseEvent-CaseFlags-nonprod.json @@ -22,5 +22,41 @@ "CaseEventID": "manageSupport", "UserRole": "caseworker-employment-api", "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseEventID": "reviewAdminSupportRequest", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseEventID": "reviewAdminSupportRequest", + "UserRole": "caseworker-employment-englandwales", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseEventID": "reviewLOSupportRequest", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseEventID": "reviewLOSupportRequest", + "UserRole": "caseworker-employment-englandwales", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseEventID": "reviewJudgeSupportRequest", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseEventID": "reviewJudgeSupportRequest", + "UserRole": "caseworker-employment-englandwales", + "CRUD": "CRU" } ] \ No newline at end of file diff --git a/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseEvent/AuthorisationCaseEvent-WA-nonprod.json b/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseEvent/AuthorisationCaseEvent-WA-nonprod.json index 9076676c3a..3250b2bfc6 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseEvent/AuthorisationCaseEvent-WA-nonprod.json +++ b/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseEvent/AuthorisationCaseEvent-WA-nonprod.json @@ -22,5 +22,23 @@ "CaseEventID": "manageSupport", "UserRole": "caseworker-wa-task-configuration", "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseEventID": "reviewAdminSupportRequest", + "UserRole": "caseworker-wa-task-configuration", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseEventID": "reviewLOSupportRequest", + "UserRole": "caseworker-wa-task-configuration", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseEventID": "reviewJudgeSupportRequest", + "UserRole": "caseworker-wa-task-configuration", + "CRUD": "R" } ] diff --git a/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json index 8285374d62..83d0f74b82 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json @@ -1006,5 +1006,17 @@ "CaseFieldID": "supportTaskState", "UserRole": "caseworker-wa-task-configuration", "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "reviewSupportRequestFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "reviewSupportRequestFlags", + "UserRole": "caseworker-employment-englandwales", + "CRUD": "CRUD" } ] diff --git a/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json index 26d59d29d6..e262fc4470 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json @@ -1,4 +1,46 @@ [ + { + "CaseTypeID": "ET_EnglandWales", + "ID": "reviewAdminSupportRequest", + "Name": "Review Admin RA Request", + "Description": "Review Admin RA Request", + "PreConditionState(s)": "*", + "PostConditionState": "*", + "SecurityClassification": "Public", + "ShowEventNotes": "N", + "ShowSummary": "N", + "Publish": "Y", + "CallBackURLAboutToStartEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToStart", + "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToSubmit" + }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "reviewLOSupportRequest", + "Name": "Review LO RA Request", + "Description": "Review Legal Officer RA Request", + "PreConditionState(s)": "*", + "PostConditionState": "*", + "SecurityClassification": "Public", + "ShowEventNotes": "N", + "ShowSummary": "N", + "Publish": "Y", + "CallBackURLAboutToStartEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToStart", + "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToSubmit" + }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "reviewJudgeSupportRequest", + "Name": "Review Judge RA Request", + "Description": "Review Judge RA Request", + "PreConditionState(s)": "*", + "PostConditionState": "*", + "SecurityClassification": "Public", + "ShowEventNotes": "N", + "ShowSummary": "N", + "Publish": "Y", + "CallBackURLAboutToStartEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToStart", + "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToSubmit" + }, { "CaseTypeID": "ET_EnglandWales", "ID": "createFlag", diff --git a/ccd-definitions/jurisdictions/england-wales/json/CaseEventToFields/CaseEventToFields-SupportTasks.json b/ccd-definitions/jurisdictions/england-wales/json/CaseEventToFields/CaseEventToFields-SupportTasks.json index cc59bb565e..e6379855b8 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/CaseEventToFields/CaseEventToFields-SupportTasks.json +++ b/ccd-definitions/jurisdictions/england-wales/json/CaseEventToFields/CaseEventToFields-SupportTasks.json @@ -90,5 +90,110 @@ "FieldShowCondition": "flagLauncherExternal=\"hidden\"", "ShowSummaryChangeOption": "N", "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "reviewAdminSupportRequest", + "CaseFieldID": "flagLauncher", + "DisplayContext": "OPTIONAL", + "DisplayContextParameter": "#ARGUMENT(UPDATE,VERSION2.1)", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 1, + "ShowSummaryChangeOption": "N" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "reviewAdminSupportRequest", + "CaseFieldID": "reviewSupportRequestFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 2, + "FieldShowCondition": "flagLauncher=\"DUMMY_VALUE_TO_HIDE_FIELD\"", + "ShowSummaryChangeOption": "N", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "reviewAdminSupportRequest", + "CaseFieldID": "supportTaskState", + "DisplayContext": "COMPLEX", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 99, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "N", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "reviewLOSupportRequest", + "CaseFieldID": "flagLauncher", + "DisplayContext": "OPTIONAL", + "DisplayContextParameter": "#ARGUMENT(UPDATE,VERSION2.1)", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 1, + "ShowSummaryChangeOption": "N" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "reviewLOSupportRequest", + "CaseFieldID": "reviewSupportRequestFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 2, + "FieldShowCondition": "flagLauncher=\"DUMMY_VALUE_TO_HIDE_FIELD\"", + "ShowSummaryChangeOption": "N", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "reviewLOSupportRequest", + "CaseFieldID": "supportTaskState", + "DisplayContext": "COMPLEX", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 99, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "N", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "reviewJudgeSupportRequest", + "CaseFieldID": "flagLauncher", + "DisplayContext": "OPTIONAL", + "DisplayContextParameter": "#ARGUMENT(UPDATE,VERSION2.1)", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 1, + "ShowSummaryChangeOption": "N" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "reviewJudgeSupportRequest", + "CaseFieldID": "reviewSupportRequestFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 2, + "FieldShowCondition": "flagLauncher=\"DUMMY_VALUE_TO_HIDE_FIELD\"", + "ShowSummaryChangeOption": "N", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "reviewJudgeSupportRequest", + "CaseFieldID": "supportTaskState", + "DisplayContext": "COMPLEX", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 99, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "N", + "RetainHiddenValue": "Yes" } ] diff --git a/ccd-definitions/jurisdictions/england-wales/json/CaseField/CaseField-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/england-wales/json/CaseField/CaseField-CaseFlagsCaseLinking.json index b2de1ec693..2545513606 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/CaseField/CaseField-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/england-wales/json/CaseField/CaseField-CaseFlagsCaseLinking.json @@ -328,6 +328,15 @@ "FieldType": "Flags", "SecurityClassification": "Public" }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "reviewSupportRequestFlags", + "Label": " ", + "FieldType": "Collection", + "FieldTypeParameter": "Flags", + "SecurityClassification": "Public", + "Searchable": "N" + }, { "CaseTypeID": "ET_EnglandWales", "ID": "supportTaskState", diff --git a/ccd-definitions/jurisdictions/england-wales/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json b/ccd-definitions/jurisdictions/england-wales/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json index c92557e041..6ef5a10b51 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json +++ b/ccd-definitions/jurisdictions/england-wales/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json @@ -277,5 +277,59 @@ "FieldDisplayOrder": 3, "DisplayContext": "OPTIONAL", "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "reviewAdminSupportRequest", + "CaseFieldID": "supportTaskState", + "ListElementCode": "adminTaskRequired", + "FieldDisplayOrder": 1, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "reviewAdminSupportRequest", + "CaseFieldID": "supportTaskState", + "ListElementCode": "arrangeSupportTaskName", + "FieldDisplayOrder": 4, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "reviewLOSupportRequest", + "CaseFieldID": "supportTaskState", + "ListElementCode": "legalOfficerTaskRequired", + "FieldDisplayOrder": 2, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "reviewLOSupportRequest", + "CaseFieldID": "supportTaskState", + "ListElementCode": "arrangeSupportTaskName", + "FieldDisplayOrder": 4, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "reviewJudgeSupportRequest", + "CaseFieldID": "supportTaskState", + "ListElementCode": "judgeTaskRequired", + "FieldDisplayOrder": 3, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "reviewJudgeSupportRequest", + "CaseFieldID": "supportTaskState", + "ListElementCode": "arrangeSupportTaskName", + "FieldDisplayOrder": 4, + "DisplayContext": "OPTIONAL", + "Publish": "Y" } ] diff --git a/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseEvent/AuthorisationCaseEvent-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseEvent/AuthorisationCaseEvent-CaseFlagsCaseLinking.json index d7c2281bfe..ef1aec7265 100644 --- a/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseEvent/AuthorisationCaseEvent-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseEvent/AuthorisationCaseEvent-CaseFlagsCaseLinking.json @@ -64,5 +64,41 @@ "CaseEventID": "rollbackCaseFlags", "UserRole": "caseworker-employment-api", "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseEventID": "reviewAdminSupportRequest", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseEventID": "reviewAdminSupportRequest", + "UserRole": "caseworker-employment-scotland", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseEventID": "reviewLOSupportRequest", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseEventID": "reviewLOSupportRequest", + "UserRole": "caseworker-employment-scotland", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseEventID": "reviewJudgeSupportRequest", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseEventID": "reviewJudgeSupportRequest", + "UserRole": "caseworker-employment-scotland", + "CRUD": "CRU" } -] \ No newline at end of file +] diff --git a/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseEvent/AuthorisationCaseEvent-WA.json b/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseEvent/AuthorisationCaseEvent-WA.json index 10a151d2d9..8228fb2f8c 100644 --- a/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseEvent/AuthorisationCaseEvent-WA.json +++ b/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseEvent/AuthorisationCaseEvent-WA.json @@ -197,5 +197,23 @@ "CaseEventID": "manageSupport", "UserRole": "caseworker-wa-task-configuration", "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseEventID": "reviewAdminSupportRequest", + "UserRole": "caseworker-wa-task-configuration", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseEventID": "reviewLOSupportRequest", + "UserRole": "caseworker-wa-task-configuration", + "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseEventID": "reviewJudgeSupportRequest", + "UserRole": "caseworker-wa-task-configuration", + "CRUD": "R" } ] diff --git a/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json index 81c8570aaf..e1fb63e56a 100644 --- a/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json @@ -1000,5 +1000,17 @@ "CaseFieldID": "supportTaskState", "UserRole": "caseworker-wa-task-configuration", "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "reviewSupportRequestFlags", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "reviewSupportRequestFlags", + "UserRole": "caseworker-employment-scotland", + "CRUD": "CRUD" } ] diff --git a/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json index 2cb223fb9c..235a6566c2 100644 --- a/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json @@ -1,4 +1,46 @@ [ + { + "CaseTypeID": "ET_Scotland", + "ID": "reviewAdminSupportRequest", + "Name": "Review Admin RA Request", + "Description": "Review Admin RA Request", + "PreConditionState(s)": "*", + "PostConditionState": "*", + "SecurityClassification": "Public", + "ShowEventNotes": "N", + "ShowSummary": "N", + "Publish": "Y", + "CallBackURLAboutToStartEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToStart", + "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToSubmit" + }, + { + "CaseTypeID": "ET_Scotland", + "ID": "reviewLOSupportRequest", + "Name": "Review LO RA Request", + "Description": "Review Legal Officer RA Request", + "PreConditionState(s)": "*", + "PostConditionState": "*", + "SecurityClassification": "Public", + "ShowEventNotes": "N", + "ShowSummary": "N", + "Publish": "Y", + "CallBackURLAboutToStartEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToStart", + "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToSubmit" + }, + { + "CaseTypeID": "ET_Scotland", + "ID": "reviewJudgeSupportRequest", + "Name": "Review Judge RA Request", + "Description": "Review Judge RA Request", + "PreConditionState(s)": "*", + "PostConditionState": "*", + "SecurityClassification": "Public", + "ShowEventNotes": "N", + "ShowSummary": "N", + "Publish": "Y", + "CallBackURLAboutToStartEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToStart", + "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToSubmit" + }, { "CaseTypeID": "ET_Scotland", "ID": "createFlag", diff --git a/ccd-definitions/jurisdictions/scotland/json/CaseEventToFields/CaseEventToFields-SupportTasks.json b/ccd-definitions/jurisdictions/scotland/json/CaseEventToFields/CaseEventToFields-SupportTasks.json index 617ad23ace..002492eee5 100644 --- a/ccd-definitions/jurisdictions/scotland/json/CaseEventToFields/CaseEventToFields-SupportTasks.json +++ b/ccd-definitions/jurisdictions/scotland/json/CaseEventToFields/CaseEventToFields-SupportTasks.json @@ -90,5 +90,110 @@ "FieldShowCondition": "flagLauncherExternal=\"hidden\"", "ShowSummaryChangeOption": "N", "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "reviewAdminSupportRequest", + "CaseFieldID": "flagLauncher", + "DisplayContext": "OPTIONAL", + "DisplayContextParameter": "#ARGUMENT(UPDATE,VERSION2.1)", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 1, + "ShowSummaryChangeOption": "N" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "reviewAdminSupportRequest", + "CaseFieldID": "reviewSupportRequestFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 2, + "FieldShowCondition": "flagLauncher=\"DUMMY_VALUE_TO_HIDE_FIELD\"", + "ShowSummaryChangeOption": "N", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "reviewAdminSupportRequest", + "CaseFieldID": "supportTaskState", + "DisplayContext": "COMPLEX", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 99, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "N", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "reviewLOSupportRequest", + "CaseFieldID": "flagLauncher", + "DisplayContext": "OPTIONAL", + "DisplayContextParameter": "#ARGUMENT(UPDATE,VERSION2.1)", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 1, + "ShowSummaryChangeOption": "N" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "reviewLOSupportRequest", + "CaseFieldID": "reviewSupportRequestFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 2, + "FieldShowCondition": "flagLauncher=\"DUMMY_VALUE_TO_HIDE_FIELD\"", + "ShowSummaryChangeOption": "N", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "reviewLOSupportRequest", + "CaseFieldID": "supportTaskState", + "DisplayContext": "COMPLEX", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 99, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "N", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "reviewJudgeSupportRequest", + "CaseFieldID": "flagLauncher", + "DisplayContext": "OPTIONAL", + "DisplayContextParameter": "#ARGUMENT(UPDATE,VERSION2.1)", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 1, + "ShowSummaryChangeOption": "N" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "reviewJudgeSupportRequest", + "CaseFieldID": "reviewSupportRequestFlags", + "DisplayContext": "OPTIONAL", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 2, + "FieldShowCondition": "flagLauncher=\"DUMMY_VALUE_TO_HIDE_FIELD\"", + "ShowSummaryChangeOption": "N", + "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "reviewJudgeSupportRequest", + "CaseFieldID": "supportTaskState", + "DisplayContext": "COMPLEX", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 99, + "FieldShowCondition": "flagLauncher=\"hidden\"", + "ShowSummaryChangeOption": "N", + "RetainHiddenValue": "Yes" } ] diff --git a/ccd-definitions/jurisdictions/scotland/json/CaseField/CaseField-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/scotland/json/CaseField/CaseField-CaseFlagsCaseLinking.json index 2c82538696..91af57cf82 100644 --- a/ccd-definitions/jurisdictions/scotland/json/CaseField/CaseField-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/scotland/json/CaseField/CaseField-CaseFlagsCaseLinking.json @@ -329,6 +329,15 @@ "FieldType": "Flags", "SecurityClassification": "Public" }, + { + "CaseTypeID": "ET_Scotland", + "ID": "reviewSupportRequestFlags", + "Label": " ", + "FieldType": "Collection", + "FieldTypeParameter": "Flags", + "SecurityClassification": "Public", + "Searchable": "N" + }, { "CaseTypeID": "ET_Scotland", "ID": "supportTaskState", diff --git a/ccd-definitions/jurisdictions/scotland/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json b/ccd-definitions/jurisdictions/scotland/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json index c92557e041..6ef5a10b51 100644 --- a/ccd-definitions/jurisdictions/scotland/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json +++ b/ccd-definitions/jurisdictions/scotland/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json @@ -277,5 +277,59 @@ "FieldDisplayOrder": 3, "DisplayContext": "OPTIONAL", "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "reviewAdminSupportRequest", + "CaseFieldID": "supportTaskState", + "ListElementCode": "adminTaskRequired", + "FieldDisplayOrder": 1, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "reviewAdminSupportRequest", + "CaseFieldID": "supportTaskState", + "ListElementCode": "arrangeSupportTaskName", + "FieldDisplayOrder": 4, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "reviewLOSupportRequest", + "CaseFieldID": "supportTaskState", + "ListElementCode": "legalOfficerTaskRequired", + "FieldDisplayOrder": 2, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "reviewLOSupportRequest", + "CaseFieldID": "supportTaskState", + "ListElementCode": "arrangeSupportTaskName", + "FieldDisplayOrder": 4, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "reviewJudgeSupportRequest", + "CaseFieldID": "supportTaskState", + "ListElementCode": "judgeTaskRequired", + "FieldDisplayOrder": 3, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "reviewJudgeSupportRequest", + "CaseFieldID": "supportTaskState", + "ListElementCode": "arrangeSupportTaskName", + "FieldDisplayOrder": 4, + "DisplayContext": "OPTIONAL", + "Publish": "Y" } ] diff --git a/charts/et-cos/Chart.yaml b/charts/et-cos/Chart.yaml index aa7c51a049..b992ed2f0e 100644 --- a/charts/et-cos/Chart.yaml +++ b/charts/et-cos/Chart.yaml @@ -7,7 +7,7 @@ maintainers: - name: HMCTS Employment Tribunals Team dependencies: - name: java - version: 5.3.0 + version: 6.1.1 repository: 'oci://hmctsprod.azurecr.io/helm' condition: java.enabled # Below charts are used for Preview environments only @@ -50,7 +50,7 @@ dependencies: repository: 'oci://hmctsprod.azurecr.io/helm' condition: wa.enabled - name: servicebus - version: ~1.2.1 + version: ~1.3.0 repository: 'oci://hmctsprod.azurecr.io/helm' condition: servicebus.enabled - name: ccd-message-publisher @@ -70,7 +70,7 @@ dependencies: repository: 'oci://hmctsprod.azurecr.io/helm' condition: rd-caseworker-ref-api.enabled - name: postgresql - version: 1.1.1 + version: 1.1.3 repository: 'oci://hmctsprod.azurecr.io/helm' condition: postgresql.enabled - name: rd-professional-api @@ -94,6 +94,6 @@ dependencies: repository: 'oci://hmctsprod.azurecr.io/helm' condition: rd-judicial-data-load.enabled - name: em-ccdorc - version: 2.1.4 + version: 2.2.0 repository: 'oci://hmctsprod.azurecr.io/helm' condition: em-ccdorc.enabled diff --git a/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/CaseData.java b/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/CaseData.java index d1be96c811..e83c0ce655 100644 --- a/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/CaseData.java +++ b/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/CaseData.java @@ -29,6 +29,7 @@ import uk.gov.hmcts.et.common.model.ccd.types.AddressLabelsSelectionType; import uk.gov.hmcts.et.common.model.ccd.types.AllPartyFlags; import uk.gov.hmcts.et.common.model.ccd.types.CaseLink; +import uk.gov.hmcts.et.common.model.ccd.types.CaseFlagsType; import uk.gov.hmcts.et.common.model.ccd.types.CaseNote; import uk.gov.hmcts.et.common.model.ccd.types.CasePreAcceptType; import uk.gov.hmcts.et.common.model.ccd.types.ChangeOrganisationRequest; @@ -1595,6 +1596,9 @@ public class CaseData extends Et1CaseData { @JsonProperty("supportTaskState") private SupportTaskState supportTaskState; + @JsonProperty("reviewSupportRequestFlags") + private ListTypeItem reviewSupportRequestFlags; + //et-hearings-api @JsonProperty("autoListFlag") private String autoListFlag; diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/constants/SupportTaskConstants.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/constants/SupportTaskConstants.java index 4a9ce2b0ca..cbacfacbb9 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/constants/SupportTaskConstants.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/constants/SupportTaskConstants.java @@ -10,6 +10,9 @@ public final class SupportTaskConstants { public static final String EVENT_UPDATE_ET3_FORM = "UPDATE_ET3_FORM"; public static final String EVENT_REQUEST_SUPPORT = "requestSupport"; public static final String EVENT_MANAGE_SUPPORT = "manageSupport"; + public static final String EVENT_REVIEW_ADMIN_SUPPORT_REQUEST = "reviewAdminSupportRequest"; + public static final String EVENT_REVIEW_LEGAL_OFFICER_SUPPORT_REQUEST = "reviewLOSupportRequest"; + public static final String EVENT_REVIEW_JUDGE_SUPPORT_REQUEST = "reviewJudgeSupportRequest"; public static final String FLAG_STATUS_ACTIVE = "Active"; public static final String FLAG_STATUS_REQUESTED = "Requested"; diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java index 627a57c5cd..ceab69ea9f 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java @@ -190,6 +190,7 @@ public ResponseEntity postDefaultValues( if (featureToggleService.isCaseFlagsV2Enabled(caseDetails.getCaseTypeId()) && REVIEW_SUPPORT_TASK_EVENTS.contains(ccdRequest.getEventId())) { + caseManagementForCaseWorkerService.setNextListedDate(caseData); supportTaskService.prepareReviewSupportTasks(caseData); CaseData caseDataBefore = ccdRequest.getCaseDetailsBefore() == null ? null @@ -225,6 +226,7 @@ public ResponseEntity prepareSupportTasks( CaseData caseData = caseDetails.getCaseData(); if (featureToggleService.isCaseFlagsV2Enabled(caseDetails.getCaseTypeId())) { + caseManagementForCaseWorkerService.setNextListedDate(caseData); CaseData caseDataBefore = callbackRequest.getCaseDetailsBefore() == null ? null : callbackRequest.getCaseDetailsBefore().getCaseData(); @@ -249,6 +251,40 @@ public ResponseEntity prepareSupportTasks( return getCallbackRespEntityNoErrors(caseData); } + @PostMapping(value = "/reviewSupportRequest/aboutToStart", consumes = APPLICATION_JSON_VALUE) + @Operation(summary = "Prepare the requested Case Flags for review.") + public ResponseEntity prepareReviewSupportRequest( + @RequestBody CallbackRequest callbackRequest) { + CaseDetails caseDetails = callbackRequest.getCaseDetails(); + CaseData caseData = caseDetails.getCaseData(); + if (featureToggleService.isCaseFlagsV2Enabled(caseDetails.getCaseTypeId())) { + supportTaskService.prepareReviewSupportRequest(caseData, callbackRequest.getEventId()); + } + return getCallbackRespEntityNoErrors(caseData); + } + + @PostMapping(value = "/reviewSupportRequest/aboutToSubmit", consumes = APPLICATION_JSON_VALUE) + @Operation(summary = "Apply reviewed Case Flags and prepare the related support tasks.") + public ResponseEntity applyReviewSupportRequest( + @RequestBody CallbackRequest callbackRequest) { + CaseDetails caseDetails = callbackRequest.getCaseDetails(); + CaseData caseData = caseDetails.getCaseData(); + List errors = new ArrayList<>(); + if (featureToggleService.isCaseFlagsV2Enabled(caseDetails.getCaseTypeId())) { + if (!supportTaskService.applyReviewSupportRequest(caseData)) { + errors.add("Please select status other than Requested"); + } else { + caseManagementForCaseWorkerService.setNextListedDate(caseData); + CaseData caseDataBefore = callbackRequest.getCaseDetailsBefore() == null + ? null + : callbackRequest.getCaseDetailsBefore().getCaseData(); + supportTaskService.prepareManagedReviewSupportTasks(caseData, caseDataBefore); + supportTaskService.prepareArrangeSupportTask(caseData, caseDataBefore); + } + } + return getCallbackRespEntityErrors(errors, caseData); + } + private List getValidationDate(String eventId, CaseDetails caseDetails) { if (!CREATE_ECM_CASE.equals(eventId)) { return eventValidationService.validateReceiptDate(caseDetails); diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/PartyCaseFlagUtils.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/PartyCaseFlagUtils.java index 44f9b1272c..84e0d20735 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/PartyCaseFlagUtils.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/PartyCaseFlagUtils.java @@ -37,6 +37,36 @@ static Stream> allFlagItems(AllPartyFlags flags) Stream.concat(respondentFlagItems(flags), representativeFlagItems(flags))); } + static Stream allPartyFlagSections(AllPartyFlags flags) { + if (flags == null) { + return Stream.empty(); + } + return Stream.of( + flags.getClaimantFlags(), flags.getClaimantExternalFlags(), + flags.getRespondentFlags(), flags.getRespondentExternalFlags(), + flags.getRespondent1Flags(), flags.getRespondent1ExternalFlags(), + flags.getRespondent2Flags(), flags.getRespondent2ExternalFlags(), + flags.getRespondent3Flags(), flags.getRespondent3ExternalFlags(), + flags.getRespondent4Flags(), flags.getRespondent4ExternalFlags(), + flags.getRespondent5Flags(), flags.getRespondent5ExternalFlags(), + flags.getRespondent6Flags(), flags.getRespondent6ExternalFlags(), + flags.getRespondent7Flags(), flags.getRespondent7ExternalFlags(), + flags.getRespondent8Flags(), flags.getRespondent8ExternalFlags(), + flags.getRespondent9Flags(), flags.getRespondent9ExternalFlags(), + flags.getClaimantRepresentativeFlags(), flags.getClaimantRepresentativeExternalFlags(), + flags.getRepresentativeFlags(), flags.getRepresentativeExternalFlags(), + flags.getRepresentative1Flags(), flags.getRepresentative1ExternalFlags(), + flags.getRepresentative2Flags(), flags.getRepresentative2ExternalFlags(), + flags.getRepresentative3Flags(), flags.getRepresentative3ExternalFlags(), + flags.getRepresentative4Flags(), flags.getRepresentative4ExternalFlags(), + flags.getRepresentative5Flags(), flags.getRepresentative5ExternalFlags(), + flags.getRepresentative6Flags(), flags.getRepresentative6ExternalFlags(), + flags.getRepresentative7Flags(), flags.getRepresentative7ExternalFlags(), + flags.getRepresentative8Flags(), flags.getRepresentative8ExternalFlags(), + flags.getRepresentative9Flags(), flags.getRepresentative9ExternalFlags()) + .filter(java.util.Objects::nonNull); + } + static Stream flagDetails(CaseFlagsType... flags) { return flagItems(flags).map(GenericTypeItem::getValue); } diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java index 5acc4cef7f..8b1a498522 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java @@ -5,11 +5,14 @@ import uk.gov.hmcts.et.common.model.ccd.CaseData; import uk.gov.hmcts.et.common.model.ccd.items.FlagDetailType; import uk.gov.hmcts.et.common.model.ccd.items.GenericTypeItem; +import uk.gov.hmcts.et.common.model.ccd.items.ListTypeItem; import uk.gov.hmcts.et.common.model.ccd.types.AllPartyFlags; +import uk.gov.hmcts.et.common.model.ccd.types.CaseFlagsType; import uk.gov.hmcts.et.common.model.ccd.types.SupportTaskState; import uk.gov.hmcts.ethos.replacement.docmosis.config.SupportTaskConfiguration; import java.util.Comparator; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; @@ -18,12 +21,17 @@ import java.util.function.Consumer; import java.util.function.Predicate; import java.util.stream.Collectors; +import java.util.stream.Stream; import static uk.gov.hmcts.ecm.common.model.helper.Constants.NO; import static uk.gov.hmcts.ecm.common.model.helper.Constants.YES; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.EVENT_REVIEW_ADMIN_SUPPORT_REQUEST; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.EVENT_REVIEW_JUDGE_SUPPORT_REQUEST; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.EVENT_REVIEW_LEGAL_OFFICER_SUPPORT_REQUEST; import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.FLAG_STATUS_ACTIVE; import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.FLAG_STATUS_REQUESTED; import static uk.gov.hmcts.ethos.replacement.docmosis.service.PartyCaseFlagUtils.allFlagItems; +import static uk.gov.hmcts.ethos.replacement.docmosis.service.PartyCaseFlagUtils.allPartyFlagSections; import static uk.gov.hmcts.ethos.replacement.docmosis.service.PartyCaseFlagUtils.flagDetails; import static uk.gov.hmcts.ethos.replacement.docmosis.service.PartyCaseFlagUtils.respondentFlagDetails; @@ -92,36 +100,97 @@ public void prepareManagedReviewSupportTasks(CaseData caseData, CaseData caseDat .toList(); updateTaskState(flags, configuration.getReview().getAdminFlagCodes(), - taskState.getAdminTaskCreated(), taskState::setAdminTaskCreated, taskState::setAdminTaskRequired); updateTaskState(flags, configuration.getReview().getLegalOfficerFlagCodes(), - taskState.getLegalOfficerTaskCreated(), taskState::setLegalOfficerTaskCreated, taskState::setLegalOfficerTaskRequired); updateTaskState(flags, configuration.getReview().getJudgeFlagCodes(), - taskState.getJudgeTaskCreated(), taskState::setJudgeTaskCreated, taskState::setJudgeTaskRequired); } + public void prepareReviewSupportRequest(CaseData caseData, String eventId) { + Set eligibleCodes = reviewFlagCodes(eventId); + ListTypeItem selectedFlags = allPartyFlagSections(caseData.getAllPartyFlags()) + .map(flags -> requestedFlags(flags, eligibleCodes)) + .filter(flags -> !flags.getDetails().isEmpty()) + .map(GenericTypeItem::from) + .collect(Collectors.toCollection(ListTypeItem::new)); + caseData.setReviewSupportRequestFlags(selectedFlags); + } + + public boolean applyReviewSupportRequest(CaseData caseData) { + if (caseData.getReviewSupportRequestFlags() == null) { + return false; + } + + Map> originalFlags = new HashMap<>(); + allFlagItems(caseData.getAllPartyFlags()) + .filter(item -> item.getId() != null) + .forEach(item -> originalFlags.put(item.getId(), item)); + + List> updatedFlags = caseData.getReviewSupportRequestFlags().stream() + .filter(Objects::nonNull) + .map(GenericTypeItem::getValue) + .filter(Objects::nonNull) + .flatMap(flags -> flags.getDetails() == null ? Stream.empty() : flags.getDetails().stream()) + .filter(item -> item != null && item.getId() != null && item.getValue() != null) + .filter(item -> !isRequested(item.getValue())) + .filter(item -> originalFlags.containsKey(item.getId())) + .toList(); + updatedFlags.forEach(item -> originalFlags.get(item.getId()).setValue(item.getValue())); + + if (!updatedFlags.isEmpty()) { + caseData.setReviewSupportRequestFlags(null); + } + return !updatedFlags.isEmpty(); + } + + private Set reviewFlagCodes(String eventId) { + return switch (eventId) { + case EVENT_REVIEW_ADMIN_SUPPORT_REQUEST -> configuration.getReview().getAdminFlagCodes(); + case EVENT_REVIEW_LEGAL_OFFICER_SUPPORT_REQUEST -> + configuration.getReview().getLegalOfficerFlagCodes(); + case EVENT_REVIEW_JUDGE_SUPPORT_REQUEST -> configuration.getReview().getJudgeFlagCodes(); + default -> Set.of(); + }; + } + + private static CaseFlagsType requestedFlags(CaseFlagsType flags, Set eligibleCodes) { + ListTypeItem details = flags.getDetails() == null + ? new ListTypeItem<>() + : flags.getDetails().stream() + .filter(item -> item != null && item.getValue() != null) + .filter(item -> isRequested(item.getValue())) + .filter(item -> eligibleCodes.contains(item.getValue().getFlagCode())) + .collect(Collectors.toCollection(ListTypeItem::new)); + return CaseFlagsType.builder() + .partyName(flags.getPartyName()) + .roleOnCase(flags.getRoleOnCase()) + .groupId(flags.getGroupId()) + .visibility(flags.getVisibility()) + .details(details) + .build(); + } + private void prepareTasks(CaseData caseData, List flags) { SupportTaskState taskState = taskState(caseData); taskState.setAdminTaskRequired(null); taskState.setLegalOfficerTaskRequired(null); taskState.setJudgeTaskRequired(null); - if (!isTaskCreated(taskState.getAdminTaskCreated()) + if (isTaskNotCreated(taskState.getAdminTaskCreated()) && hasRequestedFlag(flags, configuration.getReview().getAdminFlagCodes())) { taskState.setAdminTaskCreated(YES); taskState.setAdminTaskRequired(YES); } - if (!isTaskCreated(taskState.getLegalOfficerTaskCreated()) + if (isTaskNotCreated(taskState.getLegalOfficerTaskCreated()) && hasRequestedFlag(flags, configuration.getReview().getLegalOfficerFlagCodes())) { taskState.setLegalOfficerTaskCreated(YES); taskState.setLegalOfficerTaskRequired(YES); } - if (!isTaskCreated(taskState.getJudgeTaskCreated()) + if (isTaskNotCreated(taskState.getJudgeTaskCreated()) && hasRequestedFlag(flags, configuration.getReview().getJudgeFlagCodes())) { taskState.setJudgeTaskCreated(YES); taskState.setJudgeTaskRequired(YES); @@ -141,18 +210,18 @@ private static boolean hasRequestedFlag(List flags, Set private static void updateTaskState(List flags, Set eligibleFlagCodes, - String taskCreated, Consumer taskCreatedSetter, Consumer taskRequiredSetter) { taskRequiredSetter.accept(null); - if (isTaskCreated(taskCreated) && !hasRequestedFlag(flags, eligibleFlagCodes)) { - taskCreatedSetter.accept(null); + if (!hasRequestedFlag(flags, eligibleFlagCodes)) { + taskCreatedSetter.accept(NO); taskRequiredSetter.accept(NO); } } - private static boolean isTaskCreated(String taskCreated) { - return YES.equalsIgnoreCase(taskCreated) || Boolean.parseBoolean(taskCreated); + private static boolean isTaskNotCreated(String taskCreated) { + return !YES.equalsIgnoreCase(taskCreated) + && !Boolean.parseBoolean(taskCreated); } private static boolean isRequested(FlagDetailType flag) { diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java index 1c833c8435..122713a7fc 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java @@ -97,6 +97,10 @@ class CaseActionsForCaseWorkerControllerTest extends BaseControllerTest { private static final String PRE_DEFAULT_VALUES_URL = "/preDefaultValues"; private static final String POST_DEFAULT_VALUES_URL = "/postDefaultValues"; private static final String SUPPORT_TASKS_URL = "/supportTasks/aboutToSubmit"; + private static final String REVIEW_SUPPORT_REQUEST_ABOUT_TO_START_URL = + "/reviewSupportRequest/aboutToStart"; + private static final String REVIEW_SUPPORT_REQUEST_ABOUT_TO_SUBMIT_URL = + "/reviewSupportRequest/aboutToSubmit"; private static final String AMEND_CASE_DETAILS_URL = "/amendCaseDetails"; private static final String AMEND_CLAIMANT_DETAILS_URL = "/amendClaimantDetails"; private static final String UPDATE_CLAIMANT_EMAIL_ABOUT_TO_START_URL = @@ -347,6 +351,7 @@ void postDefaultValuesPreparesSupportTasksForCaseFlagsV2Events(String eventId) { verify(supportTaskService).prepareReviewSupportTasks(any(CaseData.class)); verify(supportTaskService).prepareArrangeSupportTask( any(CaseData.class), any(CaseData.class)); + verify(caseManagementForCaseWorkerService).setNextListedDate(any(CaseData.class)); } @Test @@ -366,6 +371,7 @@ void postDefaultValuesDoesNotPrepareReviewSupportTasksWhenCaseFlagsV2IsDisabled( verify(supportTaskService, never()).prepareReviewSupportTasks(any(CaseData.class)); verify(supportTaskService, never()).prepareArrangeSupportTask( any(CaseData.class), nullable(CaseData.class)); + verify(caseManagementForCaseWorkerService, never()).setNextListedDate(any(CaseData.class)); } @ParameterizedTest @@ -384,6 +390,7 @@ void preparesRespondentReviewSupportTasksForEt3Events(String eventId) { verify(supportTaskService).prepareRespondentReviewSupportTasks(any(CaseData.class)); verify(supportTaskService).prepareNewFlagArrangeSupportTask( any(CaseData.class), nullable(CaseData.class)); + verify(caseManagementForCaseWorkerService).setNextListedDate(any(CaseData.class)); } @ParameterizedTest @@ -405,6 +412,7 @@ void preparesReviewSupportTasksForNewCaseFlags(String eventId) { any(CaseData.class), any(CaseData.class)); verify(supportTaskService).prepareNewFlagArrangeSupportTask( any(CaseData.class), any(CaseData.class)); + verify(caseManagementForCaseWorkerService).setNextListedDate(any(CaseData.class)); } @ParameterizedTest @@ -428,6 +436,69 @@ void preparesReviewSupportTaskCompletionForManagedCaseFlags(String eventId) { verify(supportTaskService).prepareArrangeSupportTask( any(CaseData.class), any(CaseData.class)); } + verify(caseManagementForCaseWorkerService).setNextListedDate(any(CaseData.class)); + } + + @ParameterizedTest + @ValueSource(strings = { + "reviewAdminSupportRequest", + "reviewLOSupportRequest", + "reviewJudgeSupportRequest" + }) + @SneakyThrows + void preparesRequestedFlagsForTheReviewTaskCategory(String eventId) { + ((ObjectNode) requestContent2).put("event_id", eventId); + when(featureToggleService.isCaseFlagsV2Enabled(anyString())).thenReturn(true); + + mvc.perform(post(REVIEW_SUPPORT_REQUEST_ABOUT_TO_START_URL) + .content(requestContent2.toString()) + .header(AUTHORIZATION, AUTH_TOKEN) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + + verify(supportTaskService).prepareReviewSupportRequest(any(CaseData.class), eq(eventId)); + } + + @Test + @SneakyThrows + void appliesReviewedFlagAndPreparesCompletionAndArrangeTasks() { + ((ObjectNode) requestContent2).put("event_id", "reviewAdminSupportRequest"); + ((ObjectNode) requestContent2).set("case_details_before", + requestContent2.get("case_details").deepCopy()); + when(featureToggleService.isCaseFlagsV2Enabled(anyString())).thenReturn(true); + when(supportTaskService.applyReviewSupportRequest(any(CaseData.class))).thenReturn(true); + + mvc.perform(post(REVIEW_SUPPORT_REQUEST_ABOUT_TO_SUBMIT_URL) + .content(requestContent2.toString()) + .header(AUTHORIZATION, AUTH_TOKEN) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath(JsonMapper.ERRORS, hasSize(0))); + + verify(supportTaskService).prepareManagedReviewSupportTasks( + any(CaseData.class), any(CaseData.class)); + verify(supportTaskService).prepareArrangeSupportTask( + any(CaseData.class), any(CaseData.class)); + verify(caseManagementForCaseWorkerService).setNextListedDate(any(CaseData.class)); + } + + @Test + @SneakyThrows + void rejectsReviewSupportRequestWhenNoFlagWasActioned() { + ((ObjectNode) requestContent2).put("event_id", "reviewAdminSupportRequest"); + when(featureToggleService.isCaseFlagsV2Enabled(anyString())).thenReturn(true); + + mvc.perform(post(REVIEW_SUPPORT_REQUEST_ABOUT_TO_SUBMIT_URL) + .content(requestContent2.toString()) + .header(AUTHORIZATION, AUTH_TOKEN) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath(JsonMapper.ERRORS + "[0]", + is("Please select status other than Requested"))); + + verify(supportTaskService, never()).prepareManagedReviewSupportTasks( + any(CaseData.class), nullable(CaseData.class)); + verify(caseManagementForCaseWorkerService, never()).setNextListedDate(any(CaseData.class)); } @ParameterizedTest @@ -478,6 +549,7 @@ void doesNotPrepareReviewSupportTasksWhenCaseFlagsV2IsDisabled() { any(CaseData.class), nullable(CaseData.class)); verify(supportTaskService, never()).prepareNewFlagArrangeSupportTask( any(CaseData.class), nullable(CaseData.class)); + verify(caseManagementForCaseWorkerService, never()).setNextListedDate(any(CaseData.class)); } @Test diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java index 33afd84340..d3a295f1db 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java @@ -15,14 +15,20 @@ import uk.gov.hmcts.et.common.model.ccd.types.SupportTaskState; import uk.gov.hmcts.ethos.replacement.docmosis.config.SupportTaskConfiguration; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Stream; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; import static uk.gov.hmcts.ecm.common.model.helper.Constants.NO; import static uk.gov.hmcts.ecm.common.model.helper.Constants.YES; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.EVENT_REVIEW_ADMIN_SUPPORT_REQUEST; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.EVENT_REVIEW_JUDGE_SUPPORT_REQUEST; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.EVENT_REVIEW_LEGAL_OFFICER_SUPPORT_REQUEST; class SupportTaskServiceTest { private static final String TASK_TYPE_ADMIN = "Admin"; @@ -268,11 +274,12 @@ void completes_only_task_type_without_an_eligible_requested_flag() { service.prepareManagedReviewSupportTasks(caseData, null); - assertNull(taskState(caseData).getAdminTaskCreated()); + assertEquals(NO, taskState(caseData).getAdminTaskCreated()); assertEquals(NO, taskState(caseData).getAdminTaskRequired()); assertEquals(YES, taskState(caseData).getJudgeTaskCreated()); assertNull(taskState(caseData).getJudgeTaskRequired()); - assertNull(taskState(caseData).getLegalOfficerTaskRequired()); + assertEquals(NO, taskState(caseData).getLegalOfficerTaskCreated()); + assertEquals(NO, taskState(caseData).getLegalOfficerTaskRequired()); } @Test @@ -298,6 +305,83 @@ static Stream reviewTaskCategoryScenarios() { ); } + static Stream reviewSupportRequestScenarios() { + return Stream.of( + Arguments.of(EVENT_REVIEW_ADMIN_SUPPORT_REQUEST, "RA0041", "RA0038"), + Arguments.of(EVENT_REVIEW_LEGAL_OFFICER_SUPPORT_REQUEST, "RA0034", "RA0041"), + Arguments.of(EVENT_REVIEW_JUDGE_SUPPORT_REQUEST, "RA0038", "RA0034") + ); + } + + @ParameterizedTest + @MethodSource("reviewSupportRequestScenarios") + void review_event_contains_only_requested_flags_for_its_task_category( + String eventId, String flagCode, String differentCategoryFlagCode) { + CaseData caseData = new CaseData(); + caseData.setAllPartyFlags(AllPartyFlags.builder() + .claimantFlags(caseFlags("matching-requested", flagCode, STATUS_REQUESTED)) + .respondentFlags(caseFlags("matching-active", flagCode, STATUS_ACTIVE)) + .representativeFlags(caseFlags("different-category", differentCategoryFlagCode, STATUS_REQUESTED)) + .build()); + + service.prepareReviewSupportRequest(caseData, eventId); + + assertEquals(1, caseData.getReviewSupportRequestFlags().size()); + CaseFlagsType selectedSection = caseData.getReviewSupportRequestFlags().getFirst().getValue(); + assertEquals(1, selectedSection.getDetails().size()); + assertEquals("matching-requested", selectedSection.getDetails().getFirst().getId()); + } + + @Test + void review_event_includes_matching_flags_for_every_party_type() { + CaseData caseData = new CaseData(); + caseData.setAllPartyFlags(AllPartyFlags.builder() + .claimantFlags(caseFlags("claimant", "RA0041", STATUS_REQUESTED)) + .respondent1ExternalFlags(caseFlags("respondent", "RA0041", STATUS_REQUESTED)) + .claimantRepresentativeFlags(caseFlags("claimant-representative", "RA0041", STATUS_REQUESTED)) + .representative2ExternalFlags(caseFlags("respondent-representative", "RA0041", STATUS_REQUESTED)) + .build()); + + service.prepareReviewSupportRequest(caseData, EVENT_REVIEW_ADMIN_SUPPORT_REQUEST); + + List selectedFlagIds = caseData.getReviewSupportRequestFlags().stream() + .map(GenericTypeItem::getValue) + .flatMap(flags -> flags.getDetails().stream()) + .map(GenericTypeItem::getId) + .toList(); + assertEquals(List.of("claimant", "respondent", "claimant-representative", "respondent-representative"), + selectedFlagIds); + } + + @Test + void reviewed_flag_is_updated_in_its_original_party_section() { + CaseData caseData = caseDataWithClaimantFlag("RA0041", STATUS_REQUESTED, false); + GenericTypeItem originalFlag = caseData.getAllPartyFlags() + .getClaimantFlags().getDetails().getFirst(); + originalFlag.setId("reviewed-flag"); + CaseFlagsType selectedFlags = caseFlags("reviewed-flag", "RA0041", STATUS_ACTIVE); + caseData.setReviewSupportRequestFlags(ListTypeItem.from(selectedFlags)); + + boolean updated = service.applyReviewSupportRequest(caseData); + + assertTrue(updated); + assertEquals(STATUS_ACTIVE, originalFlag.getValue().getStatus()); + assertNull(caseData.getReviewSupportRequestFlags()); + } + + @Test + void review_event_rejects_a_flag_that_is_still_requested() { + CaseData caseData = caseDataWithClaimantFlag("RA0041", STATUS_REQUESTED, false); + CaseFlagsType selectedFlags = caseFlags("selected-flag", "RA0041", STATUS_REQUESTED); + caseData.setReviewSupportRequestFlags(ListTypeItem.from(selectedFlags)); + + boolean updated = service.applyReviewSupportRequest(caseData); + + assertFalse(updated); + assertEquals(STATUS_REQUESTED, caseData.getAllPartyFlags() + .getClaimantFlags().getDetails().getFirst().getValue().getStatus()); + } + static Stream nonRequestedReviewTaskScenarios() { return Stream.of(STATUS_NOT_APPROVED, STATUS_INACTIVE) .flatMap(status -> Stream.of( @@ -322,7 +406,7 @@ void completes_each_task_category_only_after_its_last_requested_flag_is_activate activateRespondentFlag(caseData); service.prepareManagedReviewSupportTasks(caseData, null); - assertNull(getTaskCreated(taskState(caseData), taskType)); + assertEquals(NO, getTaskCreated(taskState(caseData), taskType)); assertEquals(NO, getTaskRequired(taskState(caseData), taskType)); } @@ -352,7 +436,7 @@ void restores_boolean_created_state_from_before_data_and_completes_each_category service.prepareManagedReviewSupportTasks(caseData, caseDataBefore); - assertNull(getTaskCreated(taskState(caseData), taskType)); + assertEquals(NO, getTaskCreated(taskState(caseData), taskType)); assertEquals(NO, getTaskRequired(taskState(caseData), taskType)); } @@ -379,7 +463,7 @@ void completes_each_task_category_for_every_non_requested_status( service.prepareManagedReviewSupportTasks(caseData, null); - assertNull(getTaskCreated(taskState(caseData), taskType)); + assertEquals(NO, getTaskCreated(taskState(caseData), taskType)); assertEquals(NO, getTaskRequired(taskState(caseData), taskType)); } @@ -399,7 +483,7 @@ void completes_only_categories_without_requested_flags_when_boolean_state_is_use service.prepareManagedReviewSupportTasks(caseData, null); - assertNull(taskState(caseData).getAdminTaskCreated()); + assertEquals(NO, taskState(caseData).getAdminTaskCreated()); assertEquals(NO, taskState(caseData).getAdminTaskRequired()); assertEquals(CCD_TRUE, taskState(caseData).getLegalOfficerTaskCreated()); assertNull(taskState(caseData).getLegalOfficerTaskRequired()); @@ -444,9 +528,9 @@ void completes_created_tasks_when_party_flags_are_missing() { service.prepareManagedReviewSupportTasks(caseData, null); - assertNull(taskState(caseData).getAdminTaskCreated()); - assertNull(taskState(caseData).getLegalOfficerTaskCreated()); - assertNull(taskState(caseData).getJudgeTaskCreated()); + assertEquals(NO, taskState(caseData).getAdminTaskCreated()); + assertEquals(NO, taskState(caseData).getLegalOfficerTaskCreated()); + assertEquals(NO, taskState(caseData).getJudgeTaskCreated()); assertEquals(NO, taskState(caseData).getAdminTaskRequired()); assertEquals(NO, taskState(caseData).getLegalOfficerTaskRequired()); assertEquals(NO, taskState(caseData).getJudgeTaskRequired()); @@ -460,10 +544,20 @@ void completes_judge_task_when_last_requested_flag_is_managed_and_current_state_ service.prepareManagedReviewSupportTasks(caseData, caseDataBefore); - assertNull(taskState(caseData).getJudgeTaskCreated()); + assertEquals(NO, taskState(caseData).getJudgeTaskCreated()); assertEquals(NO, taskState(caseData).getJudgeTaskRequired()); } + @Test + void completes_admin_task_when_created_marker_is_missing() { + CaseData caseData = caseDataWithClaimantFlag("RA0041", STATUS_ACTIVE, false); + + service.prepareManagedReviewSupportTasks(caseData, null); + + assertEquals(NO, taskState(caseData).getAdminTaskCreated()); + assertEquals(NO, taskState(caseData).getAdminTaskRequired()); + } + @Test void creates_a_new_task_after_the_previous_task_was_completed() { CaseData caseDataBefore = caseDataWithClaimantFlag("RA0033", STATUS_ACTIVE, false); From 3d771467e64bdc065bc510bab4ecb655512a1fe6 Mon Sep 17 00:00:00 2001 From: rajaram Date: Wed, 16 Sep 2026 10:18:52 +0100 Subject: [PATCH 064/100] Review tasks auto close issue resolved --- .../AuthorisationCaseEvent-WA-nonprod.json | 12 ++++ .../CaseEvent-CaseFlagsCaseLinking.json | 26 +++++++-- .../CaseEventToFields-SupportTasks.json | 10 ++++ .../EventToComplexTypes-SupportTasks.json | 27 +++++++++ .../AuthorisationCaseEvent-WA.json | 12 ++++ .../CaseEvent-CaseFlagsCaseLinking.json | 26 +++++++-- .../CaseEventToFields-SupportTasks.json | 10 ++++ .../EventToComplexTypes-SupportTasks.json | 27 +++++++++ .../constants/SupportTaskConstants.java | 1 + .../CaseActionsForCaseWorkerController.java | 14 +++++ .../service/SupportTaskEventService.java | 45 +++++++++++++++ .../docmosis/service/SupportTaskService.java | 14 +++++ ...aseActionsForCaseWorkerControllerTest.java | 34 +++++++++++ .../service/SupportTaskEventServiceTest.java | 57 +++++++++++++++++++ .../service/SupportTaskServiceTest.java | 31 ++++++++++ 15 files changed, 336 insertions(+), 10 deletions(-) create mode 100644 src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskEventService.java create mode 100644 src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskEventServiceTest.java diff --git a/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseEvent/AuthorisationCaseEvent-WA-nonprod.json b/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseEvent/AuthorisationCaseEvent-WA-nonprod.json index 3250b2bfc6..cd6929106f 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseEvent/AuthorisationCaseEvent-WA-nonprod.json +++ b/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseEvent/AuthorisationCaseEvent-WA-nonprod.json @@ -40,5 +40,17 @@ "CaseEventID": "reviewJudgeSupportRequest", "UserRole": "caseworker-wa-task-configuration", "CRUD": "R" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseEventID": "closeReviewSupportTasks", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseEventID": "closeReviewSupportTasks", + "UserRole": "caseworker-wa-task-configuration", + "CRUD": "CRU" } ] diff --git a/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json index e262fc4470..e3f0c76099 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json @@ -11,7 +11,8 @@ "ShowSummary": "N", "Publish": "Y", "CallBackURLAboutToStartEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToStart", - "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToSubmit" + "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToSubmit", + "CallBackURLSubmittedEvent": "${ET_COS_URL}/supportTasks/submitted" }, { "CaseTypeID": "ET_EnglandWales", @@ -25,7 +26,8 @@ "ShowSummary": "N", "Publish": "Y", "CallBackURLAboutToStartEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToStart", - "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToSubmit" + "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToSubmit", + "CallBackURLSubmittedEvent": "${ET_COS_URL}/supportTasks/submitted" }, { "CaseTypeID": "ET_EnglandWales", @@ -39,7 +41,8 @@ "ShowSummary": "N", "Publish": "Y", "CallBackURLAboutToStartEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToStart", - "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToSubmit" + "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToSubmit", + "CallBackURLSubmittedEvent": "${ET_COS_URL}/supportTasks/submitted" }, { "CaseTypeID": "ET_EnglandWales", @@ -70,7 +73,7 @@ "EventEnablingCondition": "", "CallBackURLAboutToStartEvent": "", "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/supportTasks/aboutToSubmit", - "CallBackURLSubmittedEvent": "", + "CallBackURLSubmittedEvent": "${ET_COS_URL}/supportTasks/submitted", "Publish": "Y" }, { @@ -102,7 +105,7 @@ "EventEnablingCondition": "", "CallBackURLAboutToStartEvent": "", "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/supportTasks/aboutToSubmit", - "CallBackURLSubmittedEvent": "", + "CallBackURLSubmittedEvent": "${ET_COS_URL}/supportTasks/submitted", "Publish": "Y" }, { @@ -177,5 +180,18 @@ "CallBackURLAboutToStartEvent": "", "CallBackURLAboutToSubmitEvent": "", "CallBackURLSubmittedEvent": "" + }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "closeReviewSupportTasks", + "Name": "Close review support tasks", + "Description": "Close review support tasks", + "PreConditionState(s)": "*", + "PostConditionState": "*", + "SecurityClassification": "Public", + "ShowEventNotes": "N", + "ShowSummary": "N", + "EventEnablingCondition": "caseType=\"dummy\"", + "Publish": "Y" } ] diff --git a/ccd-definitions/jurisdictions/england-wales/json/CaseEventToFields/CaseEventToFields-SupportTasks.json b/ccd-definitions/jurisdictions/england-wales/json/CaseEventToFields/CaseEventToFields-SupportTasks.json index e6379855b8..d4900c2620 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/CaseEventToFields/CaseEventToFields-SupportTasks.json +++ b/ccd-definitions/jurisdictions/england-wales/json/CaseEventToFields/CaseEventToFields-SupportTasks.json @@ -195,5 +195,15 @@ "FieldShowCondition": "flagLauncher=\"hidden\"", "ShowSummaryChangeOption": "N", "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "closeReviewSupportTasks", + "CaseFieldID": "supportTaskState", + "DisplayContext": "COMPLEX", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 1, + "ShowSummaryChangeOption": "N" } ] diff --git a/ccd-definitions/jurisdictions/england-wales/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json b/ccd-definitions/jurisdictions/england-wales/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json index 6ef5a10b51..d320a4c168 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json +++ b/ccd-definitions/jurisdictions/england-wales/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json @@ -331,5 +331,32 @@ "FieldDisplayOrder": 4, "DisplayContext": "OPTIONAL", "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "closeReviewSupportTasks", + "CaseFieldID": "supportTaskState", + "ListElementCode": "adminTaskRequired", + "FieldDisplayOrder": 1, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "closeReviewSupportTasks", + "CaseFieldID": "supportTaskState", + "ListElementCode": "legalOfficerTaskRequired", + "FieldDisplayOrder": 2, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "closeReviewSupportTasks", + "CaseFieldID": "supportTaskState", + "ListElementCode": "judgeTaskRequired", + "FieldDisplayOrder": 3, + "DisplayContext": "OPTIONAL", + "Publish": "Y" } ] diff --git a/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseEvent/AuthorisationCaseEvent-WA.json b/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseEvent/AuthorisationCaseEvent-WA.json index 8228fb2f8c..e6736173cb 100644 --- a/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseEvent/AuthorisationCaseEvent-WA.json +++ b/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseEvent/AuthorisationCaseEvent-WA.json @@ -215,5 +215,17 @@ "CaseEventID": "reviewJudgeSupportRequest", "UserRole": "caseworker-wa-task-configuration", "CRUD": "R" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseEventID": "closeReviewSupportTasks", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseEventID": "closeReviewSupportTasks", + "UserRole": "caseworker-wa-task-configuration", + "CRUD": "CRU" } ] diff --git a/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json index 235a6566c2..ae39e5e3b5 100644 --- a/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json @@ -11,7 +11,8 @@ "ShowSummary": "N", "Publish": "Y", "CallBackURLAboutToStartEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToStart", - "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToSubmit" + "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToSubmit", + "CallBackURLSubmittedEvent": "${ET_COS_URL}/supportTasks/submitted" }, { "CaseTypeID": "ET_Scotland", @@ -25,7 +26,8 @@ "ShowSummary": "N", "Publish": "Y", "CallBackURLAboutToStartEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToStart", - "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToSubmit" + "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToSubmit", + "CallBackURLSubmittedEvent": "${ET_COS_URL}/supportTasks/submitted" }, { "CaseTypeID": "ET_Scotland", @@ -39,7 +41,8 @@ "ShowSummary": "N", "Publish": "Y", "CallBackURLAboutToStartEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToStart", - "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToSubmit" + "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToSubmit", + "CallBackURLSubmittedEvent": "${ET_COS_URL}/supportTasks/submitted" }, { "CaseTypeID": "ET_Scotland", @@ -70,7 +73,7 @@ "EventEnablingCondition": "", "CallBackURLAboutToStartEvent": "", "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/supportTasks/aboutToSubmit", - "CallBackURLSubmittedEvent": "", + "CallBackURLSubmittedEvent": "${ET_COS_URL}/supportTasks/submitted", "Publish": "Y" }, { @@ -102,7 +105,7 @@ "EventEnablingCondition": "", "CallBackURLAboutToStartEvent": "", "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/supportTasks/aboutToSubmit", - "CallBackURLSubmittedEvent": "", + "CallBackURLSubmittedEvent": "${ET_COS_URL}/supportTasks/submitted", "Publish": "Y" }, { @@ -177,5 +180,18 @@ "SecurityClassification": "Public", "ShowEventNotes": "N", "ShowSummary": "N" + }, + { + "CaseTypeID": "ET_Scotland", + "ID": "closeReviewSupportTasks", + "Name": "Close review support tasks", + "Description": "Close review support tasks", + "PreConditionState(s)": "*", + "PostConditionState": "*", + "SecurityClassification": "Public", + "ShowEventNotes": "N", + "ShowSummary": "N", + "EventEnablingCondition": "caseType=\"dummy\"", + "Publish": "Y" } ] diff --git a/ccd-definitions/jurisdictions/scotland/json/CaseEventToFields/CaseEventToFields-SupportTasks.json b/ccd-definitions/jurisdictions/scotland/json/CaseEventToFields/CaseEventToFields-SupportTasks.json index 002492eee5..9ebaad8e30 100644 --- a/ccd-definitions/jurisdictions/scotland/json/CaseEventToFields/CaseEventToFields-SupportTasks.json +++ b/ccd-definitions/jurisdictions/scotland/json/CaseEventToFields/CaseEventToFields-SupportTasks.json @@ -195,5 +195,15 @@ "FieldShowCondition": "flagLauncher=\"hidden\"", "ShowSummaryChangeOption": "N", "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "closeReviewSupportTasks", + "CaseFieldID": "supportTaskState", + "DisplayContext": "COMPLEX", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 1, + "ShowSummaryChangeOption": "N" } ] diff --git a/ccd-definitions/jurisdictions/scotland/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json b/ccd-definitions/jurisdictions/scotland/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json index 6ef5a10b51..d320a4c168 100644 --- a/ccd-definitions/jurisdictions/scotland/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json +++ b/ccd-definitions/jurisdictions/scotland/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json @@ -331,5 +331,32 @@ "FieldDisplayOrder": 4, "DisplayContext": "OPTIONAL", "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "closeReviewSupportTasks", + "CaseFieldID": "supportTaskState", + "ListElementCode": "adminTaskRequired", + "FieldDisplayOrder": 1, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "closeReviewSupportTasks", + "CaseFieldID": "supportTaskState", + "ListElementCode": "legalOfficerTaskRequired", + "FieldDisplayOrder": 2, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "closeReviewSupportTasks", + "CaseFieldID": "supportTaskState", + "ListElementCode": "judgeTaskRequired", + "FieldDisplayOrder": 3, + "DisplayContext": "OPTIONAL", + "Publish": "Y" } ] diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/constants/SupportTaskConstants.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/constants/SupportTaskConstants.java index cbacfacbb9..cb44fd7cca 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/constants/SupportTaskConstants.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/constants/SupportTaskConstants.java @@ -13,6 +13,7 @@ public final class SupportTaskConstants { public static final String EVENT_REVIEW_ADMIN_SUPPORT_REQUEST = "reviewAdminSupportRequest"; public static final String EVENT_REVIEW_LEGAL_OFFICER_SUPPORT_REQUEST = "reviewLOSupportRequest"; public static final String EVENT_REVIEW_JUDGE_SUPPORT_REQUEST = "reviewJudgeSupportRequest"; + public static final String EVENT_CLOSE_REVIEW_SUPPORT_TASKS = "closeReviewSupportTasks"; public static final String FLAG_STATUS_ACTIVE = "Active"; public static final String FLAG_STATUS_REQUESTED = "Requested"; diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java index ceab69ea9f..74a8599609 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java @@ -50,6 +50,7 @@ import uk.gov.hmcts.ethos.replacement.docmosis.service.ScotlandFileLocationSelectionService; import uk.gov.hmcts.ethos.replacement.docmosis.service.SingleCaseMultipleMidEventValidationService; import uk.gov.hmcts.ethos.replacement.docmosis.service.SingleReferenceService; +import uk.gov.hmcts.ethos.replacement.docmosis.service.SupportTaskEventService; import uk.gov.hmcts.ethos.replacement.docmosis.service.SupportTaskService; import uk.gov.hmcts.ethos.replacement.docmosis.service.noc.NocRespondentRepresentativeService; import uk.gov.hmcts.ethos.replacement.docmosis.utils.LoggingUtils; @@ -120,6 +121,7 @@ public class CaseActionsForCaseWorkerController { private final FeatureToggleService featureToggleService; private final CaseFlagsService caseFlagsService; private final SupportTaskService supportTaskService; + private final SupportTaskEventService supportTaskEventService; private final CaseManagementLocationService caseManagementLocationService; private final Et1SubmissionService et1SubmissionService; private final NocRespondentHelper nocRespondentHelper; @@ -251,6 +253,18 @@ public ResponseEntity prepareSupportTasks( return getCallbackRespEntityNoErrors(caseData); } + @PostMapping(value = "/supportTasks/submitted", consumes = APPLICATION_JSON_VALUE) + @Operation(summary = "Trigger closure of Review Support tasks after Case Flags are updated.") + public ResponseEntity closeReviewSupportTasks( + @RequestBody CallbackRequest callbackRequest) { + CaseDetails caseDetails = callbackRequest.getCaseDetails(); + if (featureToggleService.isCaseFlagsV2Enabled(caseDetails.getCaseTypeId()) + && supportTaskService.hasReviewSupportTaskToClose(caseDetails.getCaseData())) { + supportTaskEventService.triggerCloseReviewSupportTasks(caseDetails); + } + return getCallbackRespEntityNoErrors(caseDetails.getCaseData()); + } + @PostMapping(value = "/reviewSupportRequest/aboutToStart", consumes = APPLICATION_JSON_VALUE) @Operation(summary = "Prepare the requested Case Flags for review.") public ResponseEntity prepareReviewSupportRequest( diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskEventService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskEventService.java new file mode 100644 index 0000000000..e09d23c1df --- /dev/null +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskEventService.java @@ -0,0 +1,45 @@ +package uk.gov.hmcts.ethos.replacement.docmosis.service; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import uk.gov.hmcts.ecm.common.client.CcdClient; +import uk.gov.hmcts.et.common.model.ccd.CCDRequest; +import uk.gov.hmcts.et.common.model.ccd.CaseDetails; +import uk.gov.hmcts.ethos.replacement.docmosis.exceptions.GenericRuntimeException; + +import static uk.gov.hmcts.ecm.common.model.helper.Constants.EMPLOYMENT; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.EVENT_CLOSE_REVIEW_SUPPORT_TASKS; + +@Service +@RequiredArgsConstructor +@Slf4j +public class SupportTaskEventService { + private final CcdClient ccdClient; + private final AdminUserService adminUserService; + + public void triggerCloseReviewSupportTasks(CaseDetails caseDetails) { + String caseId = caseDetails.getCaseId(); + try { + String adminUserToken = adminUserService.getAdminUserToken(); + CCDRequest ccdRequest = ccdClient.startEventForCase( + adminUserToken, + caseDetails.getCaseTypeId(), + EMPLOYMENT, + caseId, + EVENT_CLOSE_REVIEW_SUPPORT_TASKS); + CaseDetails latestCaseDetails = ccdRequest.getCaseDetails(); + ccdClient.submitEventForCase( + adminUserToken, + latestCaseDetails.getCaseData(), + latestCaseDetails.getCaseTypeId(), + latestCaseDetails.getJurisdiction(), + ccdRequest, + caseId); + log.info("Triggered review support task closure event for case {}", caseId); + } catch (Exception exception) { + log.error("Unable to trigger review support task closure event for case {}", caseId, exception); + throw new GenericRuntimeException(exception); + } + } +} diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java index 8b1a498522..92ccd63383 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java @@ -224,6 +224,20 @@ private static boolean isTaskNotCreated(String taskCreated) { && !Boolean.parseBoolean(taskCreated); } + public boolean hasReviewSupportTaskToClose(CaseData caseData) { + SupportTaskState state = caseData.getSupportTaskState(); + return state != null && Stream.of( + state.getAdminTaskRequired(), + state.getLegalOfficerTaskRequired(), + state.getJudgeTaskRequired()) + .anyMatch(SupportTaskService::isTaskNotRequired); + } + + private static boolean isTaskNotRequired(String taskRequired) { + return NO.equalsIgnoreCase(taskRequired) + || "false".equalsIgnoreCase(taskRequired); + } + private static boolean isRequested(FlagDetailType flag) { return FLAG_STATUS_REQUESTED.equals(flag.getStatus()); } diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java index 122713a7fc..ea582e00e3 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java @@ -49,6 +49,7 @@ import uk.gov.hmcts.ethos.replacement.docmosis.service.ScotlandFileLocationSelectionService; import uk.gov.hmcts.ethos.replacement.docmosis.service.SingleCaseMultipleMidEventValidationService; import uk.gov.hmcts.ethos.replacement.docmosis.service.SingleReferenceService; +import uk.gov.hmcts.ethos.replacement.docmosis.service.SupportTaskEventService; import uk.gov.hmcts.ethos.replacement.docmosis.service.SupportTaskService; import uk.gov.hmcts.ethos.replacement.docmosis.service.noc.NocRespondentRepresentativeService; import uk.gov.hmcts.ethos.replacement.docmosis.utils.InternalException; @@ -97,6 +98,7 @@ class CaseActionsForCaseWorkerControllerTest extends BaseControllerTest { private static final String PRE_DEFAULT_VALUES_URL = "/preDefaultValues"; private static final String POST_DEFAULT_VALUES_URL = "/postDefaultValues"; private static final String SUPPORT_TASKS_URL = "/supportTasks/aboutToSubmit"; + private static final String SUPPORT_TASKS_SUBMITTED_URL = "/supportTasks/submitted"; private static final String REVIEW_SUPPORT_REQUEST_ABOUT_TO_START_URL = "/reviewSupportRequest/aboutToStart"; private static final String REVIEW_SUPPORT_REQUEST_ABOUT_TO_SUBMIT_URL = @@ -195,6 +197,9 @@ class CaseActionsForCaseWorkerControllerTest extends BaseControllerTest { @MockitoBean private SupportTaskService supportTaskService; + @MockitoBean + private SupportTaskEventService supportTaskEventService; + @MockitoBean private FeatureToggleService featureToggleService; @@ -439,6 +444,35 @@ void preparesReviewSupportTaskCompletionForManagedCaseFlags(String eventId) { verify(caseManagementForCaseWorkerService).setNextListedDate(any(CaseData.class)); } + @Test + @SneakyThrows + void triggersDedicatedReviewSupportTaskClosureEventAfterCaseUpdate() { + when(featureToggleService.isCaseFlagsV2Enabled(anyString())).thenReturn(true); + when(supportTaskService.hasReviewSupportTaskToClose(any(CaseData.class))).thenReturn(true); + + mvc.perform(post(SUPPORT_TASKS_SUBMITTED_URL) + .content(requestContent2.toString()) + .header(AUTHORIZATION, AUTH_TOKEN) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + + verify(supportTaskEventService).triggerCloseReviewSupportTasks(any(CaseDetails.class)); + } + + @Test + @SneakyThrows + void doesNotTriggerReviewSupportTaskClosureEventWhenNoTaskNeedsClosing() { + when(featureToggleService.isCaseFlagsV2Enabled(anyString())).thenReturn(true); + + mvc.perform(post(SUPPORT_TASKS_SUBMITTED_URL) + .content(requestContent2.toString()) + .header(AUTHORIZATION, AUTH_TOKEN) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + + verify(supportTaskEventService, never()).triggerCloseReviewSupportTasks(any(CaseDetails.class)); + } + @ParameterizedTest @ValueSource(strings = { "reviewAdminSupportRequest", diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskEventServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskEventServiceTest.java new file mode 100644 index 0000000000..44b6a9110a --- /dev/null +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskEventServiceTest.java @@ -0,0 +1,57 @@ +package uk.gov.hmcts.ethos.replacement.docmosis.service; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import uk.gov.hmcts.ecm.common.client.CcdClient; +import uk.gov.hmcts.et.common.model.ccd.CCDRequest; +import uk.gov.hmcts.et.common.model.ccd.CaseData; +import uk.gov.hmcts.et.common.model.ccd.CaseDetails; + +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static uk.gov.hmcts.ecm.common.model.helper.Constants.EMPLOYMENT; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.EVENT_CLOSE_REVIEW_SUPPORT_TASKS; + +@ExtendWith(MockitoExtension.class) +class SupportTaskEventServiceTest { + private static final String ADMIN_TOKEN = "admin-token"; + private static final String CASE_ID = "1234567890123456"; + private static final String CASE_TYPE_ID = "ET_Scotland"; + + @Mock + private CcdClient ccdClient; + @Mock + private AdminUserService adminUserService; + + private SupportTaskEventService service; + + @BeforeEach + void setUp() { + service = new SupportTaskEventService(ccdClient, adminUserService); + } + + @Test + void startsAndSubmitsDedicatedTaskClosureEventUsingLatestCaseData() throws Exception { + CaseData latestCaseData = new CaseData(); + CaseDetails latestDetails = new CaseDetails(); + latestDetails.setCaseId(CASE_ID); + latestDetails.setCaseTypeId(CASE_TYPE_ID); + latestDetails.setJurisdiction(EMPLOYMENT); + latestDetails.setCaseData(latestCaseData); + CCDRequest ccdRequest = new CCDRequest(); + ccdRequest.setCaseDetails(latestDetails); + + when(adminUserService.getAdminUserToken()).thenReturn(ADMIN_TOKEN); + when(ccdClient.startEventForCase( + ADMIN_TOKEN, CASE_TYPE_ID, EMPLOYMENT, CASE_ID, EVENT_CLOSE_REVIEW_SUPPORT_TASKS)) + .thenReturn(ccdRequest); + + service.triggerCloseReviewSupportTasks(latestDetails); + + verify(ccdClient).submitEventForCase( + ADMIN_TOKEN, latestCaseData, CASE_TYPE_ID, EMPLOYMENT, ccdRequest, CASE_ID); + } +} diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java index d3a295f1db..65d83e535e 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java @@ -43,6 +43,37 @@ class SupportTaskServiceTest { private final SupportTaskService service = new SupportTaskService(configuration()); + @Test + void identifiesReviewSupportTaskThatNeedsClosing() { + CaseData caseData = new CaseData(); + SupportTaskState state = new SupportTaskState(); + state.setJudgeTaskRequired(NO); + caseData.setSupportTaskState(state); + + assertTrue(service.hasReviewSupportTaskToClose(caseData)); + } + + @Test + void identifiesBooleanReviewSupportTaskThatNeedsClosing() { + CaseData caseData = new CaseData(); + SupportTaskState state = new SupportTaskState(); + state.setAdminTaskRequired(CCD_FALSE); + caseData.setSupportTaskState(state); + + assertTrue(service.hasReviewSupportTaskToClose(caseData)); + } + + @Test + void doesNotIdentifyReviewSupportTaskWhenNoCategoryNeedsClosing() { + CaseData caseData = new CaseData(); + SupportTaskState state = new SupportTaskState(); + state.setAdminTaskRequired(YES); + state.setJudgeTaskRequired(CCD_TRUE); + caseData.setSupportTaskState(state); + + assertFalse(service.hasReviewSupportTaskToClose(caseData)); + } + private static SupportTaskConfiguration configuration() { SupportTaskConfiguration configuration = new SupportTaskConfiguration(); configuration.getReview().setAdminFlagCodes(Set.of( From 6db8797824fd531dd72d785b158c8a4604ea888b Mon Sep 17 00:00:00 2001 From: hmcts-jenkins-d-to-i <62423932+hmcts-jenkins-d-to-i[bot]@users.noreply.github.com> Date: Wed, 16 Sep 2026 09:20:25 +0000 Subject: [PATCH 065/100] Bumping chart version/ fixing aliases --- charts/et-cos/Chart.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/et-cos/Chart.yaml b/charts/et-cos/Chart.yaml index b992ed2f0e..0cfd7762d5 100644 --- a/charts/et-cos/Chart.yaml +++ b/charts/et-cos/Chart.yaml @@ -1,7 +1,7 @@ apiVersion: v2 name: et-cos home: https://github.com/hmcts/et-ccd-callbacks -version: 0.0.74 +version: 0.0.75 description: HMCTS Employment Tribunals CCD Callbacks service maintainers: - name: HMCTS Employment Tribunals Team From 0fdb851d45352a453894845de2b48a57aafe3cac Mon Sep 17 00:00:00 2001 From: rajaram Date: Wed, 16 Sep 2026 11:13:42 +0100 Subject: [PATCH 066/100] Review tasks auto close issue resolved --- .../CaseActionsForCaseWorkerController.java | 5 +- .../docmosis/service/SupportTaskService.java | 24 +++++++--- ...aseActionsForCaseWorkerControllerTest.java | 7 ++- .../service/SupportTaskServiceTest.java | 48 +++++++++++++++++-- 4 files changed, 72 insertions(+), 12 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java index 74a8599609..2c6ddd945f 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java @@ -258,8 +258,11 @@ public ResponseEntity prepareSupportTasks( public ResponseEntity closeReviewSupportTasks( @RequestBody CallbackRequest callbackRequest) { CaseDetails caseDetails = callbackRequest.getCaseDetails(); + CaseData caseDataBefore = callbackRequest.getCaseDetailsBefore() == null + ? null + : callbackRequest.getCaseDetailsBefore().getCaseData(); if (featureToggleService.isCaseFlagsV2Enabled(caseDetails.getCaseTypeId()) - && supportTaskService.hasReviewSupportTaskToClose(caseDetails.getCaseData())) { + && supportTaskService.hasReviewSupportTaskToClose(caseDetails.getCaseData(), caseDataBefore)) { supportTaskEventService.triggerCloseReviewSupportTasks(caseDetails); } return getCallbackRespEntityNoErrors(caseDetails.getCaseData()); diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java index 92ccd63383..4c772b2ec5 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java @@ -224,13 +224,23 @@ private static boolean isTaskNotCreated(String taskCreated) { && !Boolean.parseBoolean(taskCreated); } - public boolean hasReviewSupportTaskToClose(CaseData caseData) { - SupportTaskState state = caseData.getSupportTaskState(); - return state != null && Stream.of( - state.getAdminTaskRequired(), - state.getLegalOfficerTaskRequired(), - state.getJudgeTaskRequired()) - .anyMatch(SupportTaskService::isTaskNotRequired); + public boolean hasReviewSupportTaskToClose(CaseData caseData, CaseData caseDataBefore) { + SupportTaskState currentState = caseData.getSupportTaskState(); + if (currentState == null) { + return false; + } + + SupportTaskState previousState = caseDataBefore == null ? null : caseDataBefore.getSupportTaskState(); + return becameNotRequired(currentState.getAdminTaskRequired(), + previousState == null ? null : previousState.getAdminTaskRequired()) + || becameNotRequired(currentState.getLegalOfficerTaskRequired(), + previousState == null ? null : previousState.getLegalOfficerTaskRequired()) + || becameNotRequired(currentState.getJudgeTaskRequired(), + previousState == null ? null : previousState.getJudgeTaskRequired()); + } + + private static boolean becameNotRequired(String currentValue, String previousValue) { + return isTaskNotRequired(currentValue) && !isTaskNotRequired(previousValue); } private static boolean isTaskNotRequired(String taskRequired) { diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java index ea582e00e3..c5f1e8e557 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java @@ -447,8 +447,11 @@ void preparesReviewSupportTaskCompletionForManagedCaseFlags(String eventId) { @Test @SneakyThrows void triggersDedicatedReviewSupportTaskClosureEventAfterCaseUpdate() { + ((ObjectNode) requestContent2).set("case_details_before", + requestContent2.get("case_details").deepCopy()); when(featureToggleService.isCaseFlagsV2Enabled(anyString())).thenReturn(true); - when(supportTaskService.hasReviewSupportTaskToClose(any(CaseData.class))).thenReturn(true); + when(supportTaskService.hasReviewSupportTaskToClose( + any(CaseData.class), any(CaseData.class))).thenReturn(true); mvc.perform(post(SUPPORT_TASKS_SUBMITTED_URL) .content(requestContent2.toString()) @@ -457,6 +460,8 @@ void triggersDedicatedReviewSupportTaskClosureEventAfterCaseUpdate() { .andExpect(status().isOk()); verify(supportTaskEventService).triggerCloseReviewSupportTasks(any(CaseDetails.class)); + verify(supportTaskService).hasReviewSupportTaskToClose( + any(CaseData.class), any(CaseData.class)); } @Test diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java index 65d83e535e..590f1a5bac 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java @@ -50,7 +50,7 @@ void identifiesReviewSupportTaskThatNeedsClosing() { state.setJudgeTaskRequired(NO); caseData.setSupportTaskState(state); - assertTrue(service.hasReviewSupportTaskToClose(caseData)); + assertTrue(service.hasReviewSupportTaskToClose(caseData, new CaseData())); } @Test @@ -60,7 +60,7 @@ void identifiesBooleanReviewSupportTaskThatNeedsClosing() { state.setAdminTaskRequired(CCD_FALSE); caseData.setSupportTaskState(state); - assertTrue(service.hasReviewSupportTaskToClose(caseData)); + assertTrue(service.hasReviewSupportTaskToClose(caseData, new CaseData())); } @Test @@ -71,7 +71,25 @@ void doesNotIdentifyReviewSupportTaskWhenNoCategoryNeedsClosing() { state.setJudgeTaskRequired(CCD_TRUE); caseData.setSupportTaskState(state); - assertFalse(service.hasReviewSupportTaskToClose(caseData)); + assertFalse(service.hasReviewSupportTaskToClose(caseData, new CaseData())); + } + + @Test + void doesNotCloseReviewSupportTaskAgainWhenItWasAlreadyNotRequired() { + CaseData caseDataBefore = new CaseData(); + caseDataBefore.setSupportTaskState(SupportTaskState.builder().adminTaskRequired(NO).build()); + CaseData caseData = new CaseData(); + caseData.setSupportTaskState(SupportTaskState.builder().adminTaskRequired(NO).build()); + + assertFalse(service.hasReviewSupportTaskToClose(caseData, caseDataBefore)); + } + + @Test + void closesReviewSupportTaskWhenPreviousCaseDataIsUnavailable() { + CaseData caseData = new CaseData(); + caseData.setSupportTaskState(SupportTaskState.builder().legalOfficerTaskRequired(NO).build()); + + assertTrue(service.hasReviewSupportTaskToClose(caseData, null)); } private static SupportTaskConfiguration configuration() { @@ -579,6 +597,30 @@ void completes_judge_task_when_last_requested_flag_is_managed_and_current_state_ assertEquals(NO, taskState(caseData).getJudgeTaskRequired()); } + static Stream reviewAndArrangeTaskScenarios() { + return Stream.of( + Arguments.of("RA0041", TASK_TYPE_ADMIN, "Lip speaker"), + Arguments.of("RA0038", TASK_TYPE_JUDGE, "Intermediary") + ); + } + + @ParameterizedTest + @MethodSource("reviewAndArrangeTaskScenarios") + void preservesReviewCompletionAndArrangeCreationInTheSameUpdate(String flagCode, + String taskType, + String arrangeTaskName) { + CaseData caseDataBefore = caseDataWithClaimantFlag(flagCode, STATUS_REQUESTED, false); + CaseData caseData = caseDataWithClaimantFlag(flagCode, STATUS_ACTIVE, false); + caseData.setSupportTaskState(new SupportTaskState()); + setTaskCreated(taskState(caseData), taskType, YES); + + service.prepareManagedReviewSupportTasks(caseData, caseDataBefore); + service.prepareArrangeSupportTask(caseData, caseDataBefore); + + assertEquals(NO, getTaskRequired(taskState(caseData), taskType)); + assertEquals(arrangeTaskName, taskState(caseData).getArrangeSupportTaskName()); + } + @Test void completes_admin_task_when_created_marker_is_missing() { CaseData caseData = caseDataWithClaimantFlag("RA0041", STATUS_ACTIVE, false); From c10dcc0386d6eb139958497de93380395bb7daef Mon Sep 17 00:00:00 2001 From: rajaram Date: Wed, 16 Sep 2026 12:24:32 +0100 Subject: [PATCH 067/100] Review tasks auto close issue resolved --- .../CaseActionsForCaseWorkerController.java | 8 +++- .../service/SupportTaskEventService.java | 31 ++++++++++++++- .../docmosis/service/SupportTaskService.java | 25 ++++++------ .../service/SupportTaskEventServiceTest.java | 28 +++++++++++++- .../service/SupportTaskServiceTest.java | 38 +++++++++---------- 5 files changed, 95 insertions(+), 35 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java index 2c6ddd945f..acdb954f1f 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java @@ -261,8 +261,12 @@ public ResponseEntity closeReviewSupportTasks( CaseData caseDataBefore = callbackRequest.getCaseDetailsBefore() == null ? null : callbackRequest.getCaseDetailsBefore().getCaseData(); - if (featureToggleService.isCaseFlagsV2Enabled(caseDetails.getCaseTypeId()) - && supportTaskService.hasReviewSupportTaskToClose(caseDetails.getCaseData(), caseDataBefore)) { + boolean caseFlagsV2Enabled = featureToggleService.isCaseFlagsV2Enabled(caseDetails.getCaseTypeId()); + boolean reviewSupportTaskToClose = caseFlagsV2Enabled + && supportTaskService.hasReviewSupportTaskToClose(caseDetails.getCaseData(), caseDataBefore); + log.info("Review Support task closure evaluated for case {}: enabled={}, closeRequired={}", + caseDetails.getCaseId(), caseFlagsV2Enabled, reviewSupportTaskToClose); + if (reviewSupportTaskToClose) { supportTaskEventService.triggerCloseReviewSupportTasks(caseDetails); } return getCallbackRespEntityNoErrors(caseDetails.getCaseData()); diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskEventService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskEventService.java index e09d23c1df..8e538df2ee 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskEventService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskEventService.java @@ -5,10 +5,13 @@ import org.springframework.stereotype.Service; import uk.gov.hmcts.ecm.common.client.CcdClient; import uk.gov.hmcts.et.common.model.ccd.CCDRequest; +import uk.gov.hmcts.et.common.model.ccd.CaseData; import uk.gov.hmcts.et.common.model.ccd.CaseDetails; +import uk.gov.hmcts.et.common.model.ccd.types.SupportTaskState; import uk.gov.hmcts.ethos.replacement.docmosis.exceptions.GenericRuntimeException; import static uk.gov.hmcts.ecm.common.model.helper.Constants.EMPLOYMENT; +import static uk.gov.hmcts.ecm.common.model.helper.Constants.NO; import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.EVENT_CLOSE_REVIEW_SUPPORT_TASKS; @Service @@ -20,6 +23,7 @@ public class SupportTaskEventService { public void triggerCloseReviewSupportTasks(CaseDetails caseDetails) { String caseId = caseDetails.getCaseId(); + SupportTaskState completedTaskState = caseDetails.getCaseData().getSupportTaskState(); try { String adminUserToken = adminUserService.getAdminUserToken(); CCDRequest ccdRequest = ccdClient.startEventForCase( @@ -29,9 +33,14 @@ public void triggerCloseReviewSupportTasks(CaseDetails caseDetails) { caseId, EVENT_CLOSE_REVIEW_SUPPORT_TASKS); CaseDetails latestCaseDetails = ccdRequest.getCaseDetails(); + CaseData latestCaseData = latestCaseDetails.getCaseData(); + if (latestCaseData.getSupportTaskState() == null) { + latestCaseData.setSupportTaskState(new SupportTaskState()); + } + markCompletedReviewTasksNotRequired(latestCaseData.getSupportTaskState(), completedTaskState); ccdClient.submitEventForCase( adminUserToken, - latestCaseDetails.getCaseData(), + latestCaseData, latestCaseDetails.getCaseTypeId(), latestCaseDetails.getJurisdiction(), ccdRequest, @@ -42,4 +51,24 @@ public void triggerCloseReviewSupportTasks(CaseDetails caseDetails) { throw new GenericRuntimeException(exception); } } + + private static void markCompletedReviewTasksNotRequired(SupportTaskState latestTaskState, + SupportTaskState completedTaskState) { + if (completedTaskState == null) { + return; + } + if (isTaskNotCreated(completedTaskState.getAdminTaskCreated())) { + latestTaskState.setAdminTaskRequired(NO); + } + if (isTaskNotCreated(completedTaskState.getLegalOfficerTaskCreated())) { + latestTaskState.setLegalOfficerTaskRequired(NO); + } + if (isTaskNotCreated(completedTaskState.getJudgeTaskCreated())) { + latestTaskState.setJudgeTaskRequired(NO); + } + } + + private static boolean isTaskNotCreated(String taskCreated) { + return NO.equalsIgnoreCase(taskCreated) || "false".equalsIgnoreCase(taskCreated); + } } diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java index 4c772b2ec5..8504a14e8e 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java @@ -215,7 +215,8 @@ private static void updateTaskState(List flags, taskRequiredSetter.accept(null); if (!hasRequestedFlag(flags, eligibleFlagCodes)) { taskCreatedSetter.accept(NO); - taskRequiredSetter.accept(NO); + // The submitted callback changes this to No in the dedicated close event. + taskRequiredSetter.accept(YES); } } @@ -231,21 +232,21 @@ public boolean hasReviewSupportTaskToClose(CaseData caseData, CaseData caseDataB } SupportTaskState previousState = caseDataBefore == null ? null : caseDataBefore.getSupportTaskState(); - return becameNotRequired(currentState.getAdminTaskRequired(), - previousState == null ? null : previousState.getAdminTaskRequired()) - || becameNotRequired(currentState.getLegalOfficerTaskRequired(), - previousState == null ? null : previousState.getLegalOfficerTaskRequired()) - || becameNotRequired(currentState.getJudgeTaskRequired(), - previousState == null ? null : previousState.getJudgeTaskRequired()); + return becameNotCreated(currentState.getAdminTaskCreated(), + previousState == null ? null : previousState.getAdminTaskCreated()) + || becameNotCreated(currentState.getLegalOfficerTaskCreated(), + previousState == null ? null : previousState.getLegalOfficerTaskCreated()) + || becameNotCreated(currentState.getJudgeTaskCreated(), + previousState == null ? null : previousState.getJudgeTaskCreated()); } - private static boolean becameNotRequired(String currentValue, String previousValue) { - return isTaskNotRequired(currentValue) && !isTaskNotRequired(previousValue); + private static boolean becameNotCreated(String currentValue, String previousValue) { + return isTaskNotCreatedMarker(currentValue) && !isTaskNotCreatedMarker(previousValue); } - private static boolean isTaskNotRequired(String taskRequired) { - return NO.equalsIgnoreCase(taskRequired) - || "false".equalsIgnoreCase(taskRequired); + private static boolean isTaskNotCreatedMarker(String taskCreated) { + return NO.equalsIgnoreCase(taskCreated) + || "false".equalsIgnoreCase(taskCreated); } private static boolean isRequested(FlagDetailType flag) { diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskEventServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskEventServiceTest.java index 44b6a9110a..16a2a7c21a 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskEventServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskEventServiceTest.java @@ -9,10 +9,14 @@ import uk.gov.hmcts.et.common.model.ccd.CCDRequest; import uk.gov.hmcts.et.common.model.ccd.CaseData; import uk.gov.hmcts.et.common.model.ccd.CaseDetails; +import uk.gov.hmcts.et.common.model.ccd.types.SupportTaskState; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static uk.gov.hmcts.ecm.common.model.helper.Constants.EMPLOYMENT; +import static uk.gov.hmcts.ecm.common.model.helper.Constants.NO; +import static uk.gov.hmcts.ecm.common.model.helper.Constants.YES; import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.EVENT_CLOSE_REVIEW_SUPPORT_TASKS; @ExtendWith(MockitoExtension.class) @@ -35,7 +39,26 @@ void setUp() { @Test void startsAndSubmitsDedicatedTaskClosureEventUsingLatestCaseData() throws Exception { + CaseData completedCaseData = new CaseData(); + completedCaseData.setSupportTaskState(SupportTaskState.builder() + .adminTaskCreated(NO) + .legalOfficerTaskCreated(YES) + .judgeTaskCreated(YES) + .build()); + CaseDetails completedDetails = new CaseDetails(); + completedDetails.setCaseId(CASE_ID); + completedDetails.setCaseTypeId(CASE_TYPE_ID); + completedDetails.setCaseData(completedCaseData); + CaseData latestCaseData = new CaseData(); + latestCaseData.setSupportTaskState(SupportTaskState.builder() + .adminTaskCreated(YES) + .adminTaskRequired(YES) + .legalOfficerTaskCreated(YES) + .legalOfficerTaskRequired(YES) + .judgeTaskCreated(YES) + .judgeTaskRequired(YES) + .build()); CaseDetails latestDetails = new CaseDetails(); latestDetails.setCaseId(CASE_ID); latestDetails.setCaseTypeId(CASE_TYPE_ID); @@ -49,8 +72,11 @@ void startsAndSubmitsDedicatedTaskClosureEventUsingLatestCaseData() throws Excep ADMIN_TOKEN, CASE_TYPE_ID, EMPLOYMENT, CASE_ID, EVENT_CLOSE_REVIEW_SUPPORT_TASKS)) .thenReturn(ccdRequest); - service.triggerCloseReviewSupportTasks(latestDetails); + service.triggerCloseReviewSupportTasks(completedDetails); + assertEquals(NO, latestCaseData.getSupportTaskState().getAdminTaskRequired()); + assertEquals(YES, latestCaseData.getSupportTaskState().getLegalOfficerTaskRequired()); + assertEquals(YES, latestCaseData.getSupportTaskState().getJudgeTaskRequired()); verify(ccdClient).submitEventForCase( ADMIN_TOKEN, latestCaseData, CASE_TYPE_ID, EMPLOYMENT, ccdRequest, CASE_ID); } diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java index 590f1a5bac..4c550f48ad 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java @@ -47,7 +47,7 @@ class SupportTaskServiceTest { void identifiesReviewSupportTaskThatNeedsClosing() { CaseData caseData = new CaseData(); SupportTaskState state = new SupportTaskState(); - state.setJudgeTaskRequired(NO); + state.setJudgeTaskCreated(NO); caseData.setSupportTaskState(state); assertTrue(service.hasReviewSupportTaskToClose(caseData, new CaseData())); @@ -57,7 +57,7 @@ void identifiesReviewSupportTaskThatNeedsClosing() { void identifiesBooleanReviewSupportTaskThatNeedsClosing() { CaseData caseData = new CaseData(); SupportTaskState state = new SupportTaskState(); - state.setAdminTaskRequired(CCD_FALSE); + state.setAdminTaskCreated(CCD_FALSE); caseData.setSupportTaskState(state); assertTrue(service.hasReviewSupportTaskToClose(caseData, new CaseData())); @@ -67,8 +67,8 @@ void identifiesBooleanReviewSupportTaskThatNeedsClosing() { void doesNotIdentifyReviewSupportTaskWhenNoCategoryNeedsClosing() { CaseData caseData = new CaseData(); SupportTaskState state = new SupportTaskState(); - state.setAdminTaskRequired(YES); - state.setJudgeTaskRequired(CCD_TRUE); + state.setAdminTaskCreated(YES); + state.setJudgeTaskCreated(CCD_TRUE); caseData.setSupportTaskState(state); assertFalse(service.hasReviewSupportTaskToClose(caseData, new CaseData())); @@ -77,9 +77,9 @@ void doesNotIdentifyReviewSupportTaskWhenNoCategoryNeedsClosing() { @Test void doesNotCloseReviewSupportTaskAgainWhenItWasAlreadyNotRequired() { CaseData caseDataBefore = new CaseData(); - caseDataBefore.setSupportTaskState(SupportTaskState.builder().adminTaskRequired(NO).build()); + caseDataBefore.setSupportTaskState(SupportTaskState.builder().adminTaskCreated(NO).build()); CaseData caseData = new CaseData(); - caseData.setSupportTaskState(SupportTaskState.builder().adminTaskRequired(NO).build()); + caseData.setSupportTaskState(SupportTaskState.builder().adminTaskCreated(NO).build()); assertFalse(service.hasReviewSupportTaskToClose(caseData, caseDataBefore)); } @@ -87,7 +87,7 @@ void doesNotCloseReviewSupportTaskAgainWhenItWasAlreadyNotRequired() { @Test void closesReviewSupportTaskWhenPreviousCaseDataIsUnavailable() { CaseData caseData = new CaseData(); - caseData.setSupportTaskState(SupportTaskState.builder().legalOfficerTaskRequired(NO).build()); + caseData.setSupportTaskState(SupportTaskState.builder().legalOfficerTaskCreated(NO).build()); assertTrue(service.hasReviewSupportTaskToClose(caseData, null)); } @@ -324,11 +324,11 @@ void completes_only_task_type_without_an_eligible_requested_flag() { service.prepareManagedReviewSupportTasks(caseData, null); assertEquals(NO, taskState(caseData).getAdminTaskCreated()); - assertEquals(NO, taskState(caseData).getAdminTaskRequired()); + assertEquals(YES, taskState(caseData).getAdminTaskRequired()); assertEquals(YES, taskState(caseData).getJudgeTaskCreated()); assertNull(taskState(caseData).getJudgeTaskRequired()); assertEquals(NO, taskState(caseData).getLegalOfficerTaskCreated()); - assertEquals(NO, taskState(caseData).getLegalOfficerTaskRequired()); + assertEquals(YES, taskState(caseData).getLegalOfficerTaskRequired()); } @Test @@ -456,7 +456,7 @@ void completes_each_task_category_only_after_its_last_requested_flag_is_activate service.prepareManagedReviewSupportTasks(caseData, null); assertEquals(NO, getTaskCreated(taskState(caseData), taskType)); - assertEquals(NO, getTaskRequired(taskState(caseData), taskType)); + assertEquals(YES, getTaskRequired(taskState(caseData), taskType)); } @ParameterizedTest @@ -486,7 +486,7 @@ void restores_boolean_created_state_from_before_data_and_completes_each_category service.prepareManagedReviewSupportTasks(caseData, caseDataBefore); assertEquals(NO, getTaskCreated(taskState(caseData), taskType)); - assertEquals(NO, getTaskRequired(taskState(caseData), taskType)); + assertEquals(YES, getTaskRequired(taskState(caseData), taskType)); } @ParameterizedTest @@ -513,7 +513,7 @@ void completes_each_task_category_for_every_non_requested_status( service.prepareManagedReviewSupportTasks(caseData, null); assertEquals(NO, getTaskCreated(taskState(caseData), taskType)); - assertEquals(NO, getTaskRequired(taskState(caseData), taskType)); + assertEquals(YES, getTaskRequired(taskState(caseData), taskType)); } @Test @@ -533,7 +533,7 @@ void completes_only_categories_without_requested_flags_when_boolean_state_is_use service.prepareManagedReviewSupportTasks(caseData, null); assertEquals(NO, taskState(caseData).getAdminTaskCreated()); - assertEquals(NO, taskState(caseData).getAdminTaskRequired()); + assertEquals(YES, taskState(caseData).getAdminTaskRequired()); assertEquals(CCD_TRUE, taskState(caseData).getLegalOfficerTaskCreated()); assertNull(taskState(caseData).getLegalOfficerTaskRequired()); assertEquals(CCD_TRUE, taskState(caseData).getJudgeTaskCreated()); @@ -580,9 +580,9 @@ void completes_created_tasks_when_party_flags_are_missing() { assertEquals(NO, taskState(caseData).getAdminTaskCreated()); assertEquals(NO, taskState(caseData).getLegalOfficerTaskCreated()); assertEquals(NO, taskState(caseData).getJudgeTaskCreated()); - assertEquals(NO, taskState(caseData).getAdminTaskRequired()); - assertEquals(NO, taskState(caseData).getLegalOfficerTaskRequired()); - assertEquals(NO, taskState(caseData).getJudgeTaskRequired()); + assertEquals(YES, taskState(caseData).getAdminTaskRequired()); + assertEquals(YES, taskState(caseData).getLegalOfficerTaskRequired()); + assertEquals(YES, taskState(caseData).getJudgeTaskRequired()); } @Test @@ -594,7 +594,7 @@ void completes_judge_task_when_last_requested_flag_is_managed_and_current_state_ service.prepareManagedReviewSupportTasks(caseData, caseDataBefore); assertEquals(NO, taskState(caseData).getJudgeTaskCreated()); - assertEquals(NO, taskState(caseData).getJudgeTaskRequired()); + assertEquals(YES, taskState(caseData).getJudgeTaskRequired()); } static Stream reviewAndArrangeTaskScenarios() { @@ -617,7 +617,7 @@ void preservesReviewCompletionAndArrangeCreationInTheSameUpdate(String flagCode, service.prepareManagedReviewSupportTasks(caseData, caseDataBefore); service.prepareArrangeSupportTask(caseData, caseDataBefore); - assertEquals(NO, getTaskRequired(taskState(caseData), taskType)); + assertEquals(YES, getTaskRequired(taskState(caseData), taskType)); assertEquals(arrangeTaskName, taskState(caseData).getArrangeSupportTaskName()); } @@ -628,7 +628,7 @@ void completes_admin_task_when_created_marker_is_missing() { service.prepareManagedReviewSupportTasks(caseData, null); assertEquals(NO, taskState(caseData).getAdminTaskCreated()); - assertEquals(NO, taskState(caseData).getAdminTaskRequired()); + assertEquals(YES, taskState(caseData).getAdminTaskRequired()); } @Test From 41c906d74325cd852bcd905909344bc06527557e Mon Sep 17 00:00:00 2001 From: hmcts-jenkins-d-to-i <62423932+hmcts-jenkins-d-to-i[bot]@users.noreply.github.com> Date: Wed, 16 Sep 2026 11:25:56 +0000 Subject: [PATCH 068/100] Bumping chart version/ fixing aliases --- charts/et-cos/Chart.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/et-cos/Chart.yaml b/charts/et-cos/Chart.yaml index 67d1f21b7a..77b873d5bb 100644 --- a/charts/et-cos/Chart.yaml +++ b/charts/et-cos/Chart.yaml @@ -1,7 +1,7 @@ apiVersion: v2 name: et-cos home: https://github.com/hmcts/et-ccd-callbacks -version: 0.0.75 +version: 0.0.76 description: HMCTS Employment Tribunals CCD Callbacks service maintainers: - name: HMCTS Employment Tribunals Team From eb645a003b6bcda5e94e7ecd1e7508b14a7f7bfb Mon Sep 17 00:00:00 2001 From: rajaram Date: Wed, 16 Sep 2026 13:09:32 +0100 Subject: [PATCH 069/100] Review tasks auto close issue resolved --- .../CaseActionsForCaseWorkerController.java | 5 +--- .../docmosis/service/SupportTaskService.java | 27 +++++++++---------- ...aseActionsForCaseWorkerControllerTest.java | 6 ++--- .../service/SupportTaskServiceTest.java | 26 +++++++++++------- 4 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java index acdb954f1f..5e43e1b2a1 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java @@ -258,12 +258,9 @@ public ResponseEntity prepareSupportTasks( public ResponseEntity closeReviewSupportTasks( @RequestBody CallbackRequest callbackRequest) { CaseDetails caseDetails = callbackRequest.getCaseDetails(); - CaseData caseDataBefore = callbackRequest.getCaseDetailsBefore() == null - ? null - : callbackRequest.getCaseDetailsBefore().getCaseData(); boolean caseFlagsV2Enabled = featureToggleService.isCaseFlagsV2Enabled(caseDetails.getCaseTypeId()); boolean reviewSupportTaskToClose = caseFlagsV2Enabled - && supportTaskService.hasReviewSupportTaskToClose(caseDetails.getCaseData(), caseDataBefore); + && supportTaskService.hasReviewSupportTaskToClose(caseDetails.getCaseData()); log.info("Review Support task closure evaluated for case {}: enabled={}, closeRequired={}", caseDetails.getCaseId(), caseFlagsV2Enabled, reviewSupportTaskToClose); if (reviewSupportTaskToClose) { diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java index 8504a14e8e..56cdce0a73 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java @@ -99,13 +99,14 @@ public void prepareManagedReviewSupportTasks(CaseData caseData, CaseData caseDat .map(GenericTypeItem::getValue) .toList(); - updateTaskState(flags, configuration.getReview().getAdminFlagCodes(), + updateTaskState(flags, configuration.getReview().getAdminFlagCodes(), taskState.getAdminTaskCreated(), taskState::setAdminTaskCreated, taskState::setAdminTaskRequired); updateTaskState(flags, configuration.getReview().getLegalOfficerFlagCodes(), + taskState.getLegalOfficerTaskCreated(), taskState::setLegalOfficerTaskCreated, taskState::setLegalOfficerTaskRequired); - updateTaskState(flags, configuration.getReview().getJudgeFlagCodes(), + updateTaskState(flags, configuration.getReview().getJudgeFlagCodes(), taskState.getJudgeTaskCreated(), taskState::setJudgeTaskCreated, taskState::setJudgeTaskRequired); } @@ -210,10 +211,10 @@ private static boolean hasRequestedFlag(List flags, Set private static void updateTaskState(List flags, Set eligibleFlagCodes, + String taskCreated, Consumer taskCreatedSetter, Consumer taskRequiredSetter) { - taskRequiredSetter.accept(null); - if (!hasRequestedFlag(flags, eligibleFlagCodes)) { + if (!hasRequestedFlag(flags, eligibleFlagCodes) && !isTaskNotCreatedMarker(taskCreated)) { taskCreatedSetter.accept(NO); // The submitted callback changes this to No in the dedicated close event. taskRequiredSetter.accept(YES); @@ -225,23 +226,21 @@ private static boolean isTaskNotCreated(String taskCreated) { && !Boolean.parseBoolean(taskCreated); } - public boolean hasReviewSupportTaskToClose(CaseData caseData, CaseData caseDataBefore) { + public boolean hasReviewSupportTaskToClose(CaseData caseData) { SupportTaskState currentState = caseData.getSupportTaskState(); if (currentState == null) { return false; } - SupportTaskState previousState = caseDataBefore == null ? null : caseDataBefore.getSupportTaskState(); - return becameNotCreated(currentState.getAdminTaskCreated(), - previousState == null ? null : previousState.getAdminTaskCreated()) - || becameNotCreated(currentState.getLegalOfficerTaskCreated(), - previousState == null ? null : previousState.getLegalOfficerTaskCreated()) - || becameNotCreated(currentState.getJudgeTaskCreated(), - previousState == null ? null : previousState.getJudgeTaskCreated()); + return isTaskClosurePending(currentState.getAdminTaskCreated(), currentState.getAdminTaskRequired()) + || isTaskClosurePending(currentState.getLegalOfficerTaskCreated(), + currentState.getLegalOfficerTaskRequired()) + || isTaskClosurePending(currentState.getJudgeTaskCreated(), currentState.getJudgeTaskRequired()); } - private static boolean becameNotCreated(String currentValue, String previousValue) { - return isTaskNotCreatedMarker(currentValue) && !isTaskNotCreatedMarker(previousValue); + private static boolean isTaskClosurePending(String taskCreated, String taskRequired) { + return isTaskNotCreatedMarker(taskCreated) + && (YES.equalsIgnoreCase(taskRequired) || Boolean.parseBoolean(taskRequired)); } private static boolean isTaskNotCreatedMarker(String taskCreated) { diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java index c5f1e8e557..97cbeefca8 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java @@ -450,8 +450,7 @@ void triggersDedicatedReviewSupportTaskClosureEventAfterCaseUpdate() { ((ObjectNode) requestContent2).set("case_details_before", requestContent2.get("case_details").deepCopy()); when(featureToggleService.isCaseFlagsV2Enabled(anyString())).thenReturn(true); - when(supportTaskService.hasReviewSupportTaskToClose( - any(CaseData.class), any(CaseData.class))).thenReturn(true); + when(supportTaskService.hasReviewSupportTaskToClose(any(CaseData.class))).thenReturn(true); mvc.perform(post(SUPPORT_TASKS_SUBMITTED_URL) .content(requestContent2.toString()) @@ -460,8 +459,7 @@ void triggersDedicatedReviewSupportTaskClosureEventAfterCaseUpdate() { .andExpect(status().isOk()); verify(supportTaskEventService).triggerCloseReviewSupportTasks(any(CaseDetails.class)); - verify(supportTaskService).hasReviewSupportTaskToClose( - any(CaseData.class), any(CaseData.class)); + verify(supportTaskService).hasReviewSupportTaskToClose(any(CaseData.class)); } @Test diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java index 4c550f48ad..5190bd1682 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java @@ -48,9 +48,10 @@ void identifiesReviewSupportTaskThatNeedsClosing() { CaseData caseData = new CaseData(); SupportTaskState state = new SupportTaskState(); state.setJudgeTaskCreated(NO); + state.setJudgeTaskRequired(YES); caseData.setSupportTaskState(state); - assertTrue(service.hasReviewSupportTaskToClose(caseData, new CaseData())); + assertTrue(service.hasReviewSupportTaskToClose(caseData)); } @Test @@ -58,9 +59,10 @@ void identifiesBooleanReviewSupportTaskThatNeedsClosing() { CaseData caseData = new CaseData(); SupportTaskState state = new SupportTaskState(); state.setAdminTaskCreated(CCD_FALSE); + state.setAdminTaskRequired(CCD_TRUE); caseData.setSupportTaskState(state); - assertTrue(service.hasReviewSupportTaskToClose(caseData, new CaseData())); + assertTrue(service.hasReviewSupportTaskToClose(caseData)); } @Test @@ -71,25 +73,29 @@ void doesNotIdentifyReviewSupportTaskWhenNoCategoryNeedsClosing() { state.setJudgeTaskCreated(CCD_TRUE); caseData.setSupportTaskState(state); - assertFalse(service.hasReviewSupportTaskToClose(caseData, new CaseData())); + assertFalse(service.hasReviewSupportTaskToClose(caseData)); } @Test void doesNotCloseReviewSupportTaskAgainWhenItWasAlreadyNotRequired() { - CaseData caseDataBefore = new CaseData(); - caseDataBefore.setSupportTaskState(SupportTaskState.builder().adminTaskCreated(NO).build()); CaseData caseData = new CaseData(); - caseData.setSupportTaskState(SupportTaskState.builder().adminTaskCreated(NO).build()); + caseData.setSupportTaskState(SupportTaskState.builder() + .adminTaskCreated(NO) + .adminTaskRequired(NO) + .build()); - assertFalse(service.hasReviewSupportTaskToClose(caseData, caseDataBefore)); + assertFalse(service.hasReviewSupportTaskToClose(caseData)); } @Test - void closesReviewSupportTaskWhenPreviousCaseDataIsUnavailable() { + void closesReviewSupportTaskFromCurrentPendingState() { CaseData caseData = new CaseData(); - caseData.setSupportTaskState(SupportTaskState.builder().legalOfficerTaskCreated(NO).build()); + caseData.setSupportTaskState(SupportTaskState.builder() + .legalOfficerTaskCreated(NO) + .legalOfficerTaskRequired(YES) + .build()); - assertTrue(service.hasReviewSupportTaskToClose(caseData, null)); + assertTrue(service.hasReviewSupportTaskToClose(caseData)); } private static SupportTaskConfiguration configuration() { From a94a9dc304afd507bd811a385bda57717d41aa67 Mon Sep 17 00:00:00 2001 From: rajaram Date: Wed, 16 Sep 2026 13:55:47 +0100 Subject: [PATCH 070/100] Review tasks auto close issue resolved --- .../CaseEvent-CaseFlagsCaseLinking.json | 10 ++++---- .../CaseEvent-CaseFlagsCaseLinking.json | 10 ++++---- .../docmosis/service/SupportTaskService.java | 3 +-- .../service/SupportTaskServiceTest.java | 24 +++++++++---------- 4 files changed, 23 insertions(+), 24 deletions(-) diff --git a/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json index e3f0c76099..19134be395 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json @@ -12,7 +12,7 @@ "Publish": "Y", "CallBackURLAboutToStartEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToStart", "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToSubmit", - "CallBackURLSubmittedEvent": "${ET_COS_URL}/supportTasks/submitted" + "CallBackURLSubmittedEvent": "" }, { "CaseTypeID": "ET_EnglandWales", @@ -27,7 +27,7 @@ "Publish": "Y", "CallBackURLAboutToStartEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToStart", "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToSubmit", - "CallBackURLSubmittedEvent": "${ET_COS_URL}/supportTasks/submitted" + "CallBackURLSubmittedEvent": "" }, { "CaseTypeID": "ET_EnglandWales", @@ -42,7 +42,7 @@ "Publish": "Y", "CallBackURLAboutToStartEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToStart", "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToSubmit", - "CallBackURLSubmittedEvent": "${ET_COS_URL}/supportTasks/submitted" + "CallBackURLSubmittedEvent": "" }, { "CaseTypeID": "ET_EnglandWales", @@ -73,7 +73,7 @@ "EventEnablingCondition": "", "CallBackURLAboutToStartEvent": "", "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/supportTasks/aboutToSubmit", - "CallBackURLSubmittedEvent": "${ET_COS_URL}/supportTasks/submitted", + "CallBackURLSubmittedEvent": "", "Publish": "Y" }, { @@ -105,7 +105,7 @@ "EventEnablingCondition": "", "CallBackURLAboutToStartEvent": "", "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/supportTasks/aboutToSubmit", - "CallBackURLSubmittedEvent": "${ET_COS_URL}/supportTasks/submitted", + "CallBackURLSubmittedEvent": "", "Publish": "Y" }, { diff --git a/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json index ae39e5e3b5..93b926921f 100644 --- a/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json @@ -12,7 +12,7 @@ "Publish": "Y", "CallBackURLAboutToStartEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToStart", "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToSubmit", - "CallBackURLSubmittedEvent": "${ET_COS_URL}/supportTasks/submitted" + "CallBackURLSubmittedEvent": "" }, { "CaseTypeID": "ET_Scotland", @@ -27,7 +27,7 @@ "Publish": "Y", "CallBackURLAboutToStartEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToStart", "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToSubmit", - "CallBackURLSubmittedEvent": "${ET_COS_URL}/supportTasks/submitted" + "CallBackURLSubmittedEvent": "" }, { "CaseTypeID": "ET_Scotland", @@ -42,7 +42,7 @@ "Publish": "Y", "CallBackURLAboutToStartEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToStart", "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToSubmit", - "CallBackURLSubmittedEvent": "${ET_COS_URL}/supportTasks/submitted" + "CallBackURLSubmittedEvent": "" }, { "CaseTypeID": "ET_Scotland", @@ -73,7 +73,7 @@ "EventEnablingCondition": "", "CallBackURLAboutToStartEvent": "", "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/supportTasks/aboutToSubmit", - "CallBackURLSubmittedEvent": "${ET_COS_URL}/supportTasks/submitted", + "CallBackURLSubmittedEvent": "", "Publish": "Y" }, { @@ -105,7 +105,7 @@ "EventEnablingCondition": "", "CallBackURLAboutToStartEvent": "", "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/supportTasks/aboutToSubmit", - "CallBackURLSubmittedEvent": "${ET_COS_URL}/supportTasks/submitted", + "CallBackURLSubmittedEvent": "", "Publish": "Y" }, { diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java index 56cdce0a73..8671e3ef98 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java @@ -216,8 +216,7 @@ private static void updateTaskState(List flags, Consumer taskRequiredSetter) { if (!hasRequestedFlag(flags, eligibleFlagCodes) && !isTaskNotCreatedMarker(taskCreated)) { taskCreatedSetter.accept(NO); - // The submitted callback changes this to No in the dedicated close event. - taskRequiredSetter.accept(YES); + taskRequiredSetter.accept(NO); } } diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java index 5190bd1682..3c18193d97 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java @@ -330,11 +330,11 @@ void completes_only_task_type_without_an_eligible_requested_flag() { service.prepareManagedReviewSupportTasks(caseData, null); assertEquals(NO, taskState(caseData).getAdminTaskCreated()); - assertEquals(YES, taskState(caseData).getAdminTaskRequired()); + assertEquals(NO, taskState(caseData).getAdminTaskRequired()); assertEquals(YES, taskState(caseData).getJudgeTaskCreated()); assertNull(taskState(caseData).getJudgeTaskRequired()); assertEquals(NO, taskState(caseData).getLegalOfficerTaskCreated()); - assertEquals(YES, taskState(caseData).getLegalOfficerTaskRequired()); + assertEquals(NO, taskState(caseData).getLegalOfficerTaskRequired()); } @Test @@ -462,7 +462,7 @@ void completes_each_task_category_only_after_its_last_requested_flag_is_activate service.prepareManagedReviewSupportTasks(caseData, null); assertEquals(NO, getTaskCreated(taskState(caseData), taskType)); - assertEquals(YES, getTaskRequired(taskState(caseData), taskType)); + assertEquals(NO, getTaskRequired(taskState(caseData), taskType)); } @ParameterizedTest @@ -492,7 +492,7 @@ void restores_boolean_created_state_from_before_data_and_completes_each_category service.prepareManagedReviewSupportTasks(caseData, caseDataBefore); assertEquals(NO, getTaskCreated(taskState(caseData), taskType)); - assertEquals(YES, getTaskRequired(taskState(caseData), taskType)); + assertEquals(NO, getTaskRequired(taskState(caseData), taskType)); } @ParameterizedTest @@ -519,7 +519,7 @@ void completes_each_task_category_for_every_non_requested_status( service.prepareManagedReviewSupportTasks(caseData, null); assertEquals(NO, getTaskCreated(taskState(caseData), taskType)); - assertEquals(YES, getTaskRequired(taskState(caseData), taskType)); + assertEquals(NO, getTaskRequired(taskState(caseData), taskType)); } @Test @@ -539,7 +539,7 @@ void completes_only_categories_without_requested_flags_when_boolean_state_is_use service.prepareManagedReviewSupportTasks(caseData, null); assertEquals(NO, taskState(caseData).getAdminTaskCreated()); - assertEquals(YES, taskState(caseData).getAdminTaskRequired()); + assertEquals(NO, taskState(caseData).getAdminTaskRequired()); assertEquals(CCD_TRUE, taskState(caseData).getLegalOfficerTaskCreated()); assertNull(taskState(caseData).getLegalOfficerTaskRequired()); assertEquals(CCD_TRUE, taskState(caseData).getJudgeTaskCreated()); @@ -586,9 +586,9 @@ void completes_created_tasks_when_party_flags_are_missing() { assertEquals(NO, taskState(caseData).getAdminTaskCreated()); assertEquals(NO, taskState(caseData).getLegalOfficerTaskCreated()); assertEquals(NO, taskState(caseData).getJudgeTaskCreated()); - assertEquals(YES, taskState(caseData).getAdminTaskRequired()); - assertEquals(YES, taskState(caseData).getLegalOfficerTaskRequired()); - assertEquals(YES, taskState(caseData).getJudgeTaskRequired()); + assertEquals(NO, taskState(caseData).getAdminTaskRequired()); + assertEquals(NO, taskState(caseData).getLegalOfficerTaskRequired()); + assertEquals(NO, taskState(caseData).getJudgeTaskRequired()); } @Test @@ -600,7 +600,7 @@ void completes_judge_task_when_last_requested_flag_is_managed_and_current_state_ service.prepareManagedReviewSupportTasks(caseData, caseDataBefore); assertEquals(NO, taskState(caseData).getJudgeTaskCreated()); - assertEquals(YES, taskState(caseData).getJudgeTaskRequired()); + assertEquals(NO, taskState(caseData).getJudgeTaskRequired()); } static Stream reviewAndArrangeTaskScenarios() { @@ -623,7 +623,7 @@ void preservesReviewCompletionAndArrangeCreationInTheSameUpdate(String flagCode, service.prepareManagedReviewSupportTasks(caseData, caseDataBefore); service.prepareArrangeSupportTask(caseData, caseDataBefore); - assertEquals(YES, getTaskRequired(taskState(caseData), taskType)); + assertEquals(NO, getTaskRequired(taskState(caseData), taskType)); assertEquals(arrangeTaskName, taskState(caseData).getArrangeSupportTaskName()); } @@ -634,7 +634,7 @@ void completes_admin_task_when_created_marker_is_missing() { service.prepareManagedReviewSupportTasks(caseData, null); assertEquals(NO, taskState(caseData).getAdminTaskCreated()); - assertEquals(YES, taskState(caseData).getAdminTaskRequired()); + assertEquals(NO, taskState(caseData).getAdminTaskRequired()); } @Test From f6b27e40de282633605b71c130d79105983d8e0d Mon Sep 17 00:00:00 2001 From: rajaram Date: Wed, 16 Sep 2026 16:30:21 +0100 Subject: [PATCH 071/100] Review tasks auto close issue resolved --- .../AuthorisationCaseEvent-WA-nonprod.json | 12 -- ...AuthorisationComplexType-CaseFlags-WA.json | 42 +++++++ .../CaseEvent-CaseFlagsCaseLinking.json | 13 --- .../CaseEventToFields-SupportTasks.json | 10 -- .../ComplexTypes-CaseFlagsCaseLinking.json | 21 ++++ .../EventToComplexTypes-SupportTasks.json | 45 ++------ .../AuthorisationCaseEvent-WA.json | 12 -- ...AuthorisationComplexType-CaseFlags-WA.json | 42 +++++++ .../CaseEvent-CaseFlagsCaseLinking.json | 13 --- .../CaseEventToFields-SupportTasks.json | 10 -- .../ComplexTypes-CaseFlagsCaseLinking.json | 21 ++++ .../EventToComplexTypes-SupportTasks.json | 45 ++------ .../model/ccd/types/SupportTaskState.java | 3 + .../constants/SupportTaskConstants.java | 1 - .../CaseActionsForCaseWorkerController.java | 18 --- .../service/SupportTaskEventService.java | 74 ------------ .../docmosis/service/SupportTaskService.java | 36 +++--- ...aseActionsForCaseWorkerControllerTest.java | 37 ------ .../service/SupportTaskEventServiceTest.java | 83 ------------- .../service/SupportTaskServiceTest.java | 109 ++++++------------ 20 files changed, 197 insertions(+), 450 deletions(-) delete mode 100644 src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskEventService.java delete mode 100644 src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskEventServiceTest.java diff --git a/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseEvent/AuthorisationCaseEvent-WA-nonprod.json b/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseEvent/AuthorisationCaseEvent-WA-nonprod.json index cd6929106f..3250b2bfc6 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseEvent/AuthorisationCaseEvent-WA-nonprod.json +++ b/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseEvent/AuthorisationCaseEvent-WA-nonprod.json @@ -40,17 +40,5 @@ "CaseEventID": "reviewJudgeSupportRequest", "UserRole": "caseworker-wa-task-configuration", "CRUD": "R" - }, - { - "CaseTypeId": "ET_EnglandWales", - "CaseEventID": "closeReviewSupportTasks", - "UserRole": "caseworker-employment-api", - "CRUD": "CRUD" - }, - { - "CaseTypeId": "ET_EnglandWales", - "CaseEventID": "closeReviewSupportTasks", - "UserRole": "caseworker-wa-task-configuration", - "CRUD": "CRU" } ] diff --git a/ccd-definitions/jurisdictions/england-wales/json/AuthorisationComplexType/AuthorisationComplexType-CaseFlags-WA.json b/ccd-definitions/jurisdictions/england-wales/json/AuthorisationComplexType/AuthorisationComplexType-CaseFlags-WA.json index e2a0b3b178..86ec7fc1d2 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/AuthorisationComplexType/AuthorisationComplexType-CaseFlags-WA.json +++ b/ccd-definitions/jurisdictions/england-wales/json/AuthorisationComplexType/AuthorisationComplexType-CaseFlags-WA.json @@ -13,6 +13,13 @@ "UserRole": "caseworker-employment-api", "CRUD": "CRUD" }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseFieldID": "supportTaskState", + "ListElementCode": "adminTaskCompletionRequired", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, { "CaseTypeID": "ET_EnglandWales", "CaseFieldID": "supportTaskState", @@ -27,6 +34,13 @@ "UserRole": "caseworker-employment-api", "CRUD": "CRUD" }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseFieldID": "supportTaskState", + "ListElementCode": "legalOfficerTaskCompletionRequired", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, { "CaseTypeID": "ET_EnglandWales", "CaseFieldID": "supportTaskState", @@ -41,6 +55,13 @@ "UserRole": "caseworker-employment-api", "CRUD": "CRUD" }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseFieldID": "supportTaskState", + "ListElementCode": "judgeTaskCompletionRequired", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, { "CaseTypeID": "ET_EnglandWales", "CaseFieldID": "supportTaskState", @@ -62,6 +83,27 @@ "UserRole": "caseworker-wa-task-configuration", "CRUD": "R" }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseFieldID": "supportTaskState", + "ListElementCode": "adminTaskCompletionRequired", + "UserRole": "caseworker-wa-task-configuration", + "CRUD": "R" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseFieldID": "supportTaskState", + "ListElementCode": "legalOfficerTaskCompletionRequired", + "UserRole": "caseworker-wa-task-configuration", + "CRUD": "R" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseFieldID": "supportTaskState", + "ListElementCode": "judgeTaskCompletionRequired", + "UserRole": "caseworker-wa-task-configuration", + "CRUD": "R" + }, { "CaseTypeID": "ET_EnglandWales", "CaseFieldID": "supportTaskState", diff --git a/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json index 19134be395..84c5742587 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json @@ -180,18 +180,5 @@ "CallBackURLAboutToStartEvent": "", "CallBackURLAboutToSubmitEvent": "", "CallBackURLSubmittedEvent": "" - }, - { - "CaseTypeID": "ET_EnglandWales", - "ID": "closeReviewSupportTasks", - "Name": "Close review support tasks", - "Description": "Close review support tasks", - "PreConditionState(s)": "*", - "PostConditionState": "*", - "SecurityClassification": "Public", - "ShowEventNotes": "N", - "ShowSummary": "N", - "EventEnablingCondition": "caseType=\"dummy\"", - "Publish": "Y" } ] diff --git a/ccd-definitions/jurisdictions/england-wales/json/CaseEventToFields/CaseEventToFields-SupportTasks.json b/ccd-definitions/jurisdictions/england-wales/json/CaseEventToFields/CaseEventToFields-SupportTasks.json index d4900c2620..e6379855b8 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/CaseEventToFields/CaseEventToFields-SupportTasks.json +++ b/ccd-definitions/jurisdictions/england-wales/json/CaseEventToFields/CaseEventToFields-SupportTasks.json @@ -195,15 +195,5 @@ "FieldShowCondition": "flagLauncher=\"hidden\"", "ShowSummaryChangeOption": "N", "RetainHiddenValue": "Yes" - }, - { - "CaseTypeID": "ET_EnglandWales", - "CaseEventID": "closeReviewSupportTasks", - "CaseFieldID": "supportTaskState", - "DisplayContext": "COMPLEX", - "PageID": 1, - "PageDisplayOrder": 1, - "PageFieldDisplayOrder": 1, - "ShowSummaryChangeOption": "N" } ] diff --git a/ccd-definitions/jurisdictions/england-wales/json/ComplexTypes/ComplexTypes-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/england-wales/json/ComplexTypes/ComplexTypes-CaseFlagsCaseLinking.json index d1ca30e961..634643e33d 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/ComplexTypes/ComplexTypes-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/england-wales/json/ComplexTypes/ComplexTypes-CaseFlagsCaseLinking.json @@ -13,6 +13,13 @@ "ElementLabel": "Admin task required", "SecurityClassification": "Public" }, + { + "ID": "SupportTaskState", + "ListElementCode": "adminTaskCompletionRequired", + "FieldType": "YesOrNo", + "ElementLabel": "Admin task completion required", + "SecurityClassification": "Public" + }, { "ID": "SupportTaskState", "ListElementCode": "legalOfficerTaskCreated", @@ -27,6 +34,13 @@ "ElementLabel": "Legal Officer task required", "SecurityClassification": "Public" }, + { + "ID": "SupportTaskState", + "ListElementCode": "legalOfficerTaskCompletionRequired", + "FieldType": "YesOrNo", + "ElementLabel": "Legal Officer task completion required", + "SecurityClassification": "Public" + }, { "ID": "SupportTaskState", "ListElementCode": "judgeTaskCreated", @@ -41,6 +55,13 @@ "ElementLabel": "Judge task required", "SecurityClassification": "Public" }, + { + "ID": "SupportTaskState", + "ListElementCode": "judgeTaskCompletionRequired", + "FieldType": "YesOrNo", + "ElementLabel": "Judge task completion required", + "SecurityClassification": "Public" + }, { "ID": "SupportTaskState", "ListElementCode": "arrangeSupportTaskName", diff --git a/ccd-definitions/jurisdictions/england-wales/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json b/ccd-definitions/jurisdictions/england-wales/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json index d320a4c168..82258f1616 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json +++ b/ccd-definitions/jurisdictions/england-wales/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json @@ -219,7 +219,7 @@ "ID": "SupportTaskState", "CaseEventID": "manageFlags", "CaseFieldID": "supportTaskState", - "ListElementCode": "adminTaskRequired", + "ListElementCode": "adminTaskCompletionRequired", "FieldDisplayOrder": 1, "DisplayContext": "OPTIONAL", "Publish": "Y" @@ -228,7 +228,7 @@ "ID": "SupportTaskState", "CaseEventID": "manageFlags", "CaseFieldID": "supportTaskState", - "ListElementCode": "legalOfficerTaskRequired", + "ListElementCode": "legalOfficerTaskCompletionRequired", "FieldDisplayOrder": 2, "DisplayContext": "OPTIONAL", "Publish": "Y" @@ -237,7 +237,7 @@ "ID": "SupportTaskState", "CaseEventID": "manageFlags", "CaseFieldID": "supportTaskState", - "ListElementCode": "judgeTaskRequired", + "ListElementCode": "judgeTaskCompletionRequired", "FieldDisplayOrder": 3, "DisplayContext": "OPTIONAL", "Publish": "Y" @@ -255,7 +255,7 @@ "ID": "SupportTaskState", "CaseEventID": "manageSupport", "CaseFieldID": "supportTaskState", - "ListElementCode": "adminTaskRequired", + "ListElementCode": "adminTaskCompletionRequired", "FieldDisplayOrder": 1, "DisplayContext": "OPTIONAL", "Publish": "Y" @@ -264,7 +264,7 @@ "ID": "SupportTaskState", "CaseEventID": "manageSupport", "CaseFieldID": "supportTaskState", - "ListElementCode": "legalOfficerTaskRequired", + "ListElementCode": "legalOfficerTaskCompletionRequired", "FieldDisplayOrder": 2, "DisplayContext": "OPTIONAL", "Publish": "Y" @@ -273,7 +273,7 @@ "ID": "SupportTaskState", "CaseEventID": "manageSupport", "CaseFieldID": "supportTaskState", - "ListElementCode": "judgeTaskRequired", + "ListElementCode": "judgeTaskCompletionRequired", "FieldDisplayOrder": 3, "DisplayContext": "OPTIONAL", "Publish": "Y" @@ -282,7 +282,7 @@ "ID": "SupportTaskState", "CaseEventID": "reviewAdminSupportRequest", "CaseFieldID": "supportTaskState", - "ListElementCode": "adminTaskRequired", + "ListElementCode": "adminTaskCompletionRequired", "FieldDisplayOrder": 1, "DisplayContext": "OPTIONAL", "Publish": "Y" @@ -300,7 +300,7 @@ "ID": "SupportTaskState", "CaseEventID": "reviewLOSupportRequest", "CaseFieldID": "supportTaskState", - "ListElementCode": "legalOfficerTaskRequired", + "ListElementCode": "legalOfficerTaskCompletionRequired", "FieldDisplayOrder": 2, "DisplayContext": "OPTIONAL", "Publish": "Y" @@ -318,7 +318,7 @@ "ID": "SupportTaskState", "CaseEventID": "reviewJudgeSupportRequest", "CaseFieldID": "supportTaskState", - "ListElementCode": "judgeTaskRequired", + "ListElementCode": "judgeTaskCompletionRequired", "FieldDisplayOrder": 3, "DisplayContext": "OPTIONAL", "Publish": "Y" @@ -331,32 +331,5 @@ "FieldDisplayOrder": 4, "DisplayContext": "OPTIONAL", "Publish": "Y" - }, - { - "ID": "SupportTaskState", - "CaseEventID": "closeReviewSupportTasks", - "CaseFieldID": "supportTaskState", - "ListElementCode": "adminTaskRequired", - "FieldDisplayOrder": 1, - "DisplayContext": "OPTIONAL", - "Publish": "Y" - }, - { - "ID": "SupportTaskState", - "CaseEventID": "closeReviewSupportTasks", - "CaseFieldID": "supportTaskState", - "ListElementCode": "legalOfficerTaskRequired", - "FieldDisplayOrder": 2, - "DisplayContext": "OPTIONAL", - "Publish": "Y" - }, - { - "ID": "SupportTaskState", - "CaseEventID": "closeReviewSupportTasks", - "CaseFieldID": "supportTaskState", - "ListElementCode": "judgeTaskRequired", - "FieldDisplayOrder": 3, - "DisplayContext": "OPTIONAL", - "Publish": "Y" } ] diff --git a/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseEvent/AuthorisationCaseEvent-WA.json b/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseEvent/AuthorisationCaseEvent-WA.json index e6736173cb..8228fb2f8c 100644 --- a/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseEvent/AuthorisationCaseEvent-WA.json +++ b/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseEvent/AuthorisationCaseEvent-WA.json @@ -215,17 +215,5 @@ "CaseEventID": "reviewJudgeSupportRequest", "UserRole": "caseworker-wa-task-configuration", "CRUD": "R" - }, - { - "CaseTypeId": "ET_Scotland", - "CaseEventID": "closeReviewSupportTasks", - "UserRole": "caseworker-employment-api", - "CRUD": "CRUD" - }, - { - "CaseTypeId": "ET_Scotland", - "CaseEventID": "closeReviewSupportTasks", - "UserRole": "caseworker-wa-task-configuration", - "CRUD": "CRU" } ] diff --git a/ccd-definitions/jurisdictions/scotland/json/AuthorisationComplexType/AuthorisationComplexType-CaseFlags-WA.json b/ccd-definitions/jurisdictions/scotland/json/AuthorisationComplexType/AuthorisationComplexType-CaseFlags-WA.json index 01ccf71348..99824c5885 100644 --- a/ccd-definitions/jurisdictions/scotland/json/AuthorisationComplexType/AuthorisationComplexType-CaseFlags-WA.json +++ b/ccd-definitions/jurisdictions/scotland/json/AuthorisationComplexType/AuthorisationComplexType-CaseFlags-WA.json @@ -13,6 +13,13 @@ "UserRole": "caseworker-employment-api", "CRUD": "CRUD" }, + { + "CaseTypeID": "ET_Scotland", + "CaseFieldID": "supportTaskState", + "ListElementCode": "adminTaskCompletionRequired", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, { "CaseTypeID": "ET_Scotland", "CaseFieldID": "supportTaskState", @@ -27,6 +34,13 @@ "UserRole": "caseworker-employment-api", "CRUD": "CRUD" }, + { + "CaseTypeID": "ET_Scotland", + "CaseFieldID": "supportTaskState", + "ListElementCode": "legalOfficerTaskCompletionRequired", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, { "CaseTypeID": "ET_Scotland", "CaseFieldID": "supportTaskState", @@ -41,6 +55,13 @@ "UserRole": "caseworker-employment-api", "CRUD": "CRUD" }, + { + "CaseTypeID": "ET_Scotland", + "CaseFieldID": "supportTaskState", + "ListElementCode": "judgeTaskCompletionRequired", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" + }, { "CaseTypeID": "ET_Scotland", "CaseFieldID": "supportTaskState", @@ -62,6 +83,27 @@ "UserRole": "caseworker-wa-task-configuration", "CRUD": "R" }, + { + "CaseTypeID": "ET_Scotland", + "CaseFieldID": "supportTaskState", + "ListElementCode": "adminTaskCompletionRequired", + "UserRole": "caseworker-wa-task-configuration", + "CRUD": "R" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseFieldID": "supportTaskState", + "ListElementCode": "legalOfficerTaskCompletionRequired", + "UserRole": "caseworker-wa-task-configuration", + "CRUD": "R" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseFieldID": "supportTaskState", + "ListElementCode": "judgeTaskCompletionRequired", + "UserRole": "caseworker-wa-task-configuration", + "CRUD": "R" + }, { "CaseTypeID": "ET_Scotland", "CaseFieldID": "supportTaskState", diff --git a/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json index 93b926921f..94092e2c07 100644 --- a/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json @@ -180,18 +180,5 @@ "SecurityClassification": "Public", "ShowEventNotes": "N", "ShowSummary": "N" - }, - { - "CaseTypeID": "ET_Scotland", - "ID": "closeReviewSupportTasks", - "Name": "Close review support tasks", - "Description": "Close review support tasks", - "PreConditionState(s)": "*", - "PostConditionState": "*", - "SecurityClassification": "Public", - "ShowEventNotes": "N", - "ShowSummary": "N", - "EventEnablingCondition": "caseType=\"dummy\"", - "Publish": "Y" } ] diff --git a/ccd-definitions/jurisdictions/scotland/json/CaseEventToFields/CaseEventToFields-SupportTasks.json b/ccd-definitions/jurisdictions/scotland/json/CaseEventToFields/CaseEventToFields-SupportTasks.json index 9ebaad8e30..002492eee5 100644 --- a/ccd-definitions/jurisdictions/scotland/json/CaseEventToFields/CaseEventToFields-SupportTasks.json +++ b/ccd-definitions/jurisdictions/scotland/json/CaseEventToFields/CaseEventToFields-SupportTasks.json @@ -195,15 +195,5 @@ "FieldShowCondition": "flagLauncher=\"hidden\"", "ShowSummaryChangeOption": "N", "RetainHiddenValue": "Yes" - }, - { - "CaseTypeID": "ET_Scotland", - "CaseEventID": "closeReviewSupportTasks", - "CaseFieldID": "supportTaskState", - "DisplayContext": "COMPLEX", - "PageID": 1, - "PageDisplayOrder": 1, - "PageFieldDisplayOrder": 1, - "ShowSummaryChangeOption": "N" } ] diff --git a/ccd-definitions/jurisdictions/scotland/json/ComplexTypes/ComplexTypes-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/scotland/json/ComplexTypes/ComplexTypes-CaseFlagsCaseLinking.json index d1ca30e961..634643e33d 100644 --- a/ccd-definitions/jurisdictions/scotland/json/ComplexTypes/ComplexTypes-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/scotland/json/ComplexTypes/ComplexTypes-CaseFlagsCaseLinking.json @@ -13,6 +13,13 @@ "ElementLabel": "Admin task required", "SecurityClassification": "Public" }, + { + "ID": "SupportTaskState", + "ListElementCode": "adminTaskCompletionRequired", + "FieldType": "YesOrNo", + "ElementLabel": "Admin task completion required", + "SecurityClassification": "Public" + }, { "ID": "SupportTaskState", "ListElementCode": "legalOfficerTaskCreated", @@ -27,6 +34,13 @@ "ElementLabel": "Legal Officer task required", "SecurityClassification": "Public" }, + { + "ID": "SupportTaskState", + "ListElementCode": "legalOfficerTaskCompletionRequired", + "FieldType": "YesOrNo", + "ElementLabel": "Legal Officer task completion required", + "SecurityClassification": "Public" + }, { "ID": "SupportTaskState", "ListElementCode": "judgeTaskCreated", @@ -41,6 +55,13 @@ "ElementLabel": "Judge task required", "SecurityClassification": "Public" }, + { + "ID": "SupportTaskState", + "ListElementCode": "judgeTaskCompletionRequired", + "FieldType": "YesOrNo", + "ElementLabel": "Judge task completion required", + "SecurityClassification": "Public" + }, { "ID": "SupportTaskState", "ListElementCode": "arrangeSupportTaskName", diff --git a/ccd-definitions/jurisdictions/scotland/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json b/ccd-definitions/jurisdictions/scotland/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json index d320a4c168..82258f1616 100644 --- a/ccd-definitions/jurisdictions/scotland/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json +++ b/ccd-definitions/jurisdictions/scotland/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json @@ -219,7 +219,7 @@ "ID": "SupportTaskState", "CaseEventID": "manageFlags", "CaseFieldID": "supportTaskState", - "ListElementCode": "adminTaskRequired", + "ListElementCode": "adminTaskCompletionRequired", "FieldDisplayOrder": 1, "DisplayContext": "OPTIONAL", "Publish": "Y" @@ -228,7 +228,7 @@ "ID": "SupportTaskState", "CaseEventID": "manageFlags", "CaseFieldID": "supportTaskState", - "ListElementCode": "legalOfficerTaskRequired", + "ListElementCode": "legalOfficerTaskCompletionRequired", "FieldDisplayOrder": 2, "DisplayContext": "OPTIONAL", "Publish": "Y" @@ -237,7 +237,7 @@ "ID": "SupportTaskState", "CaseEventID": "manageFlags", "CaseFieldID": "supportTaskState", - "ListElementCode": "judgeTaskRequired", + "ListElementCode": "judgeTaskCompletionRequired", "FieldDisplayOrder": 3, "DisplayContext": "OPTIONAL", "Publish": "Y" @@ -255,7 +255,7 @@ "ID": "SupportTaskState", "CaseEventID": "manageSupport", "CaseFieldID": "supportTaskState", - "ListElementCode": "adminTaskRequired", + "ListElementCode": "adminTaskCompletionRequired", "FieldDisplayOrder": 1, "DisplayContext": "OPTIONAL", "Publish": "Y" @@ -264,7 +264,7 @@ "ID": "SupportTaskState", "CaseEventID": "manageSupport", "CaseFieldID": "supportTaskState", - "ListElementCode": "legalOfficerTaskRequired", + "ListElementCode": "legalOfficerTaskCompletionRequired", "FieldDisplayOrder": 2, "DisplayContext": "OPTIONAL", "Publish": "Y" @@ -273,7 +273,7 @@ "ID": "SupportTaskState", "CaseEventID": "manageSupport", "CaseFieldID": "supportTaskState", - "ListElementCode": "judgeTaskRequired", + "ListElementCode": "judgeTaskCompletionRequired", "FieldDisplayOrder": 3, "DisplayContext": "OPTIONAL", "Publish": "Y" @@ -282,7 +282,7 @@ "ID": "SupportTaskState", "CaseEventID": "reviewAdminSupportRequest", "CaseFieldID": "supportTaskState", - "ListElementCode": "adminTaskRequired", + "ListElementCode": "adminTaskCompletionRequired", "FieldDisplayOrder": 1, "DisplayContext": "OPTIONAL", "Publish": "Y" @@ -300,7 +300,7 @@ "ID": "SupportTaskState", "CaseEventID": "reviewLOSupportRequest", "CaseFieldID": "supportTaskState", - "ListElementCode": "legalOfficerTaskRequired", + "ListElementCode": "legalOfficerTaskCompletionRequired", "FieldDisplayOrder": 2, "DisplayContext": "OPTIONAL", "Publish": "Y" @@ -318,7 +318,7 @@ "ID": "SupportTaskState", "CaseEventID": "reviewJudgeSupportRequest", "CaseFieldID": "supportTaskState", - "ListElementCode": "judgeTaskRequired", + "ListElementCode": "judgeTaskCompletionRequired", "FieldDisplayOrder": 3, "DisplayContext": "OPTIONAL", "Publish": "Y" @@ -331,32 +331,5 @@ "FieldDisplayOrder": 4, "DisplayContext": "OPTIONAL", "Publish": "Y" - }, - { - "ID": "SupportTaskState", - "CaseEventID": "closeReviewSupportTasks", - "CaseFieldID": "supportTaskState", - "ListElementCode": "adminTaskRequired", - "FieldDisplayOrder": 1, - "DisplayContext": "OPTIONAL", - "Publish": "Y" - }, - { - "ID": "SupportTaskState", - "CaseEventID": "closeReviewSupportTasks", - "CaseFieldID": "supportTaskState", - "ListElementCode": "legalOfficerTaskRequired", - "FieldDisplayOrder": 2, - "DisplayContext": "OPTIONAL", - "Publish": "Y" - }, - { - "ID": "SupportTaskState", - "CaseEventID": "closeReviewSupportTasks", - "CaseFieldID": "supportTaskState", - "ListElementCode": "judgeTaskRequired", - "FieldDisplayOrder": 3, - "DisplayContext": "OPTIONAL", - "Publish": "Y" } ] diff --git a/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/types/SupportTaskState.java b/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/types/SupportTaskState.java index 231f37a560..6a2cedfd1a 100644 --- a/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/types/SupportTaskState.java +++ b/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/types/SupportTaskState.java @@ -16,9 +16,12 @@ public class SupportTaskState { private String adminTaskCreated; private String adminTaskRequired; + private String adminTaskCompletionRequired; private String legalOfficerTaskCreated; private String legalOfficerTaskRequired; + private String legalOfficerTaskCompletionRequired; private String judgeTaskCreated; private String judgeTaskRequired; + private String judgeTaskCompletionRequired; private String arrangeSupportTaskName; } diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/constants/SupportTaskConstants.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/constants/SupportTaskConstants.java index cb44fd7cca..cbacfacbb9 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/constants/SupportTaskConstants.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/constants/SupportTaskConstants.java @@ -13,7 +13,6 @@ public final class SupportTaskConstants { public static final String EVENT_REVIEW_ADMIN_SUPPORT_REQUEST = "reviewAdminSupportRequest"; public static final String EVENT_REVIEW_LEGAL_OFFICER_SUPPORT_REQUEST = "reviewLOSupportRequest"; public static final String EVENT_REVIEW_JUDGE_SUPPORT_REQUEST = "reviewJudgeSupportRequest"; - public static final String EVENT_CLOSE_REVIEW_SUPPORT_TASKS = "closeReviewSupportTasks"; public static final String FLAG_STATUS_ACTIVE = "Active"; public static final String FLAG_STATUS_REQUESTED = "Requested"; diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java index 5e43e1b2a1..ceab69ea9f 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java @@ -50,7 +50,6 @@ import uk.gov.hmcts.ethos.replacement.docmosis.service.ScotlandFileLocationSelectionService; import uk.gov.hmcts.ethos.replacement.docmosis.service.SingleCaseMultipleMidEventValidationService; import uk.gov.hmcts.ethos.replacement.docmosis.service.SingleReferenceService; -import uk.gov.hmcts.ethos.replacement.docmosis.service.SupportTaskEventService; import uk.gov.hmcts.ethos.replacement.docmosis.service.SupportTaskService; import uk.gov.hmcts.ethos.replacement.docmosis.service.noc.NocRespondentRepresentativeService; import uk.gov.hmcts.ethos.replacement.docmosis.utils.LoggingUtils; @@ -121,7 +120,6 @@ public class CaseActionsForCaseWorkerController { private final FeatureToggleService featureToggleService; private final CaseFlagsService caseFlagsService; private final SupportTaskService supportTaskService; - private final SupportTaskEventService supportTaskEventService; private final CaseManagementLocationService caseManagementLocationService; private final Et1SubmissionService et1SubmissionService; private final NocRespondentHelper nocRespondentHelper; @@ -253,22 +251,6 @@ public ResponseEntity prepareSupportTasks( return getCallbackRespEntityNoErrors(caseData); } - @PostMapping(value = "/supportTasks/submitted", consumes = APPLICATION_JSON_VALUE) - @Operation(summary = "Trigger closure of Review Support tasks after Case Flags are updated.") - public ResponseEntity closeReviewSupportTasks( - @RequestBody CallbackRequest callbackRequest) { - CaseDetails caseDetails = callbackRequest.getCaseDetails(); - boolean caseFlagsV2Enabled = featureToggleService.isCaseFlagsV2Enabled(caseDetails.getCaseTypeId()); - boolean reviewSupportTaskToClose = caseFlagsV2Enabled - && supportTaskService.hasReviewSupportTaskToClose(caseDetails.getCaseData()); - log.info("Review Support task closure evaluated for case {}: enabled={}, closeRequired={}", - caseDetails.getCaseId(), caseFlagsV2Enabled, reviewSupportTaskToClose); - if (reviewSupportTaskToClose) { - supportTaskEventService.triggerCloseReviewSupportTasks(caseDetails); - } - return getCallbackRespEntityNoErrors(caseDetails.getCaseData()); - } - @PostMapping(value = "/reviewSupportRequest/aboutToStart", consumes = APPLICATION_JSON_VALUE) @Operation(summary = "Prepare the requested Case Flags for review.") public ResponseEntity prepareReviewSupportRequest( diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskEventService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskEventService.java deleted file mode 100644 index 8e538df2ee..0000000000 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskEventService.java +++ /dev/null @@ -1,74 +0,0 @@ -package uk.gov.hmcts.ethos.replacement.docmosis.service; - -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; -import uk.gov.hmcts.ecm.common.client.CcdClient; -import uk.gov.hmcts.et.common.model.ccd.CCDRequest; -import uk.gov.hmcts.et.common.model.ccd.CaseData; -import uk.gov.hmcts.et.common.model.ccd.CaseDetails; -import uk.gov.hmcts.et.common.model.ccd.types.SupportTaskState; -import uk.gov.hmcts.ethos.replacement.docmosis.exceptions.GenericRuntimeException; - -import static uk.gov.hmcts.ecm.common.model.helper.Constants.EMPLOYMENT; -import static uk.gov.hmcts.ecm.common.model.helper.Constants.NO; -import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.EVENT_CLOSE_REVIEW_SUPPORT_TASKS; - -@Service -@RequiredArgsConstructor -@Slf4j -public class SupportTaskEventService { - private final CcdClient ccdClient; - private final AdminUserService adminUserService; - - public void triggerCloseReviewSupportTasks(CaseDetails caseDetails) { - String caseId = caseDetails.getCaseId(); - SupportTaskState completedTaskState = caseDetails.getCaseData().getSupportTaskState(); - try { - String adminUserToken = adminUserService.getAdminUserToken(); - CCDRequest ccdRequest = ccdClient.startEventForCase( - adminUserToken, - caseDetails.getCaseTypeId(), - EMPLOYMENT, - caseId, - EVENT_CLOSE_REVIEW_SUPPORT_TASKS); - CaseDetails latestCaseDetails = ccdRequest.getCaseDetails(); - CaseData latestCaseData = latestCaseDetails.getCaseData(); - if (latestCaseData.getSupportTaskState() == null) { - latestCaseData.setSupportTaskState(new SupportTaskState()); - } - markCompletedReviewTasksNotRequired(latestCaseData.getSupportTaskState(), completedTaskState); - ccdClient.submitEventForCase( - adminUserToken, - latestCaseData, - latestCaseDetails.getCaseTypeId(), - latestCaseDetails.getJurisdiction(), - ccdRequest, - caseId); - log.info("Triggered review support task closure event for case {}", caseId); - } catch (Exception exception) { - log.error("Unable to trigger review support task closure event for case {}", caseId, exception); - throw new GenericRuntimeException(exception); - } - } - - private static void markCompletedReviewTasksNotRequired(SupportTaskState latestTaskState, - SupportTaskState completedTaskState) { - if (completedTaskState == null) { - return; - } - if (isTaskNotCreated(completedTaskState.getAdminTaskCreated())) { - latestTaskState.setAdminTaskRequired(NO); - } - if (isTaskNotCreated(completedTaskState.getLegalOfficerTaskCreated())) { - latestTaskState.setLegalOfficerTaskRequired(NO); - } - if (isTaskNotCreated(completedTaskState.getJudgeTaskCreated())) { - latestTaskState.setJudgeTaskRequired(NO); - } - } - - private static boolean isTaskNotCreated(String taskCreated) { - return NO.equalsIgnoreCase(taskCreated) || "false".equalsIgnoreCase(taskCreated); - } -} diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java index 8671e3ef98..81971819eb 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java @@ -95,20 +95,26 @@ private static void retainCreatedTaskState(CaseData caseData, CaseData caseDataB public void prepareManagedReviewSupportTasks(CaseData caseData, CaseData caseDataBefore) { retainCreatedTaskState(caseData, caseDataBefore); SupportTaskState taskState = taskState(caseData); + taskState.setAdminTaskRequired(null); + taskState.setLegalOfficerTaskRequired(null); + taskState.setJudgeTaskRequired(null); + taskState.setAdminTaskCompletionRequired(null); + taskState.setLegalOfficerTaskCompletionRequired(null); + taskState.setJudgeTaskCompletionRequired(null); List flags = allFlagItems(caseData.getAllPartyFlags()) .map(GenericTypeItem::getValue) .toList(); updateTaskState(flags, configuration.getReview().getAdminFlagCodes(), taskState.getAdminTaskCreated(), taskState::setAdminTaskCreated, - taskState::setAdminTaskRequired); + taskState::setAdminTaskCompletionRequired); updateTaskState(flags, configuration.getReview().getLegalOfficerFlagCodes(), taskState.getLegalOfficerTaskCreated(), taskState::setLegalOfficerTaskCreated, - taskState::setLegalOfficerTaskRequired); + taskState::setLegalOfficerTaskCompletionRequired); updateTaskState(flags, configuration.getReview().getJudgeFlagCodes(), taskState.getJudgeTaskCreated(), taskState::setJudgeTaskCreated, - taskState::setJudgeTaskRequired); + taskState::setJudgeTaskCompletionRequired); } public void prepareReviewSupportRequest(CaseData caseData, String eventId) { @@ -180,6 +186,9 @@ private void prepareTasks(CaseData caseData, List flags) { taskState.setAdminTaskRequired(null); taskState.setLegalOfficerTaskRequired(null); taskState.setJudgeTaskRequired(null); + taskState.setAdminTaskCompletionRequired(null); + taskState.setLegalOfficerTaskCompletionRequired(null); + taskState.setJudgeTaskCompletionRequired(null); if (isTaskNotCreated(taskState.getAdminTaskCreated()) && hasRequestedFlag(flags, configuration.getReview().getAdminFlagCodes())) { @@ -213,10 +222,10 @@ private static void updateTaskState(List flags, Set eligibleFlagCodes, String taskCreated, Consumer taskCreatedSetter, - Consumer taskRequiredSetter) { + Consumer taskCompletionRequiredSetter) { if (!hasRequestedFlag(flags, eligibleFlagCodes) && !isTaskNotCreatedMarker(taskCreated)) { taskCreatedSetter.accept(NO); - taskRequiredSetter.accept(NO); + taskCompletionRequiredSetter.accept(YES); } } @@ -225,23 +234,6 @@ private static boolean isTaskNotCreated(String taskCreated) { && !Boolean.parseBoolean(taskCreated); } - public boolean hasReviewSupportTaskToClose(CaseData caseData) { - SupportTaskState currentState = caseData.getSupportTaskState(); - if (currentState == null) { - return false; - } - - return isTaskClosurePending(currentState.getAdminTaskCreated(), currentState.getAdminTaskRequired()) - || isTaskClosurePending(currentState.getLegalOfficerTaskCreated(), - currentState.getLegalOfficerTaskRequired()) - || isTaskClosurePending(currentState.getJudgeTaskCreated(), currentState.getJudgeTaskRequired()); - } - - private static boolean isTaskClosurePending(String taskCreated, String taskRequired) { - return isTaskNotCreatedMarker(taskCreated) - && (YES.equalsIgnoreCase(taskRequired) || Boolean.parseBoolean(taskRequired)); - } - private static boolean isTaskNotCreatedMarker(String taskCreated) { return NO.equalsIgnoreCase(taskCreated) || "false".equalsIgnoreCase(taskCreated); diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java index 97cbeefca8..122713a7fc 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java @@ -49,7 +49,6 @@ import uk.gov.hmcts.ethos.replacement.docmosis.service.ScotlandFileLocationSelectionService; import uk.gov.hmcts.ethos.replacement.docmosis.service.SingleCaseMultipleMidEventValidationService; import uk.gov.hmcts.ethos.replacement.docmosis.service.SingleReferenceService; -import uk.gov.hmcts.ethos.replacement.docmosis.service.SupportTaskEventService; import uk.gov.hmcts.ethos.replacement.docmosis.service.SupportTaskService; import uk.gov.hmcts.ethos.replacement.docmosis.service.noc.NocRespondentRepresentativeService; import uk.gov.hmcts.ethos.replacement.docmosis.utils.InternalException; @@ -98,7 +97,6 @@ class CaseActionsForCaseWorkerControllerTest extends BaseControllerTest { private static final String PRE_DEFAULT_VALUES_URL = "/preDefaultValues"; private static final String POST_DEFAULT_VALUES_URL = "/postDefaultValues"; private static final String SUPPORT_TASKS_URL = "/supportTasks/aboutToSubmit"; - private static final String SUPPORT_TASKS_SUBMITTED_URL = "/supportTasks/submitted"; private static final String REVIEW_SUPPORT_REQUEST_ABOUT_TO_START_URL = "/reviewSupportRequest/aboutToStart"; private static final String REVIEW_SUPPORT_REQUEST_ABOUT_TO_SUBMIT_URL = @@ -197,9 +195,6 @@ class CaseActionsForCaseWorkerControllerTest extends BaseControllerTest { @MockitoBean private SupportTaskService supportTaskService; - @MockitoBean - private SupportTaskEventService supportTaskEventService; - @MockitoBean private FeatureToggleService featureToggleService; @@ -444,38 +439,6 @@ void preparesReviewSupportTaskCompletionForManagedCaseFlags(String eventId) { verify(caseManagementForCaseWorkerService).setNextListedDate(any(CaseData.class)); } - @Test - @SneakyThrows - void triggersDedicatedReviewSupportTaskClosureEventAfterCaseUpdate() { - ((ObjectNode) requestContent2).set("case_details_before", - requestContent2.get("case_details").deepCopy()); - when(featureToggleService.isCaseFlagsV2Enabled(anyString())).thenReturn(true); - when(supportTaskService.hasReviewSupportTaskToClose(any(CaseData.class))).thenReturn(true); - - mvc.perform(post(SUPPORT_TASKS_SUBMITTED_URL) - .content(requestContent2.toString()) - .header(AUTHORIZATION, AUTH_TOKEN) - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()); - - verify(supportTaskEventService).triggerCloseReviewSupportTasks(any(CaseDetails.class)); - verify(supportTaskService).hasReviewSupportTaskToClose(any(CaseData.class)); - } - - @Test - @SneakyThrows - void doesNotTriggerReviewSupportTaskClosureEventWhenNoTaskNeedsClosing() { - when(featureToggleService.isCaseFlagsV2Enabled(anyString())).thenReturn(true); - - mvc.perform(post(SUPPORT_TASKS_SUBMITTED_URL) - .content(requestContent2.toString()) - .header(AUTHORIZATION, AUTH_TOKEN) - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()); - - verify(supportTaskEventService, never()).triggerCloseReviewSupportTasks(any(CaseDetails.class)); - } - @ParameterizedTest @ValueSource(strings = { "reviewAdminSupportRequest", diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskEventServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskEventServiceTest.java deleted file mode 100644 index 16a2a7c21a..0000000000 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskEventServiceTest.java +++ /dev/null @@ -1,83 +0,0 @@ -package uk.gov.hmcts.ethos.replacement.docmosis.service; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import uk.gov.hmcts.ecm.common.client.CcdClient; -import uk.gov.hmcts.et.common.model.ccd.CCDRequest; -import uk.gov.hmcts.et.common.model.ccd.CaseData; -import uk.gov.hmcts.et.common.model.ccd.CaseDetails; -import uk.gov.hmcts.et.common.model.ccd.types.SupportTaskState; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static uk.gov.hmcts.ecm.common.model.helper.Constants.EMPLOYMENT; -import static uk.gov.hmcts.ecm.common.model.helper.Constants.NO; -import static uk.gov.hmcts.ecm.common.model.helper.Constants.YES; -import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.EVENT_CLOSE_REVIEW_SUPPORT_TASKS; - -@ExtendWith(MockitoExtension.class) -class SupportTaskEventServiceTest { - private static final String ADMIN_TOKEN = "admin-token"; - private static final String CASE_ID = "1234567890123456"; - private static final String CASE_TYPE_ID = "ET_Scotland"; - - @Mock - private CcdClient ccdClient; - @Mock - private AdminUserService adminUserService; - - private SupportTaskEventService service; - - @BeforeEach - void setUp() { - service = new SupportTaskEventService(ccdClient, adminUserService); - } - - @Test - void startsAndSubmitsDedicatedTaskClosureEventUsingLatestCaseData() throws Exception { - CaseData completedCaseData = new CaseData(); - completedCaseData.setSupportTaskState(SupportTaskState.builder() - .adminTaskCreated(NO) - .legalOfficerTaskCreated(YES) - .judgeTaskCreated(YES) - .build()); - CaseDetails completedDetails = new CaseDetails(); - completedDetails.setCaseId(CASE_ID); - completedDetails.setCaseTypeId(CASE_TYPE_ID); - completedDetails.setCaseData(completedCaseData); - - CaseData latestCaseData = new CaseData(); - latestCaseData.setSupportTaskState(SupportTaskState.builder() - .adminTaskCreated(YES) - .adminTaskRequired(YES) - .legalOfficerTaskCreated(YES) - .legalOfficerTaskRequired(YES) - .judgeTaskCreated(YES) - .judgeTaskRequired(YES) - .build()); - CaseDetails latestDetails = new CaseDetails(); - latestDetails.setCaseId(CASE_ID); - latestDetails.setCaseTypeId(CASE_TYPE_ID); - latestDetails.setJurisdiction(EMPLOYMENT); - latestDetails.setCaseData(latestCaseData); - CCDRequest ccdRequest = new CCDRequest(); - ccdRequest.setCaseDetails(latestDetails); - - when(adminUserService.getAdminUserToken()).thenReturn(ADMIN_TOKEN); - when(ccdClient.startEventForCase( - ADMIN_TOKEN, CASE_TYPE_ID, EMPLOYMENT, CASE_ID, EVENT_CLOSE_REVIEW_SUPPORT_TASKS)) - .thenReturn(ccdRequest); - - service.triggerCloseReviewSupportTasks(completedDetails); - - assertEquals(NO, latestCaseData.getSupportTaskState().getAdminTaskRequired()); - assertEquals(YES, latestCaseData.getSupportTaskState().getLegalOfficerTaskRequired()); - assertEquals(YES, latestCaseData.getSupportTaskState().getJudgeTaskRequired()); - verify(ccdClient).submitEventForCase( - ADMIN_TOKEN, latestCaseData, CASE_TYPE_ID, EMPLOYMENT, ccdRequest, CASE_ID); - } -} diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java index 3c18193d97..4d90619b7d 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java @@ -43,61 +43,6 @@ class SupportTaskServiceTest { private final SupportTaskService service = new SupportTaskService(configuration()); - @Test - void identifiesReviewSupportTaskThatNeedsClosing() { - CaseData caseData = new CaseData(); - SupportTaskState state = new SupportTaskState(); - state.setJudgeTaskCreated(NO); - state.setJudgeTaskRequired(YES); - caseData.setSupportTaskState(state); - - assertTrue(service.hasReviewSupportTaskToClose(caseData)); - } - - @Test - void identifiesBooleanReviewSupportTaskThatNeedsClosing() { - CaseData caseData = new CaseData(); - SupportTaskState state = new SupportTaskState(); - state.setAdminTaskCreated(CCD_FALSE); - state.setAdminTaskRequired(CCD_TRUE); - caseData.setSupportTaskState(state); - - assertTrue(service.hasReviewSupportTaskToClose(caseData)); - } - - @Test - void doesNotIdentifyReviewSupportTaskWhenNoCategoryNeedsClosing() { - CaseData caseData = new CaseData(); - SupportTaskState state = new SupportTaskState(); - state.setAdminTaskCreated(YES); - state.setJudgeTaskCreated(CCD_TRUE); - caseData.setSupportTaskState(state); - - assertFalse(service.hasReviewSupportTaskToClose(caseData)); - } - - @Test - void doesNotCloseReviewSupportTaskAgainWhenItWasAlreadyNotRequired() { - CaseData caseData = new CaseData(); - caseData.setSupportTaskState(SupportTaskState.builder() - .adminTaskCreated(NO) - .adminTaskRequired(NO) - .build()); - - assertFalse(service.hasReviewSupportTaskToClose(caseData)); - } - - @Test - void closesReviewSupportTaskFromCurrentPendingState() { - CaseData caseData = new CaseData(); - caseData.setSupportTaskState(SupportTaskState.builder() - .legalOfficerTaskCreated(NO) - .legalOfficerTaskRequired(YES) - .build()); - - assertTrue(service.hasReviewSupportTaskToClose(caseData)); - } - private static SupportTaskConfiguration configuration() { SupportTaskConfiguration configuration = new SupportTaskConfiguration(); configuration.getReview().setAdminFlagCodes(Set.of( @@ -152,6 +97,9 @@ void prepares_each_eligible_task_type_once_per_case(String flagCode, String task taskState(caseData).getLegalOfficerTaskRequired()); assertEquals(TASK_TYPE_JUDGE.equals(taskType) ? YES : null, taskState(caseData).getJudgeTaskRequired()); + assertNull(taskState(caseData).getAdminTaskCompletionRequired()); + assertNull(taskState(caseData).getLegalOfficerTaskCompletionRequired()); + assertNull(taskState(caseData).getJudgeTaskCompletionRequired()); service.prepareReviewSupportTasks(caseData); @@ -330,11 +278,11 @@ void completes_only_task_type_without_an_eligible_requested_flag() { service.prepareManagedReviewSupportTasks(caseData, null); assertEquals(NO, taskState(caseData).getAdminTaskCreated()); - assertEquals(NO, taskState(caseData).getAdminTaskRequired()); + assertEquals(YES, taskState(caseData).getAdminTaskCompletionRequired()); assertEquals(YES, taskState(caseData).getJudgeTaskCreated()); - assertNull(taskState(caseData).getJudgeTaskRequired()); + assertNull(taskState(caseData).getJudgeTaskCompletionRequired()); assertEquals(NO, taskState(caseData).getLegalOfficerTaskCreated()); - assertEquals(NO, taskState(caseData).getLegalOfficerTaskRequired()); + assertEquals(YES, taskState(caseData).getLegalOfficerTaskCompletionRequired()); } @Test @@ -344,12 +292,17 @@ void keeps_task_active_when_another_party_has_an_eligible_requested_flag() { .claimantFlags(caseFlags("managed-flag", "RA0033", STATUS_ACTIVE)) .representative2ExternalFlags(caseFlags("requested-flag", "RA0033", STATUS_REQUESTED)) .build()); - caseData.setSupportTaskState(SupportTaskState.builder().adminTaskCreated(YES).build()); + caseData.setSupportTaskState(SupportTaskState.builder() + .adminTaskCreated(YES) + .adminTaskRequired(YES) + .adminTaskCompletionRequired(YES) + .build()); service.prepareManagedReviewSupportTasks(caseData, null); assertEquals(YES, taskState(caseData).getAdminTaskCreated()); assertNull(taskState(caseData).getAdminTaskRequired()); + assertNull(taskState(caseData).getAdminTaskCompletionRequired()); } static Stream reviewTaskCategoryScenarios() { @@ -456,13 +409,14 @@ void completes_each_task_category_only_after_its_last_requested_flag_is_activate service.prepareManagedReviewSupportTasks(caseData, null); assertEquals(CCD_TRUE, getTaskCreated(taskState(caseData), taskType)); - assertNull(getTaskRequired(taskState(caseData), taskType)); + assertNull(getTaskCompletionRequired(taskState(caseData), taskType)); activateRespondentFlag(caseData); service.prepareManagedReviewSupportTasks(caseData, null); assertEquals(NO, getTaskCreated(taskState(caseData), taskType)); - assertEquals(NO, getTaskRequired(taskState(caseData), taskType)); + assertNull(getTaskRequired(taskState(caseData), taskType)); + assertEquals(YES, getTaskCompletionRequired(taskState(caseData), taskType)); } @ParameterizedTest @@ -492,7 +446,7 @@ void restores_boolean_created_state_from_before_data_and_completes_each_category service.prepareManagedReviewSupportTasks(caseData, caseDataBefore); assertEquals(NO, getTaskCreated(taskState(caseData), taskType)); - assertEquals(NO, getTaskRequired(taskState(caseData), taskType)); + assertEquals(YES, getTaskCompletionRequired(taskState(caseData), taskType)); } @ParameterizedTest @@ -519,7 +473,7 @@ void completes_each_task_category_for_every_non_requested_status( service.prepareManagedReviewSupportTasks(caseData, null); assertEquals(NO, getTaskCreated(taskState(caseData), taskType)); - assertEquals(NO, getTaskRequired(taskState(caseData), taskType)); + assertEquals(YES, getTaskCompletionRequired(taskState(caseData), taskType)); } @Test @@ -539,11 +493,11 @@ void completes_only_categories_without_requested_flags_when_boolean_state_is_use service.prepareManagedReviewSupportTasks(caseData, null); assertEquals(NO, taskState(caseData).getAdminTaskCreated()); - assertEquals(NO, taskState(caseData).getAdminTaskRequired()); + assertEquals(YES, taskState(caseData).getAdminTaskCompletionRequired()); assertEquals(CCD_TRUE, taskState(caseData).getLegalOfficerTaskCreated()); - assertNull(taskState(caseData).getLegalOfficerTaskRequired()); + assertNull(taskState(caseData).getLegalOfficerTaskCompletionRequired()); assertEquals(CCD_TRUE, taskState(caseData).getJudgeTaskCreated()); - assertNull(taskState(caseData).getJudgeTaskRequired()); + assertNull(taskState(caseData).getJudgeTaskCompletionRequired()); } @Test @@ -569,7 +523,7 @@ void keeps_task_active_when_an_eligible_requested_flag_remains() { service.prepareManagedReviewSupportTasks(caseData, null); assertEquals(YES, taskState(caseData).getAdminTaskCreated()); - assertNull(taskState(caseData).getAdminTaskRequired()); + assertNull(taskState(caseData).getAdminTaskCompletionRequired()); } @Test @@ -586,9 +540,9 @@ void completes_created_tasks_when_party_flags_are_missing() { assertEquals(NO, taskState(caseData).getAdminTaskCreated()); assertEquals(NO, taskState(caseData).getLegalOfficerTaskCreated()); assertEquals(NO, taskState(caseData).getJudgeTaskCreated()); - assertEquals(NO, taskState(caseData).getAdminTaskRequired()); - assertEquals(NO, taskState(caseData).getLegalOfficerTaskRequired()); - assertEquals(NO, taskState(caseData).getJudgeTaskRequired()); + assertEquals(YES, taskState(caseData).getAdminTaskCompletionRequired()); + assertEquals(YES, taskState(caseData).getLegalOfficerTaskCompletionRequired()); + assertEquals(YES, taskState(caseData).getJudgeTaskCompletionRequired()); } @Test @@ -600,7 +554,7 @@ void completes_judge_task_when_last_requested_flag_is_managed_and_current_state_ service.prepareManagedReviewSupportTasks(caseData, caseDataBefore); assertEquals(NO, taskState(caseData).getJudgeTaskCreated()); - assertEquals(NO, taskState(caseData).getJudgeTaskRequired()); + assertEquals(YES, taskState(caseData).getJudgeTaskCompletionRequired()); } static Stream reviewAndArrangeTaskScenarios() { @@ -623,7 +577,7 @@ void preservesReviewCompletionAndArrangeCreationInTheSameUpdate(String flagCode, service.prepareManagedReviewSupportTasks(caseData, caseDataBefore); service.prepareArrangeSupportTask(caseData, caseDataBefore); - assertEquals(NO, getTaskRequired(taskState(caseData), taskType)); + assertEquals(YES, getTaskCompletionRequired(taskState(caseData), taskType)); assertEquals(arrangeTaskName, taskState(caseData).getArrangeSupportTaskName()); } @@ -634,7 +588,7 @@ void completes_admin_task_when_created_marker_is_missing() { service.prepareManagedReviewSupportTasks(caseData, null); assertEquals(NO, taskState(caseData).getAdminTaskCreated()); - assertEquals(NO, taskState(caseData).getAdminTaskRequired()); + assertEquals(YES, taskState(caseData).getAdminTaskCompletionRequired()); } @Test @@ -849,6 +803,15 @@ private static String getTaskRequired(SupportTaskState state, String taskType) { }; } + private static String getTaskCompletionRequired(SupportTaskState state, String taskType) { + return switch (taskType) { + case TASK_TYPE_ADMIN -> state.getAdminTaskCompletionRequired(); + case TASK_TYPE_LEGAL_OFFICER -> state.getLegalOfficerTaskCompletionRequired(); + case TASK_TYPE_JUDGE -> state.getJudgeTaskCompletionRequired(); + default -> throw new IllegalArgumentException("Unknown task type: " + taskType); + }; + } + private static CaseFlagsType caseFlags(String id, String flagCode, String status) { return caseFlags(id, flagCode, status, null); } From 5a6bb16934b18da1e3b7b591550ce12a1fb74eca Mon Sep 17 00:00:00 2001 From: rajaram Date: Wed, 16 Sep 2026 19:03:41 +0100 Subject: [PATCH 072/100] Review tasks auto close issue resolved --- ...AuthorisationComplexType-CaseFlags-WA.json | 42 ----- .../ComplexTypes-CaseFlagsCaseLinking.json | 21 --- .../EventToComplexTypes-SupportTasks.json | 76 +-------- ...AuthorisationComplexType-CaseFlags-WA.json | 42 ----- .../ComplexTypes-CaseFlagsCaseLinking.json | 21 --- .../EventToComplexTypes-SupportTasks.json | 76 +-------- charts/et-cos/values.preview.template.yaml | 1 + charts/et-cos/values.yaml | 1 + .../model/ccd/types/SupportTaskState.java | 3 - .../docmosis/client/WaTaskApiClient.java | 30 ++++ .../constants/SupportTaskConstants.java | 3 + .../CaseActionsForCaseWorkerController.java | 18 ++- .../docmosis/service/SupportTaskService.java | 62 +++---- .../ReviewSupportTaskCompletionService.java | 74 +++++++++ .../wa/model/TaskSearchParameter.java | 20 +++ .../docmosis/wa/model/TaskSearchRequest.java | 16 ++ .../docmosis/wa/model/TaskSearchResponse.java | 18 +++ .../docmosis/wa/model/TerminateInfo.java | 14 ++ .../wa/model/TerminateTaskRequest.java | 14 ++ .../replacement/docmosis/wa/model/WaTask.java | 18 +++ src/main/resources/application.yaml | 5 + src/test/apiTest/resources/application.yaml | 7 +- .../integration/resources/application.yaml | 7 +- ...aseActionsForCaseWorkerControllerTest.java | 15 ++ .../service/SupportTaskServiceTest.java | 73 ++++----- ...eviewSupportTaskCompletionServiceTest.java | 151 ++++++++++++++++++ 26 files changed, 477 insertions(+), 351 deletions(-) create mode 100644 src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/client/WaTaskApiClient.java create mode 100644 src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/ReviewSupportTaskCompletionService.java create mode 100644 src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/model/TaskSearchParameter.java create mode 100644 src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/model/TaskSearchRequest.java create mode 100644 src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/model/TaskSearchResponse.java create mode 100644 src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/model/TerminateInfo.java create mode 100644 src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/model/TerminateTaskRequest.java create mode 100644 src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/model/WaTask.java create mode 100644 src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/ReviewSupportTaskCompletionServiceTest.java diff --git a/ccd-definitions/jurisdictions/england-wales/json/AuthorisationComplexType/AuthorisationComplexType-CaseFlags-WA.json b/ccd-definitions/jurisdictions/england-wales/json/AuthorisationComplexType/AuthorisationComplexType-CaseFlags-WA.json index 86ec7fc1d2..e2a0b3b178 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/AuthorisationComplexType/AuthorisationComplexType-CaseFlags-WA.json +++ b/ccd-definitions/jurisdictions/england-wales/json/AuthorisationComplexType/AuthorisationComplexType-CaseFlags-WA.json @@ -13,13 +13,6 @@ "UserRole": "caseworker-employment-api", "CRUD": "CRUD" }, - { - "CaseTypeID": "ET_EnglandWales", - "CaseFieldID": "supportTaskState", - "ListElementCode": "adminTaskCompletionRequired", - "UserRole": "caseworker-employment-api", - "CRUD": "CRUD" - }, { "CaseTypeID": "ET_EnglandWales", "CaseFieldID": "supportTaskState", @@ -34,13 +27,6 @@ "UserRole": "caseworker-employment-api", "CRUD": "CRUD" }, - { - "CaseTypeID": "ET_EnglandWales", - "CaseFieldID": "supportTaskState", - "ListElementCode": "legalOfficerTaskCompletionRequired", - "UserRole": "caseworker-employment-api", - "CRUD": "CRUD" - }, { "CaseTypeID": "ET_EnglandWales", "CaseFieldID": "supportTaskState", @@ -55,13 +41,6 @@ "UserRole": "caseworker-employment-api", "CRUD": "CRUD" }, - { - "CaseTypeID": "ET_EnglandWales", - "CaseFieldID": "supportTaskState", - "ListElementCode": "judgeTaskCompletionRequired", - "UserRole": "caseworker-employment-api", - "CRUD": "CRUD" - }, { "CaseTypeID": "ET_EnglandWales", "CaseFieldID": "supportTaskState", @@ -83,27 +62,6 @@ "UserRole": "caseworker-wa-task-configuration", "CRUD": "R" }, - { - "CaseTypeID": "ET_EnglandWales", - "CaseFieldID": "supportTaskState", - "ListElementCode": "adminTaskCompletionRequired", - "UserRole": "caseworker-wa-task-configuration", - "CRUD": "R" - }, - { - "CaseTypeID": "ET_EnglandWales", - "CaseFieldID": "supportTaskState", - "ListElementCode": "legalOfficerTaskCompletionRequired", - "UserRole": "caseworker-wa-task-configuration", - "CRUD": "R" - }, - { - "CaseTypeID": "ET_EnglandWales", - "CaseFieldID": "supportTaskState", - "ListElementCode": "judgeTaskCompletionRequired", - "UserRole": "caseworker-wa-task-configuration", - "CRUD": "R" - }, { "CaseTypeID": "ET_EnglandWales", "CaseFieldID": "supportTaskState", diff --git a/ccd-definitions/jurisdictions/england-wales/json/ComplexTypes/ComplexTypes-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/england-wales/json/ComplexTypes/ComplexTypes-CaseFlagsCaseLinking.json index 634643e33d..d1ca30e961 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/ComplexTypes/ComplexTypes-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/england-wales/json/ComplexTypes/ComplexTypes-CaseFlagsCaseLinking.json @@ -13,13 +13,6 @@ "ElementLabel": "Admin task required", "SecurityClassification": "Public" }, - { - "ID": "SupportTaskState", - "ListElementCode": "adminTaskCompletionRequired", - "FieldType": "YesOrNo", - "ElementLabel": "Admin task completion required", - "SecurityClassification": "Public" - }, { "ID": "SupportTaskState", "ListElementCode": "legalOfficerTaskCreated", @@ -34,13 +27,6 @@ "ElementLabel": "Legal Officer task required", "SecurityClassification": "Public" }, - { - "ID": "SupportTaskState", - "ListElementCode": "legalOfficerTaskCompletionRequired", - "FieldType": "YesOrNo", - "ElementLabel": "Legal Officer task completion required", - "SecurityClassification": "Public" - }, { "ID": "SupportTaskState", "ListElementCode": "judgeTaskCreated", @@ -55,13 +41,6 @@ "ElementLabel": "Judge task required", "SecurityClassification": "Public" }, - { - "ID": "SupportTaskState", - "ListElementCode": "judgeTaskCompletionRequired", - "FieldType": "YesOrNo", - "ElementLabel": "Judge task completion required", - "SecurityClassification": "Public" - }, { "ID": "SupportTaskState", "ListElementCode": "arrangeSupportTaskName", diff --git a/ccd-definitions/jurisdictions/england-wales/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json b/ccd-definitions/jurisdictions/england-wales/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json index 82258f1616..9247a57ed1 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json +++ b/ccd-definitions/jurisdictions/england-wales/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json @@ -215,33 +215,6 @@ "DisplayContext": "OPTIONAL", "Publish": "Y" }, - { - "ID": "SupportTaskState", - "CaseEventID": "manageFlags", - "CaseFieldID": "supportTaskState", - "ListElementCode": "adminTaskCompletionRequired", - "FieldDisplayOrder": 1, - "DisplayContext": "OPTIONAL", - "Publish": "Y" - }, - { - "ID": "SupportTaskState", - "CaseEventID": "manageFlags", - "CaseFieldID": "supportTaskState", - "ListElementCode": "legalOfficerTaskCompletionRequired", - "FieldDisplayOrder": 2, - "DisplayContext": "OPTIONAL", - "Publish": "Y" - }, - { - "ID": "SupportTaskState", - "CaseEventID": "manageFlags", - "CaseFieldID": "supportTaskState", - "ListElementCode": "judgeTaskCompletionRequired", - "FieldDisplayOrder": 3, - "DisplayContext": "OPTIONAL", - "Publish": "Y" - }, { "ID": "SupportTaskState", "CaseEventID": "manageFlags", @@ -255,35 +228,8 @@ "ID": "SupportTaskState", "CaseEventID": "manageSupport", "CaseFieldID": "supportTaskState", - "ListElementCode": "adminTaskCompletionRequired", - "FieldDisplayOrder": 1, - "DisplayContext": "OPTIONAL", - "Publish": "Y" - }, - { - "ID": "SupportTaskState", - "CaseEventID": "manageSupport", - "CaseFieldID": "supportTaskState", - "ListElementCode": "legalOfficerTaskCompletionRequired", - "FieldDisplayOrder": 2, - "DisplayContext": "OPTIONAL", - "Publish": "Y" - }, - { - "ID": "SupportTaskState", - "CaseEventID": "manageSupport", - "CaseFieldID": "supportTaskState", - "ListElementCode": "judgeTaskCompletionRequired", - "FieldDisplayOrder": 3, - "DisplayContext": "OPTIONAL", - "Publish": "Y" - }, - { - "ID": "SupportTaskState", - "CaseEventID": "reviewAdminSupportRequest", - "CaseFieldID": "supportTaskState", - "ListElementCode": "adminTaskCompletionRequired", - "FieldDisplayOrder": 1, + "ListElementCode": "arrangeSupportTaskName", + "FieldDisplayOrder": 4, "DisplayContext": "OPTIONAL", "Publish": "Y" }, @@ -296,15 +242,6 @@ "DisplayContext": "OPTIONAL", "Publish": "Y" }, - { - "ID": "SupportTaskState", - "CaseEventID": "reviewLOSupportRequest", - "CaseFieldID": "supportTaskState", - "ListElementCode": "legalOfficerTaskCompletionRequired", - "FieldDisplayOrder": 2, - "DisplayContext": "OPTIONAL", - "Publish": "Y" - }, { "ID": "SupportTaskState", "CaseEventID": "reviewLOSupportRequest", @@ -314,15 +251,6 @@ "DisplayContext": "OPTIONAL", "Publish": "Y" }, - { - "ID": "SupportTaskState", - "CaseEventID": "reviewJudgeSupportRequest", - "CaseFieldID": "supportTaskState", - "ListElementCode": "judgeTaskCompletionRequired", - "FieldDisplayOrder": 3, - "DisplayContext": "OPTIONAL", - "Publish": "Y" - }, { "ID": "SupportTaskState", "CaseEventID": "reviewJudgeSupportRequest", diff --git a/ccd-definitions/jurisdictions/scotland/json/AuthorisationComplexType/AuthorisationComplexType-CaseFlags-WA.json b/ccd-definitions/jurisdictions/scotland/json/AuthorisationComplexType/AuthorisationComplexType-CaseFlags-WA.json index 99824c5885..01ccf71348 100644 --- a/ccd-definitions/jurisdictions/scotland/json/AuthorisationComplexType/AuthorisationComplexType-CaseFlags-WA.json +++ b/ccd-definitions/jurisdictions/scotland/json/AuthorisationComplexType/AuthorisationComplexType-CaseFlags-WA.json @@ -13,13 +13,6 @@ "UserRole": "caseworker-employment-api", "CRUD": "CRUD" }, - { - "CaseTypeID": "ET_Scotland", - "CaseFieldID": "supportTaskState", - "ListElementCode": "adminTaskCompletionRequired", - "UserRole": "caseworker-employment-api", - "CRUD": "CRUD" - }, { "CaseTypeID": "ET_Scotland", "CaseFieldID": "supportTaskState", @@ -34,13 +27,6 @@ "UserRole": "caseworker-employment-api", "CRUD": "CRUD" }, - { - "CaseTypeID": "ET_Scotland", - "CaseFieldID": "supportTaskState", - "ListElementCode": "legalOfficerTaskCompletionRequired", - "UserRole": "caseworker-employment-api", - "CRUD": "CRUD" - }, { "CaseTypeID": "ET_Scotland", "CaseFieldID": "supportTaskState", @@ -55,13 +41,6 @@ "UserRole": "caseworker-employment-api", "CRUD": "CRUD" }, - { - "CaseTypeID": "ET_Scotland", - "CaseFieldID": "supportTaskState", - "ListElementCode": "judgeTaskCompletionRequired", - "UserRole": "caseworker-employment-api", - "CRUD": "CRUD" - }, { "CaseTypeID": "ET_Scotland", "CaseFieldID": "supportTaskState", @@ -83,27 +62,6 @@ "UserRole": "caseworker-wa-task-configuration", "CRUD": "R" }, - { - "CaseTypeID": "ET_Scotland", - "CaseFieldID": "supportTaskState", - "ListElementCode": "adminTaskCompletionRequired", - "UserRole": "caseworker-wa-task-configuration", - "CRUD": "R" - }, - { - "CaseTypeID": "ET_Scotland", - "CaseFieldID": "supportTaskState", - "ListElementCode": "legalOfficerTaskCompletionRequired", - "UserRole": "caseworker-wa-task-configuration", - "CRUD": "R" - }, - { - "CaseTypeID": "ET_Scotland", - "CaseFieldID": "supportTaskState", - "ListElementCode": "judgeTaskCompletionRequired", - "UserRole": "caseworker-wa-task-configuration", - "CRUD": "R" - }, { "CaseTypeID": "ET_Scotland", "CaseFieldID": "supportTaskState", diff --git a/ccd-definitions/jurisdictions/scotland/json/ComplexTypes/ComplexTypes-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/scotland/json/ComplexTypes/ComplexTypes-CaseFlagsCaseLinking.json index 634643e33d..d1ca30e961 100644 --- a/ccd-definitions/jurisdictions/scotland/json/ComplexTypes/ComplexTypes-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/scotland/json/ComplexTypes/ComplexTypes-CaseFlagsCaseLinking.json @@ -13,13 +13,6 @@ "ElementLabel": "Admin task required", "SecurityClassification": "Public" }, - { - "ID": "SupportTaskState", - "ListElementCode": "adminTaskCompletionRequired", - "FieldType": "YesOrNo", - "ElementLabel": "Admin task completion required", - "SecurityClassification": "Public" - }, { "ID": "SupportTaskState", "ListElementCode": "legalOfficerTaskCreated", @@ -34,13 +27,6 @@ "ElementLabel": "Legal Officer task required", "SecurityClassification": "Public" }, - { - "ID": "SupportTaskState", - "ListElementCode": "legalOfficerTaskCompletionRequired", - "FieldType": "YesOrNo", - "ElementLabel": "Legal Officer task completion required", - "SecurityClassification": "Public" - }, { "ID": "SupportTaskState", "ListElementCode": "judgeTaskCreated", @@ -55,13 +41,6 @@ "ElementLabel": "Judge task required", "SecurityClassification": "Public" }, - { - "ID": "SupportTaskState", - "ListElementCode": "judgeTaskCompletionRequired", - "FieldType": "YesOrNo", - "ElementLabel": "Judge task completion required", - "SecurityClassification": "Public" - }, { "ID": "SupportTaskState", "ListElementCode": "arrangeSupportTaskName", diff --git a/ccd-definitions/jurisdictions/scotland/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json b/ccd-definitions/jurisdictions/scotland/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json index 82258f1616..9247a57ed1 100644 --- a/ccd-definitions/jurisdictions/scotland/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json +++ b/ccd-definitions/jurisdictions/scotland/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json @@ -215,33 +215,6 @@ "DisplayContext": "OPTIONAL", "Publish": "Y" }, - { - "ID": "SupportTaskState", - "CaseEventID": "manageFlags", - "CaseFieldID": "supportTaskState", - "ListElementCode": "adminTaskCompletionRequired", - "FieldDisplayOrder": 1, - "DisplayContext": "OPTIONAL", - "Publish": "Y" - }, - { - "ID": "SupportTaskState", - "CaseEventID": "manageFlags", - "CaseFieldID": "supportTaskState", - "ListElementCode": "legalOfficerTaskCompletionRequired", - "FieldDisplayOrder": 2, - "DisplayContext": "OPTIONAL", - "Publish": "Y" - }, - { - "ID": "SupportTaskState", - "CaseEventID": "manageFlags", - "CaseFieldID": "supportTaskState", - "ListElementCode": "judgeTaskCompletionRequired", - "FieldDisplayOrder": 3, - "DisplayContext": "OPTIONAL", - "Publish": "Y" - }, { "ID": "SupportTaskState", "CaseEventID": "manageFlags", @@ -255,35 +228,8 @@ "ID": "SupportTaskState", "CaseEventID": "manageSupport", "CaseFieldID": "supportTaskState", - "ListElementCode": "adminTaskCompletionRequired", - "FieldDisplayOrder": 1, - "DisplayContext": "OPTIONAL", - "Publish": "Y" - }, - { - "ID": "SupportTaskState", - "CaseEventID": "manageSupport", - "CaseFieldID": "supportTaskState", - "ListElementCode": "legalOfficerTaskCompletionRequired", - "FieldDisplayOrder": 2, - "DisplayContext": "OPTIONAL", - "Publish": "Y" - }, - { - "ID": "SupportTaskState", - "CaseEventID": "manageSupport", - "CaseFieldID": "supportTaskState", - "ListElementCode": "judgeTaskCompletionRequired", - "FieldDisplayOrder": 3, - "DisplayContext": "OPTIONAL", - "Publish": "Y" - }, - { - "ID": "SupportTaskState", - "CaseEventID": "reviewAdminSupportRequest", - "CaseFieldID": "supportTaskState", - "ListElementCode": "adminTaskCompletionRequired", - "FieldDisplayOrder": 1, + "ListElementCode": "arrangeSupportTaskName", + "FieldDisplayOrder": 4, "DisplayContext": "OPTIONAL", "Publish": "Y" }, @@ -296,15 +242,6 @@ "DisplayContext": "OPTIONAL", "Publish": "Y" }, - { - "ID": "SupportTaskState", - "CaseEventID": "reviewLOSupportRequest", - "CaseFieldID": "supportTaskState", - "ListElementCode": "legalOfficerTaskCompletionRequired", - "FieldDisplayOrder": 2, - "DisplayContext": "OPTIONAL", - "Publish": "Y" - }, { "ID": "SupportTaskState", "CaseEventID": "reviewLOSupportRequest", @@ -314,15 +251,6 @@ "DisplayContext": "OPTIONAL", "Publish": "Y" }, - { - "ID": "SupportTaskState", - "CaseEventID": "reviewJudgeSupportRequest", - "CaseFieldID": "supportTaskState", - "ListElementCode": "judgeTaskCompletionRequired", - "FieldDisplayOrder": 3, - "DisplayContext": "OPTIONAL", - "Publish": "Y" - }, { "ID": "SupportTaskState", "CaseEventID": "reviewJudgeSupportRequest", diff --git a/charts/et-cos/values.preview.template.yaml b/charts/et-cos/values.preview.template.yaml index 4c12d6f082..21115343ba 100644 --- a/charts/et-cos/values.preview.template.yaml +++ b/charts/et-cos/values.preview.template.yaml @@ -45,6 +45,7 @@ java: CASE_DOCUMENT_AM_URL: http://ccd-case-document-am-api-aat.service.core-compute-aat.internal RD_PROFESSIONAL_API_URL: http://rd-professional-api-aat.service.core-compute-aat.internal RD_COMMONDATA_API_URL: http://rd-commondata-api-aat.service.core-compute-aat.internal + WA_TASK_MANAGEMENT_API_URL: "http://{{ .Release.Name }}-wa-task-management-api" SECURE_DOC_STORE_FEATURE: true EM_CCD_ORCHESTRATOR_URL: http://em-ccd-orchestrator-{{ .Values.global.environment }}.service.core-compute-{{ .Values.global.environment }}.internal ACAS_BASE_URL: "https://api-dev-acas-01.azure-api.net/ECCLUAT" diff --git a/charts/et-cos/values.yaml b/charts/et-cos/values.yaml index b03e8b5516..887ecc3996 100644 --- a/charts/et-cos/values.yaml +++ b/charts/et-cos/values.yaml @@ -77,6 +77,7 @@ java: CASE_DOCUMENT_AM_URL: http://ccd-case-document-am-api-{{ .Values.global.environment }}.service.core-compute-{{ .Values.global.environment }}.internal RD_PROFESSIONAL_API_URL: http://rd-professional-api-{{ .Values.global.environment }}.service.core-compute-{{ .Values.global.environment }}.internal RD_COMMONDATA_API_URL: http://rd-commondata-api-{{ .Values.global.environment }}.service.core-compute-{{ .Values.global.environment }}.internal + WA_TASK_MANAGEMENT_API_URL: http://wa-task-management-api-{{ .Values.global.environment }}.service.core-compute-{{ .Values.global.environment }}.internal SECURE_DOC_STORE_FEATURE: true EXUI_CASE_DETAILS_URL: "https://manage-case.{{ .Values.global.environment }}.platform.hmcts.net/cases/case-details/" CITIZEN_CASE_DETAILS_URL: "https://et-sya.{{ .Values.global.environment }}.platform.hmcts.net/citizen-hub/" diff --git a/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/types/SupportTaskState.java b/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/types/SupportTaskState.java index 6a2cedfd1a..231f37a560 100644 --- a/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/types/SupportTaskState.java +++ b/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/types/SupportTaskState.java @@ -16,12 +16,9 @@ public class SupportTaskState { private String adminTaskCreated; private String adminTaskRequired; - private String adminTaskCompletionRequired; private String legalOfficerTaskCreated; private String legalOfficerTaskRequired; - private String legalOfficerTaskCompletionRequired; private String judgeTaskCreated; private String judgeTaskRequired; - private String judgeTaskCompletionRequired; private String arrangeSupportTaskName; } diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/client/WaTaskApiClient.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/client/WaTaskApiClient.java new file mode 100644 index 0000000000..8137ab633b --- /dev/null +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/client/WaTaskApiClient.java @@ -0,0 +1,30 @@ +package uk.gov.hmcts.ethos.replacement.docmosis.client; + +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.cloud.openfeign.FeignClientProperties; +import org.springframework.http.HttpHeaders; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; +import uk.gov.hmcts.ethos.replacement.docmosis.wa.model.TaskSearchRequest; +import uk.gov.hmcts.ethos.replacement.docmosis.wa.model.TaskSearchResponse; +import uk.gov.hmcts.ethos.replacement.docmosis.wa.model.TerminateTaskRequest; + +@FeignClient(name = "wa-task-management-api", url = "${wa.task-management.api.url}", + configuration = FeignClientProperties.FeignClientConfiguration.class) +public interface WaTaskApiClient { + + @PostMapping(value = "/task", consumes = "application/json") + TaskSearchResponse searchTasks( + @RequestHeader(HttpHeaders.AUTHORIZATION) String authorization, + @RequestHeader("ServiceAuthorization") String serviceAuthorization, + @RequestBody TaskSearchRequest searchRequest); + + @DeleteMapping(value = "/task/{taskId}", consumes = "application/json") + void terminateTask( + @RequestHeader("ServiceAuthorization") String serviceAuthorization, + @PathVariable("taskId") String taskId, + @RequestBody TerminateTaskRequest terminateTaskRequest); +} diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/constants/SupportTaskConstants.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/constants/SupportTaskConstants.java index cbacfacbb9..15cb5744e4 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/constants/SupportTaskConstants.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/constants/SupportTaskConstants.java @@ -15,6 +15,9 @@ public final class SupportTaskConstants { public static final String EVENT_REVIEW_JUDGE_SUPPORT_REQUEST = "reviewJudgeSupportRequest"; public static final String FLAG_STATUS_ACTIVE = "Active"; public static final String FLAG_STATUS_REQUESTED = "Requested"; + public static final String TASK_TYPE_REVIEW_SUPPORT_ADMIN = "ReviewSupportRequestAdmin"; + public static final String TASK_TYPE_REVIEW_SUPPORT_LEGAL_OFFICER = "ReviewSupportRequestLegalOfficer"; + public static final String TASK_TYPE_REVIEW_SUPPORT_JUDGE = "ReviewSupportRequestJudge"; private SupportTaskConstants() { } diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java index ceab69ea9f..20f41176f8 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java @@ -54,6 +54,7 @@ import uk.gov.hmcts.ethos.replacement.docmosis.service.noc.NocRespondentRepresentativeService; import uk.gov.hmcts.ethos.replacement.docmosis.utils.LoggingUtils; import uk.gov.hmcts.ethos.replacement.docmosis.utils.noc.NocUtils; +import uk.gov.hmcts.ethos.replacement.docmosis.wa.ReviewSupportTaskCompletionService; import java.io.IOException; import java.text.ParseException; @@ -120,6 +121,7 @@ public class CaseActionsForCaseWorkerController { private final FeatureToggleService featureToggleService; private final CaseFlagsService caseFlagsService; private final SupportTaskService supportTaskService; + private final ReviewSupportTaskCompletionService reviewSupportTaskCompletionService; private final CaseManagementLocationService caseManagementLocationService; private final Et1SubmissionService et1SubmissionService; private final NocRespondentHelper nocRespondentHelper; @@ -221,7 +223,8 @@ public ResponseEntity postDefaultValues( @PostMapping(value = "/supportTasks/aboutToSubmit", consumes = APPLICATION_JSON_VALUE) @Operation(summary = "Prepare Review Support and Arrange Support tasks for eligible Case Flags.") public ResponseEntity prepareSupportTasks( - @RequestBody CallbackRequest callbackRequest) { + @RequestBody CallbackRequest callbackRequest, + @RequestHeader(AUTHORIZATION) String userToken) { CaseDetails caseDetails = callbackRequest.getCaseDetails(); CaseData caseData = caseDetails.getCaseData(); @@ -237,7 +240,10 @@ public ResponseEntity prepareSupportTasks( supportTaskService.prepareNewFlagReviewSupportTasks(caseData, caseDataBefore); } else if (EVENT_MANAGE_FLAGS.equals(callbackRequest.getEventId()) || EVENT_MANAGE_SUPPORT.equals(callbackRequest.getEventId())) { - supportTaskService.prepareManagedReviewSupportTasks(caseData, caseDataBefore); + reviewSupportTaskCompletionService.completeTasks( + caseDetails.getCaseId(), + userToken, + supportTaskService.prepareManagedReviewSupportTasks(caseData, caseDataBefore)); } if (EVENT_CREATE_FLAG.equals(callbackRequest.getEventId()) @@ -266,7 +272,8 @@ public ResponseEntity prepareReviewSupportRequest( @PostMapping(value = "/reviewSupportRequest/aboutToSubmit", consumes = APPLICATION_JSON_VALUE) @Operation(summary = "Apply reviewed Case Flags and prepare the related support tasks.") public ResponseEntity applyReviewSupportRequest( - @RequestBody CallbackRequest callbackRequest) { + @RequestBody CallbackRequest callbackRequest, + @RequestHeader(AUTHORIZATION) String userToken) { CaseDetails caseDetails = callbackRequest.getCaseDetails(); CaseData caseData = caseDetails.getCaseData(); List errors = new ArrayList<>(); @@ -278,7 +285,10 @@ public ResponseEntity applyReviewSupportRequest( CaseData caseDataBefore = callbackRequest.getCaseDetailsBefore() == null ? null : callbackRequest.getCaseDetailsBefore().getCaseData(); - supportTaskService.prepareManagedReviewSupportTasks(caseData, caseDataBefore); + reviewSupportTaskCompletionService.completeTasks( + caseDetails.getCaseId(), + userToken, + supportTaskService.prepareManagedReviewSupportTasks(caseData, caseDataBefore)); supportTaskService.prepareArrangeSupportTask(caseData, caseDataBefore); } } diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java index 81971819eb..8e7410bbc0 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java @@ -13,6 +13,7 @@ import java.util.Comparator; import java.util.HashMap; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Objects; @@ -30,6 +31,9 @@ import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.EVENT_REVIEW_LEGAL_OFFICER_SUPPORT_REQUEST; import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.FLAG_STATUS_ACTIVE; import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.FLAG_STATUS_REQUESTED; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.TASK_TYPE_REVIEW_SUPPORT_ADMIN; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.TASK_TYPE_REVIEW_SUPPORT_JUDGE; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.TASK_TYPE_REVIEW_SUPPORT_LEGAL_OFFICER; import static uk.gov.hmcts.ethos.replacement.docmosis.service.PartyCaseFlagUtils.allFlagItems; import static uk.gov.hmcts.ethos.replacement.docmosis.service.PartyCaseFlagUtils.allPartyFlagSections; import static uk.gov.hmcts.ethos.replacement.docmosis.service.PartyCaseFlagUtils.flagDetails; @@ -92,29 +96,31 @@ private static void retainCreatedTaskState(CaseData caseData, CaseData caseDataB } } - public void prepareManagedReviewSupportTasks(CaseData caseData, CaseData caseDataBefore) { + public Set prepareManagedReviewSupportTasks(CaseData caseData, CaseData caseDataBefore) { retainCreatedTaskState(caseData, caseDataBefore); SupportTaskState taskState = taskState(caseData); taskState.setAdminTaskRequired(null); taskState.setLegalOfficerTaskRequired(null); taskState.setJudgeTaskRequired(null); - taskState.setAdminTaskCompletionRequired(null); - taskState.setLegalOfficerTaskCompletionRequired(null); - taskState.setJudgeTaskCompletionRequired(null); List flags = allFlagItems(caseData.getAllPartyFlags()) .map(GenericTypeItem::getValue) .toList(); + Set taskTypesToComplete = new LinkedHashSet<>(); - updateTaskState(flags, configuration.getReview().getAdminFlagCodes(), taskState.getAdminTaskCreated(), - taskState::setAdminTaskCreated, - taskState::setAdminTaskCompletionRequired); - updateTaskState(flags, configuration.getReview().getLegalOfficerFlagCodes(), + if (updateTaskState(flags, configuration.getReview().getAdminFlagCodes(), taskState.getAdminTaskCreated(), + taskState::setAdminTaskCreated)) { + taskTypesToComplete.add(TASK_TYPE_REVIEW_SUPPORT_ADMIN); + } + if (updateTaskState(flags, configuration.getReview().getLegalOfficerFlagCodes(), taskState.getLegalOfficerTaskCreated(), - taskState::setLegalOfficerTaskCreated, - taskState::setLegalOfficerTaskCompletionRequired); - updateTaskState(flags, configuration.getReview().getJudgeFlagCodes(), taskState.getJudgeTaskCreated(), - taskState::setJudgeTaskCreated, - taskState::setJudgeTaskCompletionRequired); + taskState::setLegalOfficerTaskCreated)) { + taskTypesToComplete.add(TASK_TYPE_REVIEW_SUPPORT_LEGAL_OFFICER); + } + if (updateTaskState(flags, configuration.getReview().getJudgeFlagCodes(), taskState.getJudgeTaskCreated(), + taskState::setJudgeTaskCreated)) { + taskTypesToComplete.add(TASK_TYPE_REVIEW_SUPPORT_JUDGE); + } + return taskTypesToComplete; } public void prepareReviewSupportRequest(CaseData caseData, String eventId) { @@ -186,9 +192,6 @@ private void prepareTasks(CaseData caseData, List flags) { taskState.setAdminTaskRequired(null); taskState.setLegalOfficerTaskRequired(null); taskState.setJudgeTaskRequired(null); - taskState.setAdminTaskCompletionRequired(null); - taskState.setLegalOfficerTaskCompletionRequired(null); - taskState.setJudgeTaskCompletionRequired(null); if (isTaskNotCreated(taskState.getAdminTaskCreated()) && hasRequestedFlag(flags, configuration.getReview().getAdminFlagCodes())) { @@ -218,15 +221,23 @@ private static boolean hasRequestedFlag(List flags, Set return flags.stream().anyMatch(flag -> isRequested(flag) && eligibleFlagCodes.contains(flag.getFlagCode())); } - private static void updateTaskState(List flags, - Set eligibleFlagCodes, - String taskCreated, - Consumer taskCreatedSetter, - Consumer taskCompletionRequiredSetter) { - if (!hasRequestedFlag(flags, eligibleFlagCodes) && !isTaskNotCreatedMarker(taskCreated)) { + private static boolean updateTaskState(List flags, + Set eligibleFlagCodes, + String taskCreated, + Consumer taskCreatedSetter) { + boolean categoryHasFlags = flags.stream() + .map(FlagDetailType::getFlagCode) + .anyMatch(eligibleFlagCodes::contains); + if (!hasRequestedFlag(flags, eligibleFlagCodes) + && (isTaskCreated(taskCreated) || categoryHasFlags)) { taskCreatedSetter.accept(NO); - taskCompletionRequiredSetter.accept(YES); + return true; } + return false; + } + + private static boolean isTaskCreated(String taskCreated) { + return YES.equalsIgnoreCase(taskCreated) || Boolean.parseBoolean(taskCreated); } private static boolean isTaskNotCreated(String taskCreated) { @@ -234,11 +245,6 @@ private static boolean isTaskNotCreated(String taskCreated) { && !Boolean.parseBoolean(taskCreated); } - private static boolean isTaskNotCreatedMarker(String taskCreated) { - return NO.equalsIgnoreCase(taskCreated) - || "false".equalsIgnoreCase(taskCreated); - } - private static boolean isRequested(FlagDetailType flag) { return FLAG_STATUS_REQUESTED.equals(flag.getStatus()); } diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/ReviewSupportTaskCompletionService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/ReviewSupportTaskCompletionService.java new file mode 100644 index 0000000000..9af1d056d8 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/ReviewSupportTaskCompletionService.java @@ -0,0 +1,74 @@ +package uk.gov.hmcts.ethos.replacement.docmosis.wa; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import uk.gov.hmcts.ethos.replacement.docmosis.client.WaTaskApiClient; +import uk.gov.hmcts.ethos.replacement.docmosis.wa.model.TaskSearchParameter; +import uk.gov.hmcts.ethos.replacement.docmosis.wa.model.TaskSearchRequest; +import uk.gov.hmcts.ethos.replacement.docmosis.wa.model.TaskSearchResponse; +import uk.gov.hmcts.ethos.replacement.docmosis.wa.model.TerminateInfo; +import uk.gov.hmcts.ethos.replacement.docmosis.wa.model.TerminateTaskRequest; +import uk.gov.hmcts.ethos.replacement.docmosis.wa.model.WaTask; +import uk.gov.hmcts.reform.authorisation.generators.AuthTokenGenerator; + +import java.util.List; +import java.util.Set; + +import static org.apache.commons.lang3.StringUtils.isBlank; + +@Service +@RequiredArgsConstructor +@Slf4j +public class ReviewSupportTaskCompletionService { + private static final String OPERATOR_IN = "IN"; + private static final String TERMINATE_REASON_COMPLETED = "completed"; + private static final List ACTIVE_TASK_STATES = List.of("assigned", "unassigned"); + + private final WaTaskApiClient waTaskApiClient; + private final AuthTokenGenerator serviceAuthTokenGenerator; + + public void completeTasks(String caseId, String userToken, Set taskTypes) { + if (isBlank(caseId) || isBlank(userToken) || taskTypes == null || taskTypes.isEmpty()) { + return; + } + + try { + String serviceToken = serviceAuthTokenGenerator.generate(); + List tasks = findActiveTasks(caseId, userToken, serviceToken, taskTypes); + log.info("Case {}: {} active Review Support task(s) to complete", caseId, tasks.size()); + tasks.forEach(task -> terminate(task, caseId, serviceToken)); + } catch (Exception e) { + log.error("Error completing Review Support tasks on case {}: {}", caseId, e.getMessage(), e); + } + } + + private List findActiveTasks(String caseId, String userToken, String serviceToken, + Set taskTypes) { + TaskSearchRequest request = TaskSearchRequest.builder() + .searchParameters(List.of( + searchParameter("case_id", List.of(caseId)), + searchParameter("task_type", List.copyOf(taskTypes)), + searchParameter("state", ACTIVE_TASK_STATES))) + .build(); + TaskSearchResponse response = waTaskApiClient.searchTasks(userToken, serviceToken, request); + return response == null || response.getTasks() == null ? List.of() : response.getTasks(); + } + + private void terminate(WaTask task, String caseId, String serviceToken) { + TerminateTaskRequest request = TerminateTaskRequest.builder() + .terminateInfo(TerminateInfo.builder().terminateReason(TERMINATE_REASON_COMPLETED).build()) + .build(); + try { + waTaskApiClient.terminateTask(serviceToken, task.getId(), request); + log.info("Completed task {} ({}) on case {}", task.getId(), task.getType(), caseId); + } catch (Exception e) { + log.error("Could not complete task {} ({}) on case {}: {}", + task.getId(), task.getType(), caseId, e.getMessage(), e); + } + } + + private static TaskSearchParameter searchParameter(String key, List values) { + return TaskSearchParameter.builder().key(key).operator(OPERATOR_IN).values(values).build(); + } +} diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/model/TaskSearchParameter.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/model/TaskSearchParameter.java new file mode 100644 index 0000000000..acb56bb116 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/model/TaskSearchParameter.java @@ -0,0 +1,20 @@ +package uk.gov.hmcts.ethos.replacement.docmosis.wa.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Builder; +import lombok.Data; +import lombok.extern.jackson.Jacksonized; + +import java.util.List; + +@Data +@Builder +@Jacksonized +public class TaskSearchParameter { + @JsonProperty("key") + private String key; + @JsonProperty("operator") + private String operator; + @JsonProperty("values") + private List values; +} diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/model/TaskSearchRequest.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/model/TaskSearchRequest.java new file mode 100644 index 0000000000..91533c4b7f --- /dev/null +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/model/TaskSearchRequest.java @@ -0,0 +1,16 @@ +package uk.gov.hmcts.ethos.replacement.docmosis.wa.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Builder; +import lombok.Data; +import lombok.extern.jackson.Jacksonized; + +import java.util.List; + +@Data +@Builder +@Jacksonized +public class TaskSearchRequest { + @JsonProperty("search_parameters") + private List searchParameters; +} diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/model/TaskSearchResponse.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/model/TaskSearchResponse.java new file mode 100644 index 0000000000..42288c13ac --- /dev/null +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/model/TaskSearchResponse.java @@ -0,0 +1,18 @@ +package uk.gov.hmcts.ethos.replacement.docmosis.wa.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Builder; +import lombok.Data; +import lombok.extern.jackson.Jacksonized; + +import java.util.List; + +@Data +@Builder +@Jacksonized +@JsonIgnoreProperties(ignoreUnknown = true) +public class TaskSearchResponse { + @JsonProperty("tasks") + private List tasks; +} diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/model/TerminateInfo.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/model/TerminateInfo.java new file mode 100644 index 0000000000..df751513c4 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/model/TerminateInfo.java @@ -0,0 +1,14 @@ +package uk.gov.hmcts.ethos.replacement.docmosis.wa.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Builder; +import lombok.Data; +import lombok.extern.jackson.Jacksonized; + +@Data +@Builder +@Jacksonized +public class TerminateInfo { + @JsonProperty("terminate_reason") + private String terminateReason; +} diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/model/TerminateTaskRequest.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/model/TerminateTaskRequest.java new file mode 100644 index 0000000000..506fd12a1e --- /dev/null +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/model/TerminateTaskRequest.java @@ -0,0 +1,14 @@ +package uk.gov.hmcts.ethos.replacement.docmosis.wa.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Builder; +import lombok.Data; +import lombok.extern.jackson.Jacksonized; + +@Data +@Builder +@Jacksonized +public class TerminateTaskRequest { + @JsonProperty("terminate_info") + private TerminateInfo terminateInfo; +} diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/model/WaTask.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/model/WaTask.java new file mode 100644 index 0000000000..ee8129dda9 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/model/WaTask.java @@ -0,0 +1,18 @@ +package uk.gov.hmcts.ethos.replacement.docmosis.wa.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Builder; +import lombok.Data; +import lombok.extern.jackson.Jacksonized; + +@Data +@Builder +@Jacksonized +@JsonIgnoreProperties(ignoreUnknown = true) +public class WaTask { + @JsonProperty("id") + private String id; + @JsonProperty("type") + private String type; +} diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index f9eb2dbd26..fec3c1a63e 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -120,6 +120,11 @@ case_document_am: rd_professional-api-url: ${RD_PROFESSIONAL_API_URL:http://localhost:4507} rd_commondata-api-url: ${RD_COMMONDATA_API_URL:http://localhost:4507} +wa: + task-management: + api: + url: ${WA_TASK_MANAGEMENT_API_URL:http://localhost:8087} + feature: secure-doc-store: enabled: ${SECURE_DOC_STORE_FEATURE:false} diff --git a/src/test/apiTest/resources/application.yaml b/src/test/apiTest/resources/application.yaml index 9898a50503..1193897d74 100644 --- a/src/test/apiTest/resources/application.yaml +++ b/src/test/apiTest/resources/application.yaml @@ -197,6 +197,11 @@ apply_noc_access_api_assignments_path: /noc/apply-decision rd_professional-api-url: ${RD_PROFESSIONAL_API_URL:http://localhost:4507} rd_commondata-api-url: ${RD_COMMONDATA_API_URL:http://localhost:4507} +wa: + task-management: + api: + url: ${WA_TASK_MANAGEMENT_API_URL:http://localhost:8087} + case-details-url: citizen: ${CITIZEN_CASE_DETAILS_URL:http://localhost:3001/citizen-hub/} exui: ${EXUI_CASE_DETAILS_URL:http://localhost:3000/cases/case-details/} @@ -255,4 +260,4 @@ queue: update-case: poll-interval: 1000 batch-size: 10 - threads: 15 \ No newline at end of file + threads: 15 diff --git a/src/test/integration/resources/application.yaml b/src/test/integration/resources/application.yaml index 19fabfdb00..6c5db7b840 100644 --- a/src/test/integration/resources/application.yaml +++ b/src/test/integration/resources/application.yaml @@ -45,6 +45,11 @@ case_document_am: rd_professional-api-url: http://localhost:4507 rd_commondata-api-url: http://localhost:4507 +wa: + task-management: + api: + url: http://localhost:8087 + feature: secure-doc-store: enabled: 'false' @@ -216,4 +221,4 @@ em-ccd-orchestrator: default: et-dcf-2.yaml pdf: - et3form: "ET3_0224.pdf" \ No newline at end of file + et3form: "ET3_0224.pdf" diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java index 122713a7fc..d3887d6a5d 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java @@ -53,6 +53,7 @@ import uk.gov.hmcts.ethos.replacement.docmosis.service.noc.NocRespondentRepresentativeService; import uk.gov.hmcts.ethos.replacement.docmosis.utils.InternalException; import uk.gov.hmcts.ethos.replacement.docmosis.utils.JsonMapper; +import uk.gov.hmcts.ethos.replacement.docmosis.wa.ReviewSupportTaskCompletionService; import java.io.File; import java.io.IOException; @@ -61,6 +62,7 @@ import java.util.List; import java.util.Objects; import java.util.Optional; +import java.util.Set; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.is; @@ -79,6 +81,7 @@ import static org.mockito.Mockito.same; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.when; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; @@ -195,6 +198,9 @@ class CaseActionsForCaseWorkerControllerTest extends BaseControllerTest { @MockitoBean private SupportTaskService supportTaskService; + @MockitoBean + private ReviewSupportTaskCompletionService reviewSupportTaskCompletionService; + @MockitoBean private FeatureToggleService featureToggleService; @@ -423,6 +429,8 @@ void preparesReviewSupportTaskCompletionForManagedCaseFlags(String eventId) { ((ObjectNode) requestContent2).set("case_details_before", requestContent2.get("case_details").deepCopy()); when(featureToggleService.isCaseFlagsV2Enabled(anyString())).thenReturn(true); + when(supportTaskService.prepareManagedReviewSupportTasks(any(CaseData.class), any(CaseData.class))) + .thenReturn(Set.of("ReviewSupportRequestAdmin")); mvc.perform(post(SUPPORT_TASKS_URL) .content(requestContent2.toString()) @@ -432,6 +440,8 @@ void preparesReviewSupportTaskCompletionForManagedCaseFlags(String eventId) { verify(supportTaskService).prepareManagedReviewSupportTasks( any(CaseData.class), any(CaseData.class)); + verify(reviewSupportTaskCompletionService).completeTasks( + anyString(), eq(AUTH_TOKEN), eq(Set.of("ReviewSupportRequestAdmin"))); if ("manageFlags".equals(eventId)) { verify(supportTaskService).prepareArrangeSupportTask( any(CaseData.class), any(CaseData.class)); @@ -467,6 +477,8 @@ void appliesReviewedFlagAndPreparesCompletionAndArrangeTasks() { requestContent2.get("case_details").deepCopy()); when(featureToggleService.isCaseFlagsV2Enabled(anyString())).thenReturn(true); when(supportTaskService.applyReviewSupportRequest(any(CaseData.class))).thenReturn(true); + when(supportTaskService.prepareManagedReviewSupportTasks(any(CaseData.class), any(CaseData.class))) + .thenReturn(Set.of("ReviewSupportRequestAdmin")); mvc.perform(post(REVIEW_SUPPORT_REQUEST_ABOUT_TO_SUBMIT_URL) .content(requestContent2.toString()) @@ -477,6 +489,8 @@ void appliesReviewedFlagAndPreparesCompletionAndArrangeTasks() { verify(supportTaskService).prepareManagedReviewSupportTasks( any(CaseData.class), any(CaseData.class)); + verify(reviewSupportTaskCompletionService).completeTasks( + anyString(), eq(AUTH_TOKEN), eq(Set.of("ReviewSupportRequestAdmin"))); verify(supportTaskService).prepareArrangeSupportTask( any(CaseData.class), any(CaseData.class)); verify(caseManagementForCaseWorkerService).setNextListedDate(any(CaseData.class)); @@ -498,6 +512,7 @@ void rejectsReviewSupportRequestWhenNoFlagWasActioned() { verify(supportTaskService, never()).prepareManagedReviewSupportTasks( any(CaseData.class), nullable(CaseData.class)); + verifyNoInteractions(reviewSupportTaskCompletionService); verify(caseManagementForCaseWorkerService, never()).setNextListedDate(any(CaseData.class)); } diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java index 4d90619b7d..f8648dd60d 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java @@ -29,6 +29,9 @@ import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.EVENT_REVIEW_ADMIN_SUPPORT_REQUEST; import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.EVENT_REVIEW_JUDGE_SUPPORT_REQUEST; import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.EVENT_REVIEW_LEGAL_OFFICER_SUPPORT_REQUEST; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.TASK_TYPE_REVIEW_SUPPORT_ADMIN; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.TASK_TYPE_REVIEW_SUPPORT_JUDGE; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.TASK_TYPE_REVIEW_SUPPORT_LEGAL_OFFICER; class SupportTaskServiceTest { private static final String TASK_TYPE_ADMIN = "Admin"; @@ -97,10 +100,6 @@ void prepares_each_eligible_task_type_once_per_case(String flagCode, String task taskState(caseData).getLegalOfficerTaskRequired()); assertEquals(TASK_TYPE_JUDGE.equals(taskType) ? YES : null, taskState(caseData).getJudgeTaskRequired()); - assertNull(taskState(caseData).getAdminTaskCompletionRequired()); - assertNull(taskState(caseData).getLegalOfficerTaskCompletionRequired()); - assertNull(taskState(caseData).getJudgeTaskCompletionRequired()); - service.prepareReviewSupportTasks(caseData); assertNull(taskState(caseData).getAdminTaskRequired()); @@ -275,14 +274,12 @@ void completes_only_task_type_without_an_eligible_requested_flag() { .judgeTaskCreated(YES) .build()); - service.prepareManagedReviewSupportTasks(caseData, null); + final Set taskTypesToComplete = service.prepareManagedReviewSupportTasks(caseData, null); assertEquals(NO, taskState(caseData).getAdminTaskCreated()); - assertEquals(YES, taskState(caseData).getAdminTaskCompletionRequired()); assertEquals(YES, taskState(caseData).getJudgeTaskCreated()); - assertNull(taskState(caseData).getJudgeTaskCompletionRequired()); - assertEquals(NO, taskState(caseData).getLegalOfficerTaskCreated()); - assertEquals(YES, taskState(caseData).getLegalOfficerTaskCompletionRequired()); + assertNull(taskState(caseData).getLegalOfficerTaskCreated()); + assertEquals(Set.of(TASK_TYPE_REVIEW_SUPPORT_ADMIN), taskTypesToComplete); } @Test @@ -295,14 +292,13 @@ void keeps_task_active_when_another_party_has_an_eligible_requested_flag() { caseData.setSupportTaskState(SupportTaskState.builder() .adminTaskCreated(YES) .adminTaskRequired(YES) - .adminTaskCompletionRequired(YES) .build()); - service.prepareManagedReviewSupportTasks(caseData, null); + final Set taskTypesToComplete = service.prepareManagedReviewSupportTasks(caseData, null); assertEquals(YES, taskState(caseData).getAdminTaskCreated()); assertNull(taskState(caseData).getAdminTaskRequired()); - assertNull(taskState(caseData).getAdminTaskCompletionRequired()); + assertTrue(taskTypesToComplete.isEmpty()); } static Stream reviewTaskCategoryScenarios() { @@ -406,17 +402,17 @@ void completes_each_task_category_only_after_its_last_requested_flag_is_activate CaseData caseData = caseDataWithFlags(activeFlagCode, STATUS_ACTIVE, requestedFlagCode, STATUS_REQUESTED); setTaskCreated(taskState(caseData), taskType, CCD_TRUE); - service.prepareManagedReviewSupportTasks(caseData, null); + Set firstCompletion = service.prepareManagedReviewSupportTasks(caseData, null); assertEquals(CCD_TRUE, getTaskCreated(taskState(caseData), taskType)); - assertNull(getTaskCompletionRequired(taskState(caseData), taskType)); + assertTrue(firstCompletion.isEmpty()); activateRespondentFlag(caseData); - service.prepareManagedReviewSupportTasks(caseData, null); + Set secondCompletion = service.prepareManagedReviewSupportTasks(caseData, null); assertEquals(NO, getTaskCreated(taskState(caseData), taskType)); assertNull(getTaskRequired(taskState(caseData), taskType)); - assertEquals(YES, getTaskCompletionRequired(taskState(caseData), taskType)); + assertEquals(Set.of(reviewTaskType(taskType)), secondCompletion); } @ParameterizedTest @@ -443,10 +439,10 @@ void restores_boolean_created_state_from_before_data_and_completes_each_category setTaskCreated(taskState(caseDataBefore), taskType, CCD_TRUE); CaseData caseData = caseDataWithFlags(flagCode, STATUS_ACTIVE, secondFlagCode, STATUS_ACTIVE); - service.prepareManagedReviewSupportTasks(caseData, caseDataBefore); + Set taskTypesToComplete = service.prepareManagedReviewSupportTasks(caseData, caseDataBefore); assertEquals(NO, getTaskCreated(taskState(caseData), taskType)); - assertEquals(YES, getTaskCompletionRequired(taskState(caseData), taskType)); + assertEquals(Set.of(reviewTaskType(taskType)), taskTypesToComplete); } @ParameterizedTest @@ -470,10 +466,10 @@ void completes_each_task_category_for_every_non_requested_status( caseData.setSupportTaskState(new SupportTaskState()); setTaskCreated(taskState(caseData), taskType, CCD_TRUE); - service.prepareManagedReviewSupportTasks(caseData, null); + final Set taskTypesToComplete = service.prepareManagedReviewSupportTasks(caseData, null); assertEquals(NO, getTaskCreated(taskState(caseData), taskType)); - assertEquals(YES, getTaskCompletionRequired(taskState(caseData), taskType)); + assertEquals(Set.of(reviewTaskType(taskType)), taskTypesToComplete); } @Test @@ -490,14 +486,12 @@ void completes_only_categories_without_requested_flags_when_boolean_state_is_use .judgeTaskCreated(CCD_TRUE) .build()); - service.prepareManagedReviewSupportTasks(caseData, null); + final Set taskTypesToComplete = service.prepareManagedReviewSupportTasks(caseData, null); assertEquals(NO, taskState(caseData).getAdminTaskCreated()); - assertEquals(YES, taskState(caseData).getAdminTaskCompletionRequired()); assertEquals(CCD_TRUE, taskState(caseData).getLegalOfficerTaskCreated()); - assertNull(taskState(caseData).getLegalOfficerTaskCompletionRequired()); assertEquals(CCD_TRUE, taskState(caseData).getJudgeTaskCreated()); - assertNull(taskState(caseData).getJudgeTaskCompletionRequired()); + assertEquals(Set.of(TASK_TYPE_REVIEW_SUPPORT_ADMIN), taskTypesToComplete); } @Test @@ -520,10 +514,10 @@ void keeps_task_active_when_an_eligible_requested_flag_remains() { CaseData caseData = caseDataWithClaimantFlag("RA0033", STATUS_REQUESTED, false); caseData.setSupportTaskState(SupportTaskState.builder().adminTaskCreated(YES).build()); - service.prepareManagedReviewSupportTasks(caseData, null); + Set taskTypesToComplete = service.prepareManagedReviewSupportTasks(caseData, null); assertEquals(YES, taskState(caseData).getAdminTaskCreated()); - assertNull(taskState(caseData).getAdminTaskCompletionRequired()); + assertTrue(taskTypesToComplete.isEmpty()); } @Test @@ -535,14 +529,13 @@ void completes_created_tasks_when_party_flags_are_missing() { .judgeTaskCreated(YES) .build()); - service.prepareManagedReviewSupportTasks(caseData, null); + final Set taskTypesToComplete = service.prepareManagedReviewSupportTasks(caseData, null); assertEquals(NO, taskState(caseData).getAdminTaskCreated()); assertEquals(NO, taskState(caseData).getLegalOfficerTaskCreated()); assertEquals(NO, taskState(caseData).getJudgeTaskCreated()); - assertEquals(YES, taskState(caseData).getAdminTaskCompletionRequired()); - assertEquals(YES, taskState(caseData).getLegalOfficerTaskCompletionRequired()); - assertEquals(YES, taskState(caseData).getJudgeTaskCompletionRequired()); + assertEquals(Set.of(TASK_TYPE_REVIEW_SUPPORT_ADMIN, TASK_TYPE_REVIEW_SUPPORT_LEGAL_OFFICER, + TASK_TYPE_REVIEW_SUPPORT_JUDGE), taskTypesToComplete); } @Test @@ -551,10 +544,10 @@ void completes_judge_task_when_last_requested_flag_is_managed_and_current_state_ caseDataBefore.setSupportTaskState(SupportTaskState.builder().judgeTaskCreated(YES).build()); CaseData caseData = caseDataWithClaimantFlag("RA0038", STATUS_ACTIVE, false); - service.prepareManagedReviewSupportTasks(caseData, caseDataBefore); + Set taskTypesToComplete = service.prepareManagedReviewSupportTasks(caseData, caseDataBefore); assertEquals(NO, taskState(caseData).getJudgeTaskCreated()); - assertEquals(YES, taskState(caseData).getJudgeTaskCompletionRequired()); + assertEquals(Set.of(TASK_TYPE_REVIEW_SUPPORT_JUDGE), taskTypesToComplete); } static Stream reviewAndArrangeTaskScenarios() { @@ -574,10 +567,10 @@ void preservesReviewCompletionAndArrangeCreationInTheSameUpdate(String flagCode, caseData.setSupportTaskState(new SupportTaskState()); setTaskCreated(taskState(caseData), taskType, YES); - service.prepareManagedReviewSupportTasks(caseData, caseDataBefore); + Set taskTypesToComplete = service.prepareManagedReviewSupportTasks(caseData, caseDataBefore); service.prepareArrangeSupportTask(caseData, caseDataBefore); - assertEquals(YES, getTaskCompletionRequired(taskState(caseData), taskType)); + assertEquals(Set.of(reviewTaskType(taskType)), taskTypesToComplete); assertEquals(arrangeTaskName, taskState(caseData).getArrangeSupportTaskName()); } @@ -585,10 +578,10 @@ void preservesReviewCompletionAndArrangeCreationInTheSameUpdate(String flagCode, void completes_admin_task_when_created_marker_is_missing() { CaseData caseData = caseDataWithClaimantFlag("RA0041", STATUS_ACTIVE, false); - service.prepareManagedReviewSupportTasks(caseData, null); + Set taskTypesToComplete = service.prepareManagedReviewSupportTasks(caseData, null); assertEquals(NO, taskState(caseData).getAdminTaskCreated()); - assertEquals(YES, taskState(caseData).getAdminTaskCompletionRequired()); + assertEquals(Set.of(TASK_TYPE_REVIEW_SUPPORT_ADMIN), taskTypesToComplete); } @Test @@ -803,11 +796,11 @@ private static String getTaskRequired(SupportTaskState state, String taskType) { }; } - private static String getTaskCompletionRequired(SupportTaskState state, String taskType) { + private static String reviewTaskType(String taskType) { return switch (taskType) { - case TASK_TYPE_ADMIN -> state.getAdminTaskCompletionRequired(); - case TASK_TYPE_LEGAL_OFFICER -> state.getLegalOfficerTaskCompletionRequired(); - case TASK_TYPE_JUDGE -> state.getJudgeTaskCompletionRequired(); + case TASK_TYPE_ADMIN -> TASK_TYPE_REVIEW_SUPPORT_ADMIN; + case TASK_TYPE_LEGAL_OFFICER -> TASK_TYPE_REVIEW_SUPPORT_LEGAL_OFFICER; + case TASK_TYPE_JUDGE -> TASK_TYPE_REVIEW_SUPPORT_JUDGE; default -> throw new IllegalArgumentException("Unknown task type: " + taskType); }; } diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/ReviewSupportTaskCompletionServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/ReviewSupportTaskCompletionServiceTest.java new file mode 100644 index 0000000000..63df0b38ca --- /dev/null +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/ReviewSupportTaskCompletionServiceTest.java @@ -0,0 +1,151 @@ +package uk.gov.hmcts.ethos.replacement.docmosis.wa; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.NullAndEmptySource; +import org.junit.jupiter.params.provider.ValueSource; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import uk.gov.hmcts.ethos.replacement.docmosis.client.WaTaskApiClient; +import uk.gov.hmcts.ethos.replacement.docmosis.wa.model.TaskSearchParameter; +import uk.gov.hmcts.ethos.replacement.docmosis.wa.model.TaskSearchRequest; +import uk.gov.hmcts.ethos.replacement.docmosis.wa.model.TaskSearchResponse; +import uk.gov.hmcts.ethos.replacement.docmosis.wa.model.TerminateTaskRequest; +import uk.gov.hmcts.ethos.replacement.docmosis.wa.model.WaTask; +import uk.gov.hmcts.reform.authorisation.generators.AuthTokenGenerator; + +import java.util.List; +import java.util.Set; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class ReviewSupportTaskCompletionServiceTest { + private static final String CASE_ID = "1234567890123456"; + private static final String USER_TOKEN = "Bearer user-token"; + private static final String SERVICE_TOKEN = "service-token"; + private static final String ADMIN_TASK = "ReviewSupportRequestAdmin"; + private static final String JUDGE_TASK = "ReviewSupportRequestJudge"; + + @Mock + private WaTaskApiClient waTaskApiClient; + @Mock + private AuthTokenGenerator serviceAuthTokenGenerator; + + private ReviewSupportTaskCompletionService service; + + @BeforeEach + void setUp() { + service = new ReviewSupportTaskCompletionService(waTaskApiClient, serviceAuthTokenGenerator); + } + + @Test + void searchesActiveTasksForTheCaseAndRequestedTaskTypes() { + stubSearch(TaskSearchResponse.builder().tasks(List.of()).build()); + + service.completeTasks(CASE_ID, USER_TOKEN, Set.of(ADMIN_TASK, JUDGE_TASK)); + + ArgumentCaptor request = ArgumentCaptor.forClass(TaskSearchRequest.class); + verify(waTaskApiClient).searchTasks(eq(USER_TOKEN), eq(SERVICE_TOKEN), request.capture()); + List parameters = request.getValue().getSearchParameters(); + assertThat(parameters).extracting(TaskSearchParameter::getKey) + .containsExactly("case_id", "task_type", "state"); + assertThat(parameters.get(0).getValues()).containsExactly(CASE_ID); + assertThat(parameters.get(1).getValues()).containsExactlyInAnyOrder(ADMIN_TASK, JUDGE_TASK); + assertThat(parameters.get(2).getValues()).containsExactly("assigned", "unassigned"); + assertThat(parameters).extracting(TaskSearchParameter::getOperator).containsOnly("IN"); + } + + @Test + void terminatesEveryReturnedTaskWithCompletedReason() { + stubSearch(TaskSearchResponse.builder().tasks(List.of( + WaTask.builder().id("admin-id").type(ADMIN_TASK).build(), + WaTask.builder().id("judge-id").type(JUDGE_TASK).build())).build()); + + service.completeTasks(CASE_ID, USER_TOKEN, Set.of(ADMIN_TASK, JUDGE_TASK)); + + ArgumentCaptor taskIds = ArgumentCaptor.forClass(String.class); + ArgumentCaptor requests = ArgumentCaptor.forClass(TerminateTaskRequest.class); + verify(waTaskApiClient, times(2)).terminateTask(eq(SERVICE_TOKEN), taskIds.capture(), requests.capture()); + assertThat(taskIds.getAllValues()).containsExactlyInAnyOrder("admin-id", "judge-id"); + assertThat(requests.getAllValues()) + .extracting(request -> request.getTerminateInfo().getTerminateReason()) + .containsOnly("completed"); + } + + @Test + void continuesWhenOneTerminationFails() { + stubSearch(TaskSearchResponse.builder().tasks(List.of( + WaTask.builder().id("fails").type(ADMIN_TASK).build(), + WaTask.builder().id("succeeds").type(JUDGE_TASK).build())).build()); + doThrow(new IllegalStateException("unavailable")) + .when(waTaskApiClient).terminateTask(eq(SERVICE_TOKEN), eq("fails"), any()); + + service.completeTasks(CASE_ID, USER_TOKEN, Set.of(ADMIN_TASK, JUDGE_TASK)); + + verify(waTaskApiClient).terminateTask(eq(SERVICE_TOKEN), eq("succeeds"), any()); + } + + @Test + void doesNotPropagateSearchFailure() { + when(serviceAuthTokenGenerator.generate()).thenReturn(SERVICE_TOKEN); + when(waTaskApiClient.searchTasks(anyString(), anyString(), any())) + .thenThrow(new IllegalStateException("unavailable")); + + service.completeTasks(CASE_ID, USER_TOKEN, Set.of(ADMIN_TASK)); + + verify(waTaskApiClient, never()).terminateTask(anyString(), anyString(), any()); + } + + @Test + void toleratesMissingSearchResponseOrTaskList() { + stubSearch(null); + service.completeTasks(CASE_ID, USER_TOKEN, Set.of(ADMIN_TASK)); + verify(waTaskApiClient, never()).terminateTask(anyString(), anyString(), any()); + + when(waTaskApiClient.searchTasks(anyString(), anyString(), any())) + .thenReturn(TaskSearchResponse.builder().build()); + service.completeTasks(CASE_ID, USER_TOKEN, Set.of(ADMIN_TASK)); + verify(waTaskApiClient, never()).terminateTask(anyString(), anyString(), any()); + } + + @ParameterizedTest + @NullAndEmptySource + @ValueSource(strings = " ") + void skipsWhenCaseIdIsMissing(String caseId) { + service.completeTasks(caseId, USER_TOKEN, Set.of(ADMIN_TASK)); + verifyNoInteractions(waTaskApiClient, serviceAuthTokenGenerator); + } + + @ParameterizedTest + @NullAndEmptySource + @ValueSource(strings = " ") + void skipsWhenUserTokenIsMissing(String userToken) { + service.completeTasks(CASE_ID, userToken, Set.of(ADMIN_TASK)); + verifyNoInteractions(waTaskApiClient, serviceAuthTokenGenerator); + } + + @Test + void skipsWhenNoTaskTypesNeedCompletion() { + service.completeTasks(CASE_ID, USER_TOKEN, Set.of()); + service.completeTasks(CASE_ID, USER_TOKEN, null); + verifyNoInteractions(waTaskApiClient, serviceAuthTokenGenerator); + } + + private void stubSearch(TaskSearchResponse response) { + when(serviceAuthTokenGenerator.generate()).thenReturn(SERVICE_TOKEN); + when(waTaskApiClient.searchTasks(anyString(), anyString(), any())).thenReturn(response); + } +} From 16b18b5b01c6c285b9cc0afaa7412fdcd4ac97db Mon Sep 17 00:00:00 2001 From: sonny-hmcts Date: Thu, 17 Sep 2026 06:41:52 +0100 Subject: [PATCH 073/100] Update AuthorisationCaseField-CaseFlagsCaseLinking.json --- .../AuthorisationCaseField-CaseFlagsCaseLinking.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json index e1fb63e56a..26ce866491 100644 --- a/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json @@ -989,6 +989,12 @@ "UserRole": "[CREATOR]", "CRUD": "CRU" }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "respondentExternalFlags", + "UserRole": "[DEFENDANT]", + "CRUD": "CRU" + }, { "CaseTypeId": "ET_Scotland", "CaseFieldID": "supportTaskState", From b691361ae939e3a9941852d4f459038166535520 Mon Sep 17 00:00:00 2001 From: rajaram Date: Thu, 17 Sep 2026 09:33:30 +0100 Subject: [PATCH 074/100] Given access to judges for review support tasks --- ...horisationCaseEvent-CaseFlags-nonprod.json | 10 +- ...isationCaseField-CaseFlagsCaseLinking.json | 98 ++++++++++--------- ...isationCaseEvent-CaseFlagsCaseLinking.json | 8 +- ...isationCaseField-CaseFlagsCaseLinking.json | 98 ++++++++++--------- 4 files changed, 119 insertions(+), 95 deletions(-) diff --git a/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseEvent/AuthorisationCaseEvent-CaseFlags-nonprod.json b/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseEvent/AuthorisationCaseEvent-CaseFlags-nonprod.json index 27458d4467..b2feca10ca 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseEvent/AuthorisationCaseEvent-CaseFlags-nonprod.json +++ b/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseEvent/AuthorisationCaseEvent-CaseFlags-nonprod.json @@ -47,6 +47,12 @@ "UserRole": "caseworker-employment-englandwales", "CRUD": "CRU" }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseEventID": "reviewLOSupportRequest", + "UserRole": "caseworker-employment-etjudge-englandwales", + "CRUD": "CRU" + }, { "CaseTypeId": "ET_EnglandWales", "CaseEventID": "reviewJudgeSupportRequest", @@ -56,7 +62,7 @@ { "CaseTypeId": "ET_EnglandWales", "CaseEventID": "reviewJudgeSupportRequest", - "UserRole": "caseworker-employment-englandwales", + "UserRole": "caseworker-employment-etjudge-englandwales", "CRUD": "CRU" } -] \ No newline at end of file +] diff --git a/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json index 83d0f74b82..5eb6aa9cdc 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json @@ -27,7 +27,7 @@ "CaseTypeId": "ET_EnglandWales", "CaseFieldID": "claimantFlags", "UserRole": "caseworker-employment-etjudge-englandwales", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_EnglandWales", @@ -45,7 +45,7 @@ "CaseTypeId": "ET_EnglandWales", "CaseFieldID": "flagLauncher", "UserRole": "caseworker-employment-etjudge-englandwales", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_EnglandWales", @@ -63,7 +63,7 @@ "CaseTypeId": "ET_EnglandWales", "CaseFieldID": "respondentFlags", "UserRole": "caseworker-employment-etjudge-englandwales", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_EnglandWales", @@ -81,7 +81,7 @@ "CaseTypeId": "ET_EnglandWales", "CaseFieldID": "respondent1Flags", "UserRole": "caseworker-employment-etjudge-englandwales", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_EnglandWales", @@ -99,7 +99,7 @@ "CaseTypeId": "ET_EnglandWales", "CaseFieldID": "respondent2Flags", "UserRole": "caseworker-employment-etjudge-englandwales", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_EnglandWales", @@ -117,7 +117,7 @@ "CaseTypeId": "ET_EnglandWales", "CaseFieldID": "respondent3Flags", "UserRole": "caseworker-employment-etjudge-englandwales", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_EnglandWales", @@ -135,7 +135,7 @@ "CaseTypeId": "ET_EnglandWales", "CaseFieldID": "respondent4Flags", "UserRole": "caseworker-employment-etjudge-englandwales", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_EnglandWales", @@ -153,7 +153,7 @@ "CaseTypeId": "ET_EnglandWales", "CaseFieldID": "respondent5Flags", "UserRole": "caseworker-employment-etjudge-englandwales", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_EnglandWales", @@ -171,7 +171,7 @@ "CaseTypeId": "ET_EnglandWales", "CaseFieldID": "respondent6Flags", "UserRole": "caseworker-employment-etjudge-englandwales", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_EnglandWales", @@ -189,7 +189,7 @@ "CaseTypeId": "ET_EnglandWales", "CaseFieldID": "respondent7Flags", "UserRole": "caseworker-employment-etjudge-englandwales", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_EnglandWales", @@ -207,7 +207,7 @@ "CaseTypeId": "ET_EnglandWales", "CaseFieldID": "respondent8Flags", "UserRole": "caseworker-employment-etjudge-englandwales", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_EnglandWales", @@ -225,7 +225,7 @@ "CaseTypeId": "ET_EnglandWales", "CaseFieldID": "respondent9Flags", "UserRole": "caseworker-employment-etjudge-englandwales", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_EnglandWales", @@ -243,7 +243,7 @@ "CaseTypeId": "ET_EnglandWales", "CaseFieldID": "claimantRepresentativeFlags", "UserRole": "caseworker-employment-etjudge-englandwales", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_EnglandWales", @@ -261,7 +261,7 @@ "CaseTypeId": "ET_EnglandWales", "CaseFieldID": "representativeFlags", "UserRole": "caseworker-employment-etjudge-englandwales", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_EnglandWales", @@ -279,7 +279,7 @@ "CaseTypeId": "ET_EnglandWales", "CaseFieldID": "representative1Flags", "UserRole": "caseworker-employment-etjudge-englandwales", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_EnglandWales", @@ -297,7 +297,7 @@ "CaseTypeId": "ET_EnglandWales", "CaseFieldID": "representative2Flags", "UserRole": "caseworker-employment-etjudge-englandwales", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_EnglandWales", @@ -315,7 +315,7 @@ "CaseTypeId": "ET_EnglandWales", "CaseFieldID": "representative3Flags", "UserRole": "caseworker-employment-etjudge-englandwales", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_EnglandWales", @@ -333,7 +333,7 @@ "CaseTypeId": "ET_EnglandWales", "CaseFieldID": "representative4Flags", "UserRole": "caseworker-employment-etjudge-englandwales", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_EnglandWales", @@ -351,7 +351,7 @@ "CaseTypeId": "ET_EnglandWales", "CaseFieldID": "representative5Flags", "UserRole": "caseworker-employment-etjudge-englandwales", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_EnglandWales", @@ -369,7 +369,7 @@ "CaseTypeId": "ET_EnglandWales", "CaseFieldID": "representative6Flags", "UserRole": "caseworker-employment-etjudge-englandwales", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_EnglandWales", @@ -387,7 +387,7 @@ "CaseTypeId": "ET_EnglandWales", "CaseFieldID": "representative7Flags", "UserRole": "caseworker-employment-etjudge-englandwales", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_EnglandWales", @@ -405,7 +405,7 @@ "CaseTypeId": "ET_EnglandWales", "CaseFieldID": "representative8Flags", "UserRole": "caseworker-employment-etjudge-englandwales", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_EnglandWales", @@ -423,7 +423,7 @@ "CaseTypeId": "ET_EnglandWales", "CaseFieldID": "representative9Flags", "UserRole": "caseworker-employment-etjudge-englandwales", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_EnglandWales", @@ -579,73 +579,73 @@ "CaseTypeId": "ET_EnglandWales", "CaseFieldID": "flagLauncherExternal", "UserRole": "caseworker-employment-etjudge-englandwales", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_EnglandWales", "CaseFieldID": "claimantExternalFlags", "UserRole": "caseworker-employment-etjudge-englandwales", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_EnglandWales", "CaseFieldID": "respondentExternalFlags", "UserRole": "caseworker-employment-etjudge-englandwales", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_EnglandWales", "CaseFieldID": "respondent1ExternalFlags", "UserRole": "caseworker-employment-etjudge-englandwales", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_EnglandWales", "CaseFieldID": "respondent2ExternalFlags", "UserRole": "caseworker-employment-etjudge-englandwales", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_EnglandWales", "CaseFieldID": "respondent3ExternalFlags", "UserRole": "caseworker-employment-etjudge-englandwales", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_EnglandWales", "CaseFieldID": "respondent4ExternalFlags", "UserRole": "caseworker-employment-etjudge-englandwales", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_EnglandWales", "CaseFieldID": "respondent5ExternalFlags", "UserRole": "caseworker-employment-etjudge-englandwales", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_EnglandWales", "CaseFieldID": "respondent6ExternalFlags", "UserRole": "caseworker-employment-etjudge-englandwales", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_EnglandWales", "CaseFieldID": "respondent7ExternalFlags", "UserRole": "caseworker-employment-etjudge-englandwales", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_EnglandWales", "CaseFieldID": "respondent8ExternalFlags", "UserRole": "caseworker-employment-etjudge-englandwales", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_EnglandWales", "CaseFieldID": "respondent9ExternalFlags", "UserRole": "caseworker-employment-etjudge-englandwales", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_EnglandWales", @@ -855,67 +855,67 @@ "CaseTypeId": "ET_EnglandWales", "CaseFieldID": "claimantRepresentativeExternalFlags", "UserRole": "caseworker-employment-etjudge-englandwales", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_EnglandWales", "CaseFieldID": "representativeExternalFlags", "UserRole": "caseworker-employment-etjudge-englandwales", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_EnglandWales", "CaseFieldID": "representative1ExternalFlags", "UserRole": "caseworker-employment-etjudge-englandwales", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_EnglandWales", "CaseFieldID": "representative2ExternalFlags", "UserRole": "caseworker-employment-etjudge-englandwales", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_EnglandWales", "CaseFieldID": "representative3ExternalFlags", "UserRole": "caseworker-employment-etjudge-englandwales", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_EnglandWales", "CaseFieldID": "representative4ExternalFlags", "UserRole": "caseworker-employment-etjudge-englandwales", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_EnglandWales", "CaseFieldID": "representative5ExternalFlags", "UserRole": "caseworker-employment-etjudge-englandwales", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_EnglandWales", "CaseFieldID": "representative6ExternalFlags", "UserRole": "caseworker-employment-etjudge-englandwales", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_EnglandWales", "CaseFieldID": "representative7ExternalFlags", "UserRole": "caseworker-employment-etjudge-englandwales", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_EnglandWales", "CaseFieldID": "representative8ExternalFlags", "UserRole": "caseworker-employment-etjudge-englandwales", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_EnglandWales", "CaseFieldID": "representative9ExternalFlags", "UserRole": "caseworker-employment-etjudge-englandwales", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_EnglandWales", @@ -1018,5 +1018,11 @@ "CaseFieldID": "reviewSupportRequestFlags", "UserRole": "caseworker-employment-englandwales", "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseFieldID": "reviewSupportRequestFlags", + "UserRole": "caseworker-employment-etjudge-englandwales", + "CRUD": "CRUD" } ] diff --git a/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseEvent/AuthorisationCaseEvent-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseEvent/AuthorisationCaseEvent-CaseFlagsCaseLinking.json index ef1aec7265..eb612c37de 100644 --- a/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseEvent/AuthorisationCaseEvent-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseEvent/AuthorisationCaseEvent-CaseFlagsCaseLinking.json @@ -89,6 +89,12 @@ "UserRole": "caseworker-employment-scotland", "CRUD": "CRU" }, + { + "CaseTypeId": "ET_Scotland", + "CaseEventID": "reviewLOSupportRequest", + "UserRole": "caseworker-employment-etjudge-scotland", + "CRUD": "CRU" + }, { "CaseTypeId": "ET_Scotland", "CaseEventID": "reviewJudgeSupportRequest", @@ -98,7 +104,7 @@ { "CaseTypeId": "ET_Scotland", "CaseEventID": "reviewJudgeSupportRequest", - "UserRole": "caseworker-employment-scotland", + "UserRole": "caseworker-employment-etjudge-scotland", "CRUD": "CRU" } ] diff --git a/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json index 26ce866491..aeb97c115a 100644 --- a/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseField/AuthorisationCaseField-CaseFlagsCaseLinking.json @@ -33,7 +33,7 @@ "CaseTypeId": "ET_Scotland", "CaseFieldID": "claimantFlags", "UserRole": "caseworker-employment-etjudge-scotland", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_Scotland", @@ -51,7 +51,7 @@ "CaseTypeId": "ET_Scotland", "CaseFieldID": "flagLauncher", "UserRole": "caseworker-employment-etjudge-scotland", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_Scotland", @@ -69,7 +69,7 @@ "CaseTypeId": "ET_Scotland", "CaseFieldID": "respondentFlags", "UserRole": "caseworker-employment-etjudge-scotland", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_Scotland", @@ -81,7 +81,7 @@ "CaseTypeId": "ET_Scotland", "CaseFieldID": "respondent1Flags", "UserRole": "caseworker-employment-etjudge-scotland", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_Scotland", @@ -99,7 +99,7 @@ "CaseTypeId": "ET_Scotland", "CaseFieldID": "respondent2Flags", "UserRole": "caseworker-employment-etjudge-scotland", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_Scotland", @@ -117,7 +117,7 @@ "CaseTypeId": "ET_Scotland", "CaseFieldID": "respondent3Flags", "UserRole": "caseworker-employment-etjudge-scotland", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_Scotland", @@ -135,7 +135,7 @@ "CaseTypeId": "ET_Scotland", "CaseFieldID": "respondent4Flags", "UserRole": "caseworker-employment-etjudge-scotland", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_Scotland", @@ -153,7 +153,7 @@ "CaseTypeId": "ET_Scotland", "CaseFieldID": "respondent5Flags", "UserRole": "caseworker-employment-etjudge-scotland", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_Scotland", @@ -171,7 +171,7 @@ "CaseTypeId": "ET_Scotland", "CaseFieldID": "respondent6Flags", "UserRole": "caseworker-employment-etjudge-scotland", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_Scotland", @@ -189,7 +189,7 @@ "CaseTypeId": "ET_Scotland", "CaseFieldID": "respondent7Flags", "UserRole": "caseworker-employment-etjudge-scotland", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_Scotland", @@ -207,7 +207,7 @@ "CaseTypeId": "ET_Scotland", "CaseFieldID": "respondent8Flags", "UserRole": "caseworker-employment-etjudge-scotland", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_Scotland", @@ -225,7 +225,7 @@ "CaseTypeId": "ET_Scotland", "CaseFieldID": "respondent9Flags", "UserRole": "caseworker-employment-etjudge-scotland", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_Scotland", @@ -243,7 +243,7 @@ "CaseTypeId": "ET_Scotland", "CaseFieldID": "claimantRepresentativeFlags", "UserRole": "caseworker-employment-etjudge-scotland", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_Scotland", @@ -261,7 +261,7 @@ "CaseTypeId": "ET_Scotland", "CaseFieldID": "representativeFlags", "UserRole": "caseworker-employment-etjudge-scotland", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_Scotland", @@ -279,7 +279,7 @@ "CaseTypeId": "ET_Scotland", "CaseFieldID": "representative1Flags", "UserRole": "caseworker-employment-etjudge-scotland", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_Scotland", @@ -297,7 +297,7 @@ "CaseTypeId": "ET_Scotland", "CaseFieldID": "representative2Flags", "UserRole": "caseworker-employment-etjudge-scotland", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_Scotland", @@ -315,7 +315,7 @@ "CaseTypeId": "ET_Scotland", "CaseFieldID": "representative3Flags", "UserRole": "caseworker-employment-etjudge-scotland", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_Scotland", @@ -333,7 +333,7 @@ "CaseTypeId": "ET_Scotland", "CaseFieldID": "representative4Flags", "UserRole": "caseworker-employment-etjudge-scotland", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_Scotland", @@ -351,7 +351,7 @@ "CaseTypeId": "ET_Scotland", "CaseFieldID": "representative5Flags", "UserRole": "caseworker-employment-etjudge-scotland", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_Scotland", @@ -369,7 +369,7 @@ "CaseTypeId": "ET_Scotland", "CaseFieldID": "representative6Flags", "UserRole": "caseworker-employment-etjudge-scotland", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_Scotland", @@ -387,7 +387,7 @@ "CaseTypeId": "ET_Scotland", "CaseFieldID": "representative7Flags", "UserRole": "caseworker-employment-etjudge-scotland", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_Scotland", @@ -405,7 +405,7 @@ "CaseTypeId": "ET_Scotland", "CaseFieldID": "representative8Flags", "UserRole": "caseworker-employment-etjudge-scotland", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_Scotland", @@ -423,7 +423,7 @@ "CaseTypeId": "ET_Scotland", "CaseFieldID": "representative9Flags", "UserRole": "caseworker-employment-etjudge-scotland", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_Scotland", @@ -711,139 +711,139 @@ "CaseTypeId": "ET_Scotland", "CaseFieldID": "flagLauncherExternal", "UserRole": "caseworker-employment-etjudge-scotland", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_Scotland", "CaseFieldID": "claimantExternalFlags", "UserRole": "caseworker-employment-etjudge-scotland", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_Scotland", "CaseFieldID": "respondentExternalFlags", "UserRole": "caseworker-employment-etjudge-scotland", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_Scotland", "CaseFieldID": "respondent1ExternalFlags", "UserRole": "caseworker-employment-etjudge-scotland", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_Scotland", "CaseFieldID": "respondent2ExternalFlags", "UserRole": "caseworker-employment-etjudge-scotland", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_Scotland", "CaseFieldID": "respondent3ExternalFlags", "UserRole": "caseworker-employment-etjudge-scotland", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_Scotland", "CaseFieldID": "respondent4ExternalFlags", "UserRole": "caseworker-employment-etjudge-scotland", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_Scotland", "CaseFieldID": "respondent5ExternalFlags", "UserRole": "caseworker-employment-etjudge-scotland", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_Scotland", "CaseFieldID": "respondent6ExternalFlags", "UserRole": "caseworker-employment-etjudge-scotland", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_Scotland", "CaseFieldID": "respondent7ExternalFlags", "UserRole": "caseworker-employment-etjudge-scotland", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_Scotland", "CaseFieldID": "respondent8ExternalFlags", "UserRole": "caseworker-employment-etjudge-scotland", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_Scotland", "CaseFieldID": "respondent9ExternalFlags", "UserRole": "caseworker-employment-etjudge-scotland", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_Scotland", "CaseFieldID": "claimantRepresentativeExternalFlags", "UserRole": "caseworker-employment-etjudge-scotland", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_Scotland", "CaseFieldID": "representativeExternalFlags", "UserRole": "caseworker-employment-etjudge-scotland", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_Scotland", "CaseFieldID": "representative1ExternalFlags", "UserRole": "caseworker-employment-etjudge-scotland", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_Scotland", "CaseFieldID": "representative2ExternalFlags", "UserRole": "caseworker-employment-etjudge-scotland", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_Scotland", "CaseFieldID": "representative3ExternalFlags", "UserRole": "caseworker-employment-etjudge-scotland", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_Scotland", "CaseFieldID": "representative4ExternalFlags", "UserRole": "caseworker-employment-etjudge-scotland", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_Scotland", "CaseFieldID": "representative5ExternalFlags", "UserRole": "caseworker-employment-etjudge-scotland", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_Scotland", "CaseFieldID": "representative6ExternalFlags", "UserRole": "caseworker-employment-etjudge-scotland", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_Scotland", "CaseFieldID": "representative7ExternalFlags", "UserRole": "caseworker-employment-etjudge-scotland", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_Scotland", "CaseFieldID": "representative8ExternalFlags", "UserRole": "caseworker-employment-etjudge-scotland", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_Scotland", "CaseFieldID": "representative9ExternalFlags", "UserRole": "caseworker-employment-etjudge-scotland", - "CRUD": "R" + "CRUD": "CRU" }, { "CaseTypeId": "ET_Scotland", @@ -1018,5 +1018,11 @@ "CaseFieldID": "reviewSupportRequestFlags", "UserRole": "caseworker-employment-scotland", "CRUD": "CRUD" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseFieldID": "reviewSupportRequestFlags", + "UserRole": "caseworker-employment-etjudge-scotland", + "CRUD": "CRUD" } ] From d13a7449f7d38481db5e82b68720d0e1380b2b7f Mon Sep 17 00:00:00 2001 From: rajaram Date: Thu, 17 Sep 2026 10:38:15 +0100 Subject: [PATCH 075/100] Given access to judges for review support tasks --- .../AuthorisationCaseEvent-CaseFlags-nonprod.json | 6 ------ .../AuthorisationCaseEvent-CaseFlagsCaseLinking.json | 6 ------ 2 files changed, 12 deletions(-) diff --git a/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseEvent/AuthorisationCaseEvent-CaseFlags-nonprod.json b/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseEvent/AuthorisationCaseEvent-CaseFlags-nonprod.json index b2feca10ca..2004801726 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseEvent/AuthorisationCaseEvent-CaseFlags-nonprod.json +++ b/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseEvent/AuthorisationCaseEvent-CaseFlags-nonprod.json @@ -47,12 +47,6 @@ "UserRole": "caseworker-employment-englandwales", "CRUD": "CRU" }, - { - "CaseTypeId": "ET_EnglandWales", - "CaseEventID": "reviewLOSupportRequest", - "UserRole": "caseworker-employment-etjudge-englandwales", - "CRUD": "CRU" - }, { "CaseTypeId": "ET_EnglandWales", "CaseEventID": "reviewJudgeSupportRequest", diff --git a/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseEvent/AuthorisationCaseEvent-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseEvent/AuthorisationCaseEvent-CaseFlagsCaseLinking.json index eb612c37de..656ef3f3aa 100644 --- a/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseEvent/AuthorisationCaseEvent-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseEvent/AuthorisationCaseEvent-CaseFlagsCaseLinking.json @@ -89,12 +89,6 @@ "UserRole": "caseworker-employment-scotland", "CRUD": "CRU" }, - { - "CaseTypeId": "ET_Scotland", - "CaseEventID": "reviewLOSupportRequest", - "UserRole": "caseworker-employment-etjudge-scotland", - "CRUD": "CRU" - }, { "CaseTypeId": "ET_Scotland", "CaseEventID": "reviewJudgeSupportRequest", From 301b628b4e65f32b6f7fb653bee444807413a7f9 Mon Sep 17 00:00:00 2001 From: hmcts-jenkins-d-to-i <62423932+hmcts-jenkins-d-to-i[bot]@users.noreply.github.com> Date: Thu, 17 Sep 2026 09:40:08 +0000 Subject: [PATCH 076/100] Bumping chart version/ fixing aliases --- charts/et-cos/Chart.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/et-cos/Chart.yaml b/charts/et-cos/Chart.yaml index 77b873d5bb..df116faf87 100644 --- a/charts/et-cos/Chart.yaml +++ b/charts/et-cos/Chart.yaml @@ -1,7 +1,7 @@ apiVersion: v2 name: et-cos home: https://github.com/hmcts/et-ccd-callbacks -version: 0.0.76 +version: 0.0.77 description: HMCTS Employment Tribunals CCD Callbacks service maintainers: - name: HMCTS Employment Tribunals Team From 993afc88551ff1c588dec7e171432aa2582f4bb0 Mon Sep 17 00:00:00 2001 From: rajaram Date: Thu, 17 Sep 2026 12:33:21 +0100 Subject: [PATCH 077/100] Used complete task in WA instead of terminate --- .../docmosis/client/WaTaskApiClient.java | 10 ++++----- .../ReviewSupportTaskCompletionService.java | 12 +++------- .../docmosis/wa/model/TerminateInfo.java | 14 ------------ .../wa/model/TerminateTaskRequest.java | 14 ------------ ...eviewSupportTaskCompletionServiceTest.java | 22 ++++++++----------- 5 files changed, 16 insertions(+), 56 deletions(-) delete mode 100644 src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/model/TerminateInfo.java delete mode 100644 src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/model/TerminateTaskRequest.java diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/client/WaTaskApiClient.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/client/WaTaskApiClient.java index 8137ab633b..7bd6b8c5df 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/client/WaTaskApiClient.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/client/WaTaskApiClient.java @@ -3,14 +3,12 @@ import org.springframework.cloud.openfeign.FeignClient; import org.springframework.cloud.openfeign.FeignClientProperties; import org.springframework.http.HttpHeaders; -import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; import uk.gov.hmcts.ethos.replacement.docmosis.wa.model.TaskSearchRequest; import uk.gov.hmcts.ethos.replacement.docmosis.wa.model.TaskSearchResponse; -import uk.gov.hmcts.ethos.replacement.docmosis.wa.model.TerminateTaskRequest; @FeignClient(name = "wa-task-management-api", url = "${wa.task-management.api.url}", configuration = FeignClientProperties.FeignClientConfiguration.class) @@ -22,9 +20,9 @@ TaskSearchResponse searchTasks( @RequestHeader("ServiceAuthorization") String serviceAuthorization, @RequestBody TaskSearchRequest searchRequest); - @DeleteMapping(value = "/task/{taskId}", consumes = "application/json") - void terminateTask( + @PostMapping(value = "/task/{task-id}/complete", consumes = "application/json") + void completeTask( + @RequestHeader(HttpHeaders.AUTHORIZATION) String authorization, @RequestHeader("ServiceAuthorization") String serviceAuthorization, - @PathVariable("taskId") String taskId, - @RequestBody TerminateTaskRequest terminateTaskRequest); + @PathVariable("task-id") String taskId); } diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/ReviewSupportTaskCompletionService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/ReviewSupportTaskCompletionService.java index 9af1d056d8..107a88d121 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/ReviewSupportTaskCompletionService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/ReviewSupportTaskCompletionService.java @@ -7,8 +7,6 @@ import uk.gov.hmcts.ethos.replacement.docmosis.wa.model.TaskSearchParameter; import uk.gov.hmcts.ethos.replacement.docmosis.wa.model.TaskSearchRequest; import uk.gov.hmcts.ethos.replacement.docmosis.wa.model.TaskSearchResponse; -import uk.gov.hmcts.ethos.replacement.docmosis.wa.model.TerminateInfo; -import uk.gov.hmcts.ethos.replacement.docmosis.wa.model.TerminateTaskRequest; import uk.gov.hmcts.ethos.replacement.docmosis.wa.model.WaTask; import uk.gov.hmcts.reform.authorisation.generators.AuthTokenGenerator; @@ -22,7 +20,6 @@ @Slf4j public class ReviewSupportTaskCompletionService { private static final String OPERATOR_IN = "IN"; - private static final String TERMINATE_REASON_COMPLETED = "completed"; private static final List ACTIVE_TASK_STATES = List.of("assigned", "unassigned"); private final WaTaskApiClient waTaskApiClient; @@ -37,7 +34,7 @@ public void completeTasks(String caseId, String userToken, Set taskTypes String serviceToken = serviceAuthTokenGenerator.generate(); List tasks = findActiveTasks(caseId, userToken, serviceToken, taskTypes); log.info("Case {}: {} active Review Support task(s) to complete", caseId, tasks.size()); - tasks.forEach(task -> terminate(task, caseId, serviceToken)); + tasks.forEach(task -> complete(task, caseId, userToken, serviceToken)); } catch (Exception e) { log.error("Error completing Review Support tasks on case {}: {}", caseId, e.getMessage(), e); } @@ -55,12 +52,9 @@ private List findActiveTasks(String caseId, String userToken, String ser return response == null || response.getTasks() == null ? List.of() : response.getTasks(); } - private void terminate(WaTask task, String caseId, String serviceToken) { - TerminateTaskRequest request = TerminateTaskRequest.builder() - .terminateInfo(TerminateInfo.builder().terminateReason(TERMINATE_REASON_COMPLETED).build()) - .build(); + private void complete(WaTask task, String caseId, String userToken, String serviceToken) { try { - waTaskApiClient.terminateTask(serviceToken, task.getId(), request); + waTaskApiClient.completeTask(userToken, serviceToken, task.getId()); log.info("Completed task {} ({}) on case {}", task.getId(), task.getType(), caseId); } catch (Exception e) { log.error("Could not complete task {} ({}) on case {}: {}", diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/model/TerminateInfo.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/model/TerminateInfo.java deleted file mode 100644 index df751513c4..0000000000 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/model/TerminateInfo.java +++ /dev/null @@ -1,14 +0,0 @@ -package uk.gov.hmcts.ethos.replacement.docmosis.wa.model; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.Builder; -import lombok.Data; -import lombok.extern.jackson.Jacksonized; - -@Data -@Builder -@Jacksonized -public class TerminateInfo { - @JsonProperty("terminate_reason") - private String terminateReason; -} diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/model/TerminateTaskRequest.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/model/TerminateTaskRequest.java deleted file mode 100644 index 506fd12a1e..0000000000 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/model/TerminateTaskRequest.java +++ /dev/null @@ -1,14 +0,0 @@ -package uk.gov.hmcts.ethos.replacement.docmosis.wa.model; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.Builder; -import lombok.Data; -import lombok.extern.jackson.Jacksonized; - -@Data -@Builder -@Jacksonized -public class TerminateTaskRequest { - @JsonProperty("terminate_info") - private TerminateInfo terminateInfo; -} diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/ReviewSupportTaskCompletionServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/ReviewSupportTaskCompletionServiceTest.java index 63df0b38ca..799f5da470 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/ReviewSupportTaskCompletionServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/ReviewSupportTaskCompletionServiceTest.java @@ -13,7 +13,6 @@ import uk.gov.hmcts.ethos.replacement.docmosis.wa.model.TaskSearchParameter; import uk.gov.hmcts.ethos.replacement.docmosis.wa.model.TaskSearchRequest; import uk.gov.hmcts.ethos.replacement.docmosis.wa.model.TaskSearchResponse; -import uk.gov.hmcts.ethos.replacement.docmosis.wa.model.TerminateTaskRequest; import uk.gov.hmcts.ethos.replacement.docmosis.wa.model.WaTask; import uk.gov.hmcts.reform.authorisation.generators.AuthTokenGenerator; @@ -69,7 +68,7 @@ void searchesActiveTasksForTheCaseAndRequestedTaskTypes() { } @Test - void terminatesEveryReturnedTaskWithCompletedReason() { + void completesEveryReturnedTask() { stubSearch(TaskSearchResponse.builder().tasks(List.of( WaTask.builder().id("admin-id").type(ADMIN_TASK).build(), WaTask.builder().id("judge-id").type(JUDGE_TASK).build())).build()); @@ -77,25 +76,22 @@ void terminatesEveryReturnedTaskWithCompletedReason() { service.completeTasks(CASE_ID, USER_TOKEN, Set.of(ADMIN_TASK, JUDGE_TASK)); ArgumentCaptor taskIds = ArgumentCaptor.forClass(String.class); - ArgumentCaptor requests = ArgumentCaptor.forClass(TerminateTaskRequest.class); - verify(waTaskApiClient, times(2)).terminateTask(eq(SERVICE_TOKEN), taskIds.capture(), requests.capture()); + verify(waTaskApiClient, times(2)) + .completeTask(eq(USER_TOKEN), eq(SERVICE_TOKEN), taskIds.capture()); assertThat(taskIds.getAllValues()).containsExactlyInAnyOrder("admin-id", "judge-id"); - assertThat(requests.getAllValues()) - .extracting(request -> request.getTerminateInfo().getTerminateReason()) - .containsOnly("completed"); } @Test - void continuesWhenOneTerminationFails() { + void continuesWhenOneCompletionFails() { stubSearch(TaskSearchResponse.builder().tasks(List.of( WaTask.builder().id("fails").type(ADMIN_TASK).build(), WaTask.builder().id("succeeds").type(JUDGE_TASK).build())).build()); doThrow(new IllegalStateException("unavailable")) - .when(waTaskApiClient).terminateTask(eq(SERVICE_TOKEN), eq("fails"), any()); + .when(waTaskApiClient).completeTask(eq(USER_TOKEN), eq(SERVICE_TOKEN), eq("fails")); service.completeTasks(CASE_ID, USER_TOKEN, Set.of(ADMIN_TASK, JUDGE_TASK)); - verify(waTaskApiClient).terminateTask(eq(SERVICE_TOKEN), eq("succeeds"), any()); + verify(waTaskApiClient).completeTask(eq(USER_TOKEN), eq(SERVICE_TOKEN), eq("succeeds")); } @Test @@ -106,19 +102,19 @@ void doesNotPropagateSearchFailure() { service.completeTasks(CASE_ID, USER_TOKEN, Set.of(ADMIN_TASK)); - verify(waTaskApiClient, never()).terminateTask(anyString(), anyString(), any()); + verify(waTaskApiClient, never()).completeTask(anyString(), anyString(), anyString()); } @Test void toleratesMissingSearchResponseOrTaskList() { stubSearch(null); service.completeTasks(CASE_ID, USER_TOKEN, Set.of(ADMIN_TASK)); - verify(waTaskApiClient, never()).terminateTask(anyString(), anyString(), any()); + verify(waTaskApiClient, never()).completeTask(anyString(), anyString(), anyString()); when(waTaskApiClient.searchTasks(anyString(), anyString(), any())) .thenReturn(TaskSearchResponse.builder().build()); service.completeTasks(CASE_ID, USER_TOKEN, Set.of(ADMIN_TASK)); - verify(waTaskApiClient, never()).terminateTask(anyString(), anyString(), any()); + verify(waTaskApiClient, never()).completeTask(anyString(), anyString(), anyString()); } @ParameterizedTest From 8e2022eb32edf7317f83cc1c007ab5540dc87f58 Mon Sep 17 00:00:00 2001 From: rajaram Date: Thu, 17 Sep 2026 17:10:56 +0100 Subject: [PATCH 078/100] Generate review and arrange support tasks for selective others option --- .../config/SupportTaskConfiguration.java | 18 +++ .../docmosis/service/SupportTaskService.java | 107 +++++++++---- src/main/resources/support-tasks.yml | 53 ++++++- .../config/SupportTaskConfigurationTest.java | 26 +++- .../service/SupportTaskServiceTest.java | 141 +++++++++++++++++- 5 files changed, 297 insertions(+), 48 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/config/SupportTaskConfiguration.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/config/SupportTaskConfiguration.java index ed4d843bc9..fcccd77542 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/config/SupportTaskConfiguration.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/config/SupportTaskConfiguration.java @@ -5,6 +5,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; +import java.util.List; import java.util.Map; import java.util.Set; @@ -23,10 +24,27 @@ public static class Review { private Set adminFlagCodes = Set.of(); private Set legalOfficerFlagCodes = Set.of(); private Set judgeFlagCodes = Set.of(); + private List adminPathFlags = List.of(); + private List legalOfficerPathFlags = List.of(); + private List judgePathFlags = List.of(); } @Data public static class Arrange { private Map flagTitles = Map.of(); + private List pathFlags = List.of(); + } + + @Data + public static class PathFlag { + private String flagCode; + private List path = List.of(); + } + + @Data + public static class ArrangePathFlag { + private String flagCode; + private List path = List.of(); + private String taskTitle; } } diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java index 8e7410bbc0..80c0294056 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java @@ -10,6 +10,8 @@ import uk.gov.hmcts.et.common.model.ccd.types.CaseFlagsType; import uk.gov.hmcts.et.common.model.ccd.types.SupportTaskState; import uk.gov.hmcts.ethos.replacement.docmosis.config.SupportTaskConfiguration; +import uk.gov.hmcts.ethos.replacement.docmosis.config.SupportTaskConfiguration.ArrangePathFlag; +import uk.gov.hmcts.ethos.replacement.docmosis.config.SupportTaskConfiguration.PathFlag; import java.util.Comparator; import java.util.HashMap; @@ -107,16 +109,16 @@ public Set prepareManagedReviewSupportTasks(CaseData caseData, CaseData .toList(); Set taskTypesToComplete = new LinkedHashSet<>(); - if (updateTaskState(flags, configuration.getReview().getAdminFlagCodes(), taskState.getAdminTaskCreated(), + if (updateTaskState(flags, adminReviewFlag(), taskState.getAdminTaskCreated(), taskState::setAdminTaskCreated)) { taskTypesToComplete.add(TASK_TYPE_REVIEW_SUPPORT_ADMIN); } - if (updateTaskState(flags, configuration.getReview().getLegalOfficerFlagCodes(), + if (updateTaskState(flags, legalOfficerReviewFlag(), taskState.getLegalOfficerTaskCreated(), taskState::setLegalOfficerTaskCreated)) { taskTypesToComplete.add(TASK_TYPE_REVIEW_SUPPORT_LEGAL_OFFICER); } - if (updateTaskState(flags, configuration.getReview().getJudgeFlagCodes(), taskState.getJudgeTaskCreated(), + if (updateTaskState(flags, judgeReviewFlag(), taskState.getJudgeTaskCreated(), taskState::setJudgeTaskCreated)) { taskTypesToComplete.add(TASK_TYPE_REVIEW_SUPPORT_JUDGE); } @@ -124,9 +126,9 @@ public Set prepareManagedReviewSupportTasks(CaseData caseData, CaseData } public void prepareReviewSupportRequest(CaseData caseData, String eventId) { - Set eligibleCodes = reviewFlagCodes(eventId); + Predicate eligibleFlag = reviewFlag(eventId); ListTypeItem selectedFlags = allPartyFlagSections(caseData.getAllPartyFlags()) - .map(flags -> requestedFlags(flags, eligibleCodes)) + .map(flags -> requestedFlags(flags, eligibleFlag)) .filter(flags -> !flags.getDetails().isEmpty()) .map(GenericTypeItem::from) .collect(Collectors.toCollection(ListTypeItem::new)); @@ -160,23 +162,22 @@ public boolean applyReviewSupportRequest(CaseData caseData) { return !updatedFlags.isEmpty(); } - private Set reviewFlagCodes(String eventId) { + private Predicate reviewFlag(String eventId) { return switch (eventId) { - case EVENT_REVIEW_ADMIN_SUPPORT_REQUEST -> configuration.getReview().getAdminFlagCodes(); - case EVENT_REVIEW_LEGAL_OFFICER_SUPPORT_REQUEST -> - configuration.getReview().getLegalOfficerFlagCodes(); - case EVENT_REVIEW_JUDGE_SUPPORT_REQUEST -> configuration.getReview().getJudgeFlagCodes(); - default -> Set.of(); + case EVENT_REVIEW_ADMIN_SUPPORT_REQUEST -> adminReviewFlag(); + case EVENT_REVIEW_LEGAL_OFFICER_SUPPORT_REQUEST -> legalOfficerReviewFlag(); + case EVENT_REVIEW_JUDGE_SUPPORT_REQUEST -> judgeReviewFlag(); + default -> flag -> false; }; } - private static CaseFlagsType requestedFlags(CaseFlagsType flags, Set eligibleCodes) { + private static CaseFlagsType requestedFlags(CaseFlagsType flags, Predicate eligibleFlag) { ListTypeItem details = flags.getDetails() == null ? new ListTypeItem<>() : flags.getDetails().stream() .filter(item -> item != null && item.getValue() != null) .filter(item -> isRequested(item.getValue())) - .filter(item -> eligibleCodes.contains(item.getValue().getFlagCode())) + .filter(item -> eligibleFlag.test(item.getValue())) .collect(Collectors.toCollection(ListTypeItem::new)); return CaseFlagsType.builder() .partyName(flags.getPartyName()) @@ -194,17 +195,17 @@ private void prepareTasks(CaseData caseData, List flags) { taskState.setJudgeTaskRequired(null); if (isTaskNotCreated(taskState.getAdminTaskCreated()) - && hasRequestedFlag(flags, configuration.getReview().getAdminFlagCodes())) { + && hasRequestedFlag(flags, adminReviewFlag())) { taskState.setAdminTaskCreated(YES); taskState.setAdminTaskRequired(YES); } if (isTaskNotCreated(taskState.getLegalOfficerTaskCreated()) - && hasRequestedFlag(flags, configuration.getReview().getLegalOfficerFlagCodes())) { + && hasRequestedFlag(flags, legalOfficerReviewFlag())) { taskState.setLegalOfficerTaskCreated(YES); taskState.setLegalOfficerTaskRequired(YES); } if (isTaskNotCreated(taskState.getJudgeTaskCreated()) - && hasRequestedFlag(flags, configuration.getReview().getJudgeFlagCodes())) { + && hasRequestedFlag(flags, judgeReviewFlag())) { taskState.setJudgeTaskCreated(YES); taskState.setJudgeTaskRequired(YES); } @@ -217,18 +218,16 @@ private static SupportTaskState taskState(CaseData caseData) { return caseData.getSupportTaskState(); } - private static boolean hasRequestedFlag(List flags, Set eligibleFlagCodes) { - return flags.stream().anyMatch(flag -> isRequested(flag) && eligibleFlagCodes.contains(flag.getFlagCode())); + private static boolean hasRequestedFlag(List flags, Predicate eligibleFlag) { + return flags.stream().anyMatch(flag -> isRequested(flag) && eligibleFlag.test(flag)); } private static boolean updateTaskState(List flags, - Set eligibleFlagCodes, + Predicate eligibleFlag, String taskCreated, Consumer taskCreatedSetter) { - boolean categoryHasFlags = flags.stream() - .map(FlagDetailType::getFlagCode) - .anyMatch(eligibleFlagCodes::contains); - if (!hasRequestedFlag(flags, eligibleFlagCodes) + boolean categoryHasFlags = flags.stream().anyMatch(eligibleFlag); + if (!hasRequestedFlag(flags, eligibleFlag) && (isTaskCreated(taskCreated) || categoryHasFlags)) { taskCreatedSetter.accept(NO); return true; @@ -254,7 +253,7 @@ public void prepareArrangeSupportTask(CaseData caseData, CaseData caseDataBefore taskState.setArrangeSupportTaskName(null); Map flagTitles = configuration.getArrange().getFlagTitles(); - if (flagTitles.isEmpty()) { + if (flagTitles.isEmpty() && configuration.getArrange().getPathFlags().isEmpty()) { return; } @@ -262,10 +261,11 @@ public void prepareArrangeSupportTask(CaseData caseData, CaseData caseDataBefore caseDataBefore == null ? null : caseDataBefore.getAllPartyFlags()).toList(); allFlagItems(caseData.getAllPartyFlags()) .filter(item -> FLAG_STATUS_ACTIVE.equals(item.getValue().getStatus())) - .filter(item -> flagTitles.containsKey(item.getValue().getFlagCode())) .filter(item -> wasNotPreviouslyActive(item, previousFlags)) + .map(GenericTypeItem::getValue) + .map(this::arrangeTaskName) + .flatMap(Optional::stream) .findFirst() - .map(item -> flagTitles.get(item.getValue().getFlagCode())) .ifPresent(taskState::setArrangeSupportTaskName); } @@ -275,14 +275,63 @@ public void prepareNewFlagArrangeSupportTask(CaseData caseData, CaseData caseDat return; } - Map flagTitles = configuration.getArrange().getFlagTitles(); latestCreatedFlag(caseData) .filter(flag -> FLAG_STATUS_ACTIVE.equals(flag.getStatus())) - .map(FlagDetailType::getFlagCode) - .map(flagTitles::get) + .flatMap(this::arrangeTaskName) .ifPresent(caseData.getSupportTaskState()::setArrangeSupportTaskName); } + private Predicate adminReviewFlag() { + return eligibleFlag(configuration.getReview().getAdminFlagCodes(), + configuration.getReview().getAdminPathFlags()); + } + + private Predicate legalOfficerReviewFlag() { + return eligibleFlag(configuration.getReview().getLegalOfficerFlagCodes(), + configuration.getReview().getLegalOfficerPathFlags()); + } + + private Predicate judgeReviewFlag() { + return eligibleFlag(configuration.getReview().getJudgeFlagCodes(), + configuration.getReview().getJudgePathFlags()); + } + + private static Predicate eligibleFlag(Set flagCodes, List pathFlags) { + return flag -> flagCodes.contains(flag.getFlagCode()) + || pathFlags.stream().anyMatch(pathFlag -> matchesPath(flag, pathFlag)); + } + + private Optional arrangeTaskName(FlagDetailType flag) { + String title = configuration.getArrange().getFlagTitles().get(flag.getFlagCode()); + if (title != null) { + return Optional.of(title); + } + return configuration.getArrange().getPathFlags().stream() + .filter(pathFlag -> matchesPath(flag, pathFlag)) + .map(ArrangePathFlag::getTaskTitle) + .findFirst(); + } + + private static boolean matchesPath(FlagDetailType flag, PathFlag pathFlag) { + return Objects.equals(flag.getFlagCode(), pathFlag.getFlagCode()) + && hasPath(flag, pathFlag.getPath()); + } + + private static boolean matchesPath(FlagDetailType flag, ArrangePathFlag pathFlag) { + return Objects.equals(flag.getFlagCode(), pathFlag.getFlagCode()) + && hasPath(flag, pathFlag.getPath()); + } + + private static boolean hasPath(FlagDetailType flag, List expectedPath) { + if (flag.getPath() == null) { + return false; + } + List actualPath = flag.getPath().stream() + .map(item -> item == null ? null : item.getValue()) + .toList(); + return expectedPath.equals(actualPath); + } + private static Optional latestCreatedFlag(CaseData caseData) { return allFlagItems(caseData.getAllPartyFlags()) .map(GenericTypeItem::getValue) diff --git a/src/main/resources/support-tasks.yml b/src/main/resources/support-tasks.yml index da310f51fd..f6f957e916 100644 --- a/src/main/resources/support-tasks.yml +++ b/src/main/resources/support-tasks.yml @@ -1,17 +1,48 @@ support-tasks: review: admin-flag-codes: - - RA0002 - - RA0003 - - RA0004 - - RA0005 - - RA0006 - - RA0008 - - RA0009 - RA0021 - RA0033 - RA0039 - RA0041 + admin-path-flags: + - flag-code: OT0001 + path: + - Party + - Reasonable adjustment + - I need help communicating and understanding + - Hearing Enhancement System (Hearing + - Induction Loop, Infrared Receiver) + - flag-code: OT0001 + path: + - Party + - Reasonable adjustment + - I need documents in an alternative format + - flag-code: OT0001 + path: + - Party + - Reasonable adjustment + - I need help with forms + - flag-code: OT0001 + path: + - Party + - Reasonable adjustment + - I need adjustments to get to, into and around our buildings + - flag-code: OT0001 + path: + - Party + - Reasonable adjustment + - I need to bring support with me to a hearing + - flag-code: OT0001 + path: + - Party + - Reasonable adjustment + - I need something to feel comfortable during my hearing + - flag-code: OT0001 + path: + - Party + - Reasonable adjustment + - I need help communicating and understanding judge-flag-codes: - RA0029 - RA0031 @@ -24,7 +55,6 @@ support-tasks: - RA0036 arrange: flag-titles: - RA0003: I need help with forms RA0017: Guidance on how to complete forms RA0018: Support filling in forms RA0019: Step free / wheelchair access @@ -41,3 +71,10 @@ support-tasks: RA0044: Infrared receiver (hearing enhancement system) RA0045: Induction loop (hearing enhancement system) RA0046: Visit to court or tribunal before the hearing + path-flags: + - flag-code: OT0001 + path: + - Party + - Reasonable adjustment + - I need help with forms + task-title: I need help with forms diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/config/SupportTaskConfigurationTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/config/SupportTaskConfigurationTest.java index 8853d5aedb..32e780e0e7 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/config/SupportTaskConfigurationTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/config/SupportTaskConfigurationTest.java @@ -18,16 +18,26 @@ class SupportTaskConfigurationTest { @Test void loadsFlagCodesFromYaml() { assertThat(configuration.getReview().getAdminFlagCodes()) - .containsExactlyInAnyOrder( - "RA0002", "RA0003", "RA0004", "RA0005", "RA0006", "RA0008", "RA0009", - "RA0021", "RA0033", "RA0039", "RA0041"); + .containsExactlyInAnyOrder("RA0021", "RA0033", "RA0039", "RA0041"); assertThat(configuration.getReview().getJudgeFlagCodes()) .containsExactlyInAnyOrder("RA0029", "RA0031", "RA0032", "RA0037", "RA0038"); assertThat(configuration.getReview().getLegalOfficerFlagCodes()) .containsExactlyInAnyOrder("RA0034", "RA0035", "RA0036"); + assertThat(configuration.getReview().getAdminPathFlags()) + .hasSize(7) + .allSatisfy(pathFlag -> assertThat(pathFlag.getFlagCode()).isEqualTo("OT0001")); + assertThat(configuration.getReview().getAdminPathFlags()) + .extracting(pathFlag -> pathFlag.getPath().getLast()) + .containsExactlyInAnyOrder( + "Induction Loop, Infrared Receiver)", + "I need documents in an alternative format", + "I need help with forms", + "I need adjustments to get to, into and around our buildings", + "I need to bring support with me to a hearing", + "I need something to feel comfortable during my hearing", + "I need help communicating and understanding"); assertThat(configuration.getArrange().getFlagTitles()) - .containsEntry("RA0003", "I need help with forms") .containsEntry("RA0017", "Guidance on how to complete forms") .containsEntry("RA0018", "Support filling in forms") .containsEntry("RA0019", "Step free / wheelchair access") @@ -44,6 +54,12 @@ void loadsFlagCodesFromYaml() { .containsEntry("RA0044", "Infrared receiver (hearing enhancement system)") .containsEntry("RA0045", "Induction loop (hearing enhancement system)") .containsEntry("RA0046", "Visit to court or tribunal before the hearing") - .hasSize(17); + .hasSize(16); + assertThat(configuration.getArrange().getPathFlags()).singleElement().satisfies(pathFlag -> { + assertThat(pathFlag.getFlagCode()).isEqualTo("OT0001"); + assertThat(pathFlag.getPath()).containsExactly( + "Party", "Reasonable adjustment", "I need help with forms"); + assertThat(pathFlag.getTaskTitle()).isEqualTo("I need help with forms"); + }); } } diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java index f8648dd60d..e422e01488 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java @@ -14,6 +14,8 @@ import uk.gov.hmcts.et.common.model.ccd.types.CaseFlagsType; import uk.gov.hmcts.et.common.model.ccd.types.SupportTaskState; import uk.gov.hmcts.ethos.replacement.docmosis.config.SupportTaskConfiguration; +import uk.gov.hmcts.ethos.replacement.docmosis.config.SupportTaskConfiguration.ArrangePathFlag; +import uk.gov.hmcts.ethos.replacement.docmosis.config.SupportTaskConfiguration.PathFlag; import java.util.List; import java.util.Map; @@ -43,18 +45,31 @@ class SupportTaskServiceTest { private static final String STATUS_INACTIVE = "Inactive"; private static final String CCD_TRUE = "true"; private static final String CCD_FALSE = "false"; + private static final String OTHER_FLAG_CODE = "OT0001"; + private static final List HELP_WITH_FORMS_PATH = List.of( + "Party", "Reasonable adjustment", "I need help with forms"); + private static final List> OTHER_REVIEW_PATHS = List.of( + List.of("Party", "Reasonable adjustment", "I need help communicating and understanding", + "Hearing Enhancement System (Hearing", "Induction Loop, Infrared Receiver)"), + List.of("Party", "Reasonable adjustment", "I need documents in an alternative format"), + HELP_WITH_FORMS_PATH, + List.of("Party", "Reasonable adjustment", + "I need adjustments to get to, into and around our buildings"), + List.of("Party", "Reasonable adjustment", "I need to bring support with me to a hearing"), + List.of("Party", "Reasonable adjustment", "I need something to feel comfortable during my hearing"), + List.of("Party", "Reasonable adjustment", "I need help communicating and understanding")); private final SupportTaskService service = new SupportTaskService(configuration()); private static SupportTaskConfiguration configuration() { SupportTaskConfiguration configuration = new SupportTaskConfiguration(); - configuration.getReview().setAdminFlagCodes(Set.of( - "RA0002", "RA0003", "RA0004", "RA0005", "RA0006", "RA0008", "RA0009", - "RA0021", "RA0033", "RA0039", "RA0041")); + configuration.getReview().setAdminFlagCodes(Set.of("RA0021", "RA0033", "RA0039", "RA0041")); configuration.getReview().setLegalOfficerFlagCodes(Set.of("RA0034", "RA0035", "RA0036")); configuration.getReview().setJudgeFlagCodes(Set.of("RA0029", "RA0031", "RA0032", "RA0037", "RA0038")); + configuration.getReview().setAdminPathFlags(OTHER_REVIEW_PATHS.stream() + .map(path -> pathFlag(OTHER_FLAG_CODE, path)) + .toList()); configuration.getArrange().setFlagTitles(Map.ofEntries( - Map.entry("RA0003", "I need help with forms"), Map.entry("RA0017", "Guidance on how to complete forms"), Map.entry("RA0018", "Support filling in forms"), Map.entry("RA0019", "Step free / wheelchair access"), @@ -72,13 +87,24 @@ private static SupportTaskConfiguration configuration() { Map.entry("RA0045", "Induction loop (hearing enhancement system)"), Map.entry("RA0046", "Visit to court or tribunal before the hearing") )); + ArrangePathFlag arrangePathFlag = new ArrangePathFlag(); + arrangePathFlag.setFlagCode(OTHER_FLAG_CODE); + arrangePathFlag.setPath(HELP_WITH_FORMS_PATH); + arrangePathFlag.setTaskTitle("I need help with forms"); + configuration.getArrange().setPathFlags(List.of(arrangePathFlag)); return configuration; } + private static PathFlag pathFlag(String flagCode, List path) { + PathFlag pathFlag = new PathFlag(); + pathFlag.setFlagCode(flagCode); + pathFlag.setPath(path); + return pathFlag; + } + static Stream eligibleFlagScenarios() { return Stream.of( - Stream.of("RA0002", "RA0003", "RA0004", "RA0005", "RA0006", "RA0008", "RA0009", - "RA0021", "RA0033", "RA0039", "RA0041") + Stream.of("RA0021", "RA0033", "RA0039", "RA0041") .map(code -> Arguments.of(code, TASK_TYPE_ADMIN)), Stream.of("RA0034", "RA0035", "RA0036") .map(code -> Arguments.of(code, TASK_TYPE_LEGAL_OFFICER)), @@ -117,6 +143,63 @@ void prepares_task_for_requested_external_claimant_flag() { assertEquals(YES, taskState(caseData).getJudgeTaskRequired()); } + static Stream otherReviewPathScenarios() { + return OTHER_REVIEW_PATHS.stream().map(Arguments::of); + } + + @ParameterizedTest + @MethodSource("otherReviewPathScenarios") + void prepares_admin_review_task_for_each_configured_other_flag_path(List path) { + CaseData caseData = caseDataWithClaimantFlag(OTHER_FLAG_CODE, STATUS_REQUESTED, false, path); + + service.prepareReviewSupportTasks(caseData); + + assertEquals(YES, taskState(caseData).getAdminTaskCreated()); + assertEquals(YES, taskState(caseData).getAdminTaskRequired()); + } + + @Test + void does_not_prepare_review_task_for_other_flag_with_an_unconfigured_or_missing_path() { + CaseData unconfiguredPath = caseDataWithClaimantFlag(OTHER_FLAG_CODE, STATUS_REQUESTED, false, + List.of("Party", "Other")); + CaseData missingPath = caseDataWithClaimantFlag(OTHER_FLAG_CODE, STATUS_REQUESTED, false); + + service.prepareReviewSupportTasks(unconfiguredPath); + service.prepareReviewSupportTasks(missingPath); + + assertNull(taskState(unconfiguredPath).getAdminTaskCreated()); + assertNull(taskState(missingPath).getAdminTaskCreated()); + } + + @Test + void keeps_admin_task_active_while_requested_other_flag_has_a_configured_path() { + CaseData caseData = caseDataWithClaimantFlag( + OTHER_FLAG_CODE, STATUS_REQUESTED, false, HELP_WITH_FORMS_PATH); + caseData.setSupportTaskState(SupportTaskState.builder().adminTaskCreated(YES).build()); + + Set taskTypesToComplete = service.prepareManagedReviewSupportTasks(caseData, null); + + assertEquals(YES, taskState(caseData).getAdminTaskCreated()); + assertTrue(taskTypesToComplete.isEmpty()); + } + + @Test + void admin_review_event_contains_requested_other_flag_only_for_a_configured_path() { + CaseData caseData = new CaseData(); + caseData.setAllPartyFlags(AllPartyFlags.builder() + .claimantFlags(caseFlags("matching", OTHER_FLAG_CODE, STATUS_REQUESTED, null, + HELP_WITH_FORMS_PATH)) + .respondentFlags(caseFlags("not-matching", OTHER_FLAG_CODE, STATUS_REQUESTED, null, + List.of("Party", "Other"))) + .build()); + + service.prepareReviewSupportRequest(caseData, EVENT_REVIEW_ADMIN_SUPPORT_REQUEST); + + assertEquals(1, caseData.getReviewSupportRequestFlags().size()); + assertEquals("matching", caseData.getReviewSupportRequestFlags().getFirst().getValue() + .getDetails().getFirst().getId()); + } + @Test void prepares_task_for_requested_flag_from_any_respondent() { CaseData caseData = new CaseData(); @@ -638,6 +721,26 @@ void prepares_arrange_support_task_for_each_new_active_flag(String flagCode, Str assertEquals(taskName, taskState(caseData).getArrangeSupportTaskName()); } + @Test + void prepares_arrange_support_task_for_active_other_flag_with_help_with_forms_path() { + CaseData caseData = caseDataWithClaimantFlag( + OTHER_FLAG_CODE, STATUS_ACTIVE, false, HELP_WITH_FORMS_PATH); + + service.prepareArrangeSupportTask(caseData, new CaseData()); + + assertEquals("I need help with forms", taskState(caseData).getArrangeSupportTaskName()); + } + + @Test + void does_not_prepare_arrange_support_task_for_other_flag_with_a_different_path() { + CaseData caseData = caseDataWithClaimantFlag( + OTHER_FLAG_CODE, STATUS_ACTIVE, false, OTHER_REVIEW_PATHS.get(1)); + + service.prepareArrangeSupportTask(caseData, new CaseData()); + + assertNull(taskState(caseData).getArrangeSupportTaskName()); + } + @Test void prepares_separate_arrange_support_tasks_for_the_same_code_on_separate_events() { CaseData firstEvent = new CaseData(); @@ -734,9 +837,17 @@ void does_not_prepare_arrange_support_task_for_ineligible_or_non_active_flag() { private static CaseData caseDataWithClaimantFlag(String flagCode, String status, boolean external) { + return caseDataWithClaimantFlag(flagCode, status, external, null); + } + + private static CaseData caseDataWithClaimantFlag(String flagCode, + String status, + boolean external, + List path) { FlagDetailType detail = FlagDetailType.builder() .flagCode(flagCode) .status(status) + .path(pathItems(path)) .build(); CaseFlagsType flags = CaseFlagsType.builder().details(ListTypeItem.from(detail)).build(); AllPartyFlags allPartyFlags = external @@ -810,15 +921,33 @@ private static CaseFlagsType caseFlags(String id, String flagCode, String status } private static CaseFlagsType caseFlags(String id, String flagCode, String status, String dateTimeCreated) { + return caseFlags(id, flagCode, status, dateTimeCreated, null); + } + + private static CaseFlagsType caseFlags(String id, + String flagCode, + String status, + String dateTimeCreated, + List path) { FlagDetailType detail = FlagDetailType.builder() .flagCode(flagCode) .status(status) .dateTimeCreated(dateTimeCreated) + .path(pathItems(path)) .build(); ListTypeItem details = ListTypeItem.from(GenericTypeItem.from(id, detail)); return CaseFlagsType.builder().details(details).build(); } + private static ListTypeItem pathItems(List path) { + if (path == null) { + return null; + } + ListTypeItem pathItems = new ListTypeItem<>(); + path.forEach(pathItems::addAsItem); + return pathItems; + } + private static SupportTaskState taskState(CaseData caseData) { return caseData.getSupportTaskState(); } From e06fe2a42798e0e9bb4e0d095f7a01e825b547e1 Mon Sep 17 00:00:00 2001 From: rajaram Date: Thu, 17 Sep 2026 20:19:34 +0100 Subject: [PATCH 079/100] Auto close review tasks --- ...horisationCaseEvent-CaseFlags-nonprod.json | 24 ++ ...AuthorisationComplexType-CaseFlags-WA.json | 7 + .../CaseEvent-CaseFlagsCaseLinking.json | 58 ++++- .../json/CaseEvent/CaseEvent-ET3.json | 2 + .../json/CaseEvent/CaseEvent.json | 1 + .../CaseEventToFields-SupportTasks.json | 40 ++++ .../ComplexTypes-CaseFlagsCaseLinking.json | 7 + .../EventToComplexTypes-SupportTasks.json | 46 +++- ...isationCaseEvent-CaseFlagsCaseLinking.json | 24 ++ ...AuthorisationComplexType-CaseFlags-WA.json | 7 + .../CaseEvent-CaseFlagsCaseLinking.json | 58 ++++- .../json/CaseEvent/CaseEvent-ET3.json | 2 + .../scotland/json/CaseEvent/CaseEvent.json | 1 + .../CaseEventToFields-SupportTasks.json | 40 ++++ .../ComplexTypes-CaseFlagsCaseLinking.json | 7 + .../EventToComplexTypes-SupportTasks.json | 46 +++- charts/et-cos/values.preview.template.yaml | 1 - charts/et-cos/values.yaml | 1 - .../model/ccd/types/SupportTaskState.java | 1 + .../docmosis/client/WaTaskApiClient.java | 28 --- .../config/SupportTaskConfiguration.java | 9 + .../constants/SupportTaskConstants.java | 4 + .../CaseActionsForCaseWorkerController.java | 69 ++++-- .../controllers/Et1SubmissionController.java | 12 + .../service/SupportTaskEventService.java | 182 +++++++++++++++ .../docmosis/service/SupportTaskService.java | 79 ++++++- .../ReviewSupportTaskCompletionService.java | 68 ------ .../wa/SupportTaskClientContextService.java | 50 +++++ .../wa/model/TaskSearchParameter.java | 20 -- .../docmosis/wa/model/TaskSearchRequest.java | 16 -- .../docmosis/wa/model/TaskSearchResponse.java | 18 -- .../replacement/docmosis/wa/model/WaTask.java | 18 -- src/main/resources/application.yaml | 5 - src/main/resources/support-tasks.yml | 5 + src/test/apiTest/resources/application.yaml | 5 - .../integration/resources/application.yaml | 5 - ...aseActionsForCaseWorkerControllerTest.java | 91 +++++++- .../Et1SubmissionControllerTest.java | 29 +++ .../service/SupportTaskEventServiceTest.java | 207 ++++++++++++++++++ .../service/SupportTaskServiceTest.java | 62 ++++++ ...eviewSupportTaskCompletionServiceTest.java | 147 ------------- .../SupportTaskClientContextServiceTest.java | 93 ++++++++ 42 files changed, 1212 insertions(+), 383 deletions(-) delete mode 100644 src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/client/WaTaskApiClient.java create mode 100644 src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskEventService.java delete mode 100644 src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/ReviewSupportTaskCompletionService.java create mode 100644 src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/SupportTaskClientContextService.java delete mode 100644 src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/model/TaskSearchParameter.java delete mode 100644 src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/model/TaskSearchRequest.java delete mode 100644 src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/model/TaskSearchResponse.java delete mode 100644 src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/model/WaTask.java create mode 100644 src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskEventServiceTest.java delete mode 100644 src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/ReviewSupportTaskCompletionServiceTest.java create mode 100644 src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/SupportTaskClientContextServiceTest.java diff --git a/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseEvent/AuthorisationCaseEvent-CaseFlags-nonprod.json b/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseEvent/AuthorisationCaseEvent-CaseFlags-nonprod.json index 2004801726..e93d6a435e 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseEvent/AuthorisationCaseEvent-CaseFlags-nonprod.json +++ b/ccd-definitions/jurisdictions/england-wales/json/AuthorisationCaseEvent/AuthorisationCaseEvent-CaseFlags-nonprod.json @@ -58,5 +58,29 @@ "CaseEventID": "reviewJudgeSupportRequest", "UserRole": "caseworker-employment-etjudge-englandwales", "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseEventID": "closeAdminReviewSupportTask", + "UserRole": "caseworker-employment-api", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseEventID": "closeLOReviewSupportTask", + "UserRole": "caseworker-employment-api", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseEventID": "closeJudgeReviewSupportTask", + "UserRole": "caseworker-employment-api", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_EnglandWales", + "CaseEventID": "createArrangeSupportTask", + "UserRole": "caseworker-employment-api", + "CRUD": "CRU" } ] diff --git a/ccd-definitions/jurisdictions/england-wales/json/AuthorisationComplexType/AuthorisationComplexType-CaseFlags-WA.json b/ccd-definitions/jurisdictions/england-wales/json/AuthorisationComplexType/AuthorisationComplexType-CaseFlags-WA.json index e2a0b3b178..4d242ba793 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/AuthorisationComplexType/AuthorisationComplexType-CaseFlags-WA.json +++ b/ccd-definitions/jurisdictions/england-wales/json/AuthorisationComplexType/AuthorisationComplexType-CaseFlags-WA.json @@ -75,5 +75,12 @@ "ListElementCode": "arrangeSupportTaskName", "UserRole": "caseworker-wa-task-configuration", "CRUD": "R" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseFieldID": "supportTaskState", + "ListElementCode": "arrangeSupportTaskFlagId", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" } ] diff --git a/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json index 84c5742587..6ec8561d66 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json @@ -12,7 +12,7 @@ "Publish": "Y", "CallBackURLAboutToStartEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToStart", "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToSubmit", - "CallBackURLSubmittedEvent": "" + "CallBackURLSubmittedEvent": "${ET_COS_URL}/supportTasks/submitted" }, { "CaseTypeID": "ET_EnglandWales", @@ -27,7 +27,7 @@ "Publish": "Y", "CallBackURLAboutToStartEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToStart", "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToSubmit", - "CallBackURLSubmittedEvent": "" + "CallBackURLSubmittedEvent": "${ET_COS_URL}/supportTasks/submitted" }, { "CaseTypeID": "ET_EnglandWales", @@ -42,7 +42,7 @@ "Publish": "Y", "CallBackURLAboutToStartEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToStart", "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToSubmit", - "CallBackURLSubmittedEvent": "" + "CallBackURLSubmittedEvent": "${ET_COS_URL}/supportTasks/submitted" }, { "CaseTypeID": "ET_EnglandWales", @@ -73,7 +73,7 @@ "EventEnablingCondition": "", "CallBackURLAboutToStartEvent": "", "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/supportTasks/aboutToSubmit", - "CallBackURLSubmittedEvent": "", + "CallBackURLSubmittedEvent": "${ET_COS_URL}/supportTasks/submitted", "Publish": "Y" }, { @@ -105,7 +105,55 @@ "EventEnablingCondition": "", "CallBackURLAboutToStartEvent": "", "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/supportTasks/aboutToSubmit", - "CallBackURLSubmittedEvent": "", + "CallBackURLSubmittedEvent": "${ET_COS_URL}/supportTasks/submitted", + "Publish": "Y" + }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "closeAdminReviewSupportTask", + "Name": "Close Admin review task", + "Description": "Close Admin review support task", + "PreConditionState(s)": "*", + "PostConditionState": "*", + "SecurityClassification": "Public", + "ShowEventNotes": "N", + "ShowSummary": "N", + "Publish": "Y" + }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "closeLOReviewSupportTask", + "Name": "Close LO review task", + "Description": "Close Legal Officer review support task", + "PreConditionState(s)": "*", + "PostConditionState": "*", + "SecurityClassification": "Public", + "ShowEventNotes": "N", + "ShowSummary": "N", + "Publish": "Y" + }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "closeJudgeReviewSupportTask", + "Name": "Close Judge review task", + "Description": "Close Judge review support task", + "PreConditionState(s)": "*", + "PostConditionState": "*", + "SecurityClassification": "Public", + "ShowEventNotes": "N", + "ShowSummary": "N", + "Publish": "Y" + }, + { + "CaseTypeID": "ET_EnglandWales", + "ID": "createArrangeSupportTask", + "Name": "Create Arrange Support Task", + "Description": "Create Arrange Support Task", + "PreConditionState(s)": "*", + "PostConditionState": "*", + "SecurityClassification": "Public", + "ShowEventNotes": "N", + "ShowSummary": "N", "Publish": "Y" }, { diff --git a/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent-ET3.json b/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent-ET3.json index 9d9d454fda..737b72d6b3 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent-ET3.json +++ b/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent-ET3.json @@ -7,6 +7,7 @@ "PreConditionState(s)": "Accepted", "PostConditionState": "Accepted", "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/supportTasks/aboutToSubmit", + "CallBackURLSubmittedEvent": "${ET_COS_URL}/supportTasks/submitted", "SecurityClassification": "Public", "ShowEventNotes": "N", "ShowSummary": "N", @@ -20,6 +21,7 @@ "PreConditionState(s)": "Accepted", "PostConditionState": "Accepted", "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/supportTasks/aboutToSubmit", + "CallBackURLSubmittedEvent": "${ET_COS_URL}/supportTasks/submitted", "SecurityClassification": "Public", "ShowEventNotes": "N", "ShowSummary": "N", diff --git a/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent.json b/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent.json index 871aa1cc2d..a1a8a62e2c 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent.json +++ b/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent.json @@ -130,6 +130,7 @@ "PreConditionState(s)": "*", "PostConditionState": "*", "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/postDefaultValues", + "CallBackURLSubmittedEvent": "${ET_COS_URL}/supportTasks/submitted", "SecurityClassification": "Public", "ShowEventNotes": "N", "ShowSummary": "N", diff --git a/ccd-definitions/jurisdictions/england-wales/json/CaseEventToFields/CaseEventToFields-SupportTasks.json b/ccd-definitions/jurisdictions/england-wales/json/CaseEventToFields/CaseEventToFields-SupportTasks.json index e6379855b8..de4ba8a026 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/CaseEventToFields/CaseEventToFields-SupportTasks.json +++ b/ccd-definitions/jurisdictions/england-wales/json/CaseEventToFields/CaseEventToFields-SupportTasks.json @@ -195,5 +195,45 @@ "FieldShowCondition": "flagLauncher=\"hidden\"", "ShowSummaryChangeOption": "N", "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "closeAdminReviewSupportTask", + "CaseFieldID": "supportTaskState", + "DisplayContext": "COMPLEX", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 99, + "ShowSummaryChangeOption": "N" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "closeLOReviewSupportTask", + "CaseFieldID": "supportTaskState", + "DisplayContext": "COMPLEX", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 99, + "ShowSummaryChangeOption": "N" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "closeJudgeReviewSupportTask", + "CaseFieldID": "supportTaskState", + "DisplayContext": "COMPLEX", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 99, + "ShowSummaryChangeOption": "N" + }, + { + "CaseTypeID": "ET_EnglandWales", + "CaseEventID": "createArrangeSupportTask", + "CaseFieldID": "supportTaskState", + "DisplayContext": "COMPLEX", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 99, + "ShowSummaryChangeOption": "N" } ] diff --git a/ccd-definitions/jurisdictions/england-wales/json/ComplexTypes/ComplexTypes-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/england-wales/json/ComplexTypes/ComplexTypes-CaseFlagsCaseLinking.json index d1ca30e961..c5d54a09fe 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/ComplexTypes/ComplexTypes-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/england-wales/json/ComplexTypes/ComplexTypes-CaseFlagsCaseLinking.json @@ -47,5 +47,12 @@ "FieldType": "Text", "ElementLabel": "Arrange support task name", "SecurityClassification": "Public" + }, + { + "ID": "SupportTaskState", + "ListElementCode": "arrangeSupportTaskFlagId", + "FieldType": "Text", + "ElementLabel": "Arrange support task flag ID", + "SecurityClassification": "Public" } ] diff --git a/ccd-definitions/jurisdictions/england-wales/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json b/ccd-definitions/jurisdictions/england-wales/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json index 9247a57ed1..2dfc60a569 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json +++ b/ccd-definitions/jurisdictions/england-wales/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json @@ -226,7 +226,7 @@ }, { "ID": "SupportTaskState", - "CaseEventID": "manageSupport", + "CaseEventID": "reviewAdminSupportRequest", "CaseFieldID": "supportTaskState", "ListElementCode": "arrangeSupportTaskName", "FieldDisplayOrder": 4, @@ -235,7 +235,7 @@ }, { "ID": "SupportTaskState", - "CaseEventID": "reviewAdminSupportRequest", + "CaseEventID": "reviewLOSupportRequest", "CaseFieldID": "supportTaskState", "ListElementCode": "arrangeSupportTaskName", "FieldDisplayOrder": 4, @@ -244,7 +244,7 @@ }, { "ID": "SupportTaskState", - "CaseEventID": "reviewLOSupportRequest", + "CaseEventID": "reviewJudgeSupportRequest", "CaseFieldID": "supportTaskState", "ListElementCode": "arrangeSupportTaskName", "FieldDisplayOrder": 4, @@ -253,10 +253,46 @@ }, { "ID": "SupportTaskState", - "CaseEventID": "reviewJudgeSupportRequest", + "CaseEventID": "closeAdminReviewSupportTask", + "CaseFieldID": "supportTaskState", + "ListElementCode": "adminTaskCreated", + "FieldDisplayOrder": 1, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "closeLOReviewSupportTask", + "CaseFieldID": "supportTaskState", + "ListElementCode": "legalOfficerTaskCreated", + "FieldDisplayOrder": 1, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "closeJudgeReviewSupportTask", + "CaseFieldID": "supportTaskState", + "ListElementCode": "judgeTaskCreated", + "FieldDisplayOrder": 1, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "createArrangeSupportTask", "CaseFieldID": "supportTaskState", "ListElementCode": "arrangeSupportTaskName", - "FieldDisplayOrder": 4, + "FieldDisplayOrder": 1, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "createArrangeSupportTask", + "CaseFieldID": "supportTaskState", + "ListElementCode": "arrangeSupportTaskFlagId", + "FieldDisplayOrder": 2, "DisplayContext": "OPTIONAL", "Publish": "Y" } diff --git a/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseEvent/AuthorisationCaseEvent-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseEvent/AuthorisationCaseEvent-CaseFlagsCaseLinking.json index 656ef3f3aa..72cfa219ce 100644 --- a/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseEvent/AuthorisationCaseEvent-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/scotland/json/AuthorisationCaseEvent/AuthorisationCaseEvent-CaseFlagsCaseLinking.json @@ -100,5 +100,29 @@ "CaseEventID": "reviewJudgeSupportRequest", "UserRole": "caseworker-employment-etjudge-scotland", "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseEventID": "closeAdminReviewSupportTask", + "UserRole": "caseworker-employment-api", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseEventID": "closeLOReviewSupportTask", + "UserRole": "caseworker-employment-api", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseEventID": "closeJudgeReviewSupportTask", + "UserRole": "caseworker-employment-api", + "CRUD": "CRU" + }, + { + "CaseTypeId": "ET_Scotland", + "CaseEventID": "createArrangeSupportTask", + "UserRole": "caseworker-employment-api", + "CRUD": "CRU" } ] diff --git a/ccd-definitions/jurisdictions/scotland/json/AuthorisationComplexType/AuthorisationComplexType-CaseFlags-WA.json b/ccd-definitions/jurisdictions/scotland/json/AuthorisationComplexType/AuthorisationComplexType-CaseFlags-WA.json index 01ccf71348..5bbb720fae 100644 --- a/ccd-definitions/jurisdictions/scotland/json/AuthorisationComplexType/AuthorisationComplexType-CaseFlags-WA.json +++ b/ccd-definitions/jurisdictions/scotland/json/AuthorisationComplexType/AuthorisationComplexType-CaseFlags-WA.json @@ -75,5 +75,12 @@ "ListElementCode": "arrangeSupportTaskName", "UserRole": "caseworker-wa-task-configuration", "CRUD": "R" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseFieldID": "supportTaskState", + "ListElementCode": "arrangeSupportTaskFlagId", + "UserRole": "caseworker-employment-api", + "CRUD": "CRUD" } ] diff --git a/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json index 94092e2c07..3d4b9e17df 100644 --- a/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json @@ -12,7 +12,7 @@ "Publish": "Y", "CallBackURLAboutToStartEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToStart", "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToSubmit", - "CallBackURLSubmittedEvent": "" + "CallBackURLSubmittedEvent": "${ET_COS_URL}/supportTasks/submitted" }, { "CaseTypeID": "ET_Scotland", @@ -27,7 +27,7 @@ "Publish": "Y", "CallBackURLAboutToStartEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToStart", "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToSubmit", - "CallBackURLSubmittedEvent": "" + "CallBackURLSubmittedEvent": "${ET_COS_URL}/supportTasks/submitted" }, { "CaseTypeID": "ET_Scotland", @@ -42,7 +42,7 @@ "Publish": "Y", "CallBackURLAboutToStartEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToStart", "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToSubmit", - "CallBackURLSubmittedEvent": "" + "CallBackURLSubmittedEvent": "${ET_COS_URL}/supportTasks/submitted" }, { "CaseTypeID": "ET_Scotland", @@ -73,7 +73,7 @@ "EventEnablingCondition": "", "CallBackURLAboutToStartEvent": "", "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/supportTasks/aboutToSubmit", - "CallBackURLSubmittedEvent": "", + "CallBackURLSubmittedEvent": "${ET_COS_URL}/supportTasks/submitted", "Publish": "Y" }, { @@ -105,7 +105,55 @@ "EventEnablingCondition": "", "CallBackURLAboutToStartEvent": "", "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/supportTasks/aboutToSubmit", - "CallBackURLSubmittedEvent": "", + "CallBackURLSubmittedEvent": "${ET_COS_URL}/supportTasks/submitted", + "Publish": "Y" + }, + { + "CaseTypeID": "ET_Scotland", + "ID": "closeAdminReviewSupportTask", + "Name": "Close Admin review task", + "Description": "Close Admin review support task", + "PreConditionState(s)": "*", + "PostConditionState": "*", + "SecurityClassification": "Public", + "ShowEventNotes": "N", + "ShowSummary": "N", + "Publish": "Y" + }, + { + "CaseTypeID": "ET_Scotland", + "ID": "closeLOReviewSupportTask", + "Name": "Close LO review task", + "Description": "Close Legal Officer review support task", + "PreConditionState(s)": "*", + "PostConditionState": "*", + "SecurityClassification": "Public", + "ShowEventNotes": "N", + "ShowSummary": "N", + "Publish": "Y" + }, + { + "CaseTypeID": "ET_Scotland", + "ID": "closeJudgeReviewSupportTask", + "Name": "Close Judge review task", + "Description": "Close Judge review support task", + "PreConditionState(s)": "*", + "PostConditionState": "*", + "SecurityClassification": "Public", + "ShowEventNotes": "N", + "ShowSummary": "N", + "Publish": "Y" + }, + { + "CaseTypeID": "ET_Scotland", + "ID": "createArrangeSupportTask", + "Name": "Create Arrange Support Task", + "Description": "Create Arrange Support Task", + "PreConditionState(s)": "*", + "PostConditionState": "*", + "SecurityClassification": "Public", + "ShowEventNotes": "N", + "ShowSummary": "N", "Publish": "Y" }, { diff --git a/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent-ET3.json b/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent-ET3.json index b2e7db6762..2d5b3d51b4 100644 --- a/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent-ET3.json +++ b/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent-ET3.json @@ -7,6 +7,7 @@ "PreConditionState(s)": "Accepted", "PostConditionState": "Accepted", "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/supportTasks/aboutToSubmit", + "CallBackURLSubmittedEvent": "${ET_COS_URL}/supportTasks/submitted", "SecurityClassification": "Public", "ShowEventNotes": "N", "ShowSummary": "N", @@ -20,6 +21,7 @@ "PreConditionState(s)": "Accepted", "PostConditionState": "Accepted", "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/supportTasks/aboutToSubmit", + "CallBackURLSubmittedEvent": "${ET_COS_URL}/supportTasks/submitted", "SecurityClassification": "Public", "ShowEventNotes": "N", "ShowSummary": "N", diff --git a/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent.json b/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent.json index 01537b66bc..90c824421d 100644 --- a/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent.json +++ b/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent.json @@ -98,6 +98,7 @@ "PreConditionState(s)": "*", "PostConditionState": "*", "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/postDefaultValues", + "CallBackURLSubmittedEvent": "${ET_COS_URL}/supportTasks/submitted", "SecurityClassification": "Public", "ShowEventNotes": "N", "ShowSummary": "N", diff --git a/ccd-definitions/jurisdictions/scotland/json/CaseEventToFields/CaseEventToFields-SupportTasks.json b/ccd-definitions/jurisdictions/scotland/json/CaseEventToFields/CaseEventToFields-SupportTasks.json index 002492eee5..3928dcd7e8 100644 --- a/ccd-definitions/jurisdictions/scotland/json/CaseEventToFields/CaseEventToFields-SupportTasks.json +++ b/ccd-definitions/jurisdictions/scotland/json/CaseEventToFields/CaseEventToFields-SupportTasks.json @@ -195,5 +195,45 @@ "FieldShowCondition": "flagLauncher=\"hidden\"", "ShowSummaryChangeOption": "N", "RetainHiddenValue": "Yes" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "closeAdminReviewSupportTask", + "CaseFieldID": "supportTaskState", + "DisplayContext": "COMPLEX", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 99, + "ShowSummaryChangeOption": "N" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "closeLOReviewSupportTask", + "CaseFieldID": "supportTaskState", + "DisplayContext": "COMPLEX", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 99, + "ShowSummaryChangeOption": "N" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "closeJudgeReviewSupportTask", + "CaseFieldID": "supportTaskState", + "DisplayContext": "COMPLEX", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 99, + "ShowSummaryChangeOption": "N" + }, + { + "CaseTypeID": "ET_Scotland", + "CaseEventID": "createArrangeSupportTask", + "CaseFieldID": "supportTaskState", + "DisplayContext": "COMPLEX", + "PageID": 1, + "PageDisplayOrder": 1, + "PageFieldDisplayOrder": 99, + "ShowSummaryChangeOption": "N" } ] diff --git a/ccd-definitions/jurisdictions/scotland/json/ComplexTypes/ComplexTypes-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/scotland/json/ComplexTypes/ComplexTypes-CaseFlagsCaseLinking.json index d1ca30e961..c5d54a09fe 100644 --- a/ccd-definitions/jurisdictions/scotland/json/ComplexTypes/ComplexTypes-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/scotland/json/ComplexTypes/ComplexTypes-CaseFlagsCaseLinking.json @@ -47,5 +47,12 @@ "FieldType": "Text", "ElementLabel": "Arrange support task name", "SecurityClassification": "Public" + }, + { + "ID": "SupportTaskState", + "ListElementCode": "arrangeSupportTaskFlagId", + "FieldType": "Text", + "ElementLabel": "Arrange support task flag ID", + "SecurityClassification": "Public" } ] diff --git a/ccd-definitions/jurisdictions/scotland/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json b/ccd-definitions/jurisdictions/scotland/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json index 9247a57ed1..2dfc60a569 100644 --- a/ccd-definitions/jurisdictions/scotland/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json +++ b/ccd-definitions/jurisdictions/scotland/json/EventToComplexTypes/EventToComplexTypes-SupportTasks.json @@ -226,7 +226,7 @@ }, { "ID": "SupportTaskState", - "CaseEventID": "manageSupport", + "CaseEventID": "reviewAdminSupportRequest", "CaseFieldID": "supportTaskState", "ListElementCode": "arrangeSupportTaskName", "FieldDisplayOrder": 4, @@ -235,7 +235,7 @@ }, { "ID": "SupportTaskState", - "CaseEventID": "reviewAdminSupportRequest", + "CaseEventID": "reviewLOSupportRequest", "CaseFieldID": "supportTaskState", "ListElementCode": "arrangeSupportTaskName", "FieldDisplayOrder": 4, @@ -244,7 +244,7 @@ }, { "ID": "SupportTaskState", - "CaseEventID": "reviewLOSupportRequest", + "CaseEventID": "reviewJudgeSupportRequest", "CaseFieldID": "supportTaskState", "ListElementCode": "arrangeSupportTaskName", "FieldDisplayOrder": 4, @@ -253,10 +253,46 @@ }, { "ID": "SupportTaskState", - "CaseEventID": "reviewJudgeSupportRequest", + "CaseEventID": "closeAdminReviewSupportTask", + "CaseFieldID": "supportTaskState", + "ListElementCode": "adminTaskCreated", + "FieldDisplayOrder": 1, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "closeLOReviewSupportTask", + "CaseFieldID": "supportTaskState", + "ListElementCode": "legalOfficerTaskCreated", + "FieldDisplayOrder": 1, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "closeJudgeReviewSupportTask", + "CaseFieldID": "supportTaskState", + "ListElementCode": "judgeTaskCreated", + "FieldDisplayOrder": 1, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "createArrangeSupportTask", "CaseFieldID": "supportTaskState", "ListElementCode": "arrangeSupportTaskName", - "FieldDisplayOrder": 4, + "FieldDisplayOrder": 1, + "DisplayContext": "OPTIONAL", + "Publish": "Y" + }, + { + "ID": "SupportTaskState", + "CaseEventID": "createArrangeSupportTask", + "CaseFieldID": "supportTaskState", + "ListElementCode": "arrangeSupportTaskFlagId", + "FieldDisplayOrder": 2, "DisplayContext": "OPTIONAL", "Publish": "Y" } diff --git a/charts/et-cos/values.preview.template.yaml b/charts/et-cos/values.preview.template.yaml index 21115343ba..4c12d6f082 100644 --- a/charts/et-cos/values.preview.template.yaml +++ b/charts/et-cos/values.preview.template.yaml @@ -45,7 +45,6 @@ java: CASE_DOCUMENT_AM_URL: http://ccd-case-document-am-api-aat.service.core-compute-aat.internal RD_PROFESSIONAL_API_URL: http://rd-professional-api-aat.service.core-compute-aat.internal RD_COMMONDATA_API_URL: http://rd-commondata-api-aat.service.core-compute-aat.internal - WA_TASK_MANAGEMENT_API_URL: "http://{{ .Release.Name }}-wa-task-management-api" SECURE_DOC_STORE_FEATURE: true EM_CCD_ORCHESTRATOR_URL: http://em-ccd-orchestrator-{{ .Values.global.environment }}.service.core-compute-{{ .Values.global.environment }}.internal ACAS_BASE_URL: "https://api-dev-acas-01.azure-api.net/ECCLUAT" diff --git a/charts/et-cos/values.yaml b/charts/et-cos/values.yaml index 887ecc3996..b03e8b5516 100644 --- a/charts/et-cos/values.yaml +++ b/charts/et-cos/values.yaml @@ -77,7 +77,6 @@ java: CASE_DOCUMENT_AM_URL: http://ccd-case-document-am-api-{{ .Values.global.environment }}.service.core-compute-{{ .Values.global.environment }}.internal RD_PROFESSIONAL_API_URL: http://rd-professional-api-{{ .Values.global.environment }}.service.core-compute-{{ .Values.global.environment }}.internal RD_COMMONDATA_API_URL: http://rd-commondata-api-{{ .Values.global.environment }}.service.core-compute-{{ .Values.global.environment }}.internal - WA_TASK_MANAGEMENT_API_URL: http://wa-task-management-api-{{ .Values.global.environment }}.service.core-compute-{{ .Values.global.environment }}.internal SECURE_DOC_STORE_FEATURE: true EXUI_CASE_DETAILS_URL: "https://manage-case.{{ .Values.global.environment }}.platform.hmcts.net/cases/case-details/" CITIZEN_CASE_DETAILS_URL: "https://et-sya.{{ .Values.global.environment }}.platform.hmcts.net/citizen-hub/" diff --git a/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/types/SupportTaskState.java b/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/types/SupportTaskState.java index 231f37a560..42ec66cac5 100644 --- a/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/types/SupportTaskState.java +++ b/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/types/SupportTaskState.java @@ -21,4 +21,5 @@ public class SupportTaskState { private String judgeTaskCreated; private String judgeTaskRequired; private String arrangeSupportTaskName; + private String arrangeSupportTaskFlagId; } diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/client/WaTaskApiClient.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/client/WaTaskApiClient.java deleted file mode 100644 index 7bd6b8c5df..0000000000 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/client/WaTaskApiClient.java +++ /dev/null @@ -1,28 +0,0 @@ -package uk.gov.hmcts.ethos.replacement.docmosis.client; - -import org.springframework.cloud.openfeign.FeignClient; -import org.springframework.cloud.openfeign.FeignClientProperties; -import org.springframework.http.HttpHeaders; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestHeader; -import uk.gov.hmcts.ethos.replacement.docmosis.wa.model.TaskSearchRequest; -import uk.gov.hmcts.ethos.replacement.docmosis.wa.model.TaskSearchResponse; - -@FeignClient(name = "wa-task-management-api", url = "${wa.task-management.api.url}", - configuration = FeignClientProperties.FeignClientConfiguration.class) -public interface WaTaskApiClient { - - @PostMapping(value = "/task", consumes = "application/json") - TaskSearchResponse searchTasks( - @RequestHeader(HttpHeaders.AUTHORIZATION) String authorization, - @RequestHeader("ServiceAuthorization") String serviceAuthorization, - @RequestBody TaskSearchRequest searchRequest); - - @PostMapping(value = "/task/{task-id}/complete", consumes = "application/json") - void completeTask( - @RequestHeader(HttpHeaders.AUTHORIZATION) String authorization, - @RequestHeader("ServiceAuthorization") String serviceAuthorization, - @PathVariable("task-id") String taskId); -} diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/config/SupportTaskConfiguration.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/config/SupportTaskConfiguration.java index fcccd77542..0b51039767 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/config/SupportTaskConfiguration.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/config/SupportTaskConfiguration.java @@ -18,6 +18,7 @@ public class SupportTaskConfiguration { private Review review = new Review(); private Arrange arrange = new Arrange(); + private ClosureRetry closureRetry = new ClosureRetry(); @Data public static class Review { @@ -35,6 +36,14 @@ public static class Arrange { private List pathFlags = List.of(); } + @Data + public static class ClosureRetry { + private int maxAttempts = 3; + private long initialBackoffMs = 200; + private double multiplier = 2; + private long maxBackoffMs = 1000; + } + @Data public static class PathFlag { private String flagCode; diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/constants/SupportTaskConstants.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/constants/SupportTaskConstants.java index 15cb5744e4..db253cece0 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/constants/SupportTaskConstants.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/constants/SupportTaskConstants.java @@ -13,6 +13,10 @@ public final class SupportTaskConstants { public static final String EVENT_REVIEW_ADMIN_SUPPORT_REQUEST = "reviewAdminSupportRequest"; public static final String EVENT_REVIEW_LEGAL_OFFICER_SUPPORT_REQUEST = "reviewLOSupportRequest"; public static final String EVENT_REVIEW_JUDGE_SUPPORT_REQUEST = "reviewJudgeSupportRequest"; + public static final String EVENT_CLOSE_ADMIN_REVIEW_SUPPORT_TASK = "closeAdminReviewSupportTask"; + public static final String EVENT_CLOSE_LEGAL_OFFICER_REVIEW_SUPPORT_TASK = "closeLOReviewSupportTask"; + public static final String EVENT_CLOSE_JUDGE_REVIEW_SUPPORT_TASK = "closeJudgeReviewSupportTask"; + public static final String EVENT_CREATE_ARRANGE_SUPPORT_TASK = "createArrangeSupportTask"; public static final String FLAG_STATUS_ACTIVE = "Active"; public static final String FLAG_STATUS_REQUESTED = "Requested"; public static final String TASK_TYPE_REVIEW_SUPPORT_ADMIN = "ReviewSupportRequestAdmin"; diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java index 20f41176f8..18d2a22c50 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java @@ -50,16 +50,18 @@ import uk.gov.hmcts.ethos.replacement.docmosis.service.ScotlandFileLocationSelectionService; import uk.gov.hmcts.ethos.replacement.docmosis.service.SingleCaseMultipleMidEventValidationService; import uk.gov.hmcts.ethos.replacement.docmosis.service.SingleReferenceService; +import uk.gov.hmcts.ethos.replacement.docmosis.service.SupportTaskEventService; import uk.gov.hmcts.ethos.replacement.docmosis.service.SupportTaskService; import uk.gov.hmcts.ethos.replacement.docmosis.service.noc.NocRespondentRepresentativeService; import uk.gov.hmcts.ethos.replacement.docmosis.utils.LoggingUtils; import uk.gov.hmcts.ethos.replacement.docmosis.utils.noc.NocUtils; -import uk.gov.hmcts.ethos.replacement.docmosis.wa.ReviewSupportTaskCompletionService; +import uk.gov.hmcts.ethos.replacement.docmosis.wa.SupportTaskClientContextService; import java.io.IOException; import java.text.ParseException; import java.util.ArrayList; import java.util.List; +import java.util.Set; import static org.apache.commons.collections.CollectionUtils.isNotEmpty; import static org.apache.commons.lang3.StringUtils.defaultIfEmpty; @@ -89,6 +91,7 @@ public class CaseActionsForCaseWorkerController { private static final String TWO_HUNDRED = "200"; private static final String FOUR_HUNDRED = "400"; private static final String FIVE_HUNDRED = "500"; + private static final String CLIENT_CONTEXT = "client-context"; public static final String ACCESSED_SUCCESSFULLY = "Accessed successfully"; public static final String BAD_REQUEST = "Bad Request"; public static final String INTERNAL_SERVER_ERROR = "Internal Server Error"; @@ -121,7 +124,8 @@ public class CaseActionsForCaseWorkerController { private final FeatureToggleService featureToggleService; private final CaseFlagsService caseFlagsService; private final SupportTaskService supportTaskService; - private final ReviewSupportTaskCompletionService reviewSupportTaskCompletionService; + private final SupportTaskEventService supportTaskEventService; + private final SupportTaskClientContextService supportTaskClientContextService; private final CaseManagementLocationService caseManagementLocationService; private final Et1SubmissionService et1SubmissionService; private final NocRespondentHelper nocRespondentHelper; @@ -224,9 +228,11 @@ public ResponseEntity postDefaultValues( @Operation(summary = "Prepare Review Support and Arrange Support tasks for eligible Case Flags.") public ResponseEntity prepareSupportTasks( @RequestBody CallbackRequest callbackRequest, - @RequestHeader(AUTHORIZATION) String userToken) { + @RequestHeader(AUTHORIZATION) String userToken, + @RequestHeader(value = CLIENT_CONTEXT, required = false) String clientContext) { CaseDetails caseDetails = callbackRequest.getCaseDetails(); CaseData caseData = caseDetails.getCaseData(); + Set taskTypesToComplete = null; if (featureToggleService.isCaseFlagsV2Enabled(caseDetails.getCaseTypeId())) { caseManagementForCaseWorkerService.setNextListedDate(caseData); @@ -240,10 +246,7 @@ public ResponseEntity prepareSupportTasks( supportTaskService.prepareNewFlagReviewSupportTasks(caseData, caseDataBefore); } else if (EVENT_MANAGE_FLAGS.equals(callbackRequest.getEventId()) || EVENT_MANAGE_SUPPORT.equals(callbackRequest.getEventId())) { - reviewSupportTaskCompletionService.completeTasks( - caseDetails.getCaseId(), - userToken, - supportTaskService.prepareManagedReviewSupportTasks(caseData, caseDataBefore)); + taskTypesToComplete = supportTaskService.prepareManagedReviewSupportTasks(caseData, caseDataBefore); } if (EVENT_CREATE_FLAG.equals(callbackRequest.getEventId()) @@ -254,7 +257,8 @@ public ResponseEntity prepareSupportTasks( } } - return getCallbackRespEntityNoErrors(caseData); + return addTaskCompletionHeader( + getCallbackRespEntityNoErrors(caseData), clientContext, taskTypesToComplete); } @PostMapping(value = "/reviewSupportRequest/aboutToStart", consumes = APPLICATION_JSON_VALUE) @@ -273,10 +277,12 @@ public ResponseEntity prepareReviewSupportRequest( @Operation(summary = "Apply reviewed Case Flags and prepare the related support tasks.") public ResponseEntity applyReviewSupportRequest( @RequestBody CallbackRequest callbackRequest, - @RequestHeader(AUTHORIZATION) String userToken) { + @RequestHeader(AUTHORIZATION) String userToken, + @RequestHeader(value = CLIENT_CONTEXT, required = false) String clientContext) { CaseDetails caseDetails = callbackRequest.getCaseDetails(); CaseData caseData = caseDetails.getCaseData(); List errors = new ArrayList<>(); + Set taskTypesToComplete = null; if (featureToggleService.isCaseFlagsV2Enabled(caseDetails.getCaseTypeId())) { if (!supportTaskService.applyReviewSupportRequest(caseData)) { errors.add("Please select status other than Requested"); @@ -285,14 +291,49 @@ public ResponseEntity applyReviewSupportRequest( CaseData caseDataBefore = callbackRequest.getCaseDetailsBefore() == null ? null : callbackRequest.getCaseDetailsBefore().getCaseData(); - reviewSupportTaskCompletionService.completeTasks( - caseDetails.getCaseId(), - userToken, - supportTaskService.prepareManagedReviewSupportTasks(caseData, caseDataBefore)); + taskTypesToComplete = supportTaskService.prepareManagedReviewSupportTasks(caseData, caseDataBefore); supportTaskService.prepareArrangeSupportTask(caseData, caseDataBefore); } } - return getCallbackRespEntityErrors(errors, caseData); + return addTaskCompletionHeader( + getCallbackRespEntityErrors(errors, caseData), clientContext, taskTypesToComplete); + } + + @PostMapping(value = "/supportTasks/submitted", consumes = APPLICATION_JSON_VALUE) + @Operation(summary = "Trigger category-specific Review Support task cancellation events.") + public ResponseEntity closeReviewSupportTasks( + @RequestBody CallbackRequest callbackRequest) { + CaseDetails caseDetails = callbackRequest.getCaseDetails(); + if (featureToggleService.isCaseFlagsV2Enabled(caseDetails.getCaseTypeId())) { + CaseData caseDataBefore = callbackRequest.getCaseDetailsBefore() == null + ? null + : callbackRequest.getCaseDetailsBefore().getCaseData(); + supportTaskEventService.triggerArrangeSupportTaskEvents(caseDetails, + supportTaskService.additionalArrangeSupportTasks(caseDetails.getCaseData(), caseDataBefore)); + Set taskTypesToClose = supportTaskService.reviewTaskTypesToClose(caseDetails.getCaseData()); + supportTaskEventService.triggerReviewTaskClosureEvents(caseDetails, taskTypesToClose); + } + return getCallbackRespEntityNoErrors(caseDetails.getCaseData()); + } + + private ResponseEntity addTaskCompletionHeader( + ResponseEntity response, + String clientContext, + Set taskTypesToComplete) { + if (taskTypesToComplete == null) { + return response; + } + String updatedClientContext = supportTaskClientContextService.updateTaskCompletion( + clientContext, taskTypesToComplete); + if (updatedClientContext == null) { + supportTaskService.retainReviewTasksForSubmittedCallback( + response.getBody().getData(), taskTypesToComplete); + return response; + } + return ResponseEntity.status(response.getStatusCode()) + .headers(response.getHeaders()) + .header(CLIENT_CONTEXT, updatedClientContext) + .body(response.getBody()); } private List getValidationDate(String eventId, CaseDetails caseDetails) { diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1SubmissionController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1SubmissionController.java index 0887b4b611..50d1df7e6b 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1SubmissionController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1SubmissionController.java @@ -18,6 +18,9 @@ import uk.gov.hmcts.et.common.model.ccd.CaseDetails; import uk.gov.hmcts.ethos.replacement.docmosis.service.CaseManagementForCaseWorkerService; import uk.gov.hmcts.ethos.replacement.docmosis.service.Et1SubmissionService; +import uk.gov.hmcts.ethos.replacement.docmosis.service.FeatureToggleService; +import uk.gov.hmcts.ethos.replacement.docmosis.service.SupportTaskEventService; +import uk.gov.hmcts.ethos.replacement.docmosis.service.SupportTaskService; import java.io.IOException; @@ -39,6 +42,9 @@ public class Et1SubmissionController { private final CaseManagementForCaseWorkerService caseManagementForCaseWorkerService; private final Et1SubmissionService et1SubmissionService; + private final FeatureToggleService featureToggleService; + private final SupportTaskService supportTaskService; + private final SupportTaskEventService supportTaskEventService; @PostMapping(value = "/submitted", consumes = APPLICATION_JSON_VALUE) @Operation(summary = "Add HMCTSServiceId to supplementary_data on a case and send confirmation email.") @@ -57,6 +63,12 @@ public ResponseEntity submitted( CaseDetails caseDetails = ccdRequest.getCaseDetails(); caseManagementForCaseWorkerService.setHmctsServiceIdSupplementary(caseDetails); et1SubmissionService.sendEt1ConfirmationClaimant(caseDetails, userToken); + if (featureToggleService.isCaseFlagsV2Enabled(caseDetails.getCaseTypeId())) { + CaseDetails caseDetailsBefore = ccdRequest.getCaseDetailsBefore(); + supportTaskEventService.triggerArrangeSupportTaskEvents(caseDetails, + supportTaskService.additionalArrangeSupportTasks(caseDetails.getCaseData(), + caseDetailsBefore == null ? null : caseDetailsBefore.getCaseData())); + } return getCallbackRespEntityNoErrors(caseDetails.getCaseData()); } } diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskEventService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskEventService.java new file mode 100644 index 0000000000..0c24f29ccd --- /dev/null +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskEventService.java @@ -0,0 +1,182 @@ +package uk.gov.hmcts.ethos.replacement.docmosis.service; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.retry.support.RetryTemplate; +import org.springframework.stereotype.Service; +import org.springframework.web.client.HttpClientErrorException; +import org.springframework.web.client.HttpServerErrorException; +import org.springframework.web.client.ResourceAccessException; +import uk.gov.hmcts.ecm.common.client.CcdClient; +import uk.gov.hmcts.et.common.model.ccd.CCDRequest; +import uk.gov.hmcts.et.common.model.ccd.CaseData; +import uk.gov.hmcts.et.common.model.ccd.CaseDetails; +import uk.gov.hmcts.et.common.model.ccd.types.SupportTaskState; +import uk.gov.hmcts.ethos.replacement.docmosis.config.SupportTaskConfiguration; +import uk.gov.hmcts.ethos.replacement.docmosis.config.SupportTaskConfiguration.ClosureRetry; +import uk.gov.hmcts.ethos.replacement.docmosis.exceptions.GenericRuntimeException; + +import java.io.IOException; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.function.BiConsumer; +import java.util.function.Function; + +import static uk.gov.hmcts.ecm.common.model.helper.Constants.NO; +import static uk.gov.hmcts.ecm.common.model.helper.Constants.YES; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.EVENT_CLOSE_ADMIN_REVIEW_SUPPORT_TASK; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.EVENT_CLOSE_JUDGE_REVIEW_SUPPORT_TASK; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.EVENT_CLOSE_LEGAL_OFFICER_REVIEW_SUPPORT_TASK; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.EVENT_CREATE_ARRANGE_SUPPORT_TASK; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.TASK_TYPE_REVIEW_SUPPORT_ADMIN; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.TASK_TYPE_REVIEW_SUPPORT_JUDGE; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.TASK_TYPE_REVIEW_SUPPORT_LEGAL_OFFICER; + +@Service +@Slf4j +public class SupportTaskEventService { + private final CcdClient ccdClient; + private final AdminUserService adminUserService; + private final RetryTemplate retryTemplate; + private final int maxAttempts; + + public SupportTaskEventService(CcdClient ccdClient, + AdminUserService adminUserService, + SupportTaskConfiguration configuration) { + this.ccdClient = ccdClient; + this.adminUserService = adminUserService; + ClosureRetry retry = configuration.getClosureRetry(); + maxAttempts = retry.getMaxAttempts(); + retryTemplate = RetryTemplate.builder() + .maxAttempts(maxAttempts) + .exponentialBackoff(retry.getInitialBackoffMs(), retry.getMultiplier(), retry.getMaxBackoffMs()) + .retryOn(SupportTaskEventService::isTransientFailure) + .build(); + } + + public void triggerReviewTaskClosureEvents(CaseDetails caseDetails, Set taskTypes) { + triggerIfRequired(caseDetails, taskTypes, TASK_TYPE_REVIEW_SUPPORT_ADMIN, + EVENT_CLOSE_ADMIN_REVIEW_SUPPORT_TASK, + SupportTaskState::getAdminTaskCreated, SupportTaskState::setAdminTaskCreated); + triggerIfRequired(caseDetails, taskTypes, TASK_TYPE_REVIEW_SUPPORT_LEGAL_OFFICER, + EVENT_CLOSE_LEGAL_OFFICER_REVIEW_SUPPORT_TASK, + SupportTaskState::getLegalOfficerTaskCreated, SupportTaskState::setLegalOfficerTaskCreated); + triggerIfRequired(caseDetails, taskTypes, TASK_TYPE_REVIEW_SUPPORT_JUDGE, + EVENT_CLOSE_JUDGE_REVIEW_SUPPORT_TASK, + SupportTaskState::getJudgeTaskCreated, SupportTaskState::setJudgeTaskCreated); + } + + public void triggerArrangeSupportTaskEvents( + CaseDetails caseDetails, List tasks) { + tasks.forEach(task -> triggerArrangeSupportTaskEvent(caseDetails, task)); + } + + private void triggerArrangeSupportTaskEvent( + CaseDetails caseDetails, SupportTaskService.ArrangeSupportTask task) { + String caseId = caseDetails.getCaseId(); + try { + boolean submitted = retryTemplate.execute(context -> submitArrangeSupportTaskEvent(caseDetails, task)); + if (submitted) { + log.info("Triggered {} for flag {} on case {}", EVENT_CREATE_ARRANGE_SUPPORT_TASK, + task.flagId(), caseId); + } + } catch (Exception exception) { + log.error("Unable to trigger {} for flag {} on case {} after {} attempts", + EVENT_CREATE_ARRANGE_SUPPORT_TASK, task.flagId(), caseId, maxAttempts, exception); + throw new GenericRuntimeException(exception); + } + } + + private boolean submitArrangeSupportTaskEvent( + CaseDetails caseDetails, SupportTaskService.ArrangeSupportTask task) throws IOException { + String token = adminUserService.getAdminUserToken(); + String caseId = caseDetails.getCaseId(); + CCDRequest request = ccdClient.startEventForCase(token, caseDetails.getCaseTypeId(), + caseDetails.getJurisdiction(), caseId, EVENT_CREATE_ARRANGE_SUPPORT_TASK); + CaseData latestCaseData = request.getCaseDetails().getCaseData(); + SupportTaskState state = latestCaseData.getSupportTaskState(); + if (state != null && Objects.equals(task.flagId(), state.getArrangeSupportTaskFlagId())) { + return false; + } + if (state == null) { + state = new SupportTaskState(); + latestCaseData.setSupportTaskState(state); + } + state.setArrangeSupportTaskName(task.taskName()); + state.setArrangeSupportTaskFlagId(task.flagId()); + ccdClient.submitEventForCase(token, latestCaseData, caseDetails.getCaseTypeId(), + caseDetails.getJurisdiction(), request, caseId); + return true; + } + + private void triggerIfRequired(CaseDetails caseDetails, + Set taskTypes, + String taskType, + String eventId, + Function taskCreatedGetter, + BiConsumer taskCreatedSetter) { + if (!taskTypes.contains(taskType)) { + return; + } + + String caseId = caseDetails.getCaseId(); + try { + boolean submitted = retryTemplate.execute(context -> { + if (context.getRetryCount() > 0) { + log.warn("Retrying {} for case {}, attempt {} of {}", eventId, caseId, + context.getRetryCount() + 1, maxAttempts); + } + return submitClosureEvent(caseDetails, eventId, taskCreatedGetter, taskCreatedSetter); + }); + if (submitted) { + log.info("Triggered {} for case {}", eventId, caseId); + } else { + log.info("Closure event {} was already submitted for case {}", eventId, caseId); + } + } catch (Exception exception) { + log.error("Unable to trigger {} for case {} after {} attempts", eventId, caseId, maxAttempts, exception); + throw new GenericRuntimeException(exception); + } + } + + private boolean submitClosureEvent(CaseDetails caseDetails, + String eventId, + Function taskCreatedGetter, + BiConsumer taskCreatedSetter) throws IOException { + String token = adminUserService.getAdminUserToken(); + String caseId = caseDetails.getCaseId(); + CCDRequest request = ccdClient.startEventForCase(token, caseDetails.getCaseTypeId(), + caseDetails.getJurisdiction(), caseId, eventId); + CaseData latestCaseData = request.getCaseDetails().getCaseData(); + SupportTaskState state = latestCaseData.getSupportTaskState(); + if (state != null && !isTaskCreated(taskCreatedGetter.apply(state))) { + return false; + } + if (state == null) { + state = new SupportTaskState(); + latestCaseData.setSupportTaskState(state); + } + taskCreatedSetter.accept(state, NO); + ccdClient.submitEventForCase(token, latestCaseData, caseDetails.getCaseTypeId(), + caseDetails.getJurisdiction(), request, caseId); + return true; + } + + private static boolean isTaskCreated(String taskCreated) { + return YES.equalsIgnoreCase(taskCreated) || Boolean.parseBoolean(taskCreated); + } + + private static boolean isTransientFailure(Throwable exception) { + if (exception instanceof IOException + || exception instanceof ResourceAccessException + || exception instanceof HttpServerErrorException) { + return true; + } + if (exception instanceof HttpClientErrorException clientError) { + return clientError.getStatusCode() == HttpStatus.CONFLICT + || clientError.getStatusCode() == HttpStatus.TOO_MANY_REQUESTS; + } + return false; + } +} diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java index 80c0294056..3aa7253198 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java @@ -14,6 +14,7 @@ import uk.gov.hmcts.ethos.replacement.docmosis.config.SupportTaskConfiguration.PathFlag; import java.util.Comparator; +import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashSet; import java.util.List; @@ -125,6 +126,48 @@ public Set prepareManagedReviewSupportTasks(CaseData caseData, CaseData return taskTypesToComplete; } + public void retainReviewTasksForSubmittedCallback(CaseData caseData, Set taskTypes) { + SupportTaskState state = taskState(caseData); + if (taskTypes.contains(TASK_TYPE_REVIEW_SUPPORT_ADMIN)) { + state.setAdminTaskCreated(YES); + } + if (taskTypes.contains(TASK_TYPE_REVIEW_SUPPORT_LEGAL_OFFICER)) { + state.setLegalOfficerTaskCreated(YES); + } + if (taskTypes.contains(TASK_TYPE_REVIEW_SUPPORT_JUDGE)) { + state.setJudgeTaskCreated(YES); + } + } + + public Set reviewTaskTypesToClose(CaseData caseData) { + SupportTaskState state = caseData.getSupportTaskState(); + if (state == null) { + return Set.of(); + } + + List flags = allFlagItems(caseData.getAllPartyFlags()) + .map(GenericTypeItem::getValue) + .toList(); + Set taskTypes = new LinkedHashSet<>(); + addTaskTypeToClose(flags, adminReviewFlag(), state.getAdminTaskCreated(), + TASK_TYPE_REVIEW_SUPPORT_ADMIN, taskTypes); + addTaskTypeToClose(flags, legalOfficerReviewFlag(), state.getLegalOfficerTaskCreated(), + TASK_TYPE_REVIEW_SUPPORT_LEGAL_OFFICER, taskTypes); + addTaskTypeToClose(flags, judgeReviewFlag(), state.getJudgeTaskCreated(), + TASK_TYPE_REVIEW_SUPPORT_JUDGE, taskTypes); + return taskTypes; + } + + private static void addTaskTypeToClose(List flags, + Predicate eligibleFlag, + String taskCreated, + String taskType, + Set taskTypes) { + if (isTaskCreated(taskCreated) && !hasRequestedFlag(flags, eligibleFlag)) { + taskTypes.add(taskType); + } + } + public void prepareReviewSupportRequest(CaseData caseData, String eventId) { Predicate eligibleFlag = reviewFlag(eventId); ListTypeItem selectedFlags = allPartyFlagSections(caseData.getAllPartyFlags()) @@ -251,22 +294,37 @@ private static boolean isRequested(FlagDetailType flag) { public void prepareArrangeSupportTask(CaseData caseData, CaseData caseDataBefore) { SupportTaskState taskState = taskState(caseData); taskState.setArrangeSupportTaskName(null); + arrangeSupportTasks(caseData, caseDataBefore).stream() + .findFirst() + .map(ArrangeSupportTask::taskName) + .ifPresent(taskState::setArrangeSupportTaskName); + } + + public List additionalArrangeSupportTasks(CaseData caseData, CaseData caseDataBefore) { + return arrangeSupportTasks(caseData, caseDataBefore).stream().skip(1).toList(); + } + private List arrangeSupportTasks(CaseData caseData, CaseData caseDataBefore) { Map flagTitles = configuration.getArrange().getFlagTitles(); if (flagTitles.isEmpty() && configuration.getArrange().getPathFlags().isEmpty()) { - return; + return List.of(); } List> previousFlags = allFlagItems( caseDataBefore == null ? null : caseDataBefore.getAllPartyFlags()).toList(); - allFlagItems(caseData.getAllPartyFlags()) - .filter(item -> FLAG_STATUS_ACTIVE.equals(item.getValue().getStatus())) - .filter(item -> wasNotPreviouslyActive(item, previousFlags)) - .map(GenericTypeItem::getValue) - .map(this::arrangeTaskName) - .flatMap(Optional::stream) - .findFirst() - .ifPresent(taskState::setArrangeSupportTaskName); + List> currentFlags = allFlagItems(caseData.getAllPartyFlags()).toList(); + List tasks = new ArrayList<>(); + for (int index = 0; index < currentFlags.size(); index++) { + GenericTypeItem item = currentFlags.get(index); + if (!FLAG_STATUS_ACTIVE.equals(item.getValue().getStatus()) + || !wasNotPreviouslyActive(item, previousFlags)) { + continue; + } + int flagIndex = index; + arrangeTaskName(item.getValue()).ifPresent(taskName -> tasks.add(new ArrangeSupportTask( + item.getId() == null ? "flag-" + flagIndex : item.getId(), taskName))); + } + return tasks; } public void prepareNewFlagArrangeSupportTask(CaseData caseData, CaseData caseDataBefore) { @@ -286,6 +344,9 @@ private Predicate adminReviewFlag() { configuration.getReview().getAdminPathFlags()); } + public record ArrangeSupportTask(String flagId, String taskName) { + } + private Predicate legalOfficerReviewFlag() { return eligibleFlag(configuration.getReview().getLegalOfficerFlagCodes(), configuration.getReview().getLegalOfficerPathFlags()); diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/ReviewSupportTaskCompletionService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/ReviewSupportTaskCompletionService.java deleted file mode 100644 index 107a88d121..0000000000 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/ReviewSupportTaskCompletionService.java +++ /dev/null @@ -1,68 +0,0 @@ -package uk.gov.hmcts.ethos.replacement.docmosis.wa; - -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; -import uk.gov.hmcts.ethos.replacement.docmosis.client.WaTaskApiClient; -import uk.gov.hmcts.ethos.replacement.docmosis.wa.model.TaskSearchParameter; -import uk.gov.hmcts.ethos.replacement.docmosis.wa.model.TaskSearchRequest; -import uk.gov.hmcts.ethos.replacement.docmosis.wa.model.TaskSearchResponse; -import uk.gov.hmcts.ethos.replacement.docmosis.wa.model.WaTask; -import uk.gov.hmcts.reform.authorisation.generators.AuthTokenGenerator; - -import java.util.List; -import java.util.Set; - -import static org.apache.commons.lang3.StringUtils.isBlank; - -@Service -@RequiredArgsConstructor -@Slf4j -public class ReviewSupportTaskCompletionService { - private static final String OPERATOR_IN = "IN"; - private static final List ACTIVE_TASK_STATES = List.of("assigned", "unassigned"); - - private final WaTaskApiClient waTaskApiClient; - private final AuthTokenGenerator serviceAuthTokenGenerator; - - public void completeTasks(String caseId, String userToken, Set taskTypes) { - if (isBlank(caseId) || isBlank(userToken) || taskTypes == null || taskTypes.isEmpty()) { - return; - } - - try { - String serviceToken = serviceAuthTokenGenerator.generate(); - List tasks = findActiveTasks(caseId, userToken, serviceToken, taskTypes); - log.info("Case {}: {} active Review Support task(s) to complete", caseId, tasks.size()); - tasks.forEach(task -> complete(task, caseId, userToken, serviceToken)); - } catch (Exception e) { - log.error("Error completing Review Support tasks on case {}: {}", caseId, e.getMessage(), e); - } - } - - private List findActiveTasks(String caseId, String userToken, String serviceToken, - Set taskTypes) { - TaskSearchRequest request = TaskSearchRequest.builder() - .searchParameters(List.of( - searchParameter("case_id", List.of(caseId)), - searchParameter("task_type", List.copyOf(taskTypes)), - searchParameter("state", ACTIVE_TASK_STATES))) - .build(); - TaskSearchResponse response = waTaskApiClient.searchTasks(userToken, serviceToken, request); - return response == null || response.getTasks() == null ? List.of() : response.getTasks(); - } - - private void complete(WaTask task, String caseId, String userToken, String serviceToken) { - try { - waTaskApiClient.completeTask(userToken, serviceToken, task.getId()); - log.info("Completed task {} ({}) on case {}", task.getId(), task.getType(), caseId); - } catch (Exception e) { - log.error("Could not complete task {} ({}) on case {}: {}", - task.getId(), task.getType(), caseId, e.getMessage(), e); - } - } - - private static TaskSearchParameter searchParameter(String key, List values) { - return TaskSearchParameter.builder().key(key).operator(OPERATOR_IN).values(values).build(); - } -} diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/SupportTaskClientContextService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/SupportTaskClientContextService.java new file mode 100644 index 0000000000..f362ad8b6c --- /dev/null +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/SupportTaskClientContextService.java @@ -0,0 +1,50 @@ +package uk.gov.hmcts.ethos.replacement.docmosis.wa; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.io.IOException; +import java.util.Base64; +import java.util.Set; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.apache.commons.lang3.StringUtils.isBlank; + +@Service +@RequiredArgsConstructor +@Slf4j +public class SupportTaskClientContextService { + private static final String CLIENT_CONTEXT = "client_context"; + private static final String USER_TASK = "user_task"; + private static final String TASK_DATA = "task_data"; + private static final String TASK_TYPE = "type"; + private static final String COMPLETE_TASK = "complete_task"; + + private final ObjectMapper objectMapper; + + public String updateTaskCompletion(String encodedClientContext, Set taskTypesToComplete) { + if (isBlank(encodedClientContext) || taskTypesToComplete == null) { + return null; + } + + try { + JsonNode root = objectMapper.readTree(Base64.getDecoder().decode(encodedClientContext)); + JsonNode userTask = root.path(CLIENT_CONTEXT).path(USER_TASK); + if (!(userTask instanceof ObjectNode userTaskObject)) { + return null; + } + + String taskType = userTask.path(TASK_DATA).path(TASK_TYPE).textValue(); + boolean completeTask = taskType != null && taskTypesToComplete.contains(taskType); + userTaskObject.put(COMPLETE_TASK, completeTask); + return Base64.getEncoder().encodeToString(objectMapper.writeValueAsString(root).getBytes(UTF_8)); + } catch (IllegalArgumentException | IOException e) { + log.warn("Unable to update task completion in client-context", e); + return null; + } + } +} diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/model/TaskSearchParameter.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/model/TaskSearchParameter.java deleted file mode 100644 index acb56bb116..0000000000 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/model/TaskSearchParameter.java +++ /dev/null @@ -1,20 +0,0 @@ -package uk.gov.hmcts.ethos.replacement.docmosis.wa.model; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.Builder; -import lombok.Data; -import lombok.extern.jackson.Jacksonized; - -import java.util.List; - -@Data -@Builder -@Jacksonized -public class TaskSearchParameter { - @JsonProperty("key") - private String key; - @JsonProperty("operator") - private String operator; - @JsonProperty("values") - private List values; -} diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/model/TaskSearchRequest.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/model/TaskSearchRequest.java deleted file mode 100644 index 91533c4b7f..0000000000 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/model/TaskSearchRequest.java +++ /dev/null @@ -1,16 +0,0 @@ -package uk.gov.hmcts.ethos.replacement.docmosis.wa.model; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.Builder; -import lombok.Data; -import lombok.extern.jackson.Jacksonized; - -import java.util.List; - -@Data -@Builder -@Jacksonized -public class TaskSearchRequest { - @JsonProperty("search_parameters") - private List searchParameters; -} diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/model/TaskSearchResponse.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/model/TaskSearchResponse.java deleted file mode 100644 index 42288c13ac..0000000000 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/model/TaskSearchResponse.java +++ /dev/null @@ -1,18 +0,0 @@ -package uk.gov.hmcts.ethos.replacement.docmosis.wa.model; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.Builder; -import lombok.Data; -import lombok.extern.jackson.Jacksonized; - -import java.util.List; - -@Data -@Builder -@Jacksonized -@JsonIgnoreProperties(ignoreUnknown = true) -public class TaskSearchResponse { - @JsonProperty("tasks") - private List tasks; -} diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/model/WaTask.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/model/WaTask.java deleted file mode 100644 index ee8129dda9..0000000000 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/model/WaTask.java +++ /dev/null @@ -1,18 +0,0 @@ -package uk.gov.hmcts.ethos.replacement.docmosis.wa.model; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.Builder; -import lombok.Data; -import lombok.extern.jackson.Jacksonized; - -@Data -@Builder -@Jacksonized -@JsonIgnoreProperties(ignoreUnknown = true) -public class WaTask { - @JsonProperty("id") - private String id; - @JsonProperty("type") - private String type; -} diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index fec3c1a63e..f9eb2dbd26 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -120,11 +120,6 @@ case_document_am: rd_professional-api-url: ${RD_PROFESSIONAL_API_URL:http://localhost:4507} rd_commondata-api-url: ${RD_COMMONDATA_API_URL:http://localhost:4507} -wa: - task-management: - api: - url: ${WA_TASK_MANAGEMENT_API_URL:http://localhost:8087} - feature: secure-doc-store: enabled: ${SECURE_DOC_STORE_FEATURE:false} diff --git a/src/main/resources/support-tasks.yml b/src/main/resources/support-tasks.yml index f6f957e916..4c69413754 100644 --- a/src/main/resources/support-tasks.yml +++ b/src/main/resources/support-tasks.yml @@ -1,4 +1,9 @@ support-tasks: + closure-retry: + max-attempts: 3 + initial-backoff-ms: 200 + multiplier: 2 + max-backoff-ms: 1000 review: admin-flag-codes: - RA0021 diff --git a/src/test/apiTest/resources/application.yaml b/src/test/apiTest/resources/application.yaml index 1193897d74..50f052a013 100644 --- a/src/test/apiTest/resources/application.yaml +++ b/src/test/apiTest/resources/application.yaml @@ -197,11 +197,6 @@ apply_noc_access_api_assignments_path: /noc/apply-decision rd_professional-api-url: ${RD_PROFESSIONAL_API_URL:http://localhost:4507} rd_commondata-api-url: ${RD_COMMONDATA_API_URL:http://localhost:4507} -wa: - task-management: - api: - url: ${WA_TASK_MANAGEMENT_API_URL:http://localhost:8087} - case-details-url: citizen: ${CITIZEN_CASE_DETAILS_URL:http://localhost:3001/citizen-hub/} exui: ${EXUI_CASE_DETAILS_URL:http://localhost:3000/cases/case-details/} diff --git a/src/test/integration/resources/application.yaml b/src/test/integration/resources/application.yaml index 6c5db7b840..3d50525823 100644 --- a/src/test/integration/resources/application.yaml +++ b/src/test/integration/resources/application.yaml @@ -45,11 +45,6 @@ case_document_am: rd_professional-api-url: http://localhost:4507 rd_commondata-api-url: http://localhost:4507 -wa: - task-management: - api: - url: http://localhost:8087 - feature: secure-doc-store: enabled: 'false' diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java index d3887d6a5d..903c4e32b0 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java @@ -49,11 +49,12 @@ import uk.gov.hmcts.ethos.replacement.docmosis.service.ScotlandFileLocationSelectionService; import uk.gov.hmcts.ethos.replacement.docmosis.service.SingleCaseMultipleMidEventValidationService; import uk.gov.hmcts.ethos.replacement.docmosis.service.SingleReferenceService; +import uk.gov.hmcts.ethos.replacement.docmosis.service.SupportTaskEventService; import uk.gov.hmcts.ethos.replacement.docmosis.service.SupportTaskService; import uk.gov.hmcts.ethos.replacement.docmosis.service.noc.NocRespondentRepresentativeService; import uk.gov.hmcts.ethos.replacement.docmosis.utils.InternalException; import uk.gov.hmcts.ethos.replacement.docmosis.utils.JsonMapper; -import uk.gov.hmcts.ethos.replacement.docmosis.wa.ReviewSupportTaskCompletionService; +import uk.gov.hmcts.ethos.replacement.docmosis.wa.SupportTaskClientContextService; import java.io.File; import java.io.IOException; @@ -84,6 +85,7 @@ import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.when; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static uk.gov.hmcts.ecm.common.model.helper.Constants.INDIVIDUAL_TYPE_CLAIMANT; @@ -100,6 +102,7 @@ class CaseActionsForCaseWorkerControllerTest extends BaseControllerTest { private static final String PRE_DEFAULT_VALUES_URL = "/preDefaultValues"; private static final String POST_DEFAULT_VALUES_URL = "/postDefaultValues"; private static final String SUPPORT_TASKS_URL = "/supportTasks/aboutToSubmit"; + private static final String SUPPORT_TASKS_SUBMITTED_URL = "/supportTasks/submitted"; private static final String REVIEW_SUPPORT_REQUEST_ABOUT_TO_START_URL = "/reviewSupportRequest/aboutToStart"; private static final String REVIEW_SUPPORT_REQUEST_ABOUT_TO_SUBMIT_URL = @@ -140,6 +143,9 @@ class CaseActionsForCaseWorkerControllerTest extends BaseControllerTest { private static final String ADD_SERVICE_ID_URL = "/addServiceId"; private static final String AUTHORIZATION = "Authorization"; + private static final String CLIENT_CONTEXT = "client-context"; + private static final String ENCODED_CLIENT_CONTEXT = "encoded-client-context"; + private static final String UPDATED_CLIENT_CONTEXT = "updated-client-context"; @Autowired private JsonMapper jsonMapper; @Autowired @@ -199,7 +205,10 @@ class CaseActionsForCaseWorkerControllerTest extends BaseControllerTest { private SupportTaskService supportTaskService; @MockitoBean - private ReviewSupportTaskCompletionService reviewSupportTaskCompletionService; + private SupportTaskEventService supportTaskEventService; + + @MockitoBean + private SupportTaskClientContextService supportTaskClientContextService; @MockitoBean private FeatureToggleService featureToggleService; @@ -431,17 +440,22 @@ void preparesReviewSupportTaskCompletionForManagedCaseFlags(String eventId) { when(featureToggleService.isCaseFlagsV2Enabled(anyString())).thenReturn(true); when(supportTaskService.prepareManagedReviewSupportTasks(any(CaseData.class), any(CaseData.class))) .thenReturn(Set.of("ReviewSupportRequestAdmin")); + when(supportTaskClientContextService.updateTaskCompletion( + ENCODED_CLIENT_CONTEXT, Set.of("ReviewSupportRequestAdmin"))) + .thenReturn(UPDATED_CLIENT_CONTEXT); mvc.perform(post(SUPPORT_TASKS_URL) .content(requestContent2.toString()) .header(AUTHORIZATION, AUTH_TOKEN) + .header(CLIENT_CONTEXT, ENCODED_CLIENT_CONTEXT) .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()); + .andExpect(status().isOk()) + .andExpect(header().string(CLIENT_CONTEXT, UPDATED_CLIENT_CONTEXT)); verify(supportTaskService).prepareManagedReviewSupportTasks( any(CaseData.class), any(CaseData.class)); - verify(reviewSupportTaskCompletionService).completeTasks( - anyString(), eq(AUTH_TOKEN), eq(Set.of("ReviewSupportRequestAdmin"))); + verify(supportTaskClientContextService).updateTaskCompletion( + ENCODED_CLIENT_CONTEXT, Set.of("ReviewSupportRequestAdmin")); if ("manageFlags".equals(eventId)) { verify(supportTaskService).prepareArrangeSupportTask( any(CaseData.class), any(CaseData.class)); @@ -449,6 +463,62 @@ void preparesReviewSupportTaskCompletionForManagedCaseFlags(String eventId) { verify(caseManagementForCaseWorkerService).setNextListedDate(any(CaseData.class)); } + @ParameterizedTest + @ValueSource(strings = {"manageFlags", "manageSupport"}) + @SneakyThrows + void retainsReviewTaskForSubmittedCallbackWhenClientContextIsMissing(String eventId) { + ((ObjectNode) requestContent2).put("event_id", eventId); + ((ObjectNode) requestContent2).set("case_details_before", + requestContent2.get("case_details").deepCopy()); + Set taskTypes = Set.of("ReviewSupportRequestAdmin"); + when(featureToggleService.isCaseFlagsV2Enabled(anyString())).thenReturn(true); + when(supportTaskService.prepareManagedReviewSupportTasks(any(CaseData.class), any(CaseData.class))) + .thenReturn(taskTypes); + + mvc.perform(post(SUPPORT_TASKS_URL) + .content(requestContent2.toString()) + .header(AUTHORIZATION, AUTH_TOKEN) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(header().doesNotExist(CLIENT_CONTEXT)); + + verify(supportTaskClientContextService).updateTaskCompletion(null, taskTypes); + verify(supportTaskService).retainReviewTasksForSubmittedCallback(any(CaseData.class), eq(taskTypes)); + } + + @Test + @SneakyThrows + void triggersCategorySpecificReviewTaskClosureEventsAfterSubmission() { + Set taskTypes = Set.of("ReviewSupportRequestAdmin", "ReviewSupportRequestJudge"); + List arrangeTasks = List.of( + new SupportTaskService.ArrangeSupportTask("flag-2", "Sign language interpreter")); + when(featureToggleService.isCaseFlagsV2Enabled(anyString())).thenReturn(true); + when(supportTaskService.reviewTaskTypesToClose(any(CaseData.class))).thenReturn(taskTypes); + when(supportTaskService.additionalArrangeSupportTasks(any(CaseData.class), nullable(CaseData.class))) + .thenReturn(arrangeTasks); + + mvc.perform(post(SUPPORT_TASKS_SUBMITTED_URL) + .content(requestContent2.toString()) + .header(AUTHORIZATION, AUTH_TOKEN) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + + verify(supportTaskEventService).triggerArrangeSupportTaskEvents(any(CaseDetails.class), eq(arrangeTasks)); + verify(supportTaskEventService).triggerReviewTaskClosureEvents(any(CaseDetails.class), eq(taskTypes)); + } + + @Test + @SneakyThrows + void doesNotTriggerReviewTaskClosureEventsWhenCaseFlagsV2IsDisabled() { + mvc.perform(post(SUPPORT_TASKS_SUBMITTED_URL) + .content(requestContent2.toString()) + .header(AUTHORIZATION, AUTH_TOKEN) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + + verifyNoInteractions(supportTaskEventService); + } + @ParameterizedTest @ValueSource(strings = { "reviewAdminSupportRequest", @@ -479,18 +549,23 @@ void appliesReviewedFlagAndPreparesCompletionAndArrangeTasks() { when(supportTaskService.applyReviewSupportRequest(any(CaseData.class))).thenReturn(true); when(supportTaskService.prepareManagedReviewSupportTasks(any(CaseData.class), any(CaseData.class))) .thenReturn(Set.of("ReviewSupportRequestAdmin")); + when(supportTaskClientContextService.updateTaskCompletion( + ENCODED_CLIENT_CONTEXT, Set.of("ReviewSupportRequestAdmin"))) + .thenReturn(UPDATED_CLIENT_CONTEXT); mvc.perform(post(REVIEW_SUPPORT_REQUEST_ABOUT_TO_SUBMIT_URL) .content(requestContent2.toString()) .header(AUTHORIZATION, AUTH_TOKEN) + .header(CLIENT_CONTEXT, ENCODED_CLIENT_CONTEXT) .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) + .andExpect(header().string(CLIENT_CONTEXT, UPDATED_CLIENT_CONTEXT)) .andExpect(jsonPath(JsonMapper.ERRORS, hasSize(0))); verify(supportTaskService).prepareManagedReviewSupportTasks( any(CaseData.class), any(CaseData.class)); - verify(reviewSupportTaskCompletionService).completeTasks( - anyString(), eq(AUTH_TOKEN), eq(Set.of("ReviewSupportRequestAdmin"))); + verify(supportTaskClientContextService).updateTaskCompletion( + ENCODED_CLIENT_CONTEXT, Set.of("ReviewSupportRequestAdmin")); verify(supportTaskService).prepareArrangeSupportTask( any(CaseData.class), any(CaseData.class)); verify(caseManagementForCaseWorkerService).setNextListedDate(any(CaseData.class)); @@ -512,7 +587,7 @@ void rejectsReviewSupportRequestWhenNoFlagWasActioned() { verify(supportTaskService, never()).prepareManagedReviewSupportTasks( any(CaseData.class), nullable(CaseData.class)); - verifyNoInteractions(reviewSupportTaskCompletionService); + verifyNoInteractions(supportTaskClientContextService); verify(caseManagementForCaseWorkerService, never()).setNextListedDate(any(CaseData.class)); } diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1SubmissionControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1SubmissionControllerTest.java index 1839c67cbb..c7791aedc6 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1SubmissionControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1SubmissionControllerTest.java @@ -14,11 +14,15 @@ import uk.gov.hmcts.et.common.model.ccd.CaseDetails; import uk.gov.hmcts.ethos.replacement.docmosis.service.CaseManagementForCaseWorkerService; import uk.gov.hmcts.ethos.replacement.docmosis.service.Et1SubmissionService; +import uk.gov.hmcts.ethos.replacement.docmosis.service.FeatureToggleService; +import uk.gov.hmcts.ethos.replacement.docmosis.service.SupportTaskEventService; +import uk.gov.hmcts.ethos.replacement.docmosis.service.SupportTaskService; import uk.gov.hmcts.ethos.replacement.docmosis.utils.JsonMapper; import uk.gov.hmcts.ethos.utils.CCDRequestBuilder; import java.io.IOException; import java.net.URISyntaxException; +import java.util.List; import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; @@ -42,6 +46,12 @@ class Et1SubmissionControllerTest extends BaseControllerTest { private CaseManagementForCaseWorkerService caseManagementForCaseWorkerService; @MockitoBean private Et1SubmissionService et1SubmissionService; + @MockitoBean + private FeatureToggleService featureToggleService; + @MockitoBean + private SupportTaskService supportTaskService; + @MockitoBean + private SupportTaskEventService supportTaskEventService; @Autowired private MockMvc mvc; @Autowired @@ -82,6 +92,25 @@ void addServiceId_success() throws Exception { .sendEt1ConfirmationClaimant(any(CaseDetails.class), eq(AUTH_TOKEN)); } + @Test + void createsAdditionalArrangeSupportTasksForCaseFlagsV2() throws Exception { + List tasks = List.of( + new SupportTaskService.ArrangeSupportTask("flag-2", "Support filling in forms")); + org.mockito.Mockito.when(featureToggleService.isCaseFlagsV2Enabled(ENGLANDWALES_CASE_TYPE_ID)) + .thenReturn(true); + org.mockito.Mockito.when(supportTaskService.additionalArrangeSupportTasks( + any(), org.mockito.ArgumentMatchers.nullable(CaseData.class))) + .thenReturn(tasks); + + mvc.perform(post(SUBMITTED_URL) + .contentType(APPLICATION_JSON) + .header(HttpHeaders.AUTHORIZATION, AUTH_TOKEN) + .content(jsonMapper.toJson(ccdRequest))) + .andExpect(status().isOk()); + + verify(supportTaskEventService).triggerArrangeSupportTaskEvents(any(CaseDetails.class), eq(tasks)); + } + @Test void addServiceId_missingAuthToken() throws Exception { mvc.perform(post(SUBMITTED_URL) diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskEventServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskEventServiceTest.java new file mode 100644 index 0000000000..37aa9a741b --- /dev/null +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskEventServiceTest.java @@ -0,0 +1,207 @@ +package uk.gov.hmcts.ethos.replacement.docmosis.service; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.springframework.http.HttpStatus; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.web.client.HttpClientErrorException; +import org.springframework.web.client.HttpServerErrorException; +import uk.gov.hmcts.ecm.common.client.CcdClient; +import uk.gov.hmcts.et.common.model.ccd.CCDRequest; +import uk.gov.hmcts.et.common.model.ccd.CaseData; +import uk.gov.hmcts.et.common.model.ccd.CaseDetails; +import uk.gov.hmcts.et.common.model.ccd.types.SupportTaskState; +import uk.gov.hmcts.ethos.replacement.docmosis.config.SupportTaskConfiguration; +import uk.gov.hmcts.ethos.replacement.docmosis.exceptions.GenericRuntimeException; + +import java.io.IOException; +import java.util.List; +import java.util.Set; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static uk.gov.hmcts.ecm.common.model.helper.Constants.NO; +import static uk.gov.hmcts.ecm.common.model.helper.Constants.YES; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.EVENT_CLOSE_ADMIN_REVIEW_SUPPORT_TASK; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.EVENT_CREATE_ARRANGE_SUPPORT_TASK; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.TASK_TYPE_REVIEW_SUPPORT_ADMIN; + +@ExtendWith(SpringExtension.class) +class SupportTaskEventServiceTest { + private static final String TOKEN = "token"; + private static final String CASE_ID = "1234567890123456"; + private static final String CASE_TYPE = "ET_Scotland"; + private static final String JURISDICTION = "EMPLOYMENT"; + + @Mock + private CcdClient ccdClient; + @Mock + private AdminUserService adminUserService; + private SupportTaskEventService service; + + private CaseDetails caseDetails; + private CCDRequest ccdRequest; + + @BeforeEach + void setUp() { + SupportTaskConfiguration configuration = new SupportTaskConfiguration(); + configuration.getClosureRetry().setInitialBackoffMs(1); + configuration.getClosureRetry().setMaxBackoffMs(2); + service = new SupportTaskEventService(ccdClient, adminUserService, configuration); + + caseDetails = new CaseDetails(); + caseDetails.setCaseId(CASE_ID); + caseDetails.setCaseTypeId(CASE_TYPE); + caseDetails.setJurisdiction(JURISDICTION); + + CaseData latestCaseData = new CaseData(); + latestCaseData.setSupportTaskState(SupportTaskState.builder() + .adminTaskCreated(YES) + .legalOfficerTaskCreated(YES) + .judgeTaskCreated(YES) + .build()); + CaseDetails latestCaseDetails = new CaseDetails(); + latestCaseDetails.setCaseData(latestCaseData); + ccdRequest = new CCDRequest(); + ccdRequest.setCaseDetails(latestCaseDetails); + } + + @Test + void triggersTheCategorySpecificClosureEventAndResetsOnlyItsMarker() throws IOException { + when(adminUserService.getAdminUserToken()).thenReturn(TOKEN); + when(ccdClient.startEventForCase(TOKEN, CASE_TYPE, JURISDICTION, CASE_ID, + EVENT_CLOSE_ADMIN_REVIEW_SUPPORT_TASK)).thenReturn(ccdRequest); + ArgumentCaptor caseDataCaptor = ArgumentCaptor.forClass(CaseData.class); + + service.triggerReviewTaskClosureEvents(caseDetails, Set.of(TASK_TYPE_REVIEW_SUPPORT_ADMIN)); + + verify(ccdClient).submitEventForCase(eq(TOKEN), caseDataCaptor.capture(), eq(CASE_TYPE), + eq(JURISDICTION), eq(ccdRequest), eq(CASE_ID)); + SupportTaskState state = caseDataCaptor.getValue().getSupportTaskState(); + assertEquals(NO, state.getAdminTaskCreated()); + assertEquals(YES, state.getLegalOfficerTaskCreated()); + assertEquals(YES, state.getJudgeTaskCreated()); + } + + @Test + void doesNothingWhenNoReviewTaskCategoryNeedsClosing() throws IOException { + service.triggerReviewTaskClosureEvents(caseDetails, Set.of()); + + verify(ccdClient, never()).startEventForCase(any(), any(), any(), any(), any()); + verify(ccdClient, never()).submitEventForCase(any(), any(), any(), any(), any(), any()); + } + + @Test + void triggersOneArrangeSupportEventForEachAdditionalFlag() throws IOException { + when(adminUserService.getAdminUserToken()).thenReturn(TOKEN); + when(ccdClient.startEventForCase(TOKEN, CASE_TYPE, JURISDICTION, CASE_ID, + EVENT_CREATE_ARRANGE_SUPPORT_TASK)).thenReturn(ccdRequest); + ArgumentCaptor caseDataCaptor = ArgumentCaptor.forClass(CaseData.class); + + service.triggerArrangeSupportTaskEvents(caseDetails, List.of( + new SupportTaskService.ArrangeSupportTask("flag-2", "Support filling in forms"), + new SupportTaskService.ArrangeSupportTask("flag-3", "Sign language interpreter"))); + + verify(ccdClient, times(2)).submitEventForCase(eq(TOKEN), caseDataCaptor.capture(), eq(CASE_TYPE), + eq(JURISDICTION), eq(ccdRequest), eq(CASE_ID)); + SupportTaskState finalState = caseDataCaptor.getAllValues().getLast().getSupportTaskState(); + assertEquals("Sign language interpreter", finalState.getArrangeSupportTaskName()); + assertEquals("flag-3", finalState.getArrangeSupportTaskFlagId()); + } + + @Test + void doesNotDuplicateArrangeSupportTaskWhenRetryFollowsACommittedEvent() throws IOException { + when(adminUserService.getAdminUserToken()).thenReturn(TOKEN); + when(ccdClient.startEventForCase(TOKEN, CASE_TYPE, JURISDICTION, CASE_ID, + EVENT_CREATE_ARRANGE_SUPPORT_TASK)).thenReturn(ccdRequest); + when(ccdClient.submitEventForCase(eq(TOKEN), any(CaseData.class), eq(CASE_TYPE), + eq(JURISDICTION), eq(ccdRequest), eq(CASE_ID))) + .thenThrow(new HttpServerErrorException(HttpStatus.SERVICE_UNAVAILABLE)); + + service.triggerArrangeSupportTaskEvents(caseDetails, List.of( + new SupportTaskService.ArrangeSupportTask("flag-2", "Support filling in forms"))); + + verify(ccdClient, times(2)).startEventForCase(TOKEN, CASE_TYPE, JURISDICTION, CASE_ID, + EVENT_CREATE_ARRANGE_SUPPORT_TASK); + verify(ccdClient).submitEventForCase(eq(TOKEN), any(CaseData.class), eq(CASE_TYPE), + eq(JURISDICTION), eq(ccdRequest), eq(CASE_ID)); + } + + @Test + void wrapsFailureToTriggerTheClosureEvent() throws IOException { + when(adminUserService.getAdminUserToken()).thenReturn(TOKEN); + when(ccdClient.startEventForCase(TOKEN, CASE_TYPE, JURISDICTION, CASE_ID, + EVENT_CLOSE_ADMIN_REVIEW_SUPPORT_TASK)).thenThrow(new IOException("CCD unavailable")); + + assertThrows(GenericRuntimeException.class, + () -> service.triggerReviewTaskClosureEvents(caseDetails, Set.of(TASK_TYPE_REVIEW_SUPPORT_ADMIN))); + verify(ccdClient, times(3)).startEventForCase(TOKEN, CASE_TYPE, JURISDICTION, CASE_ID, + EVENT_CLOSE_ADMIN_REVIEW_SUPPORT_TASK); + } + + @Test + void retriesTransientFailureAndSubmitsTheClosureEvent() throws IOException { + when(adminUserService.getAdminUserToken()).thenReturn(TOKEN); + when(ccdClient.startEventForCase(TOKEN, CASE_TYPE, JURISDICTION, CASE_ID, + EVENT_CLOSE_ADMIN_REVIEW_SUPPORT_TASK)) + .thenThrow(new IOException("CCD temporarily unavailable")) + .thenReturn(ccdRequest); + + service.triggerReviewTaskClosureEvents(caseDetails, Set.of(TASK_TYPE_REVIEW_SUPPORT_ADMIN)); + + verify(ccdClient, times(2)).startEventForCase(TOKEN, CASE_TYPE, JURISDICTION, CASE_ID, + EVENT_CLOSE_ADMIN_REVIEW_SUPPORT_TASK); + verify(ccdClient).submitEventForCase(eq(TOKEN), any(CaseData.class), eq(CASE_TYPE), + eq(JURISDICTION), eq(ccdRequest), eq(CASE_ID)); + } + + @Test + void doesNotRetryPermanentClientFailure() throws IOException { + when(adminUserService.getAdminUserToken()).thenReturn(TOKEN); + when(ccdClient.startEventForCase(TOKEN, CASE_TYPE, JURISDICTION, CASE_ID, + EVENT_CLOSE_ADMIN_REVIEW_SUPPORT_TASK)) + .thenThrow(new HttpClientErrorException(HttpStatus.BAD_REQUEST)); + + assertThrows(GenericRuntimeException.class, + () -> service.triggerReviewTaskClosureEvents(caseDetails, Set.of(TASK_TYPE_REVIEW_SUPPORT_ADMIN))); + verify(ccdClient).startEventForCase(TOKEN, CASE_TYPE, JURISDICTION, CASE_ID, + EVENT_CLOSE_ADMIN_REVIEW_SUPPORT_TASK); + } + + @Test + void doesNotResubmitWhenPreviousAttemptWasCommitted() throws IOException { + CCDRequest persistedRequest = requestWithAdminTaskCreated(NO); + when(adminUserService.getAdminUserToken()).thenReturn(TOKEN); + when(ccdClient.startEventForCase(TOKEN, CASE_TYPE, JURISDICTION, CASE_ID, + EVENT_CLOSE_ADMIN_REVIEW_SUPPORT_TASK)).thenReturn(ccdRequest, persistedRequest); + when(ccdClient.submitEventForCase(eq(TOKEN), any(CaseData.class), eq(CASE_TYPE), + eq(JURISDICTION), eq(ccdRequest), eq(CASE_ID))) + .thenThrow(new HttpServerErrorException(HttpStatus.SERVICE_UNAVAILABLE)); + + service.triggerReviewTaskClosureEvents(caseDetails, Set.of(TASK_TYPE_REVIEW_SUPPORT_ADMIN)); + + verify(ccdClient, times(2)).startEventForCase(TOKEN, CASE_TYPE, JURISDICTION, CASE_ID, + EVENT_CLOSE_ADMIN_REVIEW_SUPPORT_TASK); + verify(ccdClient).submitEventForCase(eq(TOKEN), any(CaseData.class), eq(CASE_TYPE), + eq(JURISDICTION), eq(ccdRequest), eq(CASE_ID)); + } + + private static CCDRequest requestWithAdminTaskCreated(String taskCreated) { + CaseData caseData = new CaseData(); + caseData.setSupportTaskState(SupportTaskState.builder().adminTaskCreated(taskCreated).build()); + CaseDetails details = new CaseDetails(); + details.setCaseData(caseData); + CCDRequest request = new CCDRequest(); + request.setCaseDetails(details); + return request; + } +} diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java index e422e01488..d693232275 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java @@ -577,6 +577,47 @@ void completes_only_categories_without_requested_flags_when_boolean_state_is_use assertEquals(Set.of(TASK_TYPE_REVIEW_SUPPORT_ADMIN), taskTypesToComplete); } + @Test + void retains_only_review_tasks_that_need_the_submitted_callback() { + CaseData caseData = new CaseData(); + caseData.setSupportTaskState(SupportTaskState.builder() + .adminTaskCreated(NO) + .legalOfficerTaskCreated(NO) + .judgeTaskCreated(NO) + .build()); + + service.retainReviewTasksForSubmittedCallback(caseData, + Set.of(TASK_TYPE_REVIEW_SUPPORT_ADMIN, TASK_TYPE_REVIEW_SUPPORT_JUDGE)); + + assertEquals(YES, taskState(caseData).getAdminTaskCreated()); + assertEquals(NO, taskState(caseData).getLegalOfficerTaskCreated()); + assertEquals(YES, taskState(caseData).getJudgeTaskCreated()); + } + + @Test + void finds_only_created_review_tasks_without_requested_flags() { + CaseData caseData = new CaseData(); + caseData.setAllPartyFlags(AllPartyFlags.builder() + .claimantFlags(caseFlags("admin-flag", "RA0041", STATUS_ACTIVE)) + .respondentFlags(caseFlags("legal-flag", "RA0034", STATUS_REQUESTED)) + .respondent1Flags(caseFlags("judge-flag", "RA0038", STATUS_ACTIVE)) + .build()); + caseData.setSupportTaskState(SupportTaskState.builder() + .adminTaskCreated(YES) + .legalOfficerTaskCreated(YES) + .judgeTaskCreated(NO) + .build()); + + Set taskTypesToClose = service.reviewTaskTypesToClose(caseData); + + assertEquals(Set.of(TASK_TYPE_REVIEW_SUPPORT_ADMIN), taskTypesToClose); + } + + @Test + void finds_no_review_tasks_to_close_when_task_state_is_missing() { + assertTrue(service.reviewTaskTypesToClose(new CaseData()).isEmpty()); + } + @Test void ccd_boolean_task_state_is_deserialized_to_boolean_strings() throws JsonProcessingException { SupportTaskState state = new ObjectMapper().readValue(""" @@ -760,6 +801,27 @@ void prepares_separate_arrange_support_tasks_for_the_same_code_on_separate_event assertEquals("Guidance on how to complete forms", taskState(secondEvent).getArrangeSupportTaskName()); } + @Test + void prepares_an_arrange_support_task_for_every_new_active_flag_in_one_event() { + CaseData caseData = new CaseData(); + caseData.setAllPartyFlags(AllPartyFlags.builder() + .claimantFlags(caseFlags("claimant-flag", "RA0017", STATUS_ACTIVE)) + .respondentFlags(caseFlags("respondent-flag", "RA0017", STATUS_ACTIVE)) + .representative1ExternalFlags(caseFlags("representative-flag", "RA0042", STATUS_ACTIVE)) + .build()); + + service.prepareArrangeSupportTask(caseData, new CaseData()); + List additionalTasks = + service.additionalArrangeSupportTasks(caseData, new CaseData()); + + assertEquals("Guidance on how to complete forms", taskState(caseData).getArrangeSupportTaskName()); + assertEquals(List.of( + new SupportTaskService.ArrangeSupportTask( + "respondent-flag", "Guidance on how to complete forms"), + new SupportTaskService.ArrangeSupportTask("representative-flag", "Sign language interpreter") + ), additionalTasks); + } + @Test void prepares_arrange_support_task_when_existing_flag_becomes_active() { CaseData caseDataBefore = new CaseData(); diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/ReviewSupportTaskCompletionServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/ReviewSupportTaskCompletionServiceTest.java deleted file mode 100644 index 799f5da470..0000000000 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/ReviewSupportTaskCompletionServiceTest.java +++ /dev/null @@ -1,147 +0,0 @@ -package uk.gov.hmcts.ethos.replacement.docmosis.wa; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.NullAndEmptySource; -import org.junit.jupiter.params.provider.ValueSource; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import uk.gov.hmcts.ethos.replacement.docmosis.client.WaTaskApiClient; -import uk.gov.hmcts.ethos.replacement.docmosis.wa.model.TaskSearchParameter; -import uk.gov.hmcts.ethos.replacement.docmosis.wa.model.TaskSearchRequest; -import uk.gov.hmcts.ethos.replacement.docmosis.wa.model.TaskSearchResponse; -import uk.gov.hmcts.ethos.replacement.docmosis.wa.model.WaTask; -import uk.gov.hmcts.reform.authorisation.generators.AuthTokenGenerator; - -import java.util.List; -import java.util.Set; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoInteractions; -import static org.mockito.Mockito.when; - -@ExtendWith(MockitoExtension.class) -class ReviewSupportTaskCompletionServiceTest { - private static final String CASE_ID = "1234567890123456"; - private static final String USER_TOKEN = "Bearer user-token"; - private static final String SERVICE_TOKEN = "service-token"; - private static final String ADMIN_TASK = "ReviewSupportRequestAdmin"; - private static final String JUDGE_TASK = "ReviewSupportRequestJudge"; - - @Mock - private WaTaskApiClient waTaskApiClient; - @Mock - private AuthTokenGenerator serviceAuthTokenGenerator; - - private ReviewSupportTaskCompletionService service; - - @BeforeEach - void setUp() { - service = new ReviewSupportTaskCompletionService(waTaskApiClient, serviceAuthTokenGenerator); - } - - @Test - void searchesActiveTasksForTheCaseAndRequestedTaskTypes() { - stubSearch(TaskSearchResponse.builder().tasks(List.of()).build()); - - service.completeTasks(CASE_ID, USER_TOKEN, Set.of(ADMIN_TASK, JUDGE_TASK)); - - ArgumentCaptor request = ArgumentCaptor.forClass(TaskSearchRequest.class); - verify(waTaskApiClient).searchTasks(eq(USER_TOKEN), eq(SERVICE_TOKEN), request.capture()); - List parameters = request.getValue().getSearchParameters(); - assertThat(parameters).extracting(TaskSearchParameter::getKey) - .containsExactly("case_id", "task_type", "state"); - assertThat(parameters.get(0).getValues()).containsExactly(CASE_ID); - assertThat(parameters.get(1).getValues()).containsExactlyInAnyOrder(ADMIN_TASK, JUDGE_TASK); - assertThat(parameters.get(2).getValues()).containsExactly("assigned", "unassigned"); - assertThat(parameters).extracting(TaskSearchParameter::getOperator).containsOnly("IN"); - } - - @Test - void completesEveryReturnedTask() { - stubSearch(TaskSearchResponse.builder().tasks(List.of( - WaTask.builder().id("admin-id").type(ADMIN_TASK).build(), - WaTask.builder().id("judge-id").type(JUDGE_TASK).build())).build()); - - service.completeTasks(CASE_ID, USER_TOKEN, Set.of(ADMIN_TASK, JUDGE_TASK)); - - ArgumentCaptor taskIds = ArgumentCaptor.forClass(String.class); - verify(waTaskApiClient, times(2)) - .completeTask(eq(USER_TOKEN), eq(SERVICE_TOKEN), taskIds.capture()); - assertThat(taskIds.getAllValues()).containsExactlyInAnyOrder("admin-id", "judge-id"); - } - - @Test - void continuesWhenOneCompletionFails() { - stubSearch(TaskSearchResponse.builder().tasks(List.of( - WaTask.builder().id("fails").type(ADMIN_TASK).build(), - WaTask.builder().id("succeeds").type(JUDGE_TASK).build())).build()); - doThrow(new IllegalStateException("unavailable")) - .when(waTaskApiClient).completeTask(eq(USER_TOKEN), eq(SERVICE_TOKEN), eq("fails")); - - service.completeTasks(CASE_ID, USER_TOKEN, Set.of(ADMIN_TASK, JUDGE_TASK)); - - verify(waTaskApiClient).completeTask(eq(USER_TOKEN), eq(SERVICE_TOKEN), eq("succeeds")); - } - - @Test - void doesNotPropagateSearchFailure() { - when(serviceAuthTokenGenerator.generate()).thenReturn(SERVICE_TOKEN); - when(waTaskApiClient.searchTasks(anyString(), anyString(), any())) - .thenThrow(new IllegalStateException("unavailable")); - - service.completeTasks(CASE_ID, USER_TOKEN, Set.of(ADMIN_TASK)); - - verify(waTaskApiClient, never()).completeTask(anyString(), anyString(), anyString()); - } - - @Test - void toleratesMissingSearchResponseOrTaskList() { - stubSearch(null); - service.completeTasks(CASE_ID, USER_TOKEN, Set.of(ADMIN_TASK)); - verify(waTaskApiClient, never()).completeTask(anyString(), anyString(), anyString()); - - when(waTaskApiClient.searchTasks(anyString(), anyString(), any())) - .thenReturn(TaskSearchResponse.builder().build()); - service.completeTasks(CASE_ID, USER_TOKEN, Set.of(ADMIN_TASK)); - verify(waTaskApiClient, never()).completeTask(anyString(), anyString(), anyString()); - } - - @ParameterizedTest - @NullAndEmptySource - @ValueSource(strings = " ") - void skipsWhenCaseIdIsMissing(String caseId) { - service.completeTasks(caseId, USER_TOKEN, Set.of(ADMIN_TASK)); - verifyNoInteractions(waTaskApiClient, serviceAuthTokenGenerator); - } - - @ParameterizedTest - @NullAndEmptySource - @ValueSource(strings = " ") - void skipsWhenUserTokenIsMissing(String userToken) { - service.completeTasks(CASE_ID, userToken, Set.of(ADMIN_TASK)); - verifyNoInteractions(waTaskApiClient, serviceAuthTokenGenerator); - } - - @Test - void skipsWhenNoTaskTypesNeedCompletion() { - service.completeTasks(CASE_ID, USER_TOKEN, Set.of()); - service.completeTasks(CASE_ID, USER_TOKEN, null); - verifyNoInteractions(waTaskApiClient, serviceAuthTokenGenerator); - } - - private void stubSearch(TaskSearchResponse response) { - when(serviceAuthTokenGenerator.generate()).thenReturn(SERVICE_TOKEN); - when(waTaskApiClient.searchTasks(anyString(), anyString(), any())).thenReturn(response); - } -} diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/SupportTaskClientContextServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/SupportTaskClientContextServiceTest.java new file mode 100644 index 0000000000..30b4ccf648 --- /dev/null +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/wa/SupportTaskClientContextServiceTest.java @@ -0,0 +1,93 @@ +package uk.gov.hmcts.ethos.replacement.docmosis.wa; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import java.io.IOException; +import java.util.Base64; +import java.util.Set; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.assertj.core.api.Assertions.assertThat; + +class SupportTaskClientContextServiceTest { + private static final String ADMIN_TASK = "ReviewSupportRequestAdmin"; + private static final String ARRANGE_TASK = "ArrangeSupport"; + + private final ObjectMapper objectMapper = new ObjectMapper(); + private SupportTaskClientContextService service; + + @BeforeEach + void setUp() { + service = new SupportTaskClientContextService(objectMapper); + } + + @ParameterizedTest + @ValueSource(strings = { + "ReviewSupportRequestAdmin", + "ReviewSupportRequestLegalOfficer", + "ReviewSupportRequestJudge" + }) + void completesInvokingReviewTaskWhenItsCategoryNoLongerHasRequestedFlags(String taskType) throws Exception { + String updatedContext = service.updateTaskCompletion( + encode(clientContext(taskType)), Set.of(taskType)); + + JsonNode result = decode(updatedContext); + assertThat(result.at("/client_context/user_task/complete_task").booleanValue()).isTrue(); + assertThat(result.at("/client_context/user_task/task_data/id").textValue()).isEqualTo("task-id"); + assertThat(result.at("/client_context/user_language/language").textValue()).isEqualTo("en"); + } + + @Test + void keepsInvokingReviewTaskOpenWhileItsCategoryHasRequestedFlags() throws Exception { + String updatedContext = service.updateTaskCompletion(encode(clientContext(ADMIN_TASK)), Set.of()); + + assertThat(decode(updatedContext).at("/client_context/user_task/complete_task").booleanValue()).isFalse(); + } + + @Test + void doesNotCompleteArrangeTaskWhenReviewCategoryNeedsCompletion() throws Exception { + String updatedContext = service.updateTaskCompletion( + encode(clientContext(ARRANGE_TASK)), Set.of(ADMIN_TASK)); + + assertThat(decode(updatedContext).at("/client_context/user_task/complete_task").booleanValue()).isFalse(); + } + + @Test + void returnsNullWhenClientContextIsAbsentOrInvalid() { + assertThat(service.updateTaskCompletion(null, Set.of(ADMIN_TASK))).isNull(); + assertThat(service.updateTaskCompletion("not-base64", Set.of(ADMIN_TASK))).isNull(); + assertThat(service.updateTaskCompletion(encode("{}"), Set.of(ADMIN_TASK))).isNull(); + } + + private String clientContext(String taskType) { + return """ + { + "client_context": { + "user_task": { + "task_data": { + "id": "task-id", + "type": "%s" + }, + "complete_task": false + }, + "user_language": { + "language": "en" + } + } + } + """.formatted(taskType); + } + + private String encode(String value) { + return Base64.getEncoder().encodeToString(value.getBytes(UTF_8)); + } + + private JsonNode decode(String value) throws IOException { + return objectMapper.readTree(Base64.getDecoder().decode(value)); + } +} From 6eaf7ddf04e99b34c4b956ee5da3f102ebac3272 Mon Sep 17 00:00:00 2001 From: rajaram Date: Thu, 17 Sep 2026 21:35:20 +0100 Subject: [PATCH 080/100] Auto close review tasks --- .../CaseEventToFields-SupportTasks.json | 12 -- .../CaseEventToFields-SupportTasks.json | 12 -- .../config/SupportTaskConfiguration.java | 8 +- .../service/SupportTaskEventService.java | 18 ++- .../docmosis/service/SupportTaskService.java | 2 +- .../config/SupportTaskConfigurationTest.java | 8 ++ ...aseActionsForCaseWorkerControllerTest.java | 9 +- .../Et1SubmissionControllerTest.java | 3 +- .../service/SupportTaskEventServiceTest.java | 78 ++++++++++- .../service/SupportTaskServiceTest.java | 122 ++++++++++++++++++ 10 files changed, 226 insertions(+), 46 deletions(-) diff --git a/ccd-definitions/jurisdictions/england-wales/json/CaseEventToFields/CaseEventToFields-SupportTasks.json b/ccd-definitions/jurisdictions/england-wales/json/CaseEventToFields/CaseEventToFields-SupportTasks.json index de4ba8a026..ec9070a864 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/CaseEventToFields/CaseEventToFields-SupportTasks.json +++ b/ccd-definitions/jurisdictions/england-wales/json/CaseEventToFields/CaseEventToFields-SupportTasks.json @@ -79,18 +79,6 @@ "ShowSummaryChangeOption": "N", "RetainHiddenValue": "Yes" }, - { - "CaseTypeID": "ET_EnglandWales", - "CaseEventID": "manageSupport", - "CaseFieldID": "supportTaskState", - "DisplayContext": "COMPLEX", - "PageID": 1, - "PageDisplayOrder": 1, - "PageFieldDisplayOrder": 99, - "FieldShowCondition": "flagLauncherExternal=\"hidden\"", - "ShowSummaryChangeOption": "N", - "RetainHiddenValue": "Yes" - }, { "CaseTypeID": "ET_EnglandWales", "CaseEventID": "reviewAdminSupportRequest", diff --git a/ccd-definitions/jurisdictions/scotland/json/CaseEventToFields/CaseEventToFields-SupportTasks.json b/ccd-definitions/jurisdictions/scotland/json/CaseEventToFields/CaseEventToFields-SupportTasks.json index 3928dcd7e8..b995995393 100644 --- a/ccd-definitions/jurisdictions/scotland/json/CaseEventToFields/CaseEventToFields-SupportTasks.json +++ b/ccd-definitions/jurisdictions/scotland/json/CaseEventToFields/CaseEventToFields-SupportTasks.json @@ -79,18 +79,6 @@ "ShowSummaryChangeOption": "N", "RetainHiddenValue": "Yes" }, - { - "CaseTypeID": "ET_Scotland", - "CaseEventID": "manageSupport", - "CaseFieldID": "supportTaskState", - "DisplayContext": "COMPLEX", - "PageID": 1, - "PageDisplayOrder": 1, - "PageFieldDisplayOrder": 99, - "FieldShowCondition": "flagLauncherExternal=\"hidden\"", - "ShowSummaryChangeOption": "N", - "RetainHiddenValue": "Yes" - }, { "CaseTypeID": "ET_Scotland", "CaseEventID": "reviewAdminSupportRequest", diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/config/SupportTaskConfiguration.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/config/SupportTaskConfiguration.java index 0b51039767..f762b198d1 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/config/SupportTaskConfiguration.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/config/SupportTaskConfiguration.java @@ -38,10 +38,10 @@ public static class Arrange { @Data public static class ClosureRetry { - private int maxAttempts = 3; - private long initialBackoffMs = 200; - private double multiplier = 2; - private long maxBackoffMs = 1000; + private int maxAttempts; + private long initialBackoffMs; + private double multiplier; + private long maxBackoffMs; } @Data diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskEventService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskEventService.java index 0c24f29ccd..2070048094 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskEventService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskEventService.java @@ -18,7 +18,6 @@ import java.io.IOException; import java.util.List; -import java.util.Objects; import java.util.Set; import java.util.function.BiConsumer; import java.util.function.Function; @@ -69,14 +68,18 @@ public void triggerReviewTaskClosureEvents(CaseDetails caseDetails, Set public void triggerArrangeSupportTaskEvents( CaseDetails caseDetails, List tasks) { - tasks.forEach(task -> triggerArrangeSupportTaskEvent(caseDetails, task)); + List flagIds = tasks.stream().map(SupportTaskService.ArrangeSupportTask::flagId).toList(); + for (int index = 0; index < tasks.size(); index++) { + triggerArrangeSupportTaskEvent(caseDetails, tasks.get(index), flagIds.subList(index, flagIds.size())); + } } private void triggerArrangeSupportTaskEvent( - CaseDetails caseDetails, SupportTaskService.ArrangeSupportTask task) { + CaseDetails caseDetails, SupportTaskService.ArrangeSupportTask task, List remainingFlagIds) { String caseId = caseDetails.getCaseId(); try { - boolean submitted = retryTemplate.execute(context -> submitArrangeSupportTaskEvent(caseDetails, task)); + boolean submitted = retryTemplate.execute(context -> + submitArrangeSupportTaskEvent(caseDetails, task, remainingFlagIds)); if (submitted) { log.info("Triggered {} for flag {} on case {}", EVENT_CREATE_ARRANGE_SUPPORT_TASK, task.flagId(), caseId); @@ -89,14 +92,17 @@ private void triggerArrangeSupportTaskEvent( } private boolean submitArrangeSupportTaskEvent( - CaseDetails caseDetails, SupportTaskService.ArrangeSupportTask task) throws IOException { + CaseDetails caseDetails, SupportTaskService.ArrangeSupportTask task, + List remainingFlagIds) throws IOException { String token = adminUserService.getAdminUserToken(); String caseId = caseDetails.getCaseId(); CCDRequest request = ccdClient.startEventForCase(token, caseDetails.getCaseTypeId(), caseDetails.getJurisdiction(), caseId, EVENT_CREATE_ARRANGE_SUPPORT_TASK); CaseData latestCaseData = request.getCaseDetails().getCaseData(); SupportTaskState state = latestCaseData.getSupportTaskState(); - if (state != null && Objects.equals(task.flagId(), state.getArrangeSupportTaskFlagId())) { + // A later checkpoint in this ordered batch also confirms that earlier flags were submitted. + if (state != null && state.getArrangeSupportTaskFlagId() != null + && remainingFlagIds.contains(state.getArrangeSupportTaskFlagId())) { return false; } if (state == null) { diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java index 3aa7253198..d8217a5f7b 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java @@ -13,8 +13,8 @@ import uk.gov.hmcts.ethos.replacement.docmosis.config.SupportTaskConfiguration.ArrangePathFlag; import uk.gov.hmcts.ethos.replacement.docmosis.config.SupportTaskConfiguration.PathFlag; -import java.util.Comparator; import java.util.ArrayList; +import java.util.Comparator; import java.util.HashMap; import java.util.LinkedHashSet; import java.util.List; diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/config/SupportTaskConfigurationTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/config/SupportTaskConfigurationTest.java index 32e780e0e7..d25fc067f1 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/config/SupportTaskConfigurationTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/config/SupportTaskConfigurationTest.java @@ -15,6 +15,14 @@ class SupportTaskConfigurationTest { @Autowired private SupportTaskConfiguration configuration; + @Test + void loadsRetrySettingsFromYaml() { + assertThat(configuration.getClosureRetry().getMaxAttempts()).isEqualTo(3); + assertThat(configuration.getClosureRetry().getInitialBackoffMs()).isEqualTo(200); + assertThat(configuration.getClosureRetry().getMultiplier()).isEqualTo(2); + assertThat(configuration.getClosureRetry().getMaxBackoffMs()).isEqualTo(1000); + } + @Test void loadsFlagCodesFromYaml() { assertThat(configuration.getReview().getAdminFlagCodes()) diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java index 903c4e32b0..c04214b8c7 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java @@ -486,12 +486,15 @@ void retainsReviewTaskForSubmittedCallbackWhenClientContextIsMissing(String even verify(supportTaskService).retainReviewTasksForSubmittedCallback(any(CaseData.class), eq(taskTypes)); } - @Test + @ParameterizedTest + @ValueSource(strings = {"UPDATE_CASE_SUBMITTED", "SUBMIT_ET3_FORM", "UPDATE_ET3_FORM"}) @SneakyThrows - void triggersCategorySpecificReviewTaskClosureEventsAfterSubmission() { + void triggersCategorySpecificReviewTaskClosureEventsAfterSubmission(String eventId) { + ((ObjectNode) requestContent2).put("event_id", eventId); Set taskTypes = Set.of("ReviewSupportRequestAdmin", "ReviewSupportRequestJudge"); List arrangeTasks = List.of( - new SupportTaskService.ArrangeSupportTask("flag-2", "Sign language interpreter")); + new SupportTaskService.ArrangeSupportTask("flag-2", "Sign language interpreter"), + new SupportTaskService.ArrangeSupportTask("flag-3", "Sign language interpreter")); when(featureToggleService.isCaseFlagsV2Enabled(anyString())).thenReturn(true); when(supportTaskService.reviewTaskTypesToClose(any(CaseData.class))).thenReturn(taskTypes); when(supportTaskService.additionalArrangeSupportTasks(any(CaseData.class), nullable(CaseData.class))) diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1SubmissionControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1SubmissionControllerTest.java index c7791aedc6..249702b7e2 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1SubmissionControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/Et1SubmissionControllerTest.java @@ -95,7 +95,8 @@ void addServiceId_success() throws Exception { @Test void createsAdditionalArrangeSupportTasksForCaseFlagsV2() throws Exception { List tasks = List.of( - new SupportTaskService.ArrangeSupportTask("flag-2", "Support filling in forms")); + new SupportTaskService.ArrangeSupportTask("flag-2", "Support filling in forms"), + new SupportTaskService.ArrangeSupportTask("flag-3", "Support filling in forms")); org.mockito.Mockito.when(featureToggleService.isCaseFlagsV2Enabled(ENGLANDWALES_CASE_TYPE_ID)) .thenReturn(true); org.mockito.Mockito.when(supportTaskService.additionalArrangeSupportTasks( diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskEventServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskEventServiceTest.java index 37aa9a741b..be767b76b0 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskEventServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskEventServiceTest.java @@ -18,13 +18,16 @@ import uk.gov.hmcts.ethos.replacement.docmosis.exceptions.GenericRuntimeException; import java.io.IOException; +import java.util.ArrayList; import java.util.List; import java.util.Set; +import java.util.concurrent.atomic.AtomicReference; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -54,7 +57,9 @@ class SupportTaskEventServiceTest { @BeforeEach void setUp() { SupportTaskConfiguration configuration = new SupportTaskConfiguration(); + configuration.getClosureRetry().setMaxAttempts(3); configuration.getClosureRetry().setInitialBackoffMs(1); + configuration.getClosureRetry().setMultiplier(2); configuration.getClosureRetry().setMaxBackoffMs(2); service = new SupportTaskEventService(ccdClient, adminUserService, configuration); @@ -105,17 +110,26 @@ void triggersOneArrangeSupportEventForEachAdditionalFlag() throws IOException { when(adminUserService.getAdminUserToken()).thenReturn(TOKEN); when(ccdClient.startEventForCase(TOKEN, CASE_TYPE, JURISDICTION, CASE_ID, EVENT_CREATE_ARRANGE_SUPPORT_TASK)).thenReturn(ccdRequest); - ArgumentCaptor caseDataCaptor = ArgumentCaptor.forClass(CaseData.class); + List submitted = new ArrayList<>(); + when(ccdClient.submitEventForCase(eq(TOKEN), any(CaseData.class), eq(CASE_TYPE), + eq(JURISDICTION), eq(ccdRequest), eq(CASE_ID))).thenAnswer(invocation -> { + SupportTaskState state = invocation.getArgument(1).getSupportTaskState(); + submitted.add(new SupportTaskService.ArrangeSupportTask( + state.getArrangeSupportTaskFlagId(), state.getArrangeSupportTaskName())); + assertEquals(YES, state.getAdminTaskCreated()); + assertEquals(YES, state.getJudgeTaskCreated()); + assertEquals(YES, state.getLegalOfficerTaskCreated()); + return null; + }); - service.triggerArrangeSupportTaskEvents(caseDetails, List.of( + List tasks = List.of( new SupportTaskService.ArrangeSupportTask("flag-2", "Support filling in forms"), - new SupportTaskService.ArrangeSupportTask("flag-3", "Sign language interpreter"))); + new SupportTaskService.ArrangeSupportTask("flag-3", "Sign language interpreter")); + service.triggerArrangeSupportTaskEvents(caseDetails, tasks); - verify(ccdClient, times(2)).submitEventForCase(eq(TOKEN), caseDataCaptor.capture(), eq(CASE_TYPE), + verify(ccdClient, times(2)).submitEventForCase(eq(TOKEN), any(CaseData.class), eq(CASE_TYPE), eq(JURISDICTION), eq(ccdRequest), eq(CASE_ID)); - SupportTaskState finalState = caseDataCaptor.getAllValues().getLast().getSupportTaskState(); - assertEquals("Sign language interpreter", finalState.getArrangeSupportTaskName()); - assertEquals("flag-3", finalState.getArrangeSupportTaskFlagId()); + assertEquals(tasks, submitted); } @Test @@ -136,6 +150,56 @@ void doesNotDuplicateArrangeSupportTaskWhenRetryFollowsACommittedEvent() throws eq(JURISDICTION), eq(ccdRequest), eq(CASE_ID)); } + @Test + void retriesFailedBatchRemainderWithoutDuplicatingTheCommittedFlag() throws IOException { + AtomicReference persistedFlagId = new AtomicReference<>(); + List committed = new ArrayList<>(); + when(adminUserService.getAdminUserToken()).thenReturn(TOKEN); + when(ccdClient.startEventForCase(TOKEN, CASE_TYPE, JURISDICTION, CASE_ID, + EVENT_CREATE_ARRANGE_SUPPORT_TASK)).thenAnswer(invocation -> { + CCDRequest freshRequest = requestWithAdminTaskCreated(YES); + freshRequest.getCaseDetails().getCaseData().getSupportTaskState() + .setArrangeSupportTaskFlagId(persistedFlagId.get()); + return freshRequest; + }); + when(ccdClient.submitEventForCase(eq(TOKEN), any(CaseData.class), eq(CASE_TYPE), + eq(JURISDICTION), any(CCDRequest.class), eq(CASE_ID))).thenAnswer(invocation -> { + SupportTaskState state = invocation.getArgument(1).getSupportTaskState(); + if ("flag-4".equals(state.getArrangeSupportTaskFlagId())) { + throw new HttpServerErrorException(HttpStatus.SERVICE_UNAVAILABLE); + } + persistedFlagId.set(state.getArrangeSupportTaskFlagId()); + committed.add(new SupportTaskService.ArrangeSupportTask( + state.getArrangeSupportTaskFlagId(), state.getArrangeSupportTaskName())); + return null; + }); + List tasks = List.of( + new SupportTaskService.ArrangeSupportTask("flag-2", "Intermediary"), + new SupportTaskService.ArrangeSupportTask("flag-3", "Intermediary"), + new SupportTaskService.ArrangeSupportTask("flag-4", "Lip speaker")); + + assertThrows(GenericRuntimeException.class, + () -> service.triggerArrangeSupportTaskEvents(caseDetails, tasks)); + assertEquals(tasks.subList(0, 2), committed); + + doAnswer(invocation -> { + SupportTaskState state = invocation.getArgument(1).getSupportTaskState(); + persistedFlagId.set(state.getArrangeSupportTaskFlagId()); + committed.add(new SupportTaskService.ArrangeSupportTask( + state.getArrangeSupportTaskFlagId(), state.getArrangeSupportTaskName())); + return null; + }).when(ccdClient).submitEventForCase(eq(TOKEN), any(CaseData.class), eq(CASE_TYPE), + eq(JURISDICTION), any(CCDRequest.class), eq(CASE_ID)); + + service.triggerArrangeSupportTaskEvents(caseDetails, tasks); + + assertEquals(tasks, committed); + service.triggerArrangeSupportTaskEvents(caseDetails, tasks); + assertEquals(tasks, committed, "Replaying a completed batch must not create duplicate tasks"); + verify(ccdClient, times(6)).submitEventForCase(eq(TOKEN), any(CaseData.class), eq(CASE_TYPE), + eq(JURISDICTION), any(CCDRequest.class), eq(CASE_ID)); + } + @Test void wrapsFailureToTriggerTheClosureEvent() throws IOException { when(adminUserService.getAdminUserToken()).thenReturn(TOKEN); diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java index d693232275..ac8d9b7c9d 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java @@ -6,6 +6,7 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; +import org.junit.jupiter.params.provider.ValueSource; import uk.gov.hmcts.et.common.model.ccd.CaseData; import uk.gov.hmcts.et.common.model.ccd.items.FlagDetailType; import uk.gov.hmcts.et.common.model.ccd.items.GenericTypeItem; @@ -822,6 +823,127 @@ void prepares_an_arrange_support_task_for_every_new_active_flag_in_one_event() { ), additionalTasks); } + @ParameterizedTest(name = "submit and update respondent flags: {0}") + @ValueSource(booleans = {false, true}) + void submit_then_update_creates_only_new_arrange_tasks_and_no_duplicate_reviews(boolean respondent) + throws JsonProcessingException { + CaseData submitted = bulkSupportCase(respondent); + prepareSubmissionTasks(submitted, new CaseData(), respondent); + assertReviewCategories(submitted, YES); + assertEquals("Intermediary", taskState(submitted).getArrangeSupportTaskName()); + assertEquals(List.of( + new SupportTaskService.ArrangeSupportTask("active-2", "Intermediary"), + new SupportTaskService.ArrangeSupportTask("active-3", "Lip speaker")), + service.additionalArrangeSupportTasks(submitted, new CaseData())); + + // Use a separate persisted snapshot so updating flags cannot mutate the before data. + ObjectMapper mapper = new ObjectMapper(); + CaseData updated = mapper.readValue(mapper.writeValueAsString(submitted), CaseData.class); + CaseFlagsType section = respondent ? updated.getAllPartyFlags().getRespondentFlags() + : updated.getAllPartyFlags().getClaimantFlags(); + section.getDetails().addAll(caseFlags("new-active-1", "RA0038", STATUS_ACTIVE).getDetails()); + section.getDetails().addAll(caseFlags("new-active-2", "RA0041", STATUS_ACTIVE).getDetails()); + section.getDetails().addAll(caseFlags("new-active-3", "RA0042", STATUS_ACTIVE).getDetails()); + section.getDetails().addAll(caseFlags("new-admin", "RA0033", STATUS_REQUESTED).getDetails()); + section.getDetails().addAll(caseFlags("new-judge", "RA0031", STATUS_REQUESTED).getDetails()); + section.getDetails().addAll(caseFlags("new-lo", "RA0035", STATUS_REQUESTED).getDetails()); + + prepareSubmissionTasks(updated, submitted, respondent); + + assertReviewCategories(updated, null); + assertEquals("Intermediary", taskState(updated).getArrangeSupportTaskName()); + assertEquals(List.of( + new SupportTaskService.ArrangeSupportTask("new-active-2", "Lip speaker"), + new SupportTaskService.ArrangeSupportTask("new-active-3", "Sign language interpreter")), + service.additionalArrangeSupportTasks(updated, submitted)); + } + + @ParameterizedTest + @ValueSource(booleans = {false, true}) + void review_tasks_are_shared_between_claimant_and_respondent_submissions(boolean respondentFirst) + throws JsonProcessingException { + CaseData submitted = bulkSupportCase(respondentFirst); + prepareSubmissionTasks(submitted, new CaseData(), respondentFirst); + assertReviewCategories(submitted, YES); + + ObjectMapper mapper = new ObjectMapper(); + CaseData updated = mapper.readValue(mapper.writeValueAsString(submitted), CaseData.class); + CaseData secondSubmission = bulkSupportCase(!respondentFirst); + CaseFlagsType newFlags = respondentFirst ? secondSubmission.getAllPartyFlags().getClaimantFlags() + : secondSubmission.getAllPartyFlags().getRespondentFlags(); + newFlags.getDetails().forEach(item -> item.setId("second-" + item.getId())); + if (respondentFirst) { + updated.getAllPartyFlags().setClaimantFlags(newFlags); + } else { + updated.getAllPartyFlags().setRespondentFlags(newFlags); + } + + prepareSubmissionTasks(updated, submitted, !respondentFirst); + + assertReviewCategories(updated, null); + } + + @Test + void multiple_respondents_share_reviews_but_have_separate_arrange_tasks() { + CaseData caseData = new CaseData(); + CaseFlagsType first = caseFlags("respondent-1-active", "RA0038", STATUS_ACTIVE); + first.getDetails().addAll(caseFlags("respondent-1-request", "RA0038", STATUS_REQUESTED).getDetails()); + CaseFlagsType second = caseFlags("respondent-2-active", "RA0038", STATUS_ACTIVE); + second.getDetails().addAll(caseFlags("respondent-2-request", "RA0037", STATUS_REQUESTED).getDetails()); + caseData.setAllPartyFlags(AllPartyFlags.builder().respondentFlags(first) + .respondent2ExternalFlags(second) + .respondent3Flags(caseFlags("respondent-3-active", "RA0038", STATUS_ACTIVE)).build()); + + prepareSubmissionTasks(caseData, new CaseData(), true); + + assertEquals(YES, taskState(caseData).getJudgeTaskRequired()); + assertEquals(YES, taskState(caseData).getJudgeTaskCreated()); + assertNull(taskState(caseData).getAdminTaskRequired()); + assertNull(taskState(caseData).getLegalOfficerTaskRequired()); + assertEquals("Intermediary", taskState(caseData).getArrangeSupportTaskName()); + assertEquals(List.of( + new SupportTaskService.ArrangeSupportTask("respondent-2-active", "Intermediary"), + new SupportTaskService.ArrangeSupportTask("respondent-3-active", "Intermediary")), + service.additionalArrangeSupportTasks(caseData, new CaseData())); + + service.prepareRespondentReviewSupportTasks(caseData); + assertNull(taskState(caseData).getJudgeTaskRequired()); + assertEquals(YES, taskState(caseData).getJudgeTaskCreated()); + } + + private void prepareSubmissionTasks(CaseData current, CaseData before, boolean respondent) { + if (respondent) { + service.prepareRespondentReviewSupportTasks(current); + service.prepareNewFlagArrangeSupportTask(current, before); + } else { + service.prepareReviewSupportTasks(current); + service.prepareArrangeSupportTask(current, before); + } + } + + private static CaseData bulkSupportCase(boolean respondent) { + CaseFlagsType flags = caseFlags("active-1", "RA0038", STATUS_ACTIVE); + flags.getDetails().addAll(caseFlags("active-2", "RA0038", STATUS_ACTIVE).getDetails()); + flags.getDetails().addAll(caseFlags("active-3", "RA0041", STATUS_ACTIVE).getDetails()); + for (String code : List.of("RA0039", "RA0041", "RA0038", "RA0037", "RA0034", "RA0036")) { + flags.getDetails().addAll(caseFlags("requested-" + code, code, STATUS_REQUESTED).getDetails()); + } + flags.getDetails().addAll(caseFlags("inactive", "RA0038", STATUS_INACTIVE).getDetails()); + flags.getDetails().addAll(caseFlags("not-approved", "RA0041", STATUS_NOT_APPROVED).getDetails()); + flags.getDetails().addAll(caseFlags("unmapped", "UNKNOWN", STATUS_ACTIVE).getDetails()); + CaseData caseData = new CaseData(); + caseData.setAllPartyFlags(respondent ? AllPartyFlags.builder().respondentFlags(flags).build() + : AllPartyFlags.builder().claimantFlags(flags).build()); + return caseData; + } + + private static void assertReviewCategories(CaseData caseData, String required) { + for (String category : List.of(TASK_TYPE_ADMIN, TASK_TYPE_JUDGE, TASK_TYPE_LEGAL_OFFICER)) { + assertEquals(required, getTaskRequired(taskState(caseData), category), category); + assertEquals(YES, getTaskCreated(taskState(caseData), category), category); + } + } + @Test void prepares_arrange_support_task_when_existing_flag_becomes_active() { CaseData caseDataBefore = new CaseData(); From 9d50717811e46ca92fd73d0ff7b229cc1ee496fd Mon Sep 17 00:00:00 2001 From: rajaram Date: Thu, 17 Sep 2026 23:07:35 +0100 Subject: [PATCH 081/100] Test improvements --- build.gradle | 5 + .../SupportTaskCallbackLifecycleTest.java | 360 ++++++++++++++++++ .../service/SupportTaskEventServiceTest.java | 165 +++++++- 3 files changed, 523 insertions(+), 7 deletions(-) create mode 100644 src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/SupportTaskCallbackLifecycleTest.java diff --git a/build.gradle b/build.gradle index 28e3f44bc2..1351e59aca 100644 --- a/build.gradle +++ b/build.gradle @@ -235,6 +235,11 @@ configurations { test { dependsOn dumpCCDDefinitions + // Bound classpath scanning and retained Spring contexts on high-core CI agents. + maxHeapSize = '1G' + maxParallelForks = 1 + jvmArgs '-XX:ActiveProcessorCount=2' + systemProperty 'spring.test.context.cache.maxSize', '8' exclude '**/*ComponentTest*' useJUnitPlatform() testLogging { diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/SupportTaskCallbackLifecycleTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/SupportTaskCallbackLifecycleTest.java new file mode 100644 index 0000000000..892506f7ab --- /dev/null +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/SupportTaskCallbackLifecycleTest.java @@ -0,0 +1,360 @@ +package uk.gov.hmcts.ethos.replacement.docmosis.controllers; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import jakarta.servlet.ServletException; +import lombok.SneakyThrows; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.test.util.ReflectionTestUtils; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.client.HttpServerErrorException; +import uk.gov.hmcts.ecm.common.client.CcdClient; +import uk.gov.hmcts.et.common.model.ccd.CCDRequest; +import uk.gov.hmcts.et.common.model.ccd.CaseData; +import uk.gov.hmcts.et.common.model.ccd.CaseDetails; +import uk.gov.hmcts.et.common.model.ccd.items.FlagDetailType; +import uk.gov.hmcts.et.common.model.ccd.items.GenericTypeItem; +import uk.gov.hmcts.et.common.model.ccd.items.ListTypeItem; +import uk.gov.hmcts.et.common.model.ccd.types.AllPartyFlags; +import uk.gov.hmcts.et.common.model.ccd.types.CaseFlagsType; +import uk.gov.hmcts.et.common.model.ccd.types.SupportTaskState; +import uk.gov.hmcts.ethos.replacement.docmosis.config.SupportTaskConfiguration; +import uk.gov.hmcts.ethos.replacement.docmosis.exceptions.GenericRuntimeException; +import uk.gov.hmcts.ethos.replacement.docmosis.service.AdminUserService; +import uk.gov.hmcts.ethos.replacement.docmosis.service.CaseManagementForCaseWorkerService; +import uk.gov.hmcts.ethos.replacement.docmosis.service.FeatureToggleService; +import uk.gov.hmcts.ethos.replacement.docmosis.service.SupportTaskEventService; +import uk.gov.hmcts.ethos.replacement.docmosis.service.SupportTaskService; +import uk.gov.hmcts.ethos.replacement.docmosis.wa.SupportTaskClientContextService; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Base64; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static uk.gov.hmcts.ecm.common.model.helper.Constants.NO; +import static uk.gov.hmcts.ecm.common.model.helper.Constants.YES; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.EVENT_CLOSE_ADMIN_REVIEW_SUPPORT_TASK; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.EVENT_CLOSE_JUDGE_REVIEW_SUPPORT_TASK; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.EVENT_CLOSE_LEGAL_OFFICER_REVIEW_SUPPORT_TASK; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.EVENT_CREATE_ARRANGE_SUPPORT_TASK; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.EVENT_CREATE_FLAG; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.EVENT_MANAGE_FLAGS; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.EVENT_MANAGE_SUPPORT; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.EVENT_REQUEST_SUPPORT; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.EVENT_REVIEW_ADMIN_SUPPORT_REQUEST; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.EVENT_REVIEW_JUDGE_SUPPORT_REQUEST; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.EVENT_REVIEW_LEGAL_OFFICER_SUPPORT_REQUEST; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.FLAG_STATUS_ACTIVE; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.FLAG_STATUS_REQUESTED; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.TASK_TYPE_REVIEW_SUPPORT_ADMIN; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.TASK_TYPE_REVIEW_SUPPORT_JUDGE; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.TASK_TYPE_REVIEW_SUPPORT_LEGAL_OFFICER; + +@ExtendWith(MockitoExtension.class) +class SupportTaskCallbackLifecycleTest { + private static final String ABOUT_TO_SUBMIT = "/supportTasks/aboutToSubmit"; + private static final String SUBMITTED = "/supportTasks/submitted"; + private static final String REVIEW_START = "/reviewSupportRequest/aboutToStart"; + private static final String REVIEW_SUBMIT = "/reviewSupportRequest/aboutToSubmit"; + private static final String CLIENT_CONTEXT = "client-context"; + private static final String TOKEN = "token"; + private static final String CASE_ID = "1234567890123456"; + private static final String JURISDICTION = "EMPLOYMENT"; + private static final String SCOTLAND = "ET_Scotland"; + private static final String ENGLAND_WALES = "ET_EnglandWales"; + private static final String ADMIN_CODE = "RA0041"; + private static final String JUDGE_CODE = "RA0038"; + private static final String LO_CODE = "RA0034"; + private static final String LIP_SPEAKER = "Lip speaker"; + private static final String TASK_LINK = "taskLink"; + private static final String MANUAL_REVIEW = "manualReview"; + + @Mock + private FeatureToggleService featureToggleService; + @Mock + private CaseManagementForCaseWorkerService caseManagementForCaseWorkerService; + @Mock + private CcdClient ccdClient; + @Mock + private AdminUserService adminUserService; + @InjectMocks + private CaseActionsForCaseWorkerController controller; + + private final ObjectMapper mapper = new ObjectMapper(); + private final List committedEvents = new ArrayList<>(); + private final List committedArrangeFlags = new ArrayList<>(); + private MockMvc mvc; + private CaseData persisted; + private String caseType; + private boolean failArrangeSubmission; + + @BeforeEach + void setUp() { + SupportTaskConfiguration configuration = new SupportTaskConfiguration(); + configuration.getReview().setAdminFlagCodes(Set.of(ADMIN_CODE)); + configuration.getReview().setJudgeFlagCodes(Set.of(JUDGE_CODE)); + configuration.getReview().setLegalOfficerFlagCodes(Set.of(LO_CODE)); + configuration.getArrange().setFlagTitles(Map.of(ADMIN_CODE, LIP_SPEAKER, JUDGE_CODE, "Intermediary")); + configuration.getClosureRetry().setMaxAttempts(3); + configuration.getClosureRetry().setInitialBackoffMs(1); + configuration.getClosureRetry().setMultiplier(2); + configuration.getClosureRetry().setMaxBackoffMs(2); + ReflectionTestUtils.setField(controller, "supportTaskService", new SupportTaskService(configuration)); + ReflectionTestUtils.setField(controller, "supportTaskClientContextService", + new SupportTaskClientContextService(mapper)); + ReflectionTestUtils.setField(controller, "supportTaskEventService", + new SupportTaskEventService(ccdClient, adminUserService, configuration)); + mvc = MockMvcBuilders.standaloneSetup(controller).build(); + when(featureToggleService.isCaseFlagsV2Enabled(anyString())).thenReturn(true); + } + + static Stream reviewLifecycles() { + return Stream.of( + new Category(ADMIN_CODE, "admin", TASK_TYPE_REVIEW_SUPPORT_ADMIN, + EVENT_REVIEW_ADMIN_SUPPORT_REQUEST, EVENT_CLOSE_ADMIN_REVIEW_SUPPORT_TASK), + new Category(JUDGE_CODE, "judge", TASK_TYPE_REVIEW_SUPPORT_JUDGE, + EVENT_REVIEW_JUDGE_SUPPORT_REQUEST, EVENT_CLOSE_JUDGE_REVIEW_SUPPORT_TASK), + new Category(LO_CODE, "legalOfficer", TASK_TYPE_REVIEW_SUPPORT_LEGAL_OFFICER, + EVENT_REVIEW_LEGAL_OFFICER_SUPPORT_REQUEST, EVENT_CLOSE_LEGAL_OFFICER_REVIEW_SUPPORT_TASK)) + .flatMap(category -> Stream.of(TASK_LINK, MANUAL_REVIEW, EVENT_MANAGE_FLAGS, EVENT_MANAGE_SUPPORT) + .flatMap(route -> Stream.of(ENGLAND_WALES, SCOTLAND) + .map(type -> Arguments.of(category, route, type)))); + } + + @ParameterizedTest(name = "{0}, {1}, {2}") + @MethodSource("reviewLifecycles") + void reviewLifecycleThroughHttpCallbacks(Category category, String route, String type) throws Exception { + caseType = type; + CaseData data = new CaseData(); + data.setAllPartyFlags(AllPartyFlags.builder() + .claimantFlags(flags("claimant-request", category.code(), FLAG_STATUS_REQUESTED)).build()); + data = responseData(callback(ABOUT_TO_SUBMIT, EVENT_CREATE_FLAG, data, new CaseData(), null)); + assertState(data, category, YES, YES); + + CaseData before = copy(data); + data.getAllPartyFlags().setRespondentExternalFlags( + flags("respondent-request", category.code(), FLAG_STATUS_REQUESTED)); + data = responseData(callback(ABOUT_TO_SUBMIT, EVENT_REQUEST_SUPPORT, data, before, null)); + assertState(data, category, YES, null); + + data = actionFlag(data, category, route, "claimant-request", false); + assertState(data, category, YES, null); + verifyNoInteractions(ccdClient); + + if (!TASK_LINK.equals(route)) { + mockCcdPersistence(); + } + data = actionFlag(data, category, route, "respondent-request", true); + assertState(data, category, NO, null); + assertEquals(TASK_LINK.equals(route) ? List.of() : List.of(category.closeEvent()), committedEvents); + if (TASK_LINK.equals(route)) { + verifyNoInteractions(ccdClient); + } else { + verify(ccdClient).submitEventForCase(eq(TOKEN), any(CaseData.class), eq(type), + eq(JURISDICTION), any(CCDRequest.class), eq(CASE_ID)); + } + + before = copy(data); + data.getAllPartyFlags().setClaimantRepresentativeExternalFlags( + flags("new-request", category.code(), FLAG_STATUS_REQUESTED)); + data = responseData(callback(ABOUT_TO_SUBMIT, EVENT_CREATE_FLAG, data, before, null)); + assertState(data, category, YES, YES); + verify(caseManagementForCaseWorkerService, times(5)).setNextListedDate(any(CaseData.class)); + } + + private CaseData actionFlag(CaseData caseData, Category category, String route, String flagId, boolean last) + throws IOException { + CaseData data = caseData; + CaseData before = copy(data); + boolean review = TASK_LINK.equals(route) || MANUAL_REVIEW.equals(route); + String eventId = review ? category.reviewEvent() : route; + if (review) { + data = responseData(callback(REVIEW_START, eventId, data, before, null)); + assertEquals(last ? 1 : 2, data.getReviewSupportRequestFlags().size()); + data.getReviewSupportRequestFlags().stream().map(GenericTypeItem::getValue) + .flatMap(section -> section.getDetails().stream()) + .filter(item -> flagId.equals(item.getId())) + .forEach(item -> item.getValue().setStatus(FLAG_STATUS_ACTIVE)); + } else { + CaseFlagsType section = last ? data.getAllPartyFlags().getRespondentExternalFlags() + : data.getAllPartyFlags().getClaimantFlags(); + section.getDetails().getFirst().getValue().setStatus(FLAG_STATUS_ACTIVE); + } + String context = TASK_LINK.equals(route) ? taskContext(category.taskType()) : null; + MvcResult result = callback(review ? REVIEW_SUBMIT : ABOUT_TO_SUBMIT, eventId, data, before, context); + JsonNode response = mapper.readTree(result.getResponse().getContentAsString()); + assertTrue(response.path("errors").isMissingNode() || response.path("errors").isNull() + || response.path("errors").isEmpty()); + if (context == null) { + assertNull(result.getResponse().getHeader(CLIENT_CONTEXT)); + } else { + JsonNode returnedContext = mapper.readTree(Base64.getDecoder().decode( + result.getResponse().getHeader(CLIENT_CONTEXT))); + assertTrue(returnedContext.at("/client_context/user_task/complete_task").isBoolean()); + assertEquals(last, returnedContext.at("/client_context/user_task/complete_task").booleanValue()); + assertEquals("review-task-id", returnedContext.at("/client_context/user_task/task_data/id").textValue()); + } + data = responseData(result); + CaseFlagsType updated = last ? data.getAllPartyFlags().getRespondentExternalFlags() + : data.getAllPartyFlags().getClaimantFlags(); + assertEquals(FLAG_STATUS_ACTIVE, updated.getDetails().getFirst().getValue().getStatus()); + if (review) { + assertNull(data.getReviewSupportRequestFlags()); + } + assertState(data, category, last && context != null ? NO : YES, null); + persisted = copy(data); + callback(SUBMITTED, eventId, data, before, null); + return copy(persisted); + } + + @Test + void retriesArrangeFailureBeforeClosingPendingReviewWithoutDuplicatingCommittedTasks() throws Exception { + caseType = SCOTLAND; + mockCcdPersistence(); + CaseData before = new CaseData(); + before.setAllPartyFlags(AllPartyFlags.builder() + .claimantFlags(flags("flag-1", ADMIN_CODE, FLAG_STATUS_REQUESTED)).build()); + for (int index = 2; index <= 4; index++) { + before.getAllPartyFlags().getClaimantFlags().getDetails() + .addAll(flags("flag-" + index, ADMIN_CODE, FLAG_STATUS_REQUESTED).getDetails()); + } + before.setSupportTaskState(SupportTaskState.builder().adminTaskCreated(YES).build()); + CaseData current = copy(before); + current.getAllPartyFlags().getClaimantFlags().getDetails() + .forEach(item -> item.getValue().setStatus(FLAG_STATUS_ACTIVE)); + CaseData submitted = responseData(callback(ABOUT_TO_SUBMIT, EVENT_MANAGE_FLAGS, current, before, null)); + assertEquals(YES, submitted.getSupportTaskState().getAdminTaskCreated()); + assertEquals(LIP_SPEAKER, submitted.getSupportTaskState().getArrangeSupportTaskName()); + persisted = copy(submitted); + failArrangeSubmission = true; + + ServletException error = assertThrows(ServletException.class, + () -> callback(SUBMITTED, EVENT_MANAGE_FLAGS, submitted, before, null)); + assertInstanceOf(GenericRuntimeException.class, error.getCause()); + assertEquals(List.of("flag-2", "flag-3"), committedArrangeFlags); + assertEquals(YES, persisted.getSupportTaskState().getAdminTaskCreated()); + verify(ccdClient, times(5)).submitEventForCase(eq(TOKEN), any(CaseData.class), eq(caseType), + eq(JURISDICTION), any(CCDRequest.class), eq(CASE_ID)); + verify(ccdClient, never()).startEventForCase(TOKEN, caseType, JURISDICTION, CASE_ID, + EVENT_CLOSE_ADMIN_REVIEW_SUPPORT_TASK); + + failArrangeSubmission = false; + callback(SUBMITTED, EVENT_MANAGE_FLAGS, submitted, before, null); + assertEquals(List.of("flag-2", "flag-3", "flag-4"), committedArrangeFlags); + assertEquals(List.of(EVENT_CREATE_ARRANGE_SUPPORT_TASK, EVENT_CREATE_ARRANGE_SUPPORT_TASK, + EVENT_CREATE_ARRANGE_SUPPORT_TASK, EVENT_CLOSE_ADMIN_REVIEW_SUPPORT_TASK), committedEvents); + assertEquals(NO, persisted.getSupportTaskState().getAdminTaskCreated()); + + callback(SUBMITTED, EVENT_MANAGE_FLAGS, submitted, before, null); + assertEquals(4, committedEvents.size()); + assertEquals(List.of("flag-2", "flag-3", "flag-4"), committedArrangeFlags); + verify(ccdClient, times(7)).submitEventForCase(eq(TOKEN), any(CaseData.class), eq(caseType), + eq(JURISDICTION), any(CCDRequest.class), eq(CASE_ID)); + } + + private void mockCcdPersistence() throws IOException { + when(adminUserService.getAdminUserToken()).thenReturn(TOKEN); + when(ccdClient.startEventForCase(eq(TOKEN), eq(caseType), eq(JURISDICTION), eq(CASE_ID), anyString())) + .thenAnswer(invocation -> { + CCDRequest request = new CCDRequest(details(copy(persisted))); + request.setEventId(invocation.getArgument(4)); + return request; + }); + when(ccdClient.submitEventForCase(eq(TOKEN), any(CaseData.class), eq(caseType), eq(JURISDICTION), + any(CCDRequest.class), eq(CASE_ID))).thenAnswer(invocation -> { + CaseData data = invocation.getArgument(1); + CCDRequest request = invocation.getArgument(4); + String flagId = data.getSupportTaskState().getArrangeSupportTaskFlagId(); + if (EVENT_CREATE_ARRANGE_SUPPORT_TASK.equals(request.getEventId())) { + if (failArrangeSubmission && "flag-4".equals(flagId)) { + throw new HttpServerErrorException(HttpStatus.SERVICE_UNAVAILABLE); + } + committedArrangeFlags.add(flagId); + } + persisted = copy(data); + committedEvents.add(request.getEventId()); + return null; + }); + } + + @SneakyThrows + private MvcResult callback(String url, String event, CaseData data, CaseData before, String context) { + MockHttpServletRequestBuilder request = post(url).contentType(MediaType.APPLICATION_JSON) + .header("Authorization", TOKEN).content(mapper.writeValueAsBytes(Map.of( + "event_id", event, "case_details", details(data), "case_details_before", details(before)))); + if (context != null) { + request.header(CLIENT_CONTEXT, context); + } + return mvc.perform(request).andExpect(status().isOk()).andReturn(); + } + + private CaseDetails details(CaseData data) { + CaseDetails details = new CaseDetails(); + details.setCaseId(CASE_ID); + details.setCaseTypeId(caseType); + details.setJurisdiction(JURISDICTION); + details.setCaseData(data); + return details; + } + + private CaseData responseData(MvcResult result) throws IOException { + return mapper.treeToValue(mapper.readTree(result.getResponse().getContentAsString()).path("data"), + CaseData.class); + } + + private CaseData copy(CaseData data) throws IOException { + return mapper.readValue(mapper.writeValueAsBytes(data), CaseData.class); + } + + private String taskContext(String type) throws IOException { + return Base64.getEncoder().encodeToString(mapper.writeValueAsBytes(Map.of("client_context", + Map.of("user_task", Map.of("task_data", Map.of("id", "review-task-id", "type", type), + "complete_task", true))))); + } + + private void assertState(CaseData data, Category category, String created, String required) { + JsonNode state = mapper.valueToTree(data.getSupportTaskState()); + assertEquals(created, state.path(category.fieldPrefix() + "TaskCreated").asText(null)); + assertEquals(required, state.path(category.fieldPrefix() + "TaskRequired").asText(null)); + } + + private static CaseFlagsType flags(String id, String code, String status) { + return CaseFlagsType.builder().details(ListTypeItem.from(GenericTypeItem.from(id, + FlagDetailType.builder().flagCode(code).status(status).build()))).build(); + } + + private record Category(String code, String fieldPrefix, String taskType, String reviewEvent, String closeEvent) { + } +} diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskEventServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskEventServiceTest.java index be767b76b0..4f645d2736 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskEventServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskEventServiceTest.java @@ -1,8 +1,12 @@ package uk.gov.hmcts.ethos.replacement.docmosis.service; +import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.springframework.http.HttpStatus; @@ -13,30 +17,47 @@ import uk.gov.hmcts.et.common.model.ccd.CCDRequest; import uk.gov.hmcts.et.common.model.ccd.CaseData; import uk.gov.hmcts.et.common.model.ccd.CaseDetails; +import uk.gov.hmcts.et.common.model.ccd.items.FlagDetailType; +import uk.gov.hmcts.et.common.model.ccd.items.GenericTypeItem; +import uk.gov.hmcts.et.common.model.ccd.items.ListTypeItem; +import uk.gov.hmcts.et.common.model.ccd.types.AllPartyFlags; +import uk.gov.hmcts.et.common.model.ccd.types.CaseFlagsType; import uk.gov.hmcts.et.common.model.ccd.types.SupportTaskState; import uk.gov.hmcts.ethos.replacement.docmosis.config.SupportTaskConfiguration; import uk.gov.hmcts.ethos.replacement.docmosis.exceptions.GenericRuntimeException; +import uk.gov.hmcts.ethos.replacement.docmosis.wa.SupportTaskClientContextService; import java.io.IOException; import java.util.ArrayList; +import java.util.Base64; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Stream; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; +import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; import static uk.gov.hmcts.ecm.common.model.helper.Constants.NO; import static uk.gov.hmcts.ecm.common.model.helper.Constants.YES; import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.EVENT_CLOSE_ADMIN_REVIEW_SUPPORT_TASK; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.EVENT_CLOSE_JUDGE_REVIEW_SUPPORT_TASK; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.EVENT_CLOSE_LEGAL_OFFICER_REVIEW_SUPPORT_TASK; import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.EVENT_CREATE_ARRANGE_SUPPORT_TASK; import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.TASK_TYPE_REVIEW_SUPPORT_ADMIN; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.TASK_TYPE_REVIEW_SUPPORT_JUDGE; +import static uk.gov.hmcts.ethos.replacement.docmosis.constants.SupportTaskConstants.TASK_TYPE_REVIEW_SUPPORT_LEGAL_OFFICER; @ExtendWith(SpringExtension.class) class SupportTaskEventServiceTest { @@ -44,6 +65,11 @@ class SupportTaskEventServiceTest { private static final String CASE_ID = "1234567890123456"; private static final String CASE_TYPE = "ET_Scotland"; private static final String JURISDICTION = "EMPLOYMENT"; + private static final String REQUESTED = "Requested"; + private static final String ACTIVE = "Active"; + private static final String NOT_APPROVED = "Not Approved"; + private static final String INACTIVE = "Inactive"; + private static final String COMPLETE_TASK_PATH = "/client_context/user_task/complete_task"; @Mock private CcdClient ccdClient; @@ -80,21 +106,146 @@ void setUp() { ccdRequest.setCaseDetails(latestCaseDetails); } - @Test - void triggersTheCategorySpecificClosureEventAndResetsOnlyItsMarker() throws IOException { + static Stream closureCategories() { + return Stream.of( + Arguments.of(TASK_TYPE_REVIEW_SUPPORT_ADMIN, EVENT_CLOSE_ADMIN_REVIEW_SUPPORT_TASK), + Arguments.of(TASK_TYPE_REVIEW_SUPPORT_JUDGE, EVENT_CLOSE_JUDGE_REVIEW_SUPPORT_TASK), + Arguments.of(TASK_TYPE_REVIEW_SUPPORT_LEGAL_OFFICER, EVENT_CLOSE_LEGAL_OFFICER_REVIEW_SUPPORT_TASK)); + } + + @ParameterizedTest + @MethodSource("closureCategories") + void triggersTheCategorySpecificClosureEventAndResetsOnlyItsMarker(String taskType, String eventId) + throws IOException { when(adminUserService.getAdminUserToken()).thenReturn(TOKEN); when(ccdClient.startEventForCase(TOKEN, CASE_TYPE, JURISDICTION, CASE_ID, - EVENT_CLOSE_ADMIN_REVIEW_SUPPORT_TASK)).thenReturn(ccdRequest); + eventId)).thenReturn(ccdRequest); ArgumentCaptor caseDataCaptor = ArgumentCaptor.forClass(CaseData.class); - service.triggerReviewTaskClosureEvents(caseDetails, Set.of(TASK_TYPE_REVIEW_SUPPORT_ADMIN)); + service.triggerReviewTaskClosureEvents(caseDetails, Set.of(taskType)); + verify(ccdClient).startEventForCase(TOKEN, CASE_TYPE, JURISDICTION, CASE_ID, eventId); verify(ccdClient).submitEventForCase(eq(TOKEN), caseDataCaptor.capture(), eq(CASE_TYPE), eq(JURISDICTION), eq(ccdRequest), eq(CASE_ID)); SupportTaskState state = caseDataCaptor.getValue().getSupportTaskState(); - assertEquals(NO, state.getAdminTaskCreated()); - assertEquals(YES, state.getLegalOfficerTaskCreated()); - assertEquals(YES, state.getJudgeTaskCreated()); + assertEquals(TASK_TYPE_REVIEW_SUPPORT_ADMIN.equals(taskType) ? NO : YES, state.getAdminTaskCreated()); + assertEquals(TASK_TYPE_REVIEW_SUPPORT_LEGAL_OFFICER.equals(taskType) ? NO : YES, + state.getLegalOfficerTaskCreated()); + assertEquals(TASK_TYPE_REVIEW_SUPPORT_JUDGE.equals(taskType) ? NO : YES, state.getJudgeTaskCreated()); + verifyNoMoreInteractions(ccdClient); + } + + static Stream reviewLifecycles() { + return closureCategories().flatMap(category -> Stream.of(false, true) + .flatMap(fromTask -> Stream.of(ACTIVE, NOT_APPROVED, INACTIVE) + .map(status -> Arguments.of(category.get()[0], category.get()[1], fromTask, status)))); + } + + @ParameterizedTest(name = "{0}, task link={2}, final status={3}") + @MethodSource("reviewLifecycles") + void completesReviewLifecycleAndAllowsANewRequest(String taskType, String closureEvent, + boolean fromTask, String finalStatus) throws IOException { + ObjectMapper mapper = new ObjectMapper(); + final SupportTaskClientContextService contextService = new SupportTaskClientContextService(mapper); + SupportTaskConfiguration configuration = new SupportTaskConfiguration(); + configuration.getReview().setAdminFlagCodes(Set.of("RA0039", "RA0041")); + configuration.getReview().setJudgeFlagCodes(Set.of("RA0037", "RA0038")); + configuration.getReview().setLegalOfficerFlagCodes(Set.of("RA0034", "RA0035")); + SupportTaskService taskService = new SupportTaskService(configuration); + List codes = switch (taskType) { + case TASK_TYPE_REVIEW_SUPPORT_ADMIN -> List.of("RA0039", "RA0041"); + case TASK_TYPE_REVIEW_SUPPORT_JUDGE -> List.of("RA0037", "RA0038"); + case TASK_TYPE_REVIEW_SUPPORT_LEGAL_OFFICER -> List.of("RA0034", "RA0035"); + default -> throw new IllegalArgumentException(taskType); + }; + final String context = fromTask ? Base64.getEncoder().encodeToString(mapper.writeValueAsBytes( + Map.of("client_context", Map.of("user_task", Map.of( + "task_data", Map.of("id", "review-task-id", "type", taskType), + "complete_task", true))))) : null; + CaseData data = new CaseData(); + data.setAllPartyFlags(AllPartyFlags.builder() + .claimantFlags(requestedFlag("claimant-request", codes.getFirst())).build()); + taskService.prepareNewFlagReviewSupportTasks(data, new CaseData()); + assertCategoryState(data, taskType, YES, YES); + + CaseData before = mapper.readValue(mapper.writeValueAsBytes(data), CaseData.class); + data.getAllPartyFlags().setRespondentExternalFlags(requestedFlag("respondent-request", codes.getLast())); + taskService.prepareNewFlagReviewSupportTasks(data, before); + assertCategoryState(data, taskType, YES, null); + + before = mapper.readValue(mapper.writeValueAsBytes(data), CaseData.class); + data.getAllPartyFlags().getClaimantFlags().getDetails().getFirst().getValue().setStatus(ACTIVE); + Set closures = taskService.prepareManagedReviewSupportTasks(data, before); + assertTrue(closures.isEmpty()); + assertCategoryState(data, taskType, YES, null); + assertCompletionContext(mapper, contextService.updateTaskCompletion(context, closures), fromTask, false); + service.triggerReviewTaskClosureEvents(caseDetails, taskService.reviewTaskTypesToClose(data)); + verifyNoInteractions(ccdClient); + + before = mapper.readValue(mapper.writeValueAsBytes(data), CaseData.class); + data.getAllPartyFlags().getRespondentExternalFlags().getDetails().getFirst().getValue().setStatus(finalStatus); + closures = taskService.prepareManagedReviewSupportTasks(data, before); + assertEquals(Set.of(taskType), closures); + assertCategoryState(data, taskType, NO, null); + assertCompletionContext(mapper, contextService.updateTaskCompletion(context, closures), fromTask, true); + if (!fromTask) { + taskService.retainReviewTasksForSubmittedCallback(data, closures); + assertCategoryState(data, taskType, YES, null); + ccdRequest.getCaseDetails().setCaseData(data); + when(adminUserService.getAdminUserToken()).thenReturn(TOKEN); + when(ccdClient.startEventForCase(TOKEN, CASE_TYPE, JURISDICTION, CASE_ID, closureEvent)) + .thenReturn(ccdRequest); + assertEquals(Set.of(taskType), taskService.reviewTaskTypesToClose(data)); + service.triggerReviewTaskClosureEvents(caseDetails, taskService.reviewTaskTypesToClose(data)); + verify(ccdClient).startEventForCase(TOKEN, CASE_TYPE, JURISDICTION, CASE_ID, closureEvent); + verify(ccdClient).submitEventForCase(TOKEN, data, CASE_TYPE, JURISDICTION, ccdRequest, CASE_ID); + } else { + service.triggerReviewTaskClosureEvents(caseDetails, taskService.reviewTaskTypesToClose(data)); + } + assertCategoryState(data, taskType, NO, null); + assertTrue(taskService.reviewTaskTypesToClose(data).isEmpty()); + verifyNoMoreInteractions(ccdClient); + + before = mapper.readValue(mapper.writeValueAsBytes(data), CaseData.class); + data.getAllPartyFlags().setClaimantRepresentativeExternalFlags(requestedFlag("new-request", codes.getFirst())); + taskService.prepareNewFlagReviewSupportTasks(data, before); + assertCategoryState(data, taskType, YES, YES); + taskService.prepareNewFlagReviewSupportTasks(data, before); + assertCategoryState(data, taskType, YES, null); + } + + private static CaseFlagsType requestedFlag(String id, String code) { + return CaseFlagsType.builder().details(ListTypeItem.from(GenericTypeItem.from(id, + FlagDetailType.builder().flagCode(code).status(REQUESTED).build()))).build(); + } + + private static void assertCategoryState(CaseData data, String taskType, String created, String required) { + SupportTaskState state = data.getSupportTaskState(); + switch (taskType) { + case TASK_TYPE_REVIEW_SUPPORT_ADMIN -> { + assertEquals(created, state.getAdminTaskCreated()); + assertEquals(required, state.getAdminTaskRequired()); + } + case TASK_TYPE_REVIEW_SUPPORT_JUDGE -> { + assertEquals(created, state.getJudgeTaskCreated()); + assertEquals(required, state.getJudgeTaskRequired()); + } + case TASK_TYPE_REVIEW_SUPPORT_LEGAL_OFFICER -> { + assertEquals(created, state.getLegalOfficerTaskCreated()); + assertEquals(required, state.getLegalOfficerTaskRequired()); + } + default -> throw new IllegalArgumentException(taskType); + } + } + + private static void assertCompletionContext(ObjectMapper mapper, String context, boolean fromTask, + boolean expected) throws IOException { + if (fromTask) { + assertEquals(expected, mapper.readTree(Base64.getDecoder().decode(context)) + .at(COMPLETE_TASK_PATH).booleanValue()); + } else { + assertNull(context); + } } @Test From 253e30b44df763f4720421473d03c51355cb70cd Mon Sep 17 00:00:00 2001 From: rajaram Date: Fri, 18 Sep 2026 11:00:00 +0100 Subject: [PATCH 082/100] ET needs an adaptation: read client-context from the servlet request and write the updated header onto the servlet response due to CCD decentralised runtime 7.2.0 --- .../CaseActionsForCaseWorkerController.java | 24 +++-- .../SupportTaskCallbackLifecycleTest.java | 93 +++++++++++++++++++ 2 files changed, 110 insertions(+), 7 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java index 18d2a22c50..d1ad497d2f 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java @@ -13,6 +13,9 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; import uk.gov.hmcts.ecm.common.model.helper.Constants; import uk.gov.hmcts.ecm.common.model.helper.DefaultValues; import uk.gov.hmcts.et.common.model.ccd.CCDCallbackResponse; @@ -228,8 +231,7 @@ public ResponseEntity postDefaultValues( @Operation(summary = "Prepare Review Support and Arrange Support tasks for eligible Case Flags.") public ResponseEntity prepareSupportTasks( @RequestBody CallbackRequest callbackRequest, - @RequestHeader(AUTHORIZATION) String userToken, - @RequestHeader(value = CLIENT_CONTEXT, required = false) String clientContext) { + @RequestHeader(AUTHORIZATION) String userToken) { CaseDetails caseDetails = callbackRequest.getCaseDetails(); CaseData caseData = caseDetails.getCaseData(); Set taskTypesToComplete = null; @@ -258,7 +260,7 @@ public ResponseEntity prepareSupportTasks( } return addTaskCompletionHeader( - getCallbackRespEntityNoErrors(caseData), clientContext, taskTypesToComplete); + getCallbackRespEntityNoErrors(caseData), taskTypesToComplete); } @PostMapping(value = "/reviewSupportRequest/aboutToStart", consumes = APPLICATION_JSON_VALUE) @@ -277,8 +279,7 @@ public ResponseEntity prepareReviewSupportRequest( @Operation(summary = "Apply reviewed Case Flags and prepare the related support tasks.") public ResponseEntity applyReviewSupportRequest( @RequestBody CallbackRequest callbackRequest, - @RequestHeader(AUTHORIZATION) String userToken, - @RequestHeader(value = CLIENT_CONTEXT, required = false) String clientContext) { + @RequestHeader(AUTHORIZATION) String userToken) { CaseDetails caseDetails = callbackRequest.getCaseDetails(); CaseData caseData = caseDetails.getCaseData(); List errors = new ArrayList<>(); @@ -296,7 +297,7 @@ public ResponseEntity applyReviewSupportRequest( } } return addTaskCompletionHeader( - getCallbackRespEntityErrors(errors, caseData), clientContext, taskTypesToComplete); + getCallbackRespEntityErrors(errors, caseData), taskTypesToComplete); } @PostMapping(value = "/supportTasks/submitted", consumes = APPLICATION_JSON_VALUE) @@ -318,11 +319,16 @@ public ResponseEntity closeReviewSupportTasks( private ResponseEntity addTaskCompletionHeader( ResponseEntity response, - String clientContext, Set taskTypesToComplete) { if (taskTypesToComplete == null) { return response; } + // The SDK callback bridge only accepts Authorization/ServiceAuthorization header parameters. + RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); + ServletRequestAttributes servletAttributes = requestAttributes instanceof ServletRequestAttributes attributes + ? attributes : null; + String clientContext = servletAttributes == null ? null + : servletAttributes.getRequest().getHeader(CLIENT_CONTEXT); String updatedClientContext = supportTaskClientContextService.updateTaskCompletion( clientContext, taskTypesToComplete); if (updatedClientContext == null) { @@ -330,6 +336,10 @@ private ResponseEntity addTaskCompletionHeader( response.getBody().getData(), taskTypesToComplete); return response; } + // SDK invocation unwraps ResponseEntity, so also preserve the header on the enclosing HTTP response. + if (servletAttributes != null && servletAttributes.getResponse() != null) { + servletAttributes.getResponse().setHeader(CLIENT_CONTEXT, updatedClientContext); + } return ResponseEntity.status(response.getStatusCode()) .headers(response.getHeaders()) .header(CLIENT_CONTEXT, updatedClientContext) diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/SupportTaskCallbackLifecycleTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/SupportTaskCallbackLifecycleTest.java index 892506f7ab..5907c751d0 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/SupportTaskCallbackLifecycleTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/SupportTaskCallbackLifecycleTest.java @@ -10,17 +10,28 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; +import org.junit.jupiter.params.provider.ValueSource; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.beans.BeanUtils; +import org.springframework.context.ApplicationContext; +import org.springframework.core.env.Environment; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; +import org.springframework.mock.env.MockEnvironment; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.test.util.ReflectionTestUtils; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.client.HttpServerErrorException; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; +import uk.gov.hmcts.ccd.sdk.impl.json.JsonCallbackBridge; import uk.gov.hmcts.ecm.common.client.CcdClient; import uk.gov.hmcts.et.common.model.ccd.CCDRequest; import uk.gov.hmcts.et.common.model.ccd.CaseData; @@ -48,6 +59,7 @@ import java.util.Set; import java.util.stream.Stream; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertNull; @@ -100,6 +112,7 @@ class SupportTaskCallbackLifecycleTest { private static final String LIP_SPEAKER = "Lip speaker"; private static final String TASK_LINK = "taskLink"; private static final String MANUAL_REVIEW = "manualReview"; + private static final String LOCAL_CALLBACK = "${ET_COS_URL}"; @Mock private FeatureToggleService featureToggleService; @@ -153,6 +166,86 @@ static Stream reviewLifecycles() { .map(type -> Arguments.of(category, route, type)))); } + @ParameterizedTest + @ValueSource(strings = {ABOUT_TO_SUBMIT, REVIEW_SUBMIT}) + void callbackSignatureIsAcceptedByDeployedCcdSdk(String callbackUrl) throws Exception { + JsonCallbackBridge bridge = sdkBridge(); + + assertDoesNotThrow(() -> bridge.validate(LOCAL_CALLBACK + callbackUrl)); + + caseType = SCOTLAND; + callback(callbackUrl, EVENT_CREATE_FLAG, new CaseData(), new CaseData(), null); + } + + private JsonCallbackBridge sdkBridge() throws NoSuchMethodException { + ApplicationContext context = mvc.getDispatcherServlet().getWebApplicationContext(); + return BeanUtils.instantiateClass(JsonCallbackBridge.class.getDeclaredConstructor( + ApplicationContext.class, ObjectMapper.class, RequestMappingHandlerMapping.class, Environment.class), + context, mapper, context.getBean(RequestMappingHandlerMapping.class), + new MockEnvironment().withProperty("decentralisation.local-callback-placeholder", "ET_COS_URL")); + } + + static Stream sdkInvocations() { + return Stream.of(ABOUT_TO_SUBMIT, REVIEW_SUBMIT) + .flatMap(url -> Stream.of(false, true).flatMap(requestedRemains -> Stream.of(false, true) + .map(withContext -> Arguments.of(url, requestedRemains, withContext)))); + } + + @ParameterizedTest + @MethodSource("sdkInvocations") + void sdkInvocationPreservesCompletionHeaderAndManualClosureFallback( + String url, boolean requestedRemains, boolean withContext) throws Exception { + caseType = SCOTLAND; + CaseData before = new CaseData(); + before.setAllPartyFlags(AllPartyFlags.builder() + .claimantFlags(flags("claimant-request", ADMIN_CODE, FLAG_STATUS_REQUESTED)).build()); + before.setSupportTaskState(SupportTaskState.builder().adminTaskCreated(YES).build()); + if (requestedRemains) { + before.getAllPartyFlags().setRespondentExternalFlags( + flags("remaining-request", ADMIN_CODE, FLAG_STATUS_REQUESTED)); + } + CaseData data = copy(before); + if (REVIEW_SUBMIT.equals(url)) { + data.setReviewSupportRequestFlags(ListTypeItem.from(GenericTypeItem.from("reviewed-section", + flags("claimant-request", ADMIN_CODE, FLAG_STATUS_ACTIVE)))); + } else { + data.getAllPartyFlags().getClaimantFlags().getDetails().getFirst().getValue().setStatus(FLAG_STATUS_ACTIVE); + } + MockHttpServletRequest request = new MockHttpServletRequest(); + request.addHeader("Authorization", TOKEN); + if (withContext) { + request.addHeader(CLIENT_CONTEXT, taskContext(TASK_TYPE_REVIEW_SUPPORT_ADMIN)); + } + MockHttpServletResponse response = new MockHttpServletResponse(); + JsonCallbackBridge bridge = sdkBridge(); + Map payload = Map.of("case_details", details(data), "case_details_before", details(before), + "event_id", REVIEW_SUBMIT.equals(url) ? EVENT_REVIEW_ADMIN_SUPPORT_REQUEST : EVENT_MANAGE_FLAGS); + + RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request, response)); + try { + bridge.validate(LOCAL_CALLBACK + url); + Object body = ReflectionTestUtils.invokeMethod(bridge, "invoke", LOCAL_CALLBACK + url, payload); + JsonNode result = mapper.valueToTree(body); + assertEquals(withContext && !requestedRemains ? NO : YES, + result.at("/data/supportTaskState/adminTaskCreated").textValue()); + assertEquals(FLAG_STATUS_ACTIVE, + result.at("/data/claimantFlags/details/0/value/status").textValue()); + if (withContext) { + JsonNode returnedContext = mapper.readTree( + Base64.getDecoder().decode(response.getHeader(CLIENT_CONTEXT))); + assertTrue(returnedContext.at("/client_context/user_task/complete_task").isBoolean()); + assertEquals(!requestedRemains, + returnedContext.at("/client_context/user_task/complete_task").booleanValue()); + assertEquals("review-task-id", + returnedContext.at("/client_context/user_task/task_data/id").textValue()); + } else { + assertNull(response.getHeader(CLIENT_CONTEXT)); + } + } finally { + RequestContextHolder.resetRequestAttributes(); + } + } + @ParameterizedTest(name = "{0}, {1}, {2}") @MethodSource("reviewLifecycles") void reviewLifecycleThroughHttpCallbacks(Category category, String route, String type) throws Exception { From 833c900d1bb5a434d34550b60b9b69b4cb062c89 Mon Sep 17 00:00:00 2001 From: rajaram Date: Fri, 18 Sep 2026 15:22:42 +0100 Subject: [PATCH 083/100] Arrange flags without a review mapping fall back to Admin Review when Requested --- .../docmosis/service/SupportTaskService.java | 5 +- .../service/SupportTaskServiceTest.java | 89 +++++++++++++++++++ 2 files changed, 93 insertions(+), 1 deletion(-) diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java index d8217a5f7b..ca9b9d58ff 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java @@ -341,7 +341,10 @@ public void prepareNewFlagArrangeSupportTask(CaseData caseData, CaseData caseDat private Predicate adminReviewFlag() { return eligibleFlag(configuration.getReview().getAdminFlagCodes(), - configuration.getReview().getAdminPathFlags()); + configuration.getReview().getAdminPathFlags()) + .or(flag -> arrangeTaskName(flag).isPresent() + && !judgeReviewFlag().test(flag) + && !legalOfficerReviewFlag().test(flag)); } public record ArrangeSupportTask(String flagId, String taskName) { diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java index ac8d9b7c9d..7d41f902d2 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java @@ -750,6 +750,95 @@ static Stream arrangeSupportFlagScenarios() { .map(entry -> Arguments.of(entry.getKey(), entry.getValue())); } + static Stream arrangeOnlyFlagCodes() { + SupportTaskConfiguration config = configuration(); + return config.getArrange().getFlagTitles().keySet().stream() + .filter(code -> !config.getReview().getAdminFlagCodes().contains(code) + && !config.getReview().getJudgeFlagCodes().contains(code) + && !config.getReview().getLegalOfficerFlagCodes().contains(code)); + } + + @ParameterizedTest + @MethodSource("arrangeOnlyFlagCodes") + void arrange_only_requested_flags_create_one_admin_review_and_appear_in_review_list(String code) { + CaseData data = caseDataWithClaimantFlag(code, STATUS_REQUESTED, true); + + service.prepareReviewSupportTasks(data); + service.prepareReviewSupportRequest(data, EVENT_REVIEW_ADMIN_SUPPORT_REQUEST); + + assertEquals(YES, taskState(data).getAdminTaskRequired()); + assertEquals(YES, taskState(data).getAdminTaskCreated()); + assertNull(taskState(data).getJudgeTaskRequired()); + assertNull(taskState(data).getLegalOfficerTaskRequired()); + assertEquals(1, data.getReviewSupportRequestFlags().size()); + assertEquals(code, data.getReviewSupportRequestFlags().getFirst().getValue() + .getDetails().getFirst().getValue().getFlagCode()); + + service.prepareReviewSupportTasks(data); + + assertNull(taskState(data).getAdminTaskRequired()); + assertTrue(service.reviewTaskTypesToClose(data).isEmpty()); + } + + @ParameterizedTest + @ValueSource(strings = {STATUS_ACTIVE, STATUS_INACTIVE, STATUS_NOT_APPROVED}) + void arrange_fallback_review_closes_only_after_last_requested_flag_changes_status(String status) { + CaseData data = caseDataWithFlags("RA0033", STATUS_ACTIVE, "RA0017", STATUS_REQUESTED); + taskState(data).setAdminTaskCreated(YES); + + assertTrue(service.prepareManagedReviewSupportTasks(data, null).isEmpty()); + assertEquals(YES, taskState(data).getAdminTaskCreated()); + assertTrue(service.reviewTaskTypesToClose(data).isEmpty()); + + data.getAllPartyFlags().getRespondentFlags().getDetails().getFirst().getValue().setStatus(status); + assertEquals(Set.of(TASK_TYPE_REVIEW_SUPPORT_ADMIN), service.reviewTaskTypesToClose(data)); + assertEquals(Set.of(TASK_TYPE_REVIEW_SUPPORT_ADMIN), service.prepareManagedReviewSupportTasks(data, null)); + assertEquals(NO, taskState(data).getAdminTaskCreated()); + + CaseData fresh = caseDataWithClaimantFlag("RA0017", status, false); + service.prepareReviewSupportTasks(fresh); + assertNull(taskState(fresh).getAdminTaskRequired()); + } + + @ParameterizedTest + @ValueSource(strings = {TASK_TYPE_JUDGE, TASK_TYPE_LEGAL_OFFICER}) + void explicit_review_mapping_takes_precedence_over_arrange_fallback(String category) { + SupportTaskConfiguration config = configuration(); + if (TASK_TYPE_JUDGE.equals(category)) { + config.getReview().setJudgeFlagCodes(Set.of("RA0017")); + } else { + config.getReview().setLegalOfficerFlagCodes(Set.of("RA0017")); + } + SupportTaskService configuredService = new SupportTaskService(config); + CaseData data = caseDataWithClaimantFlag("RA0017", STATUS_REQUESTED, false); + + configuredService.prepareReviewSupportTasks(data); + configuredService.prepareReviewSupportRequest(data, EVENT_REVIEW_ADMIN_SUPPORT_REQUEST); + + assertNull(taskState(data).getAdminTaskRequired()); + assertEquals(TASK_TYPE_JUDGE.equals(category) ? YES : null, taskState(data).getJudgeTaskRequired()); + assertEquals(TASK_TYPE_LEGAL_OFFICER.equals(category) ? YES : null, + taskState(data).getLegalOfficerTaskRequired()); + assertTrue(data.getReviewSupportRequestFlags().isEmpty()); + } + + @Test + void arrange_path_fallback_respects_explicit_review_path_mapping() { + SupportTaskConfiguration config = configuration(); + config.getReview().setAdminPathFlags(List.of()); + SupportTaskService configuredService = new SupportTaskService(config); + CaseData data = caseDataWithClaimantFlag(OTHER_FLAG_CODE, STATUS_REQUESTED, false, HELP_WITH_FORMS_PATH); + + configuredService.prepareReviewSupportTasks(data); + assertEquals(YES, taskState(data).getAdminTaskRequired()); + + config.getReview().setJudgePathFlags(List.of(pathFlag(OTHER_FLAG_CODE, HELP_WITH_FORMS_PATH))); + CaseData mapped = caseDataWithClaimantFlag(OTHER_FLAG_CODE, STATUS_REQUESTED, false, HELP_WITH_FORMS_PATH); + configuredService.prepareReviewSupportTasks(mapped); + assertNull(taskState(mapped).getAdminTaskRequired()); + assertEquals(YES, taskState(mapped).getJudgeTaskRequired()); + } + @ParameterizedTest @MethodSource("arrangeSupportFlagScenarios") void prepares_arrange_support_task_for_each_new_active_flag(String flagCode, String taskName) { From 80d4b0c6788802de7a5a167940d910f07a723cca Mon Sep 17 00:00:00 2001 From: rajaram Date: Tue, 22 Sep 2026 15:57:23 +0100 Subject: [PATCH 084/100] Admin review tasks fallback for all RA codes with requested status --- .../config/SupportTaskConfiguration.java | 1 - .../docmosis/service/SupportTaskService.java | 19 ++++++-- src/main/resources/support-tasks.yml | 38 --------------- .../config/SupportTaskConfigurationTest.java | 19 ++------ .../SupportTaskCallbackLifecycleTest.java | 1 - .../service/SupportTaskEventServiceTest.java | 1 - .../service/SupportTaskServiceTest.java | 48 +++++++++++++++---- 7 files changed, 58 insertions(+), 69 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/config/SupportTaskConfiguration.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/config/SupportTaskConfiguration.java index f762b198d1..701fb6cad2 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/config/SupportTaskConfiguration.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/config/SupportTaskConfiguration.java @@ -22,7 +22,6 @@ public class SupportTaskConfiguration { @Data public static class Review { - private Set adminFlagCodes = Set.of(); private Set legalOfficerFlagCodes = Set.of(); private Set judgeFlagCodes = Set.of(); private List adminPathFlags = List.of(); diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java index ca9b9d58ff..ba74c63f56 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java @@ -340,11 +340,20 @@ public void prepareNewFlagArrangeSupportTask(CaseData caseData, CaseData caseDat } private Predicate adminReviewFlag() { - return eligibleFlag(configuration.getReview().getAdminFlagCodes(), - configuration.getReview().getAdminPathFlags()) - .or(flag -> arrangeTaskName(flag).isPresent() - && !judgeReviewFlag().test(flag) - && !legalOfficerReviewFlag().test(flag)); + return flag -> !judgeReviewFlag().test(flag) && !legalOfficerReviewFlag().test(flag) + && ((flag.getFlagCode() != null && flag.getFlagCode().startsWith("RA")) + || configuration.getReview().getAdminPathFlags().stream() + .anyMatch(pathFlag -> Objects.equals(flag.getFlagCode(), pathFlag.getFlagCode()) + && hasPathPrefix(flag, pathFlag.getPath()))); + } + + private static boolean hasPathPrefix(FlagDetailType flag, List expectedPath) { + if (expectedPath.isEmpty() || flag.getPath() == null || flag.getPath().size() < expectedPath.size()) { + return false; + } + List actualPrefix = flag.getPath().stream().limit(expectedPath.size()) + .map(item -> item == null ? null : item.getValue()).toList(); + return expectedPath.equals(actualPrefix); } public record ArrangeSupportTask(String flagId, String taskName) { diff --git a/src/main/resources/support-tasks.yml b/src/main/resources/support-tasks.yml index 4c69413754..f39d63d641 100644 --- a/src/main/resources/support-tasks.yml +++ b/src/main/resources/support-tasks.yml @@ -5,49 +5,11 @@ support-tasks: multiplier: 2 max-backoff-ms: 1000 review: - admin-flag-codes: - - RA0021 - - RA0033 - - RA0039 - - RA0041 admin-path-flags: - flag-code: OT0001 path: - Party - Reasonable adjustment - - I need help communicating and understanding - - Hearing Enhancement System (Hearing - - Induction Loop, Infrared Receiver) - - flag-code: OT0001 - path: - - Party - - Reasonable adjustment - - I need documents in an alternative format - - flag-code: OT0001 - path: - - Party - - Reasonable adjustment - - I need help with forms - - flag-code: OT0001 - path: - - Party - - Reasonable adjustment - - I need adjustments to get to, into and around our buildings - - flag-code: OT0001 - path: - - Party - - Reasonable adjustment - - I need to bring support with me to a hearing - - flag-code: OT0001 - path: - - Party - - Reasonable adjustment - - I need something to feel comfortable during my hearing - - flag-code: OT0001 - path: - - Party - - Reasonable adjustment - - I need help communicating and understanding judge-flag-codes: - RA0029 - RA0031 diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/config/SupportTaskConfigurationTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/config/SupportTaskConfigurationTest.java index d25fc067f1..e78d201178 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/config/SupportTaskConfigurationTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/config/SupportTaskConfigurationTest.java @@ -25,25 +25,14 @@ void loadsRetrySettingsFromYaml() { @Test void loadsFlagCodesFromYaml() { - assertThat(configuration.getReview().getAdminFlagCodes()) - .containsExactlyInAnyOrder("RA0021", "RA0033", "RA0039", "RA0041"); assertThat(configuration.getReview().getJudgeFlagCodes()) .containsExactlyInAnyOrder("RA0029", "RA0031", "RA0032", "RA0037", "RA0038"); assertThat(configuration.getReview().getLegalOfficerFlagCodes()) .containsExactlyInAnyOrder("RA0034", "RA0035", "RA0036"); - assertThat(configuration.getReview().getAdminPathFlags()) - .hasSize(7) - .allSatisfy(pathFlag -> assertThat(pathFlag.getFlagCode()).isEqualTo("OT0001")); - assertThat(configuration.getReview().getAdminPathFlags()) - .extracting(pathFlag -> pathFlag.getPath().getLast()) - .containsExactlyInAnyOrder( - "Induction Loop, Infrared Receiver)", - "I need documents in an alternative format", - "I need help with forms", - "I need adjustments to get to, into and around our buildings", - "I need to bring support with me to a hearing", - "I need something to feel comfortable during my hearing", - "I need help communicating and understanding"); + assertThat(configuration.getReview().getAdminPathFlags()).singleElement().satisfies(pathFlag -> { + assertThat(pathFlag.getFlagCode()).isEqualTo("OT0001"); + assertThat(pathFlag.getPath()).containsExactly("Party", "Reasonable adjustment"); + }); assertThat(configuration.getArrange().getFlagTitles()) .containsEntry("RA0017", "Guidance on how to complete forms") diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/SupportTaskCallbackLifecycleTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/SupportTaskCallbackLifecycleTest.java index 5907c751d0..c11d243960 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/SupportTaskCallbackLifecycleTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/SupportTaskCallbackLifecycleTest.java @@ -136,7 +136,6 @@ class SupportTaskCallbackLifecycleTest { @BeforeEach void setUp() { SupportTaskConfiguration configuration = new SupportTaskConfiguration(); - configuration.getReview().setAdminFlagCodes(Set.of(ADMIN_CODE)); configuration.getReview().setJudgeFlagCodes(Set.of(JUDGE_CODE)); configuration.getReview().setLegalOfficerFlagCodes(Set.of(LO_CODE)); configuration.getArrange().setFlagTitles(Map.of(ADMIN_CODE, LIP_SPEAKER, JUDGE_CODE, "Intermediary")); diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskEventServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskEventServiceTest.java index 4f645d2736..6b833fab73 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskEventServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskEventServiceTest.java @@ -148,7 +148,6 @@ void completesReviewLifecycleAndAllowsANewRequest(String taskType, String closur ObjectMapper mapper = new ObjectMapper(); final SupportTaskClientContextService contextService = new SupportTaskClientContextService(mapper); SupportTaskConfiguration configuration = new SupportTaskConfiguration(); - configuration.getReview().setAdminFlagCodes(Set.of("RA0039", "RA0041")); configuration.getReview().setJudgeFlagCodes(Set.of("RA0037", "RA0038")); configuration.getReview().setLegalOfficerFlagCodes(Set.of("RA0034", "RA0035")); SupportTaskService taskService = new SupportTaskService(configuration); diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java index 7d41f902d2..95f454edc7 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java @@ -64,12 +64,10 @@ class SupportTaskServiceTest { private static SupportTaskConfiguration configuration() { SupportTaskConfiguration configuration = new SupportTaskConfiguration(); - configuration.getReview().setAdminFlagCodes(Set.of("RA0021", "RA0033", "RA0039", "RA0041")); configuration.getReview().setLegalOfficerFlagCodes(Set.of("RA0034", "RA0035", "RA0036")); configuration.getReview().setJudgeFlagCodes(Set.of("RA0029", "RA0031", "RA0032", "RA0037", "RA0038")); - configuration.getReview().setAdminPathFlags(OTHER_REVIEW_PATHS.stream() - .map(path -> pathFlag(OTHER_FLAG_CODE, path)) - .toList()); + configuration.getReview().setAdminPathFlags(List.of( + pathFlag(OTHER_FLAG_CODE, List.of("Party", "Reasonable adjustment")))); configuration.getArrange().setFlagTitles(Map.ofEntries( Map.entry("RA0017", "Guidance on how to complete forms"), Map.entry("RA0018", "Support filling in forms"), @@ -729,7 +727,7 @@ static Stream ineligibleFlagScenarios() { return Stream.of( Arguments.of("RA0033", STATUS_ACTIVE), Arguments.of("RA0033", null), - Arguments.of("RA9999", STATUS_REQUESTED) + Arguments.of("XX9999", STATUS_REQUESTED) ); } @@ -750,11 +748,46 @@ static Stream arrangeSupportFlagScenarios() { .map(entry -> Arguments.of(entry.getKey(), entry.getValue())); } + @ParameterizedTest + @ValueSource(strings = {"RA0003", "RA9999"}) + void unconfigured_ra_codes_require_admin_review_but_not_arrange(String code) { + CaseData data = caseDataWithClaimantFlag(code, STATUS_REQUESTED, false); + service.prepareReviewSupportTasks(data); + assertEquals(YES, taskState(data).getAdminTaskRequired()); + assertNull(taskState(data).getJudgeTaskRequired()); + assertNull(taskState(data).getLegalOfficerTaskRequired()); + service.prepareReviewSupportRequest(data, EVENT_REVIEW_ADMIN_SUPPORT_REQUEST); + assertEquals(1, data.getReviewSupportRequestFlags().size()); + + data.getAllPartyFlags().getClaimantFlags().getDetails().getFirst().getValue().setStatus(STATUS_ACTIVE); + assertEquals(Set.of(TASK_TYPE_REVIEW_SUPPORT_ADMIN), service.prepareManagedReviewSupportTasks(data, null)); + service.prepareArrangeSupportTask(data, null); + assertNull(taskState(data).getArrangeSupportTaskName()); + } + + static Stream adminPathPrefixScenarios() { + return Stream.of( + Arguments.of(List.of("Party", "Reasonable adjustment"), true), + Arguments.of(List.of("Party", "Reasonable adjustment", "New category", "Other"), true), + Arguments.of(List.of("Party"), false), + Arguments.of(List.of("Party", "Other", "Reasonable adjustment"), false), + Arguments.of(List.of("Case", "Reasonable adjustment"), false)); + } + + @ParameterizedTest + @MethodSource("adminPathPrefixScenarios") + void other_flags_use_reasonable_adjustment_parent_prefix(List path, boolean eligible) { + CaseData data = caseDataWithClaimantFlag(OTHER_FLAG_CODE, STATUS_REQUESTED, true, path); + service.prepareReviewSupportTasks(data); + assertEquals(eligible ? YES : null, taskState(data).getAdminTaskRequired()); + service.prepareReviewSupportRequest(data, EVENT_REVIEW_ADMIN_SUPPORT_REQUEST); + assertEquals(eligible ? 1 : 0, data.getReviewSupportRequestFlags().size()); + } + static Stream arrangeOnlyFlagCodes() { SupportTaskConfiguration config = configuration(); return config.getArrange().getFlagTitles().keySet().stream() - .filter(code -> !config.getReview().getAdminFlagCodes().contains(code) - && !config.getReview().getJudgeFlagCodes().contains(code) + .filter(code -> !config.getReview().getJudgeFlagCodes().contains(code) && !config.getReview().getLegalOfficerFlagCodes().contains(code)); } @@ -825,7 +858,6 @@ void explicit_review_mapping_takes_precedence_over_arrange_fallback(String categ @Test void arrange_path_fallback_respects_explicit_review_path_mapping() { SupportTaskConfiguration config = configuration(); - config.getReview().setAdminPathFlags(List.of()); SupportTaskService configuredService = new SupportTaskService(config); CaseData data = caseDataWithClaimantFlag(OTHER_FLAG_CODE, STATUS_REQUESTED, false, HELP_WITH_FORMS_PATH); From 190273672e9d94caf8894b33a820fbf1f04f38f9 Mon Sep 17 00:00:00 2001 From: hmcts-jenkins-d-to-i <62423932+hmcts-jenkins-d-to-i[bot]@users.noreply.github.com> Date: Tue, 22 Sep 2026 14:58:43 +0000 Subject: [PATCH 085/100] Bumping chart version/ fixing aliases --- charts/et-cos/Chart.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/et-cos/Chart.yaml b/charts/et-cos/Chart.yaml index 2aff67cec7..5c3b7b6f4d 100644 --- a/charts/et-cos/Chart.yaml +++ b/charts/et-cos/Chart.yaml @@ -1,7 +1,7 @@ apiVersion: v2 name: et-cos home: https://github.com/hmcts/et-ccd-callbacks -version: 0.0.77 +version: 0.0.78 description: HMCTS Employment Tribunals CCD Callbacks service maintainers: - name: HMCTS Employment Tribunals Team From 088a56f1b4748a205ae4db234f981e81c757aac2 Mon Sep 17 00:00:00 2001 From: rajaram Date: Thu, 24 Sep 2026 14:41:24 +0100 Subject: [PATCH 086/100] Show summary pages for the review tasks --- .../json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json | 6 +++--- .../CaseEventToFields/CaseEventToFields-SupportTasks.json | 6 +++--- .../json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json | 6 +++--- .../CaseEventToFields/CaseEventToFields-SupportTasks.json | 6 +++--- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json index 6ec8561d66..b359ea9177 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/england-wales/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json @@ -8,7 +8,7 @@ "PostConditionState": "*", "SecurityClassification": "Public", "ShowEventNotes": "N", - "ShowSummary": "N", + "ShowSummary": "Y", "Publish": "Y", "CallBackURLAboutToStartEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToStart", "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToSubmit", @@ -23,7 +23,7 @@ "PostConditionState": "*", "SecurityClassification": "Public", "ShowEventNotes": "N", - "ShowSummary": "N", + "ShowSummary": "Y", "Publish": "Y", "CallBackURLAboutToStartEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToStart", "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToSubmit", @@ -38,7 +38,7 @@ "PostConditionState": "*", "SecurityClassification": "Public", "ShowEventNotes": "N", - "ShowSummary": "N", + "ShowSummary": "Y", "Publish": "Y", "CallBackURLAboutToStartEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToStart", "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToSubmit", diff --git a/ccd-definitions/jurisdictions/england-wales/json/CaseEventToFields/CaseEventToFields-SupportTasks.json b/ccd-definitions/jurisdictions/england-wales/json/CaseEventToFields/CaseEventToFields-SupportTasks.json index ec9070a864..26470a19b3 100644 --- a/ccd-definitions/jurisdictions/england-wales/json/CaseEventToFields/CaseEventToFields-SupportTasks.json +++ b/ccd-definitions/jurisdictions/england-wales/json/CaseEventToFields/CaseEventToFields-SupportTasks.json @@ -88,7 +88,7 @@ "PageID": 1, "PageDisplayOrder": 1, "PageFieldDisplayOrder": 1, - "ShowSummaryChangeOption": "N" + "ShowSummaryChangeOption": "Y" }, { "CaseTypeID": "ET_EnglandWales", @@ -123,7 +123,7 @@ "PageID": 1, "PageDisplayOrder": 1, "PageFieldDisplayOrder": 1, - "ShowSummaryChangeOption": "N" + "ShowSummaryChangeOption": "Y" }, { "CaseTypeID": "ET_EnglandWales", @@ -158,7 +158,7 @@ "PageID": 1, "PageDisplayOrder": 1, "PageFieldDisplayOrder": 1, - "ShowSummaryChangeOption": "N" + "ShowSummaryChangeOption": "Y" }, { "CaseTypeID": "ET_EnglandWales", diff --git a/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json b/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json index 3d4b9e17df..c3af785a0b 100644 --- a/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json +++ b/ccd-definitions/jurisdictions/scotland/json/CaseEvent/CaseEvent-CaseFlagsCaseLinking.json @@ -8,7 +8,7 @@ "PostConditionState": "*", "SecurityClassification": "Public", "ShowEventNotes": "N", - "ShowSummary": "N", + "ShowSummary": "Y", "Publish": "Y", "CallBackURLAboutToStartEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToStart", "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToSubmit", @@ -23,7 +23,7 @@ "PostConditionState": "*", "SecurityClassification": "Public", "ShowEventNotes": "N", - "ShowSummary": "N", + "ShowSummary": "Y", "Publish": "Y", "CallBackURLAboutToStartEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToStart", "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToSubmit", @@ -38,7 +38,7 @@ "PostConditionState": "*", "SecurityClassification": "Public", "ShowEventNotes": "N", - "ShowSummary": "N", + "ShowSummary": "Y", "Publish": "Y", "CallBackURLAboutToStartEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToStart", "CallBackURLAboutToSubmitEvent": "${ET_COS_URL}/reviewSupportRequest/aboutToSubmit", diff --git a/ccd-definitions/jurisdictions/scotland/json/CaseEventToFields/CaseEventToFields-SupportTasks.json b/ccd-definitions/jurisdictions/scotland/json/CaseEventToFields/CaseEventToFields-SupportTasks.json index b995995393..d918dbdd2e 100644 --- a/ccd-definitions/jurisdictions/scotland/json/CaseEventToFields/CaseEventToFields-SupportTasks.json +++ b/ccd-definitions/jurisdictions/scotland/json/CaseEventToFields/CaseEventToFields-SupportTasks.json @@ -88,7 +88,7 @@ "PageID": 1, "PageDisplayOrder": 1, "PageFieldDisplayOrder": 1, - "ShowSummaryChangeOption": "N" + "ShowSummaryChangeOption": "Y" }, { "CaseTypeID": "ET_Scotland", @@ -123,7 +123,7 @@ "PageID": 1, "PageDisplayOrder": 1, "PageFieldDisplayOrder": 1, - "ShowSummaryChangeOption": "N" + "ShowSummaryChangeOption": "Y" }, { "CaseTypeID": "ET_Scotland", @@ -158,7 +158,7 @@ "PageID": 1, "PageDisplayOrder": 1, "PageFieldDisplayOrder": 1, - "ShowSummaryChangeOption": "N" + "ShowSummaryChangeOption": "Y" }, { "CaseTypeID": "ET_Scotland", From 53c22146eb3c4f285edec4d481521cebbe82ab2a Mon Sep 17 00:00:00 2001 From: rajaram Date: Wed, 30 Sep 2026 15:11:08 +0100 Subject: [PATCH 087/100] UPDATE_CASE_SUBMITTED to check respondent flags --- .../CaseActionsForCaseWorkerController.java | 6 +- .../docmosis/service/SupportTaskService.java | 27 ++++++- ...aseActionsForCaseWorkerControllerTest.java | 8 +- .../service/SupportTaskServiceTest.java | 77 +++++++++++++++++++ 4 files changed, 112 insertions(+), 6 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java index d1ad497d2f..3335b2c486 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java @@ -200,10 +200,14 @@ public ResponseEntity postDefaultValues( if (featureToggleService.isCaseFlagsV2Enabled(caseDetails.getCaseTypeId()) && REVIEW_SUPPORT_TASK_EVENTS.contains(ccdRequest.getEventId())) { caseManagementForCaseWorkerService.setNextListedDate(caseData); - supportTaskService.prepareReviewSupportTasks(caseData); CaseData caseDataBefore = ccdRequest.getCaseDetailsBefore() == null ? null : ccdRequest.getCaseDetailsBefore().getCaseData(); + if (EVENT_SUBMIT_CASE_DRAFT.equals(ccdRequest.getEventId())) { + supportTaskService.prepareReviewSupportTasks(caseData); + } else { + supportTaskService.prepareUpdatedCaseReviewSupportTasks(caseData, caseDataBefore); + } supportTaskService.prepareArrangeSupportTask(caseData, caseDataBefore); } diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java index ba74c63f56..a8d5dc2c6c 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskService.java @@ -48,10 +48,29 @@ public class SupportTaskService { private final SupportTaskConfiguration configuration; public void prepareReviewSupportTasks(CaseData caseData) { - AllPartyFlags allPartyFlags = caseData.getAllPartyFlags(); - prepareTasks(caseData, allPartyFlags == null - ? List.of() - : flagDetails(allPartyFlags.getClaimantFlags(), allPartyFlags.getClaimantExternalFlags()).toList()); + prepareTasks(caseData, claimantFlagDetails(caseData.getAllPartyFlags())); + } + + public void prepareUpdatedCaseReviewSupportTasks(CaseData caseData, CaseData caseDataBefore) { + retainCreatedTaskState(caseData, caseDataBefore); + AllPartyFlags current = caseData.getAllPartyFlags(); + AllPartyFlags previous = caseDataBefore == null ? null : caseDataBefore.getAllPartyFlags(); + List claimantFlags = claimantFlagDetails(current); + List respondentFlags = respondentFlagDetails(current).toList(); + List changedPartyFlags = new ArrayList<>(); + // Both citizen journeys use UPDATE_CASE_SUBMITTED; only review the parties whose flags changed. + if (!claimantFlags.equals(claimantFlagDetails(previous))) { + changedPartyFlags.addAll(claimantFlags); + } + if (!respondentFlags.equals(respondentFlagDetails(previous).toList())) { + changedPartyFlags.addAll(respondentFlags); + } + prepareTasks(caseData, changedPartyFlags); + } + + private static List claimantFlagDetails(AllPartyFlags flags) { + return flags == null ? List.of() + : flagDetails(flags.getClaimantFlags(), flags.getClaimantExternalFlags()).toList(); } public void prepareRespondentReviewSupportTasks(CaseData caseData) { diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java index c04214b8c7..dbddb1123b 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerControllerTest.java @@ -363,7 +363,13 @@ void postDefaultValuesPreparesSupportTasksForCaseFlagsV2Events(String eventId) { .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()); - verify(supportTaskService).prepareReviewSupportTasks(any(CaseData.class)); + if ("SUBMIT_CASE_DRAFT".equals(eventId)) { + verify(supportTaskService).prepareReviewSupportTasks(any(CaseData.class)); + verify(supportTaskService, never()).prepareUpdatedCaseReviewSupportTasks(any(), any()); + } else { + verify(supportTaskService).prepareUpdatedCaseReviewSupportTasks(any(CaseData.class), any(CaseData.class)); + verify(supportTaskService, never()).prepareReviewSupportTasks(any()); + } verify(supportTaskService).prepareArrangeSupportTask( any(CaseData.class), any(CaseData.class)); verify(caseManagementForCaseWorkerService).setNextListedDate(any(CaseData.class)); diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java index 95f454edc7..2e08d8476c 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/SupportTaskServiceTest.java @@ -7,6 +7,7 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; import org.junit.jupiter.params.provider.ValueSource; +import org.springframework.beans.BeanWrapperImpl; import uk.gov.hmcts.et.common.model.ccd.CaseData; import uk.gov.hmcts.et.common.model.ccd.items.FlagDetailType; import uk.gov.hmcts.et.common.model.ccd.items.GenericTypeItem; @@ -21,6 +22,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.stream.IntStream; import java.util.stream.Stream; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -62,6 +64,81 @@ class SupportTaskServiceTest { private final SupportTaskService service = new SupportTaskService(configuration()); + static Stream updatedPartyScenarios() { + return Stream.of(Arguments.of("RA0041", TASK_TYPE_ADMIN), Arguments.of("RA0038", TASK_TYPE_JUDGE), + Arguments.of("RA0034", TASK_TYPE_LEGAL_OFFICER)) + .flatMap(category -> Stream.concat(Stream.of("claimantFlags", "claimantExternalFlags"), + respondentFlagFields()) + .map(field -> Arguments.of(category.get()[0], category.get()[1], field))); + } + + static Stream respondentFlagFields() { + return IntStream.range(0, 10).boxed().flatMap(index -> { + String prefix = "respondent" + (index == 0 ? "" : index); + return Stream.of(prefix + "Flags", prefix + "ExternalFlags"); + }); + } + + static Stream nonRequestedRespondentFlagScenarios() { + return respondentFlagFields().flatMap(field -> Stream.of(STATUS_ACTIVE, STATUS_INACTIVE, STATUS_NOT_APPROVED) + .map(status -> Arguments.of(field, status))); + } + + @ParameterizedTest + @MethodSource("updatedPartyScenarios") + void submittedCaseUpdateReviewsOnlyChangedPartyAndRetainsCaseWideDeduplication( + String code, String category, String field) throws JsonProcessingException { + boolean respondent = field.startsWith("respondent"); + CaseData before = bulkSupportCase(!respondent); + ObjectMapper mapper = new ObjectMapper(); + CaseData current = mapper.readValue(mapper.writeValueAsString(before), CaseData.class); + CaseFlagsType requested = caseFlags("new-request", code, STATUS_REQUESTED); + new BeanWrapperImpl(current.getAllPartyFlags()).setPropertyValue(field, requested); + + service.prepareUpdatedCaseReviewSupportTasks(current, before); + + for (String taskType : List.of(TASK_TYPE_ADMIN, TASK_TYPE_JUDGE, TASK_TYPE_LEGAL_OFFICER)) { + assertEquals(category.equals(taskType) ? YES : null, getTaskRequired(taskState(current), taskType)); + } + + // An existing task from either citizen journey must prevent another task in the same category. + before.setSupportTaskState(new SupportTaskState()); + setTaskCreated(taskState(before), category, YES); + current.setSupportTaskState(null); + service.prepareUpdatedCaseReviewSupportTasks(current, before); + + assertEquals(YES, getTaskCreated(taskState(current), category)); + assertNull(getTaskRequired(taskState(current), category)); + } + + @ParameterizedTest + @MethodSource("nonRequestedRespondentFlagScenarios") + void submittedCaseUpdateDoesNotReviewNonRequestedRespondentFlags(String field, String status) { + CaseData current = new CaseData(); + current.setAllPartyFlags(new ObjectMapper().convertValue( + Map.of(field, caseFlags("new-flag", "RA0041", status)), AllPartyFlags.class)); + + service.prepareUpdatedCaseReviewSupportTasks(current, null); + + assertNull(taskState(current).getAdminTaskRequired()); + } + + @ParameterizedTest + @MethodSource("respondentFlagFields") + void submittedCaseUpdateDoesNotReviewUnchangedFlags(String field) throws JsonProcessingException { + ObjectMapper mapper = new ObjectMapper(); + CaseData before = new CaseData(); + before.setAllPartyFlags(mapper.convertValue( + Map.of(field, bulkSupportCase(true).getAllPartyFlags().getRespondentFlags()), AllPartyFlags.class)); + CaseData current = mapper.readValue(mapper.writeValueAsString(before), CaseData.class); + + service.prepareUpdatedCaseReviewSupportTasks(current, before); + + assertNull(taskState(current).getAdminTaskRequired()); + assertNull(taskState(current).getJudgeTaskRequired()); + assertNull(taskState(current).getLegalOfficerTaskRequired()); + } + private static SupportTaskConfiguration configuration() { SupportTaskConfiguration configuration = new SupportTaskConfiguration(); configuration.getReview().setLegalOfficerFlagCodes(Set.of("RA0034", "RA0035", "RA0036")); From 41f8de35587e3bf60c8bcbc118de984b219fc770 Mon Sep 17 00:00:00 2001 From: hmcts-jenkins-d-to-i <62423932+hmcts-jenkins-d-to-i[bot]@users.noreply.github.com> Date: Wed, 30 Sep 2026 14:12:22 +0000 Subject: [PATCH 088/100] Bumping chart version/ fixing aliases --- charts/et-cos/Chart.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/et-cos/Chart.yaml b/charts/et-cos/Chart.yaml index 4e834ca06e..721b5332ec 100644 --- a/charts/et-cos/Chart.yaml +++ b/charts/et-cos/Chart.yaml @@ -1,7 +1,7 @@ apiVersion: v2 name: et-cos home: https://github.com/hmcts/et-ccd-callbacks -version: 0.0.78 +version: 0.0.79 description: HMCTS Employment Tribunals CCD Callbacks service maintainers: - name: HMCTS Employment Tribunals Team From e80c8c6019b42dab521c0c2ad100a3ba48f4d2fe Mon Sep 17 00:00:00 2001 From: rajaram Date: Wed, 30 Sep 2026 15:28:56 +0100 Subject: [PATCH 089/100] Fixed build issue --- .../applications/admin/TseAdminControllerTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/admin/TseAdminControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/admin/TseAdminControllerTest.java index 97361cdd7b..f42701ccae 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/admin/TseAdminControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/applications/admin/TseAdminControllerTest.java @@ -310,7 +310,7 @@ void aboutToSubmitCloseApplication_tokenOk() throws Exception { .andExpect(jsonPath(JsonMapper.WARNINGS, nullValue())); verify(tseAdmCloseService).aboutToSubmitCloseApplication( any(CaseData.class), - ENGLANDWALES_CASE_TYPE_ID); + eq(ENGLANDWALES_CASE_TYPE_ID)); } @Test @@ -323,7 +323,7 @@ void aboutToSubmitCloseApplication_tokenFail() throws Exception { .andExpect(status().isForbidden()); verify(tseAdmCloseService, never()).aboutToSubmitCloseApplication( any(CaseData.class), - ENGLANDWALES_CASE_TYPE_ID); + eq(ENGLANDWALES_CASE_TYPE_ID)); } @Test @@ -335,7 +335,7 @@ void aboutToSubmitCloseApplication_badRequest() throws Exception { .andExpect(status().isBadRequest()); verify(tseAdmCloseService, never()).aboutToSubmitCloseApplication( any(CaseData.class), - ENGLANDWALES_CASE_TYPE_ID); + eq(ENGLANDWALES_CASE_TYPE_ID)); } @Test From 7ab2fac94008a93cd81956d15d1f43d3c76e281b Mon Sep 17 00:00:00 2001 From: rajaram Date: Mon, 5 Oct 2026 09:36:54 +0100 Subject: [PATCH 090/100] Added error message for review tasks event --- .../CaseActionsForCaseWorkerController.java | 5 ++ .../SupportTaskCallbackLifecycleTest.java | 50 +++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java index c03f31f9cc..9e463e9a7c 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java @@ -67,6 +67,7 @@ import java.util.List; import java.util.Set; +import static org.apache.commons.collections.CollectionUtils.isEmpty; import static org.apache.commons.collections.CollectionUtils.isNotEmpty; import static org.apache.commons.lang3.StringUtils.defaultIfEmpty; import static org.springframework.http.HttpHeaders.AUTHORIZATION; @@ -278,6 +279,10 @@ public ResponseEntity prepareReviewSupportRequest( CaseData caseData = caseDetails.getCaseData(); if (featureToggleService.isCaseFlagsV2Enabled(caseDetails.getCaseTypeId())) { supportTaskService.prepareReviewSupportRequest(caseData, callbackRequest.getEventId()); + if (isEmpty(caseData.getReviewSupportRequestFlags())) { + return getCallbackRespEntityErrors( + List.of("This case has no requested flags for your role"), caseData); + } } return getCallbackRespEntityNoErrors(caseData); } diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/SupportTaskCallbackLifecycleTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/SupportTaskCallbackLifecycleTest.java index c11d243960..f6a8f54926 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/SupportTaskCallbackLifecycleTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/SupportTaskCallbackLifecycleTest.java @@ -176,6 +176,56 @@ void callbackSignatureIsAcceptedByDeployedCcdSdk(String callbackUrl) throws Exce callback(callbackUrl, EVENT_CREATE_FLAG, new CaseData(), new CaseData(), null); } + static Stream reviewStartCategories() { + return reviewLifecycles().filter(arguments -> MANUAL_REVIEW.equals(arguments.get()[1])) + .map(arguments -> Arguments.of(arguments.get()[0], arguments.get()[2])); + } + + @ParameterizedTest + @MethodSource("reviewStartCategories") + void reviewStartShowsRoleSpecificErrorWhenNoEligibleFlags(Category category, String type) + throws Exception { + caseType = type; + String otherCode = ADMIN_CODE.equals(category.code()) ? JUDGE_CODE : ADMIN_CODE; + for (AllPartyFlags partyFlags : List.of( + new AllPartyFlags(), + AllPartyFlags.builder().claimantFlags(flags("active", category.code(), FLAG_STATUS_ACTIVE)).build(), + AllPartyFlags.builder().claimantFlags(flags("other", otherCode, FLAG_STATUS_REQUESTED)).build())) { + CaseData data = new CaseData(); + data.setAllPartyFlags(partyFlags); + MvcResult result = callback(REVIEW_START, category.reviewEvent(), data, new CaseData(), null); + + JsonNode errors = mapper.readTree(result.getResponse().getContentAsString()).path("errors"); + assertEquals(1, errors.size()); + assertEquals("This case has no requested flags for your role", errors.get(0).asText()); + } + } + + @ParameterizedTest + @MethodSource("reviewStartCategories") + void reviewStartAllowsEligibleRequestedFlags(Category category, String type) throws Exception { + caseType = type; + CaseData data = new CaseData(); + data.setAllPartyFlags(AllPartyFlags.builder() + .claimantFlags(flags("requested", category.code(), FLAG_STATUS_REQUESTED)).build()); + + MvcResult result = callback(REVIEW_START, category.reviewEvent(), data, new CaseData(), null); + + assertEquals(0, mapper.readTree(result.getResponse().getContentAsString()).path("errors").size()); + assertEquals(1, responseData(result).getReviewSupportRequestFlags().size()); + } + + @ParameterizedTest + @MethodSource("reviewStartCategories") + void reviewStartDoesNotValidateWhenV2Disabled(Category category, String type) throws Exception { + caseType = type; + when(featureToggleService.isCaseFlagsV2Enabled(type)).thenReturn(false); + + MvcResult result = callback(REVIEW_START, category.reviewEvent(), new CaseData(), new CaseData(), null); + + assertEquals(0, mapper.readTree(result.getResponse().getContentAsString()).path("errors").size()); + } + private JsonCallbackBridge sdkBridge() throws NoSuchMethodException { ApplicationContext context = mvc.getDispatcherServlet().getWebApplicationContext(); return BeanUtils.instantiateClass(JsonCallbackBridge.class.getDeclaredConstructor( From 1d428b454f2bb9a0ae00a9b0d3086351f1254986 Mon Sep 17 00:00:00 2001 From: rajaram Date: Tue, 6 Oct 2026 15:49:04 +0100 Subject: [PATCH 091/100] RET-6912 - Amend Respondent representative fix --- .../RespondentRepresentativeController.java | 26 ++++++++++++-- .../docmosis/utils/noc/NocUtils.java | 9 +++++ ...espondentRepresentativeControllerTest.java | 10 ++++-- ...ocRespondentRepresentativeServiceTest.java | 36 +++++++++++++++++++ .../docmosis/utils/noc/NocUtilsTest.java | 34 ++++++++++++++++++ 5 files changed, 110 insertions(+), 5 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/RespondentRepresentativeController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/RespondentRepresentativeController.java index fb823a19a9..917be9e81e 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/RespondentRepresentativeController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/RespondentRepresentativeController.java @@ -170,7 +170,12 @@ public ResponseEntity amendRespondentRepresentativeAboutToS .validateRespondentRepresentativesOrganisationMatch(caseDetails)); if (errors.isEmpty()) { try { - NocUtils.mapRepresentativesToRespondents(caseData, caseDetails.getCaseId()); + NocUtils.mapRepresentativesToRespondents(caseData, caseDetails.getCaseId(), + featureToggleService.isCaseFlagsV2Enabled(caseDetails.getCaseTypeId())); + if (featureToggleService.isCaseFlagsV2Enabled(caseDetails.getCaseTypeId()) + && respondentRepresentationChanged(callbackRequest)) { + nocRespondentHelper.amendRespondentNameRepresentativeNames(caseData, true); + } nocRespondentHelper.removeUnmatchedRepresentations(caseData); nocRespondentRepresentativeService.prepopulateOrgAddress(caseData, userToken); NocUtils.assignNonMyHmctsOrganisationIds(caseData.getRepCollection()); @@ -205,6 +210,9 @@ public void amendRespondentRepresentativeSubmitted( try { NocUtils.validateCallbackRequest(callbackRequest); nocRespondentRepresentativeService.updateRepresentativesAccess(callbackRequest, userToken); + if (featureToggleService.isCaseFlagsV2Enabled(callbackRequest.getCaseDetails().getCaseTypeId())) { + nocRespondentRepresentativeService.realignRespondentRepresentativeAccess(callbackRequest); + } } catch (GenericServiceException | GenericRuntimeException e) { log.error(ERROR_UNABLE_TO_MODIFY_REPRESENTATIVE_ACCESS, callbackRequest.getCaseDetails().getCaseId(), e.getMessage()); @@ -308,7 +316,8 @@ private void setupCaseFlagsIfRespondentRepresentativeChanged(CallbackRequest cal List changedRepresentativeIndexes = changedRespondentRepresentativeIndexes(callbackRequest); boolean representativeRemoved = respondentRepresentativeRemoved(callbackRequest); if (featureToggleService.isCaseFlagsV2Enabled(callbackRequest.getCaseDetails().getCaseTypeId()) - && (CollectionUtils.isNotEmpty(changedRepresentativeIndexes) || representativeRemoved)) { + && (CollectionUtils.isNotEmpty(changedRepresentativeIndexes) || representativeRemoved + || respondentRepresentationChanged(callbackRequest))) { List representativeIndexesToClear = changedRepresentativeIndexes.stream() .filter(index -> shouldClearChangedRepresentativeFlags(callbackRequest, index)) .toList(); @@ -351,6 +360,19 @@ private static boolean sameRepresentativeIdentity( StringUtils.trimToEmpty(representativeEmail(secondRepresentative))); } + private static boolean respondentRepresentationChanged(CallbackRequest callbackRequest) { + if (callbackRequest.getCaseDetailsBefore() == null + || callbackRequest.getCaseDetailsBefore().getCaseData() == null) { + return false; + } + List previous = callbackRequest.getCaseDetailsBefore().getCaseData().getRepCollection(); + List current = callbackRequest.getCaseDetails().getCaseData().getRepCollection(); + return CollectionUtils.isNotEmpty(previous) && CollectionUtils.isNotEmpty(current) + && current.stream().anyMatch(rep -> previous.stream() + .filter(old -> sameRepresentative(old, rep)) + .anyMatch(old -> !Objects.equals(representativeRespondentId(old), representativeRespondentId(rep)))); + } + private static boolean respondentRepresentativeRemoved(CallbackRequest callbackRequest) { if (callbackRequest.getCaseDetailsBefore() == null || callbackRequest.getCaseDetailsBefore().getCaseData() == null diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/utils/noc/NocUtils.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/utils/noc/NocUtils.java index 8a85cea2d4..511435fdbd 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/utils/noc/NocUtils.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/utils/noc/NocUtils.java @@ -263,6 +263,12 @@ public static boolean isValidNocRepresentative(RepresentedTypeRItem representati */ public static void mapRepresentativesToRespondents(CaseData caseData, String submissionReference) throws GenericServiceException { + mapRepresentativesToRespondents(caseData, submissionReference, false); + } + + public static void mapRepresentativesToRespondents(CaseData caseData, String submissionReference, + boolean useSelectedRespondent) + throws GenericServiceException { if (!RespondentUtils.hasRespondents(caseData) || !RespondentRepresentativeUtils.hasRespondentRepresentative(caseData)) { return; @@ -282,6 +288,9 @@ public static void mapRepresentativesToRespondents(CaseData caseData, String sub } String repRespondentId = representative.getValue().getRespondentId(); String repRespondentName = representative.getValue().getDynamicRespRepName().getValue().getLabel(); + if (useSelectedRespondent && respondentsByName.containsKey(repRespondentName)) { + repRespondentId = respondentsByName.get(repRespondentName).getId(); + } if (StringUtils.isNotBlank(repRespondentId) || StringUtils.isNotBlank(repRespondentName)) { setMatchingRespondent(respondentsById, respondentsByName, repRespondentId, repRespondentName, representative, submissionReference); diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/RespondentRepresentativeControllerTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/RespondentRepresentativeControllerTest.java index b99c4ef434..c2305043f9 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/RespondentRepresentativeControllerTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/RespondentRepresentativeControllerTest.java @@ -674,9 +674,10 @@ void amendRespondentRepresentativeMidEventWithWarning() { .andExpect(jsonPath(JsonMapper.WARNINGS, notNullValue())); } - @Test + @ParameterizedTest + @ValueSource(booleans = {true, false}) @SneakyThrows - void amendRespondentRepresentativeSubmitted() { + void amendRespondentRepresentativeSubmitted(boolean caseFlagsV2Enabled) { CaseData caseData = new CaseData(); RespondentSumTypeItem respondent = new RespondentSumTypeItem(); respondent.setValue(RespondentSumType.builder().respondentName(RESPONDENT_NAME_1).build()); @@ -690,6 +691,8 @@ void amendRespondentRepresentativeSubmitted() { RepresentedTypeR.builder().dynamicRespRepName(dynamicFixedListType).build()).build())); CaseDetails caseDetails = new CaseDetails(); caseDetails.setCaseData(caseData); + caseDetails.setCaseTypeId("ET_Scotland"); + when(featureToggleService.isCaseFlagsV2Enabled("ET_Scotland")).thenReturn(caseFlagsV2Enabled); CallbackRequest callbackRequest = CallbackRequest.builder().caseDetails(caseDetails) .caseDetailsBefore(caseDetails).build(); callbackRequest.getCaseDetails().setCaseId(DUMMY_SUBMISSION_REFERENCE); @@ -699,7 +702,8 @@ void amendRespondentRepresentativeSubmitted() { .header(HEADER_AUTHORIZATION, DUMMY_TOKEN) .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()); - + verify(nocRespondentRepresentativeService, times(caseFlagsV2Enabled ? 1 : 0)) + .realignRespondentRepresentativeAccess(any(CallbackRequest.class)); } @Test diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocRespondentRepresentativeServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocRespondentRepresentativeServiceTest.java index 70ac2d9224..2523c77690 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocRespondentRepresentativeServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/noc/NocRespondentRepresentativeServiceTest.java @@ -955,6 +955,42 @@ void revokeOldRespondentRepresentativeAccessOnlyRevokesDeletedMiddleRepresentati .containsExactlyInAnyOrder(removedRep2Respondent2Assignment, removedRep2Respondent3Assignment); } + @Test + void realignRespondentRepresentativeAccessRotatesThreeRepresentatives() { + CaseData current = new CaseData(); + current.setRepCollection(List.of( + representativeForRespondent("rep-1", RESPONDENT_ID_ONE, ROLE_SOLICITORA, + REPRESENTATIVE_ID_ONE, ORGANISATION_ID_ONE), + representativeForRespondent("rep-2", RESPONDENT_ID_THREE, ROLE_SOLICITORC, + REPRESENTATIVE_ID_TWO, ORGANISATION_ID_TWO), + representativeForRespondent("rep-3", RESPONDENT_ID_TWO, ROLE_SOLICITORB, + REPRESENTATIVE_ID_THREE, ORGANISATION_ID_THREE))); + CaseDetails details = new CaseDetails(); + details.setCaseId(CASE_ID_1); + details.setCaseData(current); + when(adminUserService.getAdminUserToken()).thenReturn(ADMIN_USER_TOKEN); + when(nocCcdService.retrieveCaseUserAssignments(ADMIN_USER_TOKEN, CASE_ID_1)) + .thenReturn(CaseUserAssignmentData.builder().caseUserAssignments(List.of( + assignment(REPRESENTATIVE_ID_ONE, ROLE_SOLICITORB, ORGANISATION_ID_ONE), + assignment(REPRESENTATIVE_ID_TWO, ROLE_SOLICITORA, ORGANISATION_ID_TWO), + assignment(REPRESENTATIVE_ID_THREE, ROLE_SOLICITORC, ORGANISATION_ID_THREE))).build()); + when(nocService.grantCaseAccess(anyString(), eq(CASE_ID_1), anyString())).thenReturn(true); + + nocRespondentRepresentativeService.realignRespondentRepresentativeAccess( + CallbackRequest.builder().caseDetails(details).build()); + + verify(nocService).grantCaseAccess(REPRESENTATIVE_ID_ONE, CASE_ID_1, ROLE_SOLICITORA); + verify(nocService).grantCaseAccess(REPRESENTATIVE_ID_TWO, CASE_ID_1, ROLE_SOLICITORC); + verify(nocService).grantCaseAccess(REPRESENTATIVE_ID_THREE, CASE_ID_1, ROLE_SOLICITORB); + ArgumentCaptor revoked = ArgumentCaptor.forClass(CaseUserAssignmentData.class); + verify(nocCcdService).revokeCaseAssignments(eq(ADMIN_USER_TOKEN), revoked.capture()); + assertThat(revoked.getValue().getCaseUserAssignments()) + .extracting(assignment -> assignment.getUserId() + ":" + assignment.getCaseRole()) + .containsExactlyInAnyOrder(REPRESENTATIVE_ID_ONE + ":" + ROLE_SOLICITORB, + REPRESENTATIVE_ID_TWO + ":" + ROLE_SOLICITORA, + REPRESENTATIVE_ID_THREE + ":" + ROLE_SOLICITORC); + } + @Test void realignRespondentRepresentativeAccessMovesAssignmentsWithRespondents() { CaseData previousCaseData = new CaseData(); diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/utils/noc/NocUtilsTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/utils/noc/NocUtilsTest.java index 9a2272221d..877b3ce06a 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/utils/noc/NocUtilsTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/utils/noc/NocUtilsTest.java @@ -107,6 +107,40 @@ final class NocUtilsTest { private static final String USER_TOKEN = "userToken"; private static final String CASE_ID = "1234567890123456"; + @Test + void mapsThreeRepresentativesToNewSelectionsInsteadOfSavedRespondentIds() throws GenericServiceException { + CaseData data = new CaseData(); + List respondents = new ArrayList<>(); + List representatives = new ArrayList<>(); + int[] previousRespondents = {2, 1, 3}; + int[] selectedRespondents = {1, 3, 2}; + for (int index = 0; index < 3; index++) { + RespondentSumTypeItem respondent = new RespondentSumTypeItem(); + respondent.setId("respondent-" + (index + 1)); + respondent.setValue(RespondentSumType.builder().respondentName("Respondent " + (index + 1)).build()); + respondents.add(respondent); + DynamicValueType selected = new DynamicValueType(); + selected.setLabel("Respondent " + selectedRespondents[index]); + DynamicFixedListType selection = new DynamicFixedListType(); + selection.setValue(selected); + representatives.add(RepresentedTypeRItem.builder().id("representative-" + (index + 1)) + .value(RepresentedTypeR.builder().nameOfRepresentative("Representative " + (index + 1)) + .respondentId("respondent-" + previousRespondents[index]) + .dynamicRespRepName(selection).build()).build()); + } + data.setRespondentCollection(respondents); + data.setRepCollection(representatives); + + NocUtils.mapRepresentativesToRespondents(data, DUMMY_CASE_SUBMISSION_REFERENCE_1, true); + + for (int index = 0; index < 3; index++) { + assertThat(representatives.get(index).getValue().getRespondentId()) + .isEqualTo("respondent-" + selectedRespondents[index]); + assertThat(respondents.get(selectedRespondents[index] - 1).getValue().getRepresentativeId()) + .isEqualTo(representatives.get(index).getId()); + } + } + @Test void theValidateRepresentativeRespondentMapping() { // when representative collection is empty should return an empty list From ddc993df1079cf63bfa862365f973f601980df4e Mon Sep 17 00:00:00 2001 From: rajaram Date: Thu, 8 Oct 2026 10:34:35 +0100 Subject: [PATCH 092/100] RET-7049: Added update comment welsh field --- .../model/ccd/items/FlagDetailType.java | 1 + .../model/ccd/items/FlagDetailTypeTest.java | 97 +++++++++++++++++++ 2 files changed, 98 insertions(+) create mode 100644 et-shared/src/test/java/uk/gov/hmcts/et/common/model/ccd/items/FlagDetailTypeTest.java diff --git a/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/items/FlagDetailType.java b/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/items/FlagDetailType.java index 9323db5636..92f4b9aba6 100644 --- a/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/items/FlagDetailType.java +++ b/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/items/FlagDetailType.java @@ -23,6 +23,7 @@ public class FlagDetailType { private String flagComment; private String flagComment_cy; private String flagUpdateComment; + private String flagUpdateComment_cy; private String dateTimeModified; private String dateTimeCreated; private ListTypeItem path; diff --git a/et-shared/src/test/java/uk/gov/hmcts/et/common/model/ccd/items/FlagDetailTypeTest.java b/et-shared/src/test/java/uk/gov/hmcts/et/common/model/ccd/items/FlagDetailTypeTest.java new file mode 100644 index 0000000000..68ad745adc --- /dev/null +++ b/et-shared/src/test/java/uk/gov/hmcts/et/common/model/ccd/items/FlagDetailTypeTest.java @@ -0,0 +1,97 @@ +package uk.gov.hmcts.et.common.model.ccd.items; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +class FlagDetailTypeTest { + private static final String COMPLETE_FLAG_JSON = """ + { + "name": "Other support", + "name_cy": "Cymorth arall", + "subTypeValue": "Forms", + "subTypeValue_cy": "Ffurflenni", + "subTypeKey": "forms", + "otherDescription": "Help reading forms", + "otherDescription_cy": "Help i ddarllen ffurflenni", + "flagComment": "Support requested", + "flagComment_cy": "Cais am gymorth", + "flagUpdateComment": "Support approved", + "flagUpdateComment_cy": "Cymorth wedi ei gymeradwyo", + "dateTimeModified": "2026-10-08T11:30:00.123Z", + "dateTimeCreated": "2026-10-07T10:00:00.000Z", + "path": [ + {"id": "party", "value": "Party"}, + {"id": "adjustment", "value": "Reasonable adjustment"} + ], + "hearingRelevant": "Yes", + "flagCode": "OT0001", + "status": "Active", + "requestReason": "No", + "availableExternally": "Yes" + } + """; + + private final ObjectMapper mapper = new ObjectMapper(); + + @Test + void serializesEveryFieldUsingCcdPropertyNames() throws JsonProcessingException { + JsonNode actual = mapper.readTree(mapper.writeValueAsString(completeFlag())); + + assertEquals(mapper.readTree(COMPLETE_FLAG_JSON), actual); + } + + @Test + void deserializesEveryFieldIncludingWelshUpdateComment() throws JsonProcessingException { + FlagDetailType actual = mapper.readValue(COMPLETE_FLAG_JSON, FlagDetailType.class); + + assertEquals(completeFlag(), actual); + assertEquals("Cymorth wedi ei gymeradwyo", actual.getFlagUpdateComment_cy()); + assertEquals("party", actual.getPath().getFirst().getId()); + assertEquals("Reasonable adjustment", actual.getPath().get(1).getValue()); + } + + @Test + void acceptsLegacyFlagsWithMissingOptionalAndUnknownFields() throws JsonProcessingException { + FlagDetailType actual = mapper.readValue(""" + {"name": "Intermediary", "flagCode": "RA0038", "status": "Requested", "futureField": "value"} + """, FlagDetailType.class); + + assertEquals(FlagDetailType.builder().name("Intermediary").flagCode("RA0038") + .status("Requested").build(), actual); + assertNull(actual.getFlagUpdateComment_cy()); + assertNull(actual.getPath()); + } + + @ParameterizedTest + @ValueSource(strings = {"2026-10-08T11:30:00", "2026-10-08T11:30:00.123Z", "2026-10-08T12:30:00+01:00"}) + void preservesDateStringsWithoutReformatting(String dateTime) throws JsonProcessingException { + FlagDetailType original = FlagDetailType.builder() + .dateTimeCreated(dateTime).dateTimeModified(dateTime).build(); + + FlagDetailType actual = mapper.readValue(mapper.writeValueAsString(original), FlagDetailType.class); + + assertEquals(dateTime, actual.getDateTimeCreated()); + assertEquals(dateTime, actual.getDateTimeModified()); + } + + private static FlagDetailType completeFlag() { + return FlagDetailType.builder() + .name("Other support").name_cy("Cymorth arall") + .subTypeValue("Forms").subTypeValue_cy("Ffurflenni").subTypeKey("forms") + .otherDescription("Help reading forms").otherDescription_cy("Help i ddarllen ffurflenni") + .flagComment("Support requested").flagComment_cy("Cais am gymorth") + .flagUpdateComment("Support approved").flagUpdateComment_cy("Cymorth wedi ei gymeradwyo") + .dateTimeModified("2026-10-08T11:30:00.123Z").dateTimeCreated("2026-10-07T10:00:00.000Z") + .path(ListTypeItem.from(GenericTypeItem.from("party", "Party"), + GenericTypeItem.from("adjustment", "Reasonable adjustment"))) + .hearingRelevant("Yes").flagCode("OT0001").status("Active") + .requestReason("No").availableExternally("Yes").build(); + } +} From e33227157bf129a9eeeed1aff2527ec7bd40d09b Mon Sep 17 00:00:00 2001 From: hmcts-jenkins-d-to-i <62423932+hmcts-jenkins-d-to-i[bot]@users.noreply.github.com> Date: Thu, 8 Oct 2026 09:38:11 +0000 Subject: [PATCH 093/100] Bumping chart version/ fixing aliases --- charts/et-cos/Chart.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/et-cos/Chart.yaml b/charts/et-cos/Chart.yaml index 5e9538096b..82dbd9599d 100644 --- a/charts/et-cos/Chart.yaml +++ b/charts/et-cos/Chart.yaml @@ -1,7 +1,7 @@ apiVersion: v2 name: et-cos home: https://github.com/hmcts/et-ccd-callbacks -version: 0.0.79 +version: 0.0.80 description: HMCTS Employment Tribunals CCD Callbacks service maintainers: - name: HMCTS Employment Tribunals Team From 3aa428bd6c4ff9255431e54fbc3bc6be4e3a5d63 Mon Sep 17 00:00:00 2001 From: rajaram Date: Thu, 8 Oct 2026 14:17:11 +0100 Subject: [PATCH 094/100] Revert "RET-7049: Added update comment welsh field" This reverts commit ddc993df1079cf63bfa862365f973f601980df4e. --- .../model/ccd/items/FlagDetailType.java | 1 - .../model/ccd/items/FlagDetailTypeTest.java | 97 ------------------- 2 files changed, 98 deletions(-) delete mode 100644 et-shared/src/test/java/uk/gov/hmcts/et/common/model/ccd/items/FlagDetailTypeTest.java diff --git a/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/items/FlagDetailType.java b/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/items/FlagDetailType.java index 92f4b9aba6..9323db5636 100644 --- a/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/items/FlagDetailType.java +++ b/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/items/FlagDetailType.java @@ -23,7 +23,6 @@ public class FlagDetailType { private String flagComment; private String flagComment_cy; private String flagUpdateComment; - private String flagUpdateComment_cy; private String dateTimeModified; private String dateTimeCreated; private ListTypeItem path; diff --git a/et-shared/src/test/java/uk/gov/hmcts/et/common/model/ccd/items/FlagDetailTypeTest.java b/et-shared/src/test/java/uk/gov/hmcts/et/common/model/ccd/items/FlagDetailTypeTest.java deleted file mode 100644 index 68ad745adc..0000000000 --- a/et-shared/src/test/java/uk/gov/hmcts/et/common/model/ccd/items/FlagDetailTypeTest.java +++ /dev/null @@ -1,97 +0,0 @@ -package uk.gov.hmcts.et.common.model.ccd.items; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ValueSource; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; - -class FlagDetailTypeTest { - private static final String COMPLETE_FLAG_JSON = """ - { - "name": "Other support", - "name_cy": "Cymorth arall", - "subTypeValue": "Forms", - "subTypeValue_cy": "Ffurflenni", - "subTypeKey": "forms", - "otherDescription": "Help reading forms", - "otherDescription_cy": "Help i ddarllen ffurflenni", - "flagComment": "Support requested", - "flagComment_cy": "Cais am gymorth", - "flagUpdateComment": "Support approved", - "flagUpdateComment_cy": "Cymorth wedi ei gymeradwyo", - "dateTimeModified": "2026-10-08T11:30:00.123Z", - "dateTimeCreated": "2026-10-07T10:00:00.000Z", - "path": [ - {"id": "party", "value": "Party"}, - {"id": "adjustment", "value": "Reasonable adjustment"} - ], - "hearingRelevant": "Yes", - "flagCode": "OT0001", - "status": "Active", - "requestReason": "No", - "availableExternally": "Yes" - } - """; - - private final ObjectMapper mapper = new ObjectMapper(); - - @Test - void serializesEveryFieldUsingCcdPropertyNames() throws JsonProcessingException { - JsonNode actual = mapper.readTree(mapper.writeValueAsString(completeFlag())); - - assertEquals(mapper.readTree(COMPLETE_FLAG_JSON), actual); - } - - @Test - void deserializesEveryFieldIncludingWelshUpdateComment() throws JsonProcessingException { - FlagDetailType actual = mapper.readValue(COMPLETE_FLAG_JSON, FlagDetailType.class); - - assertEquals(completeFlag(), actual); - assertEquals("Cymorth wedi ei gymeradwyo", actual.getFlagUpdateComment_cy()); - assertEquals("party", actual.getPath().getFirst().getId()); - assertEquals("Reasonable adjustment", actual.getPath().get(1).getValue()); - } - - @Test - void acceptsLegacyFlagsWithMissingOptionalAndUnknownFields() throws JsonProcessingException { - FlagDetailType actual = mapper.readValue(""" - {"name": "Intermediary", "flagCode": "RA0038", "status": "Requested", "futureField": "value"} - """, FlagDetailType.class); - - assertEquals(FlagDetailType.builder().name("Intermediary").flagCode("RA0038") - .status("Requested").build(), actual); - assertNull(actual.getFlagUpdateComment_cy()); - assertNull(actual.getPath()); - } - - @ParameterizedTest - @ValueSource(strings = {"2026-10-08T11:30:00", "2026-10-08T11:30:00.123Z", "2026-10-08T12:30:00+01:00"}) - void preservesDateStringsWithoutReformatting(String dateTime) throws JsonProcessingException { - FlagDetailType original = FlagDetailType.builder() - .dateTimeCreated(dateTime).dateTimeModified(dateTime).build(); - - FlagDetailType actual = mapper.readValue(mapper.writeValueAsString(original), FlagDetailType.class); - - assertEquals(dateTime, actual.getDateTimeCreated()); - assertEquals(dateTime, actual.getDateTimeModified()); - } - - private static FlagDetailType completeFlag() { - return FlagDetailType.builder() - .name("Other support").name_cy("Cymorth arall") - .subTypeValue("Forms").subTypeValue_cy("Ffurflenni").subTypeKey("forms") - .otherDescription("Help reading forms").otherDescription_cy("Help i ddarllen ffurflenni") - .flagComment("Support requested").flagComment_cy("Cais am gymorth") - .flagUpdateComment("Support approved").flagUpdateComment_cy("Cymorth wedi ei gymeradwyo") - .dateTimeModified("2026-10-08T11:30:00.123Z").dateTimeCreated("2026-10-07T10:00:00.000Z") - .path(ListTypeItem.from(GenericTypeItem.from("party", "Party"), - GenericTypeItem.from("adjustment", "Reasonable adjustment"))) - .hearingRelevant("Yes").flagCode("OT0001").status("Active") - .requestReason("No").availableExternally("Yes").build(); - } -} From 6c4ba99589d5420392563837fb20b6ba102b23c3 Mon Sep 17 00:00:00 2001 From: rajaram Date: Thu, 8 Oct 2026 14:19:30 +0100 Subject: [PATCH 095/100] RET-6998: Retain case flags when both case types are enabled for cfv2.1 --- .../messagehandler/SingleCreationService.java | 11 ++--- .../SingleCreationServiceTest.java | 48 +++++++++++++------ 2 files changed, 38 insertions(+), 21 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/messagehandler/SingleCreationService.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/messagehandler/SingleCreationService.java index ed2374d78e..851c0d015c 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/messagehandler/SingleCreationService.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/service/messagehandler/SingleCreationService.java @@ -19,6 +19,8 @@ import java.util.List; import static uk.gov.hmcts.ecm.common.model.helper.Constants.CLOSED_STATE; +import static uk.gov.hmcts.ecm.common.model.helper.Constants.ENGLANDWALES_CASE_TYPE_ID; +import static uk.gov.hmcts.ecm.common.model.helper.Constants.SCOTLAND_CASE_TYPE_ID; import static uk.gov.hmcts.ethos.replacement.docmosis.helpers.MultiplesHelper.generateMarkUp; /** @@ -37,7 +39,6 @@ public class SingleCreationService { private static class CaseTransferContext { private final String caseId; - private final String caseTypeId; private final String ccdGatewayBaseUrl; private final String positionTypeCT; private final String jurisdiction; @@ -45,10 +46,9 @@ private static class CaseTransferContext { private final String owningOfficeCT; private final String reasonForCT; - CaseTransferContext(String caseId, String caseTypeId, String ccdGatewayBaseUrl, String positionTypeCT, + CaseTransferContext(String caseId, String ccdGatewayBaseUrl, String positionTypeCT, String jurisdiction, String state, String owningOfficeCT, String reasonForCT) { this.caseId = caseId; - this.caseTypeId = caseTypeId; this.ccdGatewayBaseUrl = ccdGatewayBaseUrl; this.positionTypeCT = positionTypeCT; this.jurisdiction = jurisdiction; @@ -95,7 +95,6 @@ private void updateExistingCase(SubmitEvent caseDestinationOffice, SubmitEvent o CaseTransferContext context = new CaseTransferContext( caseId, - caseTypeId, ccdGatewayBaseUrl, creationSingleDataModel.getPositionTypeCT(), jurisdiction, @@ -126,7 +125,6 @@ private void transferNewCase(SubmitEvent oldSubmitEvent, String jurisdiction, St CaseTransferContext context = new CaseTransferContext( caseId, - caseTypeId, ccdGatewayBaseUrl, creationSingleDataModel.getPositionTypeCT(), jurisdiction, @@ -275,7 +273,8 @@ private CaseData copyCaseData(CaseData oldCaseData, CaseData newCaseData, CaseTr newCaseData.setRespondentOrganisationPolicy8(oldCaseData.getRespondentOrganisationPolicy8()); newCaseData.setRespondentOrganisationPolicy9(oldCaseData.getRespondentOrganisationPolicy9()); - if (featureToggleService.isCaseFlagsV2Enabled(context.caseTypeId)) { + if (featureToggleService.isCaseFlagsV2Enabled(ENGLANDWALES_CASE_TYPE_ID) + && featureToggleService.isCaseFlagsV2Enabled(SCOTLAND_CASE_TYPE_ID)) { newCaseData.setAllPartyFlags(oldCaseData.getAllPartyFlags()); } diff --git a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/messagehandler/SingleCreationServiceTest.java b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/messagehandler/SingleCreationServiceTest.java index 7a6d78b152..6cc787d11c 100644 --- a/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/messagehandler/SingleCreationServiceTest.java +++ b/src/test/java/uk/gov/hmcts/ethos/replacement/docmosis/service/messagehandler/SingleCreationServiceTest.java @@ -1,7 +1,8 @@ package uk.gov.hmcts.ethos.replacement.docmosis.service.messagehandler; -import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.InjectMocks; @@ -56,15 +57,17 @@ class SingleCreationServiceTest { ArgumentCaptor caseDataArgumentCaptor; private static final String USER_TOKEN = "accessToken"; - @Test + @ParameterizedTest + @CsvSource({"false, false", "false, true", "true, false", "true, true"}) @SuppressWarnings({"PMD.LawOfDemeter"}) - void caseTransferToScotlandCreateCase() throws IOException { + void caseTransferToScotlandCreateCase(boolean englandWalesEnabled, boolean scotlandEnabled) throws IOException { var ethosCaseReference = "4150002/2020"; var managingOffice = TribunalOffice.MANCHESTER.getOfficeName(); var caseData = new CaseData(); caseData.setEthosCaseReference(ethosCaseReference); caseData.setManagingOffice(managingOffice); - caseData.setAllPartyFlags(createAllPartyFlags()); + AllPartyFlags allPartyFlags = createAllPartyFlags(); + caseData.setAllPartyFlags(allPartyFlags); var submitEvent = new SubmitEvent(); submitEvent.setCaseData(caseData); CaseData newCaseData = new CaseData(); @@ -93,14 +96,16 @@ void caseTransferToScotlandCreateCase() throws IOException { .thenReturn(new ArrayList<>()); when(ccdClient.startCaseCreationTransfer(eq(USER_TOKEN), any())) .thenReturn(updateCCDRequest); - when(featureToggleService.isCaseFlagsV2Enabled(SCOTLAND_CASE_TYPE_ID)).thenReturn(false); + when(featureToggleService.isCaseFlagsV2Enabled(ENGLANDWALES_CASE_TYPE_ID)).thenReturn(englandWalesEnabled); + when(featureToggleService.isCaseFlagsV2Enabled(SCOTLAND_CASE_TYPE_ID)).thenReturn(scotlandEnabled); singleCreationService.sendCreation(submitEvent, USER_TOKEN, updateCaseMsg); verify(ccdClient, times(1)) .retrieveCasesElasticSearch(USER_TOKEN, SCOTLAND_CASE_TYPE_ID, List.of(ethosCaseReference)); verify(ccdClient, times(1)).startCaseCreationTransfer(eq(USER_TOKEN), caseDetailsArgumentCaptor.capture()); - assertNull(caseDetailsArgumentCaptor.getValue().getCaseData().getAllPartyFlags()); + assertSame(englandWalesEnabled && scotlandEnabled ? allPartyFlags : null, + caseDetailsArgumentCaptor.getValue().getCaseData().getAllPartyFlags()); var expectedEventSummary = String.format(CREATE_CASE_EVENT_SUMMARY_TEMPLATE, managingOffice); verify(ccdClient, times(1)).submitCaseCreation(eq(USER_TOKEN), any(), any(), eq(expectedEventSummary)); @@ -115,9 +120,10 @@ void caseTransferToScotlandCreateCase() throws IOException { verifyNoMoreInteractions(ccdClient); } - @Test + @ParameterizedTest + @CsvSource({"false, false", "false, true", "true, false", "true, true"}) @SuppressWarnings({"PMD.LawOfDemeter"}) - void caseTransferToEnglandCreateCase() throws IOException { + void caseTransferToEnglandCreateCase(boolean englandWalesEnabled, boolean scotlandEnabled) throws IOException { String ethosCaseReference = "4150002/2020"; String managingOffice = TribunalOffice.DUNDEE.getOfficeName(); CaseData caseData = new CaseData(); @@ -132,7 +138,8 @@ void caseTransferToEnglandCreateCase() throws IOException { UpdateCaseMsg updateCaseMsg = MessageHandlerTestHelper.generateCreationSingleCaseMsg(); ((CreationSingleDataModel)updateCaseMsg.getDataModelParent()).setOfficeCT( TribunalOffice.NEWCASTLE.getOfficeName()); - when(featureToggleService.isCaseFlagsV2Enabled(ENGLANDWALES_CASE_TYPE_ID)).thenReturn(true); + when(featureToggleService.isCaseFlagsV2Enabled(ENGLANDWALES_CASE_TYPE_ID)).thenReturn(englandWalesEnabled); + when(featureToggleService.isCaseFlagsV2Enabled(SCOTLAND_CASE_TYPE_ID)).thenReturn(scotlandEnabled); singleCreationService.sendCreation(submitEvent, USER_TOKEN, updateCaseMsg); @@ -140,7 +147,8 @@ void caseTransferToEnglandCreateCase() throws IOException { List.of(ethosCaseReference)); verify(ccdClient).startCaseCreationTransfer(eq(USER_TOKEN), caseDetailsArgumentCaptor.capture()); assertNull(caseDetailsArgumentCaptor.getValue().getCaseData().getFeeGroupReference()); - assertSame(allPartyFlags, caseDetailsArgumentCaptor.getValue().getCaseData().getAllPartyFlags()); + assertSame(englandWalesEnabled && scotlandEnabled ? allPartyFlags : null, + caseDetailsArgumentCaptor.getValue().getCaseData().getAllPartyFlags()); var expectedEventSummary = String.format(CREATE_CASE_EVENT_SUMMARY_TEMPLATE, managingOffice); verify(ccdClient).submitCaseCreation(eq(USER_TOKEN), any(), any(), eq(expectedEventSummary)); verify(ccdClient, times(0)).returnCaseCreationTransfer(eq(USER_TOKEN), any(), any(), @@ -148,9 +156,10 @@ void caseTransferToEnglandCreateCase() throws IOException { verifyNoMoreInteractions(ccdClient); } - @Test + @ParameterizedTest + @CsvSource({"false, false", "false, true", "true, false", "true, true"}) @SuppressWarnings({"PMD.LawOfDemeter"}) - void caseTransferToScotlandUpdateExisting() throws IOException { + void caseTransferToScotlandUpdateExisting(boolean englandWalesEnabled, boolean scotlandEnabled) throws IOException { var ethosCaseReference = "4150002/2020"; var managingOffice = TribunalOffice.MANCHESTER.getOfficeName(); var caseData = new CaseData(); @@ -166,10 +175,18 @@ void caseTransferToScotlandUpdateExisting() throws IOException { var updateCaseMsg = MessageHandlerTestHelper.generateCreationSingleCaseMsg(); ((CreationSingleDataModel)updateCaseMsg.getDataModelParent()).setOfficeCT( TribunalOffice.GLASGOW.getOfficeName()); - when(featureToggleService.isCaseFlagsV2Enabled(SCOTLAND_CASE_TYPE_ID)).thenReturn(true); + when(featureToggleService.isCaseFlagsV2Enabled(ENGLANDWALES_CASE_TYPE_ID)).thenReturn(englandWalesEnabled); + when(featureToggleService.isCaseFlagsV2Enabled(SCOTLAND_CASE_TYPE_ID)).thenReturn(scotlandEnabled); + + AllPartyFlags existingFlags = createAllPartyFlags(); + CaseData existingCaseData = new CaseData(); + existingCaseData.setAllPartyFlags(existingFlags); + SubmitEvent existingCase = new SubmitEvent(); + existingCase.setCaseId(caseId); + existingCase.setCaseData(existingCaseData); when(ccdClient.retrieveCasesElasticSearch(USER_TOKEN, SCOTLAND_CASE_TYPE_ID, List.of(ethosCaseReference))) - .thenReturn(new ArrayList<>(Collections.singletonList(submitEvent))); + .thenReturn(new ArrayList<>(Collections.singletonList(existingCase))); singleCreationService.sendCreation(submitEvent, USER_TOKEN, updateCaseMsg); @@ -179,7 +196,8 @@ void caseTransferToScotlandUpdateExisting() throws IOException { verify(ccdClient).submitEventForCase(eq(USER_TOKEN), caseDataArgumentCaptor.capture(), eq(SCOTLAND_CASE_TYPE_ID), eq("EMPLOYMENT"), any(), eq(String.valueOf(caseId))); - assertSame(allPartyFlags, caseDataArgumentCaptor.getValue().getAllPartyFlags()); + assertSame(englandWalesEnabled && scotlandEnabled ? allPartyFlags : existingFlags, + caseDataArgumentCaptor.getValue().getAllPartyFlags()); verify(ccdClient, times(0)).startCaseCreationTransfer(eq(USER_TOKEN), any()); verifyNoMoreInteractions(ccdClient); } From 6054ad074de85fb6f7ae70f6ffebef88223222ac Mon Sep 17 00:00:00 2001 From: hmcts-jenkins-d-to-i <62423932+hmcts-jenkins-d-to-i[bot]@users.noreply.github.com> Date: Thu, 8 Oct 2026 15:30:19 +0000 Subject: [PATCH 096/100] Bumping chart version/ fixing aliases --- charts/et-cos/Chart.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/et-cos/Chart.yaml b/charts/et-cos/Chart.yaml index 82dbd9599d..adbfe92580 100644 --- a/charts/et-cos/Chart.yaml +++ b/charts/et-cos/Chart.yaml @@ -1,7 +1,7 @@ apiVersion: v2 name: et-cos home: https://github.com/hmcts/et-ccd-callbacks -version: 0.0.80 +version: 0.0.81 description: HMCTS Employment Tribunals CCD Callbacks service maintainers: - name: HMCTS Employment Tribunals Team From 2ed655e6ad40b721a2253c59f3053b3683c8ffe1 Mon Sep 17 00:00:00 2001 From: rajaram Date: Tue, 13 Oct 2026 09:39:39 +0100 Subject: [PATCH 097/100] RET-7049: Added update comment welsh field --- .../model/ccd/items/FlagDetailType.java | 1 + .../model/ccd/items/FlagDetailTypeTest.java | 97 +++++++++++++++++++ 2 files changed, 98 insertions(+) create mode 100644 et-shared/src/test/java/uk/gov/hmcts/et/common/model/ccd/items/FlagDetailTypeTest.java diff --git a/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/items/FlagDetailType.java b/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/items/FlagDetailType.java index 9323db5636..92f4b9aba6 100644 --- a/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/items/FlagDetailType.java +++ b/et-shared/src/main/java/uk/gov/hmcts/et/common/model/ccd/items/FlagDetailType.java @@ -23,6 +23,7 @@ public class FlagDetailType { private String flagComment; private String flagComment_cy; private String flagUpdateComment; + private String flagUpdateComment_cy; private String dateTimeModified; private String dateTimeCreated; private ListTypeItem path; diff --git a/et-shared/src/test/java/uk/gov/hmcts/et/common/model/ccd/items/FlagDetailTypeTest.java b/et-shared/src/test/java/uk/gov/hmcts/et/common/model/ccd/items/FlagDetailTypeTest.java new file mode 100644 index 0000000000..68ad745adc --- /dev/null +++ b/et-shared/src/test/java/uk/gov/hmcts/et/common/model/ccd/items/FlagDetailTypeTest.java @@ -0,0 +1,97 @@ +package uk.gov.hmcts.et.common.model.ccd.items; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +class FlagDetailTypeTest { + private static final String COMPLETE_FLAG_JSON = """ + { + "name": "Other support", + "name_cy": "Cymorth arall", + "subTypeValue": "Forms", + "subTypeValue_cy": "Ffurflenni", + "subTypeKey": "forms", + "otherDescription": "Help reading forms", + "otherDescription_cy": "Help i ddarllen ffurflenni", + "flagComment": "Support requested", + "flagComment_cy": "Cais am gymorth", + "flagUpdateComment": "Support approved", + "flagUpdateComment_cy": "Cymorth wedi ei gymeradwyo", + "dateTimeModified": "2026-10-08T11:30:00.123Z", + "dateTimeCreated": "2026-10-07T10:00:00.000Z", + "path": [ + {"id": "party", "value": "Party"}, + {"id": "adjustment", "value": "Reasonable adjustment"} + ], + "hearingRelevant": "Yes", + "flagCode": "OT0001", + "status": "Active", + "requestReason": "No", + "availableExternally": "Yes" + } + """; + + private final ObjectMapper mapper = new ObjectMapper(); + + @Test + void serializesEveryFieldUsingCcdPropertyNames() throws JsonProcessingException { + JsonNode actual = mapper.readTree(mapper.writeValueAsString(completeFlag())); + + assertEquals(mapper.readTree(COMPLETE_FLAG_JSON), actual); + } + + @Test + void deserializesEveryFieldIncludingWelshUpdateComment() throws JsonProcessingException { + FlagDetailType actual = mapper.readValue(COMPLETE_FLAG_JSON, FlagDetailType.class); + + assertEquals(completeFlag(), actual); + assertEquals("Cymorth wedi ei gymeradwyo", actual.getFlagUpdateComment_cy()); + assertEquals("party", actual.getPath().getFirst().getId()); + assertEquals("Reasonable adjustment", actual.getPath().get(1).getValue()); + } + + @Test + void acceptsLegacyFlagsWithMissingOptionalAndUnknownFields() throws JsonProcessingException { + FlagDetailType actual = mapper.readValue(""" + {"name": "Intermediary", "flagCode": "RA0038", "status": "Requested", "futureField": "value"} + """, FlagDetailType.class); + + assertEquals(FlagDetailType.builder().name("Intermediary").flagCode("RA0038") + .status("Requested").build(), actual); + assertNull(actual.getFlagUpdateComment_cy()); + assertNull(actual.getPath()); + } + + @ParameterizedTest + @ValueSource(strings = {"2026-10-08T11:30:00", "2026-10-08T11:30:00.123Z", "2026-10-08T12:30:00+01:00"}) + void preservesDateStringsWithoutReformatting(String dateTime) throws JsonProcessingException { + FlagDetailType original = FlagDetailType.builder() + .dateTimeCreated(dateTime).dateTimeModified(dateTime).build(); + + FlagDetailType actual = mapper.readValue(mapper.writeValueAsString(original), FlagDetailType.class); + + assertEquals(dateTime, actual.getDateTimeCreated()); + assertEquals(dateTime, actual.getDateTimeModified()); + } + + private static FlagDetailType completeFlag() { + return FlagDetailType.builder() + .name("Other support").name_cy("Cymorth arall") + .subTypeValue("Forms").subTypeValue_cy("Ffurflenni").subTypeKey("forms") + .otherDescription("Help reading forms").otherDescription_cy("Help i ddarllen ffurflenni") + .flagComment("Support requested").flagComment_cy("Cais am gymorth") + .flagUpdateComment("Support approved").flagUpdateComment_cy("Cymorth wedi ei gymeradwyo") + .dateTimeModified("2026-10-08T11:30:00.123Z").dateTimeCreated("2026-10-07T10:00:00.000Z") + .path(ListTypeItem.from(GenericTypeItem.from("party", "Party"), + GenericTypeItem.from("adjustment", "Reasonable adjustment"))) + .hearingRelevant("Yes").flagCode("OT0001").status("Active") + .requestReason("No").availableExternally("Yes").build(); + } +} From 19250104156df14629aa665a03d58bca463b17a9 Mon Sep 17 00:00:00 2001 From: hmcts-jenkins-d-to-i <62423932+hmcts-jenkins-d-to-i[bot]@users.noreply.github.com> Date: Tue, 13 Oct 2026 08:43:20 +0000 Subject: [PATCH 098/100] Bumping chart version/ fixing aliases --- charts/et-cos/Chart.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/et-cos/Chart.yaml b/charts/et-cos/Chart.yaml index 6cc091ce83..af9f4399d0 100644 --- a/charts/et-cos/Chart.yaml +++ b/charts/et-cos/Chart.yaml @@ -1,7 +1,7 @@ apiVersion: v2 name: et-cos home: https://github.com/hmcts/et-ccd-callbacks -version: 0.0.81 +version: 0.0.82 description: HMCTS Employment Tribunals CCD Callbacks service maintainers: - name: HMCTS Employment Tribunals Team From 12f0ca88f9b18c63f6ffa03039acb644cf6355f3 Mon Sep 17 00:00:00 2001 From: hmcts-jenkins-d-to-i <62423932+hmcts-jenkins-d-to-i[bot]@users.noreply.github.com> Date: Thu, 22 Oct 2026 11:05:21 +0000 Subject: [PATCH 099/100] Bumping chart version/ fixing aliases --- charts/et-cos/Chart.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/et-cos/Chart.yaml b/charts/et-cos/Chart.yaml index 4d76e09ee1..61c82caf06 100644 --- a/charts/et-cos/Chart.yaml +++ b/charts/et-cos/Chart.yaml @@ -1,7 +1,7 @@ apiVersion: v2 name: et-cos home: https://github.com/hmcts/et-ccd-callbacks -version: 0.0.82 +version: 0.0.83 description: HMCTS Employment Tribunals CCD Callbacks service maintainers: - name: HMCTS Employment Tribunals Team From 9791c8285b13193540c85804b27781343716a254 Mon Sep 17 00:00:00 2001 From: rajaram Date: Thu, 22 Oct 2026 12:22:38 +0100 Subject: [PATCH 100/100] Fixed build issue --- .../controllers/CaseActionsForCaseWorkerController.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java index 0c4e01e497..3ac7ba5b52 100644 --- a/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java +++ b/src/main/java/uk/gov/hmcts/ethos/replacement/docmosis/controllers/CaseActionsForCaseWorkerController.java @@ -108,8 +108,8 @@ public class CaseActionsForCaseWorkerController { private static final List NEW_FLAG_REVIEW_SUPPORT_TASK_EVENTS = List.of(EVENT_REQUEST_SUPPORT, EVENT_CREATE_FLAG); public static final String CREATE_ECM_CASE = "createEcmCase"; - private static final List SUBMISSION_EVENTS = List.of(EVENT_SUBMIT_CASE_DRAFT, "initiateCase", "submitEt1Draft", - CREATE_ECM_CASE); + private static final List SUBMISSION_EVENTS = List.of(EVENT_SUBMIT_CASE_DRAFT, "initiateCase", + "submitEt1Draft", CREATE_ECM_CASE); private final CaseCloseValidator caseCloseValidator; private final CaseManagementForCaseWorkerService caseManagementForCaseWorkerService;