Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NFDIV-4448: Add configuration for NFD case deletion #4252

Open
wants to merge 19 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion ccd-definitions/AuthorisationComplexType.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,8 @@
{"CaseTypeID": "NFD", "CaseFieldID": "applicant2SolicitorOrganisationPolicy", "ListElementCode": "Organisation.OrganisationID", "UserRole": "caseworker-approver", "CRUD": "CRU"},
{"CaseTypeID": "NFD", "CaseFieldID": "applicant2SolicitorOrganisationPolicy", "ListElementCode": "Organisation.OrganisationName", "UserRole": "caseworker-approver", "CRUD": "CRU"},
{"CaseTypeID": "NFD", "CaseFieldID": "applicant2SolicitorOrganisationPolicy", "ListElementCode": "PrepopulateToUsersOrganisation", "UserRole": "caseworker-approver", "CRUD": "CRU"},
{"CaseTypeID": "NFD", "CaseFieldID": "applicant2SolicitorOrganisationPolicy", "ListElementCode": "PreviousOrganisations", "UserRole": "caseworker-approver", "CRUD": "CRU"}
{"CaseTypeID": "NFD", "CaseFieldID": "applicant2SolicitorOrganisationPolicy", "ListElementCode": "PreviousOrganisations", "UserRole": "caseworker-approver", "CRUD": "CRU"},
{"CaseTypeID": "NFD", "CaseFieldID": "TTL", "ListElementCode": "SystemTTL", "UserRole": "TTL_profile", "CRUD": "R"},
{"CaseTypeID": "NFD", "CaseFieldID": "TTL", "ListElementCode": "Suspended", "UserRole": "TTL_profile", "CRUD": "CRU"},
{"CaseTypeID": "NFD", "CaseFieldID": "TTL", "ListElementCode": "OverrideTTL", "UserRole": "TTL_profile", "CRUD": "CRU"}
]
6 changes: 4 additions & 2 deletions src/cftlib/java/uk/gov/hmcts/divorce/cftlib/CftLibConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public class CftLibConfig implements CFTLibConfigurer {
@Override
public void configure(CFTLib lib) throws Exception {
var users = Map.of(
"[email protected]", List.of("caseworker", "caseworker-divorce", "caseworker-divorce-courtadmin_beta"),
"[email protected]", List.of("caseworker", "caseworker-divorce", "caseworker-divorce-courtadmin_beta", "TTL_profile"),
"[email protected]", List.of(
"caseworker", "caseworker-divorce", "caseworker-divorce-superuser", "caseworker-divorce-courtadmin_beta"),
"[email protected]", List.of("caseworker", "caseworker-divorce", "caseworker-divorce-courtadmin_beta"),
Expand Down Expand Up @@ -65,7 +65,9 @@ public void configure(CFTLib lib) throws Exception {
"pui-case-manager",
"pui-finance-manager",
"pui-organisation-manager",
"pui-user-manager"
"pui-user-manager",
"TTL_profile",
"idam:cft-ttl-manager"
FaisalMoJ marked this conversation as resolved.
Show resolved Hide resolved
);

ResourceLoader resourceLoader = new DefaultResourceLoader();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public void configure(final ConfigBuilder<CaseData, State, UserRole> configBuild
.event(CITIZEN_PAYMENT_MADE)
.forState(AwaitingPayment)
.showCondition(NEVER_SHOW)
.ttlIncrement(36524)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we also need to account for the scenarios where a sol submits an application or a citizen submits using HWF?

.name("Payment made")
.description("Payment made")
.retries(120, 120)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
package uk.gov.hmcts.divorce.citizen.event;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import uk.gov.hmcts.ccd.sdk.api.CCDConfig;
import uk.gov.hmcts.ccd.sdk.api.CaseDetails;
import uk.gov.hmcts.ccd.sdk.api.ConfigBuilder;
import uk.gov.hmcts.ccd.sdk.api.callback.AboutToStartOrSubmitResponse;
import uk.gov.hmcts.divorce.divorcecase.model.CaseData;
import uk.gov.hmcts.divorce.divorcecase.model.State;
import uk.gov.hmcts.divorce.divorcecase.model.UserRole;
import uk.gov.hmcts.divorce.idam.IdamService;
import uk.gov.hmcts.divorce.idam.User;
import uk.gov.hmcts.divorce.systemupdate.service.CcdUpdateService;
import uk.gov.hmcts.reform.authorisation.generators.AuthTokenGenerator;

import static uk.gov.hmcts.divorce.common.ccd.CcdPageConfiguration.NEVER_SHOW;
import static uk.gov.hmcts.divorce.divorcecase.model.State.AwaitingApplicant1Response;
Expand All @@ -21,12 +29,19 @@
import static uk.gov.hmcts.divorce.divorcecase.model.State.RequestedInformationSubmitted;
import static uk.gov.hmcts.divorce.divorcecase.model.UserRole.CREATOR;
import static uk.gov.hmcts.divorce.divorcecase.model.access.Permissions.CREATE_READ_UPDATE;
import static uk.gov.hmcts.divorce.systemupdate.event.SystemUpdateTTL.SYSTEM_UPDATE_TTL;

@Component
@RequiredArgsConstructor
@Slf4j
public class CitizenUpdateApplication implements CCDConfig<CaseData, State, UserRole> {

public static final String CITIZEN_UPDATE = "citizen-update-application";

private final CcdUpdateService ccdUpdateService;
private final IdamService idamService;
private final AuthTokenGenerator authTokenGenerator;

@Override
public void configure(final ConfigBuilder<CaseData, State, UserRole> configBuilder) {

Expand All @@ -40,4 +55,23 @@ public void configure(final ConfigBuilder<CaseData, State, UserRole> configBuild
.description("Patch a divorce or dissolution")
.grant(CREATE_READ_UPDATE, CREATOR);
}

public AboutToStartOrSubmitResponse<CaseData, State> aboutToSubmit(CaseDetails<CaseData, State> details,
CaseDetails<CaseData, State> beforeDetails) {

CaseData caseData = details.getData();

//Set TTL for newly created cases from today's date to 6 months in future
if (caseData.getRetainAndDisposeTimeToLive() == null && details.getState() == Draft) {
final User user = idamService.retrieveSystemUpdateUserDetails();
final String serviceAuthorization = authTokenGenerator.generate();

ccdUpdateService.submitEvent(details.getId(), SYSTEM_UPDATE_TTL, user, serviceAuthorization);
}

return AboutToStartOrSubmitResponse.<CaseData, State>builder()
.data(details.getData())
.state(details.getState())
.build();
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we also need to set the TTL in citizenCreateApplication and solicitorCreateApplication to avoid old drafts being left from the start of the application process? It might work using ttlIncrement rather than a custom event

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added TtlIncreament to be 180 days (6 months) as suggested

}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ public class HighLevelDataSetupApp extends DataLoaderToDefinitionStore {
new CcdRoleConfig("pui-case-manager", "PUBLIC"),
new CcdRoleConfig("pui-finance-manager", "PUBLIC"),
new CcdRoleConfig("pui-organisation-manager", "PUBLIC"),
new CcdRoleConfig("pui-user-manager", "PUBLIC")
new CcdRoleConfig("pui-user-manager", "PUBLIC"),
new CcdRoleConfig("TTL_profile", "PUBLIC"),
new CcdRoleConfig("idam:cft-ttl-manager", "PUBLIC")
FaisalMoJ marked this conversation as resolved.
Show resolved Hide resolved
};

private final CcdEnvironment environment;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package uk.gov.hmcts.divorce.common.service.task;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import uk.gov.hmcts.ccd.sdk.api.CaseDetails;
Expand All @@ -17,6 +18,7 @@
import static uk.gov.hmcts.divorce.divorcecase.model.State.WelshTranslationReview;

@Component
@RequiredArgsConstructor
@Slf4j
public class SetStateAfterSubmission implements CaseTask {

Expand Down
11 changes: 11 additions & 0 deletions src/main/java/uk/gov/hmcts/divorce/divorcecase/model/CaseData.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonUnwrapped;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
Expand All @@ -19,6 +20,7 @@
import uk.gov.hmcts.ccd.sdk.type.ListValue;
import uk.gov.hmcts.ccd.sdk.type.OrderSummary;
import uk.gov.hmcts.ccd.sdk.type.ScannedDocument;
import uk.gov.hmcts.ccd.sdk.type.TTL;
import uk.gov.hmcts.ccd.sdk.type.YesOrNo;
import uk.gov.hmcts.divorce.caseworker.model.CaseNote;
import uk.gov.hmcts.divorce.divorcecase.model.access.AcaSystemUserAccess;
Expand All @@ -31,6 +33,7 @@
import uk.gov.hmcts.divorce.divorcecase.model.access.DefaultAccess;
import uk.gov.hmcts.divorce.divorcecase.model.access.SolicitorAndSystemUpdateAccess;
import uk.gov.hmcts.divorce.divorcecase.model.access.SystemUpdateAndSuperUserAccess;
import uk.gov.hmcts.divorce.divorcecase.model.access.TtlProfileAccess;
import uk.gov.hmcts.divorce.document.model.DivorceDocument;
import uk.gov.hmcts.divorce.document.model.DocumentType;
import uk.gov.hmcts.divorce.noticeofchange.model.ChangeOfRepresentative;
Expand Down Expand Up @@ -328,6 +331,14 @@ public class CaseData {
@Builder.Default
private SentNotifications sentNotifications = new SentNotifications();

@JsonProperty("TTL")
@CCD(
label = "Set up TTL",
typeOverride = FieldType.TTL,
access = {TtlProfileAccess.class}
FaisalMoJ marked this conversation as resolved.
Show resolved Hide resolved
)
private TTL retainAndDisposeTimeToLive;

@JsonUnwrapped
@Builder.Default
private RequestForInformationList requestForInformationList = new RequestForInformationList();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public enum UserRole implements HasRole {
JUDGE("caseworker-divorce-judge", "CRU"),
NOC_APPROVER("caseworker-approver", "CRU"),
RPA_ROBOT("caseworker-divorce-rparobot", "CRU"),
TTL_PROFILE("TTL_profile", "CRU"),

SOLICITOR("caseworker-divorce-solicitor", "CRU"),
APPLICANT_1_SOLICITOR("[APPONESOLICITOR]", "CRU"),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package uk.gov.hmcts.divorce.divorcecase.model.access;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.SetMultimap;
import uk.gov.hmcts.ccd.sdk.api.HasAccessControl;
import uk.gov.hmcts.ccd.sdk.api.HasRole;
import uk.gov.hmcts.ccd.sdk.api.Permission;

import static uk.gov.hmcts.divorce.divorcecase.model.UserRole.TTL_PROFILE;

public class TtlProfileAccess implements HasAccessControl {
@Override
public SetMultimap<HasRole, Permission> getGrants() {

SetMultimap<HasRole, Permission> grants = HashMultimap.create();
grants.putAll(TTL_PROFILE, Permissions.CREATE_READ_UPDATE);

return grants;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package uk.gov.hmcts.divorce.systemupdate.event;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import uk.gov.hmcts.ccd.sdk.api.CCDConfig;
import uk.gov.hmcts.ccd.sdk.api.CaseDetails;
import uk.gov.hmcts.ccd.sdk.api.ConfigBuilder;
import uk.gov.hmcts.ccd.sdk.api.callback.AboutToStartOrSubmitResponse;
import uk.gov.hmcts.ccd.sdk.type.TTL;
import uk.gov.hmcts.ccd.sdk.type.YesOrNo;
import uk.gov.hmcts.divorce.common.ccd.PageBuilder;
import uk.gov.hmcts.divorce.divorcecase.model.CaseData;
import uk.gov.hmcts.divorce.divorcecase.model.State;
import uk.gov.hmcts.divorce.divorcecase.model.UserRole;

import java.time.LocalDate;
import java.util.Arrays;

import static uk.gov.hmcts.divorce.common.ccd.CcdPageConfiguration.NEVER_SHOW;
import static uk.gov.hmcts.divorce.divorcecase.model.State.AwaitingPayment;
import static uk.gov.hmcts.divorce.divorcecase.model.State.Draft;
import static uk.gov.hmcts.divorce.divorcecase.model.UserRole.TTL_PROFILE;
import static uk.gov.hmcts.divorce.divorcecase.model.access.Permissions.CREATE_READ_UPDATE;

@Component
@Slf4j
public class SystemUpdateTTL implements CCDConfig<CaseData, State, UserRole> {

public static final String SYSTEM_UPDATE_TTL = "system-update-ttl";
private static final LocalDate CURRENT_DATE_PLUS_SIX_MONTH = LocalDate.now().plusMonths(6);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As it's static, it will get initialised once (when a pod starts), meaning that if we have long-running pods, the TTL will be too short for some cases


@Override
public void configure(final ConfigBuilder<CaseData, State, UserRole> configBuilder) {

new PageBuilder(configBuilder
.event(SYSTEM_UPDATE_TTL)
.forStates(Draft, AwaitingPayment)
.name("Resolve time to live")
.showCondition(NEVER_SHOW)
.aboutToStartCallback(this::aboutToStart)
.description("Resolve time to live")
.fields()
.complex(CaseData::getRetainAndDisposeTimeToLive)
.readonly(TTL::getSystemTTL)
.optional(TTL::getOverrideTTL)
.optional(TTL::getSuspended)
.done()
.done()
.grant(CREATE_READ_UPDATE, TTL_PROFILE));

Arrays.stream(UserRole.values()).forEach(
userRole -> {
if (userRole.getRole().contains("caseworker")) {
configBuilder.caseRoleToAccessProfile(userRole).legacyIdamRole()
.accessProfiles(userRole.getRole(), "TTL_profile").build();
}
}
);
}

public AboutToStartOrSubmitResponse<CaseData, State> aboutToStart(final CaseDetails<CaseData, State> details) {

log.info("{} about to start callback invoked for Case Id: {}", SYSTEM_UPDATE_TTL, details.getId());
final CaseData caseData = details.getData();

if (caseData.getRetainAndDisposeTimeToLive() == null && details.getState() == Draft) {
caseData.setRetainAndDisposeTimeToLive(TTL.builder().systemTTL(CURRENT_DATE_PLUS_SIX_MONTH)
.suspended(YesOrNo.NO)
.build());
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we'll need to set it like this if using TTL Increment? I'm not sure R&D allows it to be manually set without going through CCD config (based on discussions last week)


return AboutToStartOrSubmitResponse.<CaseData, State>builder()
.data(caseData)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,47 @@
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import uk.gov.hmcts.ccd.sdk.ConfigBuilderImpl;
import uk.gov.hmcts.ccd.sdk.api.CaseDetails;
import uk.gov.hmcts.ccd.sdk.api.Event;
import uk.gov.hmcts.divorce.divorcecase.model.CaseData;
import uk.gov.hmcts.divorce.divorcecase.model.State;
import uk.gov.hmcts.divorce.divorcecase.model.UserRole;
import uk.gov.hmcts.divorce.idam.IdamService;
import uk.gov.hmcts.divorce.idam.User;
import uk.gov.hmcts.divorce.systemupdate.service.CcdUpdateService;
import uk.gov.hmcts.reform.authorisation.generators.AuthTokenGenerator;
import uk.gov.hmcts.reform.idam.client.models.UserInfo;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.when;
import static uk.gov.hmcts.divorce.citizen.event.CitizenUpdateApplication.CITIZEN_UPDATE;
import static uk.gov.hmcts.divorce.divorcecase.model.State.Draft;
import static uk.gov.hmcts.divorce.divorcecase.model.State.Submitted;
import static uk.gov.hmcts.divorce.systemupdate.event.SystemUpdateTTL.SYSTEM_UPDATE_TTL;
import static uk.gov.hmcts.divorce.testutil.ConfigTestUtil.createCaseDataConfigBuilder;
import static uk.gov.hmcts.divorce.testutil.ConfigTestUtil.getEventsFrom;
import static uk.gov.hmcts.divorce.testutil.TestConstants.SYSTEM_UPDATE_AUTH_TOKEN;
import static uk.gov.hmcts.divorce.testutil.TestConstants.SYSTEM_USER_USER_ID;
import static uk.gov.hmcts.divorce.testutil.TestConstants.TEST_CASE_ID;
import static uk.gov.hmcts.divorce.testutil.TestConstants.TEST_SERVICE_AUTH_TOKEN;

@ExtendWith(MockitoExtension.class)
class CitizenUpdateApplicationTest {

@Mock
private IdamService idamService;

@Mock
private AuthTokenGenerator authTokenGenerator;

@Mock
private CcdUpdateService ccdUpdateService;

@InjectMocks
private CitizenUpdateApplication citizenUpdateApplication;

Expand All @@ -31,4 +57,39 @@ void shouldAddConfigurationToConfigBuilder() {
.extracting(Event::getId)
.contains(CITIZEN_UPDATE);
}

@Test
void shouldCallSystemUpdateTTLEventForDraftStateAndTTLNotSetAboutToSubmitCallback() {

var userDetails = UserInfo.builder().uid(SYSTEM_USER_USER_ID).build();
var user = new User(SYSTEM_UPDATE_AUTH_TOKEN, userDetails);
when(idamService.retrieveSystemUpdateUserDetails()).thenReturn(user);
when(authTokenGenerator.generate()).thenReturn(TEST_SERVICE_AUTH_TOKEN);

CaseDetails<CaseData, State> beforeDetails = getCaseDetails(Draft);

citizenUpdateApplication.aboutToSubmit(beforeDetails, beforeDetails);

verify(ccdUpdateService).submitEvent(beforeDetails.getId(), SYSTEM_UPDATE_TTL, user, TEST_SERVICE_AUTH_TOKEN);
}

@Test
void shouldNotCallSystemUpdateTTLEventForDraftStateAndTTLNotSetAboutToSubmitCallback() {

CaseDetails<CaseData, State> beforeDetails = getCaseDetails(Submitted);

citizenUpdateApplication.aboutToSubmit(beforeDetails, beforeDetails);

verifyNoInteractions(ccdUpdateService);
}

private CaseDetails<CaseData, State> getCaseDetails(State state) {
return CaseDetails.<CaseData, State>builder()
.id(TEST_CASE_ID)
.state(state)
.data(CaseData.builder()

.build())
.build();
}
}
Loading
Loading