diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml index 97f6a97480..6b39ea2065 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml @@ -142,6 +142,7 @@ org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService.updateDispositionActionDefinition=RM_ALLOW org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService.isNextDispositionActionEligible=RM.Read.0 org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService.getNextDispositionAction=RM.Read.0 + org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService.recalculateNextDispositionStep=RM.Read.0 org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService.getCompletedDispositionActions=RM.Read.0 org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService.getLastCompletedDispostionAction=RM.Read.0 org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService.isDisposableItemCutoff=RM.Read.0 diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionService.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionService.java index ed2ed79ecd..a666b950c4 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionService.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionService.java @@ -264,4 +264,12 @@ public interface DispositionService * @return the initial disposition */ DispositionSchedule getOriginDispositionSchedule(NodeRef nodeRef); + + /** + * Updates disposition action step when linking or unlinking + * the given record to/from a record folder + * + * @param record + */ + void recalculateNextDispositionStep(NodeRef record); } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionServiceImpl.java index 3a6e1d5beb..907c6c2b90 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionServiceImpl.java @@ -1094,6 +1094,32 @@ public class DispositionServiceImpl extends ServiceBaseImpl } return null; } + + public void recalculateNextDispositionStep(NodeRef record) + { + List recordFolders = recordFolderService.getRecordFolders(record); + + DispositionAction nextDispositionAction = getNextDispositionAction(record); + + if (nextDispositionAction != null) + { + NextActionFromDisposition dsNextAction = getNextDispositionAction(record, recordFolders, nextDispositionAction); + if (dsNextAction != null) + { + final NodeRef action = dsNextAction.getNextActionNodeRef(); + final Date dispositionActionDate = dsNextAction.getNextActionDateAsOf(); + AuthenticationUtil.runAsSystem(new RunAsWork() + { + @Override + public Void doWork() + { + nodeService.setProperty(action, PROP_DISPOSITION_AS_OF, dispositionActionDate); + return null; + } + }); + } + } + } /** * Helper method to determine if a node is frozen or has frozen children diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java index a523ac93b6..22d4c95733 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java @@ -34,14 +34,12 @@ import java.util.Set; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.model.ContentModel; -import org.alfresco.module.org_alfresco_module_rm.RecordsManagementServiceRegistry; import org.alfresco.module.org_alfresco_module_rm.RecordsManagementPolicies.BeforeFileRecord; import org.alfresco.module.org_alfresco_module_rm.RecordsManagementPolicies.OnFileRecord; import org.alfresco.module.org_alfresco_module_rm.capability.Capability; import org.alfresco.module.org_alfresco_module_rm.capability.CapabilityService; import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule; -import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionScheduleImpl; import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService; import org.alfresco.module.org_alfresco_module_rm.dod5015.DOD5015Model; import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService; @@ -547,6 +545,8 @@ public class RecordServiceImpl extends BaseBehaviourBean // create and file the content as a record file(nodeRef); + // recalculate disposition schedule for the record when linking it + dispositionService.recalculateNextDispositionStep(nodeRef); } } } @@ -1695,7 +1695,7 @@ public class RecordServiceImpl extends BaseBehaviourBean // ensure we are linking a record to a record folder if(isRecord(record) && isRecordFolder(recordFolder)) { - // ensure that we are not linking a record to an exisiting location + // ensure that we are not linking a record to an existing location List parents = nodeService.getParentAssocs(record); for (ChildAssociationRef parent : parents) { @@ -1718,6 +1718,9 @@ public class RecordServiceImpl extends BaseBehaviourBean record, ContentModel.ASSOC_CONTAINS, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, name)); + + // recalculate disposition schedule for the record when linking it + dispositionService.recalculateNextDispositionStep(record); } else { @@ -1774,6 +1777,9 @@ public class RecordServiceImpl extends BaseBehaviourBean // remove the link nodeService.removeChild(recordFolder, record); + + // recalculate disposition schedule for record after unlinking it + dispositionService.recalculateNextDispositionStep(record); } else { diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/disposition/MultipleSchedulesTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/disposition/MultipleSchedulesTest.java index f166c97a1f..26d119210d 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/disposition/MultipleSchedulesTest.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/disposition/MultipleSchedulesTest.java @@ -173,4 +173,33 @@ public class MultipleSchedulesTest extends BaseRMTestCase .from(() -> dispositionService.getNextDispositionAction(record).getAsOfDate()) .because("Record should follow largest rentention schedule period, which is one week."); } + + /** + * RM-4292 + *

+     * Given a record subject to a mixed disposition schedule
+     * When the record is unlinked from one of its secondary parents
+     * Then the next disposition action is recalculated.
+     * 
+ */ + public void testRecalculateDispositionWhenUnlinking() + { + test() + .given(() -> { + setUpFilePlan(); + // Create a record filed under category A and linked to category B. + record = fileFolderService.create(folderA, RECORD_NAME, ContentModel.TYPE_CONTENT).getNodeRef(); + recordService.link(record, folderB); + }) + .when(() -> { + // Cut off the record. + dispositionService.cutoffDisposableItem(record); + // Unlink the record from folder B. + recordService.unlink(record, folderB); + }) + .then() + .expect(true) + .from(() -> dispositionService.isNextDispositionActionEligible(record)) + .because("Destroy action should be available, as the record should follow its origin disposition schedule."); + } } diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/disposition/UpdateNextDispositionActionTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/disposition/UpdateNextDispositionActionTest.java index d8dbb0b078..66bf5513b8 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/disposition/UpdateNextDispositionActionTest.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/disposition/UpdateNextDispositionActionTest.java @@ -26,13 +26,11 @@ import static org.alfresco.util.GUID.generate; import java.io.Serializable; import java.util.Collections; -import java.util.Date; import java.util.HashMap; import java.util.Map; import org.alfresco.module.org_alfresco_module_rm.action.impl.CutOffAction; import org.alfresco.module.org_alfresco_module_rm.action.impl.DestroyAction; -import org.alfresco.module.org_alfresco_module_rm.action.impl.EditDispositionActionAsOfDateAction; import org.alfresco.module.org_alfresco_module_rm.action.impl.TransferAction; import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule; import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase;