package com.constellio.app.modules.rm.model.calculators.document; import static com.constellio.app.modules.rm.model.enums.DecommissioningDateBasedOn.OPEN_DATE; import static com.constellio.app.modules.rm.model.enums.DisposalType.DEPOSIT; import static com.constellio.app.modules.rm.model.enums.DisposalType.DESTRUCTION; import static com.constellio.app.modules.rm.model.enums.RetentionRuleScope.DOCUMENTS; import static com.constellio.app.modules.rm.wrappers.RetentionRule.SCOPE; import static com.constellio.data.utils.LangUtils.max; import static java.util.Arrays.asList; import java.util.List; import org.joda.time.LocalDate; import com.constellio.app.modules.rm.RMConfigs; import com.constellio.app.modules.rm.model.CopyRetentionRule; import com.constellio.app.modules.rm.model.calculators.CalculatorUtils; import com.constellio.app.modules.rm.model.enums.DecommissioningDateBasedOn; import com.constellio.app.modules.rm.model.enums.DisposalType; import com.constellio.app.modules.rm.model.enums.FolderStatus; import com.constellio.app.modules.rm.model.enums.RetentionRuleScope; import com.constellio.app.modules.rm.wrappers.Document; import com.constellio.app.modules.rm.wrappers.Folder; import com.constellio.model.entities.calculators.CalculatorParameters; import com.constellio.model.entities.calculators.DynamicDependencyValues; import com.constellio.model.entities.calculators.MetadataValueCalculator; import com.constellio.model.entities.calculators.dependencies.ConfigDependency; import com.constellio.model.entities.calculators.dependencies.Dependency; import com.constellio.model.entities.calculators.dependencies.LocalDependency; import com.constellio.model.entities.calculators.dependencies.ReferenceDependency; import com.constellio.model.entities.schemas.MetadataValueType; public abstract class DocumentExpectedInactiveDateCalculator implements MetadataValueCalculator<LocalDate> { ReferenceDependency<LocalDate> folderOpenDateParam = ReferenceDependency .toADate(Document.FOLDER, Folder.OPENING_DATE); ReferenceDependency<LocalDate> folderCloseDateParam = ReferenceDependency .toADate(Document.FOLDER, Folder.CLOSING_DATE); ReferenceDependency<LocalDate> folderExpectedDestructionDateParam = ReferenceDependency .toADate(Document.FOLDER, Folder.EXPECTED_DESTRUCTION_DATE); ReferenceDependency<LocalDate> folderExpectedDepositDateParam = ReferenceDependency .toADate(Document.FOLDER, Folder.EXPECTED_DEPOSIT_DATE); LocalDependency<LocalDate> expectedTransferDateParam = LocalDependency.toADate(Document.FOLDER_EXPECTED_TRANSFER_DATE); LocalDependency<LocalDate> actualTransferDateParam = LocalDependency.toADate(Document.FOLDER_ACTUAL_TRANSFER_DATE); LocalDependency<LocalDate> actualDepositDateParam = LocalDependency.toADate(Document.FOLDER_ACTUAL_DEPOSIT_DATE); LocalDependency<LocalDate> actualDestructionDateParam = LocalDependency.toADate(Document.FOLDER_ACTUAL_DESTRUCTION_DATE); LocalDependency<CopyRetentionRule> copyParam = LocalDependency.toAStructure(Document.MAIN_COPY_RULE); LocalDependency<FolderStatus> archivisticTypeParam = LocalDependency.toAnEnum(Document.FOLDER_ARCHIVISTIC_STATUS); ConfigDependency<DecommissioningDateBasedOn> decommissioningDateBasedOnParam = RMConfigs.DECOMMISSIONING_DATE_BASED_ON.dependency(); ConfigDependency<Integer> numberOfYearWhenInactiveVariableDelayParam = RMConfigs.CALCULATED_INACTIVE_DATE_NUMBER_OF_YEAR_WHEN_VARIABLE_PERIOD.dependency(); ConfigDependency<Integer> numberOfYearWhenSemiActiveVariableDelayParam = RMConfigs.CALCULATED_SEMIACTIVE_DATE_NUMBER_OF_YEAR_WHEN_VARIABLE_PERIOD.dependency(); ConfigDependency<Integer> requiredDaysBeforeYearEndParam = RMConfigs.REQUIRED_DAYS_BEFORE_YEAR_END_FOR_NOT_ADDING_A_YEAR .dependency(); ConfigDependency<Boolean> documentRetentionRulesEnabledParam = RMConfigs.DOCUMENT_RETENTION_RULES.dependency(); ConfigDependency<Boolean> calculatedMetadatasBasedOnFirstTimerangePartParam = RMConfigs.CALCULATED_METADATAS_BASED_ON_FIRST_TIMERANGE_PART .dependency(); ReferenceDependency<RetentionRuleScope> retentionRuleScopeParam = ReferenceDependency .toAnEnum(Document.FOLDER_RETENTION_RULE, SCOPE); LocalDependency<String> documentTypeParam = LocalDependency.toAReference(Document.TYPE); DocumentDecomDatesDynamicLocalDependency datesAndDateTimesParam = new DocumentDecomDatesDynamicLocalDependency(); @Override public LocalDate calculate(CalculatorParameters parameters) { CalculatorInput input = new CalculatorInput(parameters); if (!input.documentRetentionRulesEnabled || (input.retentionRuleScope != DOCUMENTS && input.documentType == null)) { if (input.disposalType == DEPOSIT) { return input.folderExpectedDepositDate; } else { return input.folderExpectedDestructionDate; } } else if (input.actualDepositDate != null || input.actualDestructionDate != null || !input.isCalculated()) { return null; } else { LocalDate transferDate; if (input.actualTransferDate != null) { transferDate = input.adjustToFinancialYear(input.actualTransferDate); } else { transferDate = input.expectedTransferDate; } LocalDate baseDate; if (input.copy.getSemiActiveRetentionPeriod().isZero()) { baseDate = getBaseAjustedDate(input); baseDate = input.calculateInactiveBasedOn(baseDate); return max(transferDate, baseDate); } else { LocalDate baseDateFromDelay = input.getAdjustedBaseDateFromSemiActiveDelay(parameters.get(yearEndParam)); if (!input.copy.isIgnoreActivePeriod()) { baseDateFromDelay = CalculatorUtils.calculateExpectedTransferDate(input.copy, baseDateFromDelay, input.numberOfYearWhenSemiActiveVariableDelay); } baseDate = max(transferDate, baseDateFromDelay); return input.calculateInactiveBasedOn(baseDate); } } } ConfigDependency<String> yearEndParam = RMConfigs.YEAR_END_DATE.dependency(); private LocalDate getBaseAjustedDate(CalculatorInput input) { if (input.preferedDecommissioningDateBasedOn == OPEN_DATE || input.folderCloseDate == null) { return input.adjustToFinancialYear(input.folderOpenDate); } else { return input.folderCloseDate; } } @Override public LocalDate getDefaultValue() { return null; } @Override public MetadataValueType getReturnType() { return MetadataValueType.DATE; } @Override public boolean isMultiValue() { return false; } @Override public List<? extends Dependency> getDependencies() { return asList(folderOpenDateParam, folderCloseDateParam, actualTransferDateParam, copyParam, decommissioningDateBasedOnParam, numberOfYearWhenInactiveVariableDelayParam, yearEndParam, requiredDaysBeforeYearEndParam, folderExpectedDestructionDateParam, folderExpectedDepositDateParam, expectedTransferDateParam, documentRetentionRulesEnabledParam, archivisticTypeParam, actualDepositDateParam, actualDestructionDateParam, numberOfYearWhenSemiActiveVariableDelayParam, numberOfYearWhenInactiveVariableDelayParam, datesAndDateTimesParam, calculatedMetadatasBasedOnFirstTimerangePartParam, retentionRuleScopeParam, documentTypeParam); } private class CalculatorInput { LocalDate folderOpenDate; LocalDate folderCloseDate; LocalDate folderExpectedDestructionDate; LocalDate folderExpectedDepositDate; LocalDate expectedTransferDate; DecommissioningDateBasedOn preferedDecommissioningDateBasedOn; CopyRetentionRule copy; LocalDate actualTransferDate; LocalDate actualDepositDate; LocalDate actualDestructionDate; int numberOfYearWhenInactiveVariableDelay; int numberOfYearWhenSemiActiveVariableDelay; String yearEnd; int requiredDaysBeforeYearEnd; boolean documentRetentionRulesEnabled; DisposalType disposalType; FolderStatus archivisticType; DynamicDependencyValues datesAndDateTimes; boolean calculatedMetadatasBasedOnFirstTimerangePart; RetentionRuleScope retentionRuleScope; String documentType; public CalculatorInput(CalculatorParameters parameters) { this.expectedTransferDate = parameters.get(expectedTransferDateParam); this.folderOpenDate = parameters.get(folderOpenDateParam); this.folderCloseDate = parameters.get(folderCloseDateParam); this.preferedDecommissioningDateBasedOn = parameters.get(decommissioningDateBasedOnParam); this.copy = parameters.get(copyParam); this.actualTransferDate = parameters.get(actualTransferDateParam); this.numberOfYearWhenSemiActiveVariableDelay = parameters.get(numberOfYearWhenSemiActiveVariableDelayParam); this.numberOfYearWhenInactiveVariableDelay = parameters.get(numberOfYearWhenInactiveVariableDelayParam); this.yearEnd = parameters.get(yearEndParam); this.requiredDaysBeforeYearEnd = parameters.get(requiredDaysBeforeYearEndParam); this.folderExpectedDestructionDate = parameters.get(folderExpectedDestructionDateParam); this.folderExpectedDepositDate = parameters.get(folderExpectedDepositDateParam); this.documentRetentionRulesEnabled = parameters.get(documentRetentionRulesEnabledParam); this.archivisticType = parameters.get(archivisticTypeParam); this.disposalType = getCalculatedDisposalType(); this.actualDepositDate = parameters.get(actualDepositDateParam); this.actualDestructionDate = parameters.get(actualDestructionDateParam); this.datesAndDateTimes = parameters.get(datesAndDateTimesParam); this.calculatedMetadatasBasedOnFirstTimerangePart = parameters.get(calculatedMetadatasBasedOnFirstTimerangePartParam); this.retentionRuleScope = parameters.get(retentionRuleScopeParam); this.documentType = parameters.get(documentTypeParam); } LocalDate calculateInactiveBasedOn(LocalDate baseDate) { return CalculatorUtils.calculateExpectedInactiveDate(copy, baseDate, numberOfYearWhenInactiveVariableDelay); } LocalDate adjustToFinancialYear(LocalDate date) { return CalculatorUtils.toNextEndOfYearDateIfNotAlready(date, yearEnd, requiredDaysBeforeYearEnd); } public boolean isCalculated() { if (disposalType == DEPOSIT) { return copy != null && copy.getInactiveDisposalType() != DESTRUCTION; } else { return copy != null && copy.getInactiveDisposalType() != DEPOSIT; } } public LocalDate getAdjustedBaseDateFromSemiActiveDelay(String yearEnd) { String metadata = copy.getSemiActiveDateMetadata(); if (metadata != null && metadata.startsWith("folder_")) { return null; } LocalDate date = datesAndDateTimesParam .getDate(metadata, datesAndDateTimes, yearEnd, calculatedMetadatasBasedOnFirstTimerangePart); if (date == null) { return null; } else { return adjustToFinancialYear(date); } } } protected abstract DisposalType getCalculatedDisposalType(); }