package com.constellio.app.modules.rm.services.decommissioning;
import com.constellio.app.modules.rm.RMConfigs;
import com.constellio.app.modules.rm.RMEmailTemplateConstants;
import com.constellio.app.modules.rm.constants.RMPermissionsTo;
import com.constellio.app.modules.rm.constants.RMTaxonomies;
import com.constellio.app.modules.rm.model.CopyRetentionRule;
import com.constellio.app.modules.rm.model.RetentionPeriod;
import com.constellio.app.modules.rm.model.enums.*;
import com.constellio.app.modules.rm.navigation.RMNavigationConfiguration;
import com.constellio.app.modules.rm.services.RMSchemasRecordsServices;
import com.constellio.app.modules.rm.services.borrowingServices.BorrowingType;
import com.constellio.app.modules.rm.wrappers.*;
import com.constellio.app.modules.rm.wrappers.structures.Comment;
import com.constellio.app.modules.rm.wrappers.structures.FolderDetailWithType;
import com.constellio.app.services.factories.AppLayerFactory;
import com.constellio.data.utils.LangUtils;
import com.constellio.data.utils.TimeProvider;
import com.constellio.model.entities.Taxonomy;
import com.constellio.model.entities.records.Content;
import com.constellio.model.entities.records.Record;
import com.constellio.model.entities.records.Transaction;
import com.constellio.model.entities.records.wrappers.EmailToSend;
import com.constellio.model.entities.records.wrappers.User;
import com.constellio.model.entities.records.wrappers.UserDocument;
import com.constellio.model.entities.records.wrappers.UserFolder;
import com.constellio.model.entities.schemas.Metadata;
import com.constellio.model.entities.schemas.MetadataSchema;
import com.constellio.model.entities.schemas.MetadataSchemaTypes;
import com.constellio.model.entities.schemas.Schemas;
import com.constellio.model.entities.structures.EmailAddress;
import com.constellio.model.extensions.ModelLayerCollectionExtensions;
import com.constellio.model.extensions.events.schemas.PutSchemaRecordsInTrashEvent;
import com.constellio.model.services.contents.ContentManager;
import com.constellio.model.services.contents.ContentVersionDataSummary;
import com.constellio.model.services.extensions.ModelLayerExtensions;
import com.constellio.model.services.factories.ModelLayerFactory;
import com.constellio.model.services.logging.LoggingServices;
import com.constellio.model.services.migrations.ConstellioEIMConfigs;
import com.constellio.model.services.records.RecordServices;
import com.constellio.model.services.records.RecordServicesException;
import com.constellio.model.services.schemas.MetadataSchemasManager;
import com.constellio.model.services.search.SearchServices;
import com.constellio.model.services.search.StatusFilter;
import com.constellio.model.services.search.query.ReturnedMetadatasFilter;
import com.constellio.model.services.search.query.logical.LogicalSearchQuery;
import com.constellio.model.services.search.query.logical.LogicalSearchQueryOperators;
import com.constellio.model.services.search.query.logical.condition.LogicalSearchCondition;
import com.constellio.model.services.taxonomies.*;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.LocalDate;
import org.joda.time.LocalDateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import static com.constellio.app.modules.rm.constants.RMTaxonomies.ADMINISTRATIVE_UNITS;
import static com.constellio.app.ui.i18n.i18n.$;
import static com.constellio.model.services.search.query.logical.LogicalSearchQueryOperators.from;
public class DecommissioningService {
private static Logger LOGGER = LoggerFactory.getLogger(DecommissioningService.class);
private final AppLayerFactory appLayerFactory;
private final ModelLayerFactory modelLayerFactory;
private final RecordServices recordServices;
private final RMSchemasRecordsServices rm;
private final TaxonomiesSearchServices taxonomiesSearchServices;
private final ConceptNodesTaxonomySearchServices conceptNodesTaxonomySearchServices;
private final TaxonomiesManager taxonomiesManager;
private final SearchServices searchServices;
private final String collection;
private final RMConfigs configs;
private final DecommissioningEmailService emailService;
private final ConstellioEIMConfigs eimConfigs;
private final MetadataSchemasManager metadataSchemasManager;
private final LoggingServices loggingServices;
public DecommissioningService(String collection, AppLayerFactory appLayerFactory) {
this.collection = collection;
this.appLayerFactory = appLayerFactory;
this.modelLayerFactory = appLayerFactory.getModelLayerFactory();
this.rm = new RMSchemasRecordsServices(collection, appLayerFactory);
this.taxonomiesSearchServices = modelLayerFactory.newTaxonomiesSearchService();
this.conceptNodesTaxonomySearchServices = new ConceptNodesTaxonomySearchServices(modelLayerFactory);
this.taxonomiesManager = modelLayerFactory.getTaxonomiesManager();
this.recordServices = modelLayerFactory.newRecordServices();
this.searchServices = modelLayerFactory.newSearchServices();
this.configs = new RMConfigs(modelLayerFactory.getSystemConfigurationsManager());
this.emailService = new DecommissioningEmailService(collection, modelLayerFactory);
this.eimConfigs = new ConstellioEIMConfigs(modelLayerFactory.getSystemConfigurationsManager());
this.metadataSchemasManager = modelLayerFactory.getMetadataSchemasManager();
this.loggingServices = modelLayerFactory.newLoggingServices();
}
public DecommissioningList createDecommissioningList(DecommissioningListParams params, User user) {
DecommissioningList decommissioningList = rm.newDecommissioningList()
.setTitle(params.getTitle())
.setDescription(params.getDescription())
.setAdministrativeUnit(params.getAdministrativeUnit())
.setDecommissioningListType(params.getSearchType().toDecomListType())
.setOriginArchivisticStatus(
params.getSearchType().isFromSemiActive() ? OriginStatus.SEMI_ACTIVE : OriginStatus.ACTIVE);
List<String> recordIds = params.getSelectedRecordIds();
if (decommissioningList.getDecommissioningListType().isDocumentList()) {
decommissioningList.setDocuments(recordIds);
} else if (params.getSearchType().isFromSemiActive()) {
List<ContainerRecord> containers = getContainersOfFolders(recordIds);
List<Folder> folders = getFolders(recordIds);
if (!configs.areMixedContainersAllowed()) {
folders.addAll(getFoldersInContainers(containers));
folders = LangUtils.withoutDuplicates(folders);
}
decommissioningList.setFolderDetailsFor(folders);
decommissioningList.setContainerDetailsFrom(containers);
} else {
decommissioningList.setFolderDetailsFor(rm.getFolders(recordIds));
}
try {
recordServices.add(decommissioningList, user);
} catch (RecordServicesException e) {
// TODO: Proper exception
throw new RuntimeException(e);
}
return decommissioningList;
}
public ModelLayerFactory getModelLayerFactory() {
return modelLayerFactory;
}
public RMSchemasRecordsServices getRMSchemasRecordServices() {
return rm;
}
public RMConfigs getRMConfigs() {
return configs;
}
public boolean isEditable(DecommissioningList decommissioningList, User user) {
return decommissioningList.isUnprocessed() && securityService().canModify(decommissioningList, user);
}
public boolean isDeletable(DecommissioningList decommissioningList, User user) {
return decommissioningList.isUnprocessed() && securityService().canDelete(decommissioningList, user);
}
public boolean isProcessable(DecommissioningList decommissioningList, User user) {
return decommissioningList.getDecommissioningListType().isFolderList() ?
isFolderListProcessable(decommissioningList, user) :
isDocumentListProcessable(decommissioningList, user);
}
private boolean isFolderListProcessable(DecommissioningList decommissioningList, User user) {
return decommissioningList.isUnprocessed() &&
areAllFoldersProcessable(decommissioningList) &&
isApprovedOrDoesNotNeedApproval(decommissioningList) &&
securityService().canProcess(decommissioningList, user);
}
private boolean isDocumentListProcessable(DecommissioningList decommissioningList, User user) {
return decommissioningList.isUnprocessed() && securityService().canProcess(decommissioningList, user);
}
private boolean isApprovedOrDoesNotNeedApproval(DecommissioningList decommissioningList) {
switch (decommissioningList.getStatus()) {
case APPROVED:
return true;
case IN_APPROVAL:
case IN_VALIDATION:
return false;
}
if (decommissioningList.getDecommissioningListType().isClosing()) {
return !configs.isApprovalRequiredForClosing();
}
if (decommissioningList.getDecommissioningListType().isTransfert()) {
return !configs.isApprovalRequiredForTransfer();
}
if (decommissioningList.getDecommissioningListType().isDeposit()) {
return decommissioningList.isFromActive() ?
!configs.isApprovalRequiredForDepositOfActive() :
!configs.isApprovalRequiredForDepositOfSemiActive();
}
if (decommissioningList.getDecommissioningListType().isDestroyal()) {
return decommissioningList.isFromActive() ?
!configs.isApprovalRequiredForDestructionOfActive() :
!configs.isApprovalRequiredForDestructionOfSemiActive();
}
return false;
}
public boolean isApprovalRequestPossible(DecommissioningList decommissioningList, User user) {
return decommissioningList.getStatus() != DecomListStatus.IN_VALIDATION &&
decommissioningList.getStatus() != DecomListStatus.APPROVED &&
decommissioningList.getStatus() != DecomListStatus.PROCESSED &&
decommissioningList.getStatus() != DecomListStatus.IN_APPROVAL &&
securityService().canAskApproval(decommissioningList, user);
}
public boolean isApprovalPossible(DecommissioningList decommissioningList, User user) {
return decommissioningList.getStatus() != DecomListStatus.IN_VALIDATION &&
decommissioningList.getStatus() == DecomListStatus.IN_APPROVAL &&
!decommissioningList.getApprovalRequest().equals(user.getId()) &&
securityService().canApprove(decommissioningList, user);
}
public boolean isValidationPossible(DecommissioningList decommissioningList, User user) {
return decommissioningList.getStatus() == DecomListStatus.IN_VALIDATION &&
securityService().canValidate(decommissioningList, user);
}
public boolean isValidationRequestPossible(DecommissioningList decommissioningList, User user) {
return decommissioningList.getStatus() != DecomListStatus.APPROVED &&
decommissioningList.getStatus() != DecomListStatus.PROCESSED &&
securityService().canAskValidation(decommissioningList, user);
}
public boolean isSortable(DecommissioningList decommissioningList) {
return decommissioningList.isToInactive() && hasFoldersToSort(decommissioningList);
}
public boolean canEditContainers(DecommissioningList decommissioningList, User user) {
return isEditable(decommissioningList, user) && needsPacking(decommissioningList);
}
public boolean isFolderProcessable(DecommissioningList decommissioningList, FolderDetailWithType folder) {
return decommissioningList.isProcessed() || folder.getDecommissioningType().isClosureOrDestroyal() ||
(isFolderProcessable(folder) && !isFolderRepackable(decommissioningList, folder));
}
public boolean isFolderRemovableFromContainer(DecommissioningList decommissioningList, FolderDetailWithType folder) {
return !decommissioningList.isProcessed() && !folder.getDecommissioningType().isClosureOrDestroyal() && isRemovableFromContainer(decommissioningList, folder);
}
public boolean isApproved(DecommissioningList decommissioningList) {
return decommissioningList.isApproved();
}
public boolean isValidationRequestedFor(DecommissioningList decommissioningList, User user) {
return securityService().canValidate(decommissioningList, user);
}
public void approveList(DecommissioningList decommissioningList, User user) {
decommissioner(decommissioningList).approve(decommissioningList, user, TimeProvider.getLocalDate());
}
public void approvalRequest(DecommissioningList decommissioningList, User approvalUser)
throws DecommissioningEmailServiceException, RecordServicesException {
List<String> parameters = new ArrayList<>();
parameters.add("decomList" + EmailToSend.PARAMETER_SEPARATOR + decommissioningList.getTitle());
sendEmailForList(decommissioningList, approvalUser, RMEmailTemplateConstants.APPROVAL_REQUEST_TEMPLATE_ID, parameters);
try {
decommissioningList.setApprovalRequest(approvalUser);
decommissioningList.setApprovalRequestDate(new LocalDate());
Transaction transaction = new Transaction().setUser(approvalUser);
transaction.add(decommissioningList);
recordServices.execute(transaction);
} catch (RecordServicesException e) {
throw new RuntimeException(e);
}
}
public void sendEmailForList(DecommissioningList list, User user, String templateID, List<String> parameters) {
EmailToSend emailToSend = rm.newEmailToSend();
try {
List<EmailAddress> toAddresses = getEmailReceivers(emailService.getManagerEmailForList(list));
emailToSend.setSubject($("DecommissionningServices.approvalRequest"))
.setSendOn(TimeProvider.getLocalDateTime())
.setParameters(parameters)
.setTemplate(templateID)
.setTo(toAddresses)
.setTryingCount(0d);
Transaction transaction = new Transaction().setUser(user);
transaction.add(emailToSend);
recordServices.execute(transaction);
} catch (DecommissioningEmailServiceException e) {
//TODO Display error cant find manager email
} catch (RecordServicesException e) {
//TODO Display error about email
throw new RuntimeException(e);
}
}
public void sendValidationRequest(DecommissioningList list, User sender, List<String> users, String comments, boolean saveComment) {
List<String> parameters = new ArrayList<>();
List<Comment> commentaires = new ArrayList<>();
parameters.add("decomList" + EmailToSend.PARAMETER_SEPARATOR + list.getTitle());
parameters.add("comments" + EmailToSend.PARAMETER_SEPARATOR + comments);
sendEmailForList(list, null, RMEmailTemplateConstants.VALIDATION_REQUEST_TEMPLATE_ID, parameters);
for (String user : users) {
list.addValidationRequest(user, TimeProvider.getLocalDate());
}
for (Comment comment : list.getComments()) {
commentaires.add(comment);
}
if (saveComment) {
Comment comment = new Comment();
comment.setMessage(comments);
comment.setUser(sender);
comment.setDateTime(LocalDateTime.now());
commentaires.add(comment);
list.setComments(commentaires);
}
try {
recordServices.update(list, sender);
} catch (RecordServicesException e) {
throw new RuntimeException(e);
}
}
private List<EmailAddress> getEmailReceivers(List<User> managersList) {
List<EmailAddress> returnAddresses = new ArrayList<>();
if (managersList == null) {
return returnAddresses;
}
for (User currentManager : managersList) {
returnAddresses.add(new EmailAddress(currentManager.getTitle(), currentManager.getEmail()));
}
return returnAddresses;
}
public void decommission(DecommissioningList decommissioningList, User user) {
decommissioner(decommissioningList).process(decommissioningList, user, TimeProvider.getLocalDate());
}
public void recycleContainer(ContainerRecord container, User user) {
Transaction transaction = new Transaction().setUser(user);
for (Folder folder : getFoldersInContainers(container)) {
transaction.add(folder.setContainer((String) null));
}
transaction.add(prepareToRecycle(container));
try {
recordServices.execute(transaction);
} catch (RecordServicesException e) {
// TODO: Proper exception
throw new RuntimeException(e);
}
}
public ContainerRecord prepareToRecycle(ContainerRecord container) {
return container.setRealTransferDate(null).setRealDepositDate(null).setFull(false).setFillRatioEntered(0.0);
}
Decommissioner decommissioner(DecommissioningList decommissioningList) {
return Decommissioner.forList(decommissioningList, this, appLayerFactory);
}
public List<Folder> getFoldersForAdministrativeUnit(String administrativeUnitId) {
LogicalSearchQuery query = new LogicalSearchQuery(
from(rm.folder.schemaType()).where(rm.folder.administrativeUnit()).is(administrativeUnitId))
.filteredByStatus(StatusFilter.ACTIVES)
.sortAsc(Schemas.TITLE);
return rm.wrapFolders(searchServices.search(query));
}
public List<Folder> getFoldersForClassificationPlan(String classificationPlanId) {
LogicalSearchQuery query = new LogicalSearchQuery(
from(rm.folder.schemaType()).where(rm.folder.category()).is(classificationPlanId))
.filteredByStatus(StatusFilter.ACTIVES)
.sortAsc(Schemas.TITLE);
return rm.wrapFolders(searchServices.search(query));
}
public long getFolderCountForRetentionRule(String retentionRuleId) {
LogicalSearchQuery query = new LogicalSearchQuery(
from(rm.folder.schemaType()).where(rm.folder.retentionRule()).is(retentionRuleId))
.filteredByStatus(StatusFilter.ACTIVES);
return searchServices.getResultsCount(query);
}
public List<RetentionRule> getRetentionRulesForAdministrativeUnit(String administrativeUnitId) {
Set<RetentionRule> retentionRules = new HashSet<>();
for (Folder folder : getFoldersForAdministrativeUnit(administrativeUnitId)) {
String retentionRuleId = folder.getRetentionRule();
if (retentionRuleId != null) {
Record retentionRuleRecord = rm.getRetentionRule(retentionRuleId).getWrappedRecord();
boolean deleted = retentionRuleRecord.get(Schemas.LOGICALLY_DELETED_STATUS) == null ?
false :
(Boolean) retentionRuleRecord.get(Schemas.LOGICALLY_DELETED_STATUS);
if (!deleted) {
RetentionRule retentionRule = rm.wrapRetentionRule(retentionRuleRecord);
retentionRules.add(retentionRule);
}
}
}
return new ArrayList<>(retentionRules);
}
private List<ContainerRecord> getContainersOfFolders(List<String> folderIds) {
Set<String> containerIds = new HashSet<>();
for (Record record : recordServices.getRecordsById(collection, folderIds)) {
Folder folder = rm.wrapFolder(record);
containerIds.add(folder.getContainer());
}
return rm.wrapContainerRecords(recordServices.getRecordsById(collection, new ArrayList<>(containerIds)));
}
private List<Folder> getFoldersInContainers(ContainerRecord... containers) {
return getFoldersInContainers(Arrays.asList(containers));
}
private List<Folder> getFoldersInContainers(List<ContainerRecord> containers) {
LogicalSearchQuery query = new LogicalSearchQuery(
from(rm.folder.schemaType()).where(rm.folder.container()).isIn(containers));
return rm.wrapFolders(searchServices.search(query));
}
private List<Folder> getFolders(List<String> folderIds) {
LogicalSearchQuery query = new LogicalSearchQuery(from(rm.folder.schemaType()).where(Schemas.IDENTIFIER).isIn(folderIds));
return rm.wrapFolders(searchServices.search(query));
}
private boolean needsPacking(DecommissioningList decommissioningList) {
return !decommissioningList.getDecommissioningListType().isClosingOrDestroyal() || isSortable(decommissioningList);
}
private boolean areAllFoldersProcessable(DecommissioningList decommissioningList) {
for (FolderDetailWithType folder : decommissioningList.getFolderDetailsWithType()) {
if (folder.isIncluded() && !folder.getDecommissioningType().isClosureOrDestroyal() && !isFolderProcessable(folder)) {
return false;
}
}
return true;
}
private boolean isFolderRepackable(DecommissioningList decommissioningList, FolderDetailWithType folder) {
return folder.getType().potentiallyHasAnalogMedium();
}
private boolean isRemovableFromContainer(DecommissioningList decommissioningList, FolderDetailWithType folder) {
return folder.getType().potentiallyHasAnalogMedium();
}
private boolean isFolderProcessable(FolderDetailWithType folder) {
return !(folder.getType().potentiallyHasAnalogMedium() && StringUtils.isBlank(folder.getDetail().getContainerRecordId()));
}
private boolean hasFoldersToSort(DecommissioningList decommissioningList) {
LogicalSearchCondition condition = from(rm.folder.schemaType())
.where(Schemas.IDENTIFIER).isIn(decommissioningList.getFolders())
.andWhere(rm.folder.inactiveDisposalType()).isEqualTo(DisposalType.SORT);
return searchServices.hasResults(condition);
}
public List<String> getAllAdminUnitIdsHierarchyOf(String administrativeUnitId) {
Record record = rm.getAdministrativeUnit(administrativeUnitId).getWrappedRecord();
return conceptNodesTaxonomySearchServices.getAllConceptIdsHierarchyOf(adminUnitsTaxonomy(), record);
}
public List<String> getChildrenAdministrativeUnit(String administrativeUnitId, User user) {
Record record = rm.getAdministrativeUnit(administrativeUnitId).getWrappedRecord();
return toIdList(taxonomiesSearchServices.getVisibleChildConcept(user, RMTaxonomies.ADMINISTRATIVE_UNITS,
record, new TaxonomiesSearchOptions()));
}
private List<String> toIdList(List<TaxonomySearchRecord> visibleChildConcept) {
List<String> ids = new ArrayList<>();
for (TaxonomySearchRecord record : visibleChildConcept) {
ids.add(record.getId());
}
return ids;
}
public List<String> getAdministrativeUnitsForUser(User user) {
return modelLayerFactory.newAuthorizationsServices()
.getConceptsForWhichUserHasPermission(RMPermissionsTo.PROCESS_DECOMMISSIONING_LIST, user);
}
public List<String> getRetentionRulesForCategory(String categoryId, String uniformSubdivisionId) {
return getRetentionRulesForCategory(categoryId, uniformSubdivisionId, StatusFilter.ALL);
}
public List<String> getRetentionRulesForCategory(String categoryId, String uniformSubdivisionId, StatusFilter statusFilter) {
List<String> rules = new ArrayList<>();
if (uniformSubdivisionId != null) {
UniformSubdivision uniformSubdivision = new UniformSubdivision(recordServices.getDocumentById(uniformSubdivisionId),
modelLayerFactory.getMetadataSchemasManager().getSchemaTypes(collection));
if (!uniformSubdivision.getRetentionRules().isEmpty()) {
rules.addAll(searchServices.searchRecordIds(new LogicalSearchQuery(from(rm.retentionRule.schemaType())
.where(Schemas.IDENTIFIER).isIn(uniformSubdivision.getRetentionRules())
.andWhere(Schemas.LOGICALLY_DELETED_STATUS).isFalseOrNull()).filteredByStatus(statusFilter)));
}
}
if (rules.isEmpty() && categoryId != null) {
Category category = new Category(recordServices.getDocumentById(categoryId),
modelLayerFactory.getMetadataSchemasManager().getSchemaTypes(collection));
if (!category.getRententionRules().isEmpty()) {
rules.addAll(searchServices.searchRecordIds(new LogicalSearchQuery(from(rm.retentionRule.schemaType())
.where(Schemas.IDENTIFIER).isIn(category.getRententionRules())
.andWhere(Schemas.LOGICALLY_DELETED_STATUS).isFalseOrNull()).filteredByStatus(statusFilter)));
}
}
return rules;
}
public boolean isCopyStatusInputPossible(Folder folder) {
return isCopyStatusInputPossible(folder, null);
}
public boolean isCopyStatusInputPossible(Folder folder, User folderCreator) {
boolean hasPrimaries = true;
boolean hasAdminUnits = true;
boolean isResponsibleAdministrativeUnits = false;
recordServices.recalculate(folder);
RetentionRule rule = null;
if (folder.getRetentionRule() != null) {
rule = rm.getRetentionRule(folder.getRetentionRule());
hasAdminUnits = !rule.getAdministrativeUnits().isEmpty();
hasPrimaries = !rule.getPrincipalCopies().isEmpty();
isResponsibleAdministrativeUnits = rule.isResponsibleAdministrativeUnits();
}
if (!hasPrimaries) {
return false;
}
if (configs.isCopyRuleTypeAlwaysModifiable()) {
return true;
} else {
if (hasAdminUnits && isResponsibleAdministrativeUnits) {
if (folder.getWrappedRecord().isSaved()) {
//folder modification
return true;
} else {
//folder creation
if (configs.isOpenHolder()) {
List<String> creatorAdminUnits = getUserAdminUnits(folderCreator);
Set<String> ruleUnitsAndSubUnits = getRuleHierarchyUnits(rule);
return CollectionUtils.intersection(creatorAdminUnits, ruleUnitsAndSubUnits).isEmpty();
}
}
}
}
return isResponsibleAdministrativeUnits;
}
private Set<String> getRuleHierarchyUnits(RetentionRule rule) {
Set<String> returnSet = new HashSet<>();
Taxonomy principalTaxonomy = modelLayerFactory.getTaxonomiesManager().getPrincipalTaxonomy(
rule.getCollection());
for (String unit : rule.getAdministrativeUnits()) {
List<String> currentUnits = conceptNodesTaxonomySearchServices
.getAllConceptIdsHierarchyOf(principalTaxonomy, rm.getAdministrativeUnit(unit).getWrappedRecord());
returnSet.addAll(currentUnits);
}
return returnSet;
}
private List<String> getUserAdminUnits(User user) {
List<String> returnList = new ArrayList<>();
LogicalSearchCondition condition = LogicalSearchQueryOperators.from(this.rm.administrativeUnit.schema()).returnAll();
List<Record> results = this.searchServices.search(new LogicalSearchQuery(condition).filteredWithUserWrite(user)
.setReturnedMetadatas(ReturnedMetadatasFilter.idVersionSchema()));
for (Record record : results) {
returnList.add(record.getId());
}
return returnList;
}
public boolean isTransferDateInputPossibleForUser(Folder folder, User user) {
recordServices.recalculate(folder);
CopyRetentionRule retentionRule = folder.getMainCopyRule();
boolean allowedByRetentionRule = retentionRule != null && retentionRule.canTransferToSemiActive();
return allowedByRetentionRule && user.has(RMPermissionsTo.MODIFY_FOLDER_DECOMMISSIONING_DATES).on(folder);
}
public boolean isDepositDateInputPossibleForUser(Folder folder, User user) {
recordServices.recalculate(folder);
CopyRetentionRule retentionRule = folder.getMainCopyRule();
boolean allowedByRetentionRule = retentionRule != null && retentionRule.canDeposit();
return allowedByRetentionRule && user.has(RMPermissionsTo.MODIFY_FOLDER_DECOMMISSIONING_DATES).on(folder);
}
public boolean isDestructionDateInputPossibleForUser(Folder folder, User user) {
recordServices.recalculate(folder);
CopyRetentionRule retentionRule = folder.getMainCopyRule();
boolean allowedByRetentionRule = retentionRule != null && retentionRule.canDestroy();
return allowedByRetentionRule && user.has(RMPermissionsTo.MODIFY_FOLDER_DECOMMISSIONING_DATES).on(folder);
}
public boolean isContainerInputPossibleForUser(Folder folder, User user) {
recordServices.recalculate(folder);
boolean folderIsNotActive = folder.getArchivisticStatus().isSemiActiveOrInactive();
return user.has(RMPermissionsTo.MODIFY_FOLDER_DECOMMISSIONING_DATES).on(folder)
&& (folderIsNotActive || configs.areActiveInContainersAllowed());
}
public String getUniformRuleOf(ContainerRecord container) {
boolean firstTime = true;
MetadataSchema folderSchema = rm.schema(Folder.DEFAULT_SCHEMA);
List<Record> records = getFoldersInContainer(container, folderSchema.getMetadata(Folder.RETENTION_RULE));
String retentionRule = null;
for (Record record : records) {
Folder folder = new Folder(record, modelLayerFactory.getMetadataSchemasManager().getSchemaTypes(collection));
if (firstTime) {
retentionRule = folder.getRetentionRule();
firstTime = false;
} else {
if (retentionRule != null && !retentionRule.equals(folder.getRetentionRule())) {
return null;
}
}
}
return retentionRule;
}
public LocalDate getDispositionDate(ContainerRecord container) {
LocalDate comparedDate = null;
List<Record> records = getFoldersInContainer(container, rm.folder.expectedDepositDate(),
rm.folder.expectedDestructionDate());
if(getRMConfigs().isPopulateBordereauxWithLesserDispositionDate()) {
for (Record record : records) {
comparedDate = getMinimumLocalDate(comparedDate, record);
}
} else {
for (Record record : records) {
comparedDate = getMaximalLocalDate(comparedDate, record);
}
}
return comparedDate;
}
public String getSemiActiveInterval(ContainerRecord container) {
Map<String, String> maximalIntervals = new HashMap<>();
maximalIntervals.put("fixed", null);
maximalIntervals.put("888", null);
maximalIntervals.put("999", null);
List<Record> records = getFoldersInContainer(container, rm.folder.mainCopyRule());
for (Record record : records) {
getMaximalSemiActiveInterval(maximalIntervals, record);
}
String interval = "";
String separator = "";
String fixed = maximalIntervals.get("fixed");
String variable888 = maximalIntervals.get("888");
String variable999 = maximalIntervals.get("999");
if(fixed != null) {
interval += fixed + " an(s)";
separator = " / ";
}
if(variable888 != null) {
interval += separator + variable888;
separator = " / ";
}
if(variable999 != null) {
interval += separator + variable999;
}
return interval;
}
public List<String> getMediumTypesOf(ContainerRecord container) {
Set<String> mediumTypesSet = new HashSet<>();
List<String> mediumTypes = new ArrayList<>();
List<Record> records = getFoldersInContainer(container, rm.folder.mediumTypes());
for (Record record : records) {
Folder folder = rm.wrapFolder(record);
mediumTypesSet.addAll(folder.getMediumTypes());
}
mediumTypes.addAll(mediumTypesSet);
return mediumTypes;
}
public boolean hasFolderToDeposit(ContainerRecord container) {
List<Record> records = getFoldersInContainer(container);
for (Record record : records) {
Folder folder = rm.wrapFolder(record);
if (DisposalType.DEPOSIT == folder.getMainCopyRule().getInactiveDisposalType()) {
return true;
}
}
return false;
}
public Folder newSubFolderIn(Folder parentfolder) {
Folder subFolder = rm.newFolder();
subFolder.setParentFolder(parentfolder);
subFolder.setRetentionRuleEntered(parentfolder.getRetentionRule());
subFolder.setMediumTypes(parentfolder.getMediumTypes());
subFolder.setCopyStatusEntered(parentfolder.getCopyStatusEntered());
subFolder.setOpenDate(TimeProvider.getLocalDate());
return subFolder;
}
private Taxonomy adminUnitsTaxonomy() {
return taxonomiesManager.getEnabledTaxonomyWithCode(collection, ADMINISTRATIVE_UNITS);
}
public Folder duplicateStructureAndSave(Folder folder, User currentUser) throws RecordServicesException {
return duplicateStructure(folder, currentUser, true);
}
public Folder duplicateStructure(Folder folder, User currentUser, boolean forceTitleDuplication) throws RecordServicesException {
Transaction transaction = new Transaction();
Folder duplicatedFolder = duplicateStructureAndAddToTransaction(folder, currentUser, transaction, forceTitleDuplication);
recordServices.execute(transaction);
return duplicatedFolder;
}
public Folder duplicateStructureAndDocuments(Folder folder, User currentUser, boolean forceTitleDuplication) {
Transaction transaction = new Transaction();
Folder duplicatedFolder = duplicateStructureAndDocumentsAndAddToTransaction(folder, currentUser, transaction, forceTitleDuplication);
try {
recordServices.execute(transaction);
} catch (RecordServicesException e) {
throw new RuntimeException(e);
}
return duplicatedFolder;
}
private Folder duplicateStructureAndAddToTransaction(Folder folder, User currentUser, Transaction transaction,
boolean forceTitleDuplication) {
Folder duplicatedFolder = duplicate(folder, currentUser, forceTitleDuplication);
transaction.add(duplicatedFolder);
List<Folder> children = rm.wrapFolders(searchServices.search(new LogicalSearchQuery()
.setCondition(from(rm.folder.schemaType()).where(rm.folder.parentFolder()).isEqualTo(folder))));
for (Folder child : children) {
Folder duplicatedChild = duplicateStructureAndAddToTransaction(child, currentUser, transaction,
forceTitleDuplication);
duplicatedChild.setTitle(child.getTitle());
duplicatedChild.setParentFolder(duplicatedFolder);
}
return duplicatedFolder;
}
private Folder duplicateStructureAndDocumentsAndAddToTransaction(Folder folder, User currentUser, Transaction transaction, boolean forceTitleDuplication) {
Folder duplicatedFolder = duplicate(folder, currentUser, forceTitleDuplication);
transaction.add(duplicatedFolder);
List<Folder> children = rm.wrapFolders(searchServices.search(new LogicalSearchQuery()
.setCondition(from(rm.folder.schemaType()).where(rm.folder.parentFolder()).isEqualTo(folder))));
for (Folder child : children) {
Folder duplicatedChild = duplicateStructureAndAddToTransaction(child, currentUser, transaction, forceTitleDuplication);
duplicatedChild.setTitle(child.getTitle());
duplicatedChild.setParentFolder(duplicatedFolder);
}
List<Document> childrenDocuments = rm.wrapDocuments(searchServices.search(new LogicalSearchQuery()
.setCondition(from(rm.document.schemaType()).where(rm.document.folder()).isEqualTo(folder))));
for (Document child : childrenDocuments) {
Document newDocument = rm.newDocument();
for(Metadata metadata: child.getSchema().getMetadatas().onlyNonSystemReserved().onlyManuals().onlyDuplicable()) {
newDocument.set(metadata, child.get(metadata));
}
newDocument.setFolder(duplicatedFolder);
transaction.add(newDocument);
}
return duplicatedFolder;
}
public Folder duplicate(Folder folder, User currentUser, boolean forceTitleDuplication) {
Folder newFolder = rm.newFolderWithType(folder.getType());
MetadataSchema schema = newFolder.getSchema();
for (Metadata metadata : schema.getMetadatas().onlyEnabled().onlyNonSystemReserved().onlyManuals().onlyDuplicable()) {
newFolder.getWrappedRecord().set(metadata, folder.getWrappedRecord().get(metadata));
}
if (folder.getSchema().getMetadata(Schemas.TITLE.getCode()).isDuplicable() || forceTitleDuplication) {
newFolder.setTitle(folder.getTitle() + " (Copie)");
}
LocalDateTime localDateTime = TimeProvider.getLocalDateTime();
newFolder.setFormCreatedBy(currentUser);
newFolder.setFormCreatedOn(localDateTime);
newFolder.setCreatedBy(currentUser.getId()).setModifiedBy(currentUser.getId());
newFolder.setCreatedOn(localDateTime).setModifiedOn(localDateTime);
return newFolder;
}
public List<RMUserFolder> getSubUserFolders(RMUserFolder userFolder) {
List<RMUserFolder> subUserFolders = new ArrayList<>();
MetadataSchema userFolderSchema = rm.userFolderSchema();
Metadata parentUserFolderMetadata = userFolderSchema.getMetadata(UserFolder.PARENT_USER_FOLDER);
LogicalSearchQuery subFoldersQuery = new LogicalSearchQuery();
subFoldersQuery.setCondition(LogicalSearchQueryOperators.from(userFolderSchema).where(parentUserFolderMetadata).isEqualTo(userFolder.getWrappedRecord()));
for (Record subFolderRecord : searchServices.search(subFoldersQuery)) {
RMUserFolder subUserFolder = rm.wrapUserFolder(subFolderRecord);
subUserFolders.add(subUserFolder);
}
return subUserFolders;
}
public List<UserDocument> getUserDocuments(RMUserFolder userFolder) {
List<UserDocument> userDocuments = new ArrayList<>();
MetadataSchema userDocumentSchema = rm.userDocumentSchema();
Metadata userFolderMetadata = userDocumentSchema.getMetadata(UserDocument.USER_FOLDER);
LogicalSearchQuery userDocumentsQuery = new LogicalSearchQuery();
userDocumentsQuery.setCondition(LogicalSearchQueryOperators.from(userDocumentSchema).where(userFolderMetadata).isEqualTo(userFolder.getWrappedRecord()));
for (Record userDocumentRecord : searchServices.search(userDocumentsQuery)) {
UserDocument userDocument = rm.wrapUserDocument(userDocumentRecord);
userDocuments.add(userDocument);
}
return userDocuments;
}
public void duplicateSubStructureAndSave(Folder folder, RMUserFolder userFolder, User currentUser) throws RecordServicesException, IOException {
Transaction transaction = new Transaction();
List<RMUserFolder> subUserFolders = getSubUserFolders(userFolder);
for (RMUserFolder subUserFolder : subUserFolders) {
duplicateStructureAndSave(subUserFolder, folder, currentUser, transaction);
}
List<UserDocument> userDocuments = getUserDocuments(userFolder);
for (UserDocument userDocument : userDocuments) {
Document document = rm.newDocument();
populateDocumentFromUserDocument(document, userDocument, currentUser);
document.setFolder(folder);
transaction.add(document);
}
recordServices.execute(transaction);
}
private void duplicateStructureAndSave(RMUserFolder userFolder, Folder parentFolder, User currentUser, Transaction transaction) throws IOException {
Folder folder = rm.newFolder();
populateFolderFromUserFolder(folder, userFolder, currentUser);
folder.setParentFolder(parentFolder);
transaction.add(folder);
List<RMUserFolder> subUserFolders = getSubUserFolders(userFolder);
for (RMUserFolder subUserFolder : subUserFolders) {
// Recursive call
duplicateStructureAndSave(subUserFolder, folder, currentUser, transaction);
}
List<UserDocument> userDocuments = getUserDocuments(userFolder);
for (UserDocument userDocument : userDocuments) {
Document document = rm.newDocument();
populateDocumentFromUserDocument(document, userDocument, currentUser);
document.setFolder(folder);
transaction.add(document);
}
}
public void populateFolderFromUserFolder(Folder folder, RMUserFolder userFolder, User currentUser) {
folder.setTitle(userFolder.getTitle());
LocalDate openDate;
if (userFolder.getFormCreatedOn() != null) {
openDate = new LocalDate(userFolder.getFormCreatedOn());
} else {
openDate = TimeProvider.getLocalDate();
}
folder.setOpenDate(openDate);
folder.setFormCreatedBy(currentUser);
folder.setFormCreatedOn(userFolder.getFormCreatedOn());
folder.setFormModifiedBy(currentUser);
folder.setFormModifiedOn(userFolder.getFormModifiedOn());
if (userFolder.getParentFolder() != null) {
folder.setParentFolder(userFolder.getParentFolder());
} else {
folder.setAdministrativeUnitEntered(userFolder.getAdministrativeUnit());
folder.setCategoryEntered(userFolder.getCategory());
folder.setRetentionRuleEntered(userFolder.getRetentionRule());
folder.setCopyStatusEntered(CopyType.PRINCIPAL);
}
}
public void populateDocumentFromUserDocument(Document document, UserDocument userDocument, User currentUser) throws IOException {
ContentManager contentManager = modelLayerFactory.getContentManager();
String filename = userDocument.getTitle();
String contentInputStreamId = userDocument.getContent().getCurrentVersion().getHash();
try (InputStream inputStream = contentManager.getContentInputStream(contentInputStreamId, "DecommissioningServices.populateDocumentFromUserDocument.in")) {
ContentVersionDataSummary contentVersion = contentManager.upload(inputStream, "DecommissioningServices.populateDocumentFromUserDocument.upload");
Content content = contentManager.createMajor(currentUser, filename, contentVersion);
document.setContent(content);
}
document.setTitle(filename);
document.setFolder(userDocument.getFolder());
document.setContent(userDocument.getContent());
document.setFormCreatedBy(currentUser);
document.setFormCreatedOn(userDocument.getFormCreatedOn());
document.setFormModifiedBy(currentUser);
document.setFormModifiedOn(userDocument.getFormModifiedOn());
}
public void deleteUserFolder(RMUserFolder userFolder, User currentUser) {
List<RMUserFolder> subUserFolders = getSubUserFolders(userFolder);
for (RMUserFolder subUserFolder : subUserFolders) {
// Recursive call
deleteUserFolder(subUserFolder, currentUser);
}
List<UserDocument> userDocuments = getUserDocuments(userFolder);
for (UserDocument userDocument : userDocuments) {
delete(userDocument.getWrappedRecord(), null, true, currentUser);
}
delete(userFolder.getWrappedRecord(), null, true, currentUser);
}
public void deleteUserDocument(UserDocument userDocument, User currentUser) {
delete(userDocument.getWrappedRecord(), null, true, currentUser);
}
private void delete(Record record, String reason, boolean physically, User user) {
boolean putFirstInTrash = putFirstInTrash(record);
if (recordServices.isLogicallyThenPhysicallyDeletable(record, user) || putFirstInTrash) {
recordServices.logicallyDelete(record, user);
modelLayerFactory.newLoggingServices().logDeleteRecordWithJustification(record, user, reason);
if (physically && !putFirstInTrash) {
recordServices.physicallyDelete(record, user);
}
}
}
private boolean putFirstInTrash(Record record) {
ModelLayerExtensions ext = modelLayerFactory.getExtensions();
if (ext == null) {
return false;
}
ModelLayerCollectionExtensions extensions = ext.forCollection(record.getCollection());
PutSchemaRecordsInTrashEvent event = new PutSchemaRecordsInTrashEvent(record.getSchemaCode());
return extensions.isPutInTrashBeforePhysicalDelete(event);
}
private List<Record> getFoldersInContainer(ContainerRecord container, Metadata... metadatas) {
LogicalSearchQuery query = new LogicalSearchQuery(
from(rm.folderSchemaType()).where(rm.folder.container()).isEqualTo(container))
.setReturnedMetadatas(ReturnedMetadatasFilter.onlyMetadatas(metadatas));
return searchServices.search(query);
}
private List<Record> getFoldersInContainer(ContainerRecord container) {
LogicalSearchQuery query = new LogicalSearchQuery(
from(rm.folderSchemaType()).where(rm.folder.container()).isEqualTo(container));
return searchServices.search(query);
}
private LocalDate getMinimumLocalDate(LocalDate minimumDate, Record record) {
Folder folder = rm.wrapFolder(record);
if (folder.getExpectedDepositDate() != null && folder.getExpectedDestructionDate() != null) {
if (folder.getExpectedDepositDate().isBefore(folder.getExpectedDestructionDate())) {
if (minimumDate != null) {
if (folder.getExpectedDepositDate().isBefore(minimumDate)) {
minimumDate = folder.getExpectedDepositDate();
}
} else {
minimumDate = folder.getExpectedDepositDate();
}
} else {
if (minimumDate != null) {
if (folder.getExpectedDestructionDate().isBefore(minimumDate)) {
minimumDate = folder.getExpectedDestructionDate();
}
} else {
minimumDate = folder.getExpectedDestructionDate();
}
}
} else if (folder.getExpectedDepositDate() != null) {
if (minimumDate != null) {
if (folder.getExpectedDepositDate().isBefore(minimumDate)) {
minimumDate = folder.getExpectedDepositDate();
}
} else {
minimumDate = folder.getExpectedDepositDate();
}
} else if (folder.getExpectedDestructionDate() != null) {
if (minimumDate != null) {
if (folder.getExpectedDestructionDate().isBefore(minimumDate)) {
minimumDate = folder.getExpectedDestructionDate();
}
} else {
minimumDate = folder.getExpectedDestructionDate();
}
}
return minimumDate;
}
private LocalDate getMaximalLocalDate(LocalDate maximalDate, Record record) {
Folder folder = rm.wrapFolder(record);
if (folder.getExpectedDepositDate() != null && folder.getExpectedDestructionDate() != null) {
if (folder.getExpectedDepositDate().isAfter(folder.getExpectedDestructionDate())) {
if (maximalDate != null) {
if (folder.getExpectedDepositDate().isAfter(maximalDate)) {
maximalDate = folder.getExpectedDepositDate();
}
} else {
maximalDate = folder.getExpectedDepositDate();
}
} else {
if (maximalDate != null) {
if (folder.getExpectedDestructionDate().isAfter(maximalDate)) {
maximalDate = folder.getExpectedDestructionDate();
}
} else {
maximalDate = folder.getExpectedDestructionDate();
}
}
} else if (folder.getExpectedDepositDate() != null) {
if (maximalDate != null) {
if (folder.getExpectedDepositDate().isAfter(maximalDate)) {
maximalDate = folder.getExpectedDepositDate();
}
} else {
maximalDate = folder.getExpectedDepositDate();
}
} else if (folder.getExpectedDestructionDate() != null) {
if (maximalDate != null) {
if (folder.getExpectedDestructionDate().isAfter(maximalDate)) {
maximalDate = folder.getExpectedDestructionDate();
}
} else {
maximalDate = folder.getExpectedDestructionDate();
}
}
return maximalDate;
}
private void getMaximalSemiActiveInterval(Map<String, String> maximalIntervals, Record record) {
Folder folder = rm.wrapFolder(record);
if (folder != null) {
CopyRetentionRule firstCopyRetentionRule = folder.getMainCopyRule();
if (firstCopyRetentionRule != null) {
RetentionPeriod retentionPeriod = firstCopyRetentionRule.getSemiActiveRetentionPeriod();
if (retentionPeriod != null) {
String interval = org.apache.commons.lang.StringUtils.defaultString(retentionPeriod.toString());
String intervalType = "fixed";
if(retentionPeriod.is888()) {
intervalType = "888";
} else if(retentionPeriod.is999()) {
intervalType = "999";
}
String maximalInterval = maximalIntervals.get(intervalType);
if(maximalInterval == null || interval.compareToIgnoreCase(maximalInterval) > 1) {
maximalIntervals.put(intervalType, interval);
}
}
}
}
}
private DecommissioningSecurityService securityService() {
return new DecommissioningSecurityService(collection, appLayerFactory);
}
public String getDecommissionningLabel(ContainerRecord record) {
return record.getDecommissioningType().getLabel();
}
public void reactivateRecordsFromTask(String taskId, LocalDate reactivationDate, User respondant, User applicant, boolean isAccepted)
throws RecordServicesException {
Record taskRecord = recordServices.getDocumentById(taskId);
RMTask task = rm.wrapRMTask(taskRecord);
String schemaType = "";
if (task.getLinkedFolders() != null) {
schemaType = Folder.SCHEMA_TYPE;
Transaction t = new Transaction();
for(String folderId: task.getLinkedFolders()) {
Folder folder = rm.getFolder(folderId);
if(isAccepted) {
t.add(folder.addReactivation(applicant, LocalDate.now()).setReactivationDecommissioningDate(reactivationDate)
.addPreviousDepositDate(folder.getActualDepositDate()).addPreviousTransferDate(folder.getActualTransferDate())
.setActualDepositDate(null).setActualTransferDate(null));
}
loggingServices.completeReactivationRequestTask(recordServices.getDocumentById(folder.getId()), task.getId(), isAccepted, applicant, respondant, task.getReason(), reactivationDate.toString());
alertUsers(RMEmailTemplateConstants.ALERT_REACTIVATED, schemaType, taskRecord, folder.getWrappedRecord(), null, null, reactivationDate, respondant, applicant, null, isAccepted);
}
recordServices.execute(t);
}
if (task.getLinkedContainers() != null) {
schemaType = ContainerRecord.SCHEMA_TYPE;
for(String containerId: task.getLinkedContainers()) {
Transaction t = new Transaction();
ContainerRecord containerRecord = rm.getContainerRecord(containerId);
List<Folder> folders = rm.searchFolders(LogicalSearchQueryOperators.from(rm.folder.schemaType()).where(rm.folder.container()).isEqualTo(containerRecord.getId()));
if(folders != null) {
for(Folder folder: folders) {
if(isAccepted && isFolderReactivable(folder, applicant)) {
t.add(folder.addReactivation(applicant, LocalDate.now()).setReactivationDecommissioningDate(reactivationDate)
.addPreviousDepositDate(folder.getActualDepositDate()).addPreviousTransferDate(folder.getActualTransferDate())
.setActualDepositDate(null).setActualTransferDate(null));
}
}
}
recordServices.execute(t);
loggingServices.completeReactivationRequestTask(recordServices.getDocumentById(containerId), task.getId(), isAccepted, applicant, respondant, task.getReason(), reactivationDate.toString());
alertUsers(RMEmailTemplateConstants.ALERT_REACTIVATED, schemaType, taskRecord, containerRecord.getWrappedRecord(), null, null, reactivationDate, respondant, applicant, null, isAccepted);
}
}
}
public boolean isFolderReactivable(Folder folder, User currentUser) {
return folder != null && folder.getArchivisticStatus().isSemiActiveOrInactive() && folder.getMediaType().potentiallyHasAnalogMedium()
&& currentUser.has(RMPermissionsTo.REACTIVATION_REQUEST_ON_FOLDER).on(folder);
}
private void alertUsers(String template, String schemaType, Record task, Record record, LocalDate borrowingDate, LocalDate returnDate, LocalDate reactivationDate, User currentUser,
User borrowerEntered, BorrowingType borrowingType, boolean isAccepted) {
try {
String displayURL = schemaType.equals(Folder.SCHEMA_TYPE) ? RMNavigationConfiguration.DISPLAY_FOLDER : RMNavigationConfiguration.DISPLAY_CONTAINER;
String subject = "";
List<String> parameters = new ArrayList<>();
Transaction transaction = new Transaction();
EmailToSend emailToSend = newEmailToSend();
EmailAddress toAddress = new EmailAddress();
subject = task.getTitle();
if (template.equals(RMEmailTemplateConstants.ALERT_BORROWED)) {
toAddress = new EmailAddress(borrowerEntered.getTitle(), borrowerEntered.getEmail());
parameters.add("borrowingType" + EmailToSend.PARAMETER_SEPARATOR + borrowingType);
parameters.add("borrowerEntered" + EmailToSend.PARAMETER_SEPARATOR + borrowerEntered);
parameters.add("borrowingDate" + EmailToSend.PARAMETER_SEPARATOR + formatDateToParameter(borrowingDate));
parameters.add("returnDate" + EmailToSend.PARAMETER_SEPARATOR + formatDateToParameter(returnDate));
} else if (template.equals(RMEmailTemplateConstants.ALERT_REACTIVATED)) {
toAddress = new EmailAddress(borrowerEntered.getTitle(), borrowerEntered.getEmail());
parameters.add("reactivationDate" + EmailToSend.PARAMETER_SEPARATOR + formatDateToParameter(reactivationDate));
} else if (template.equals(RMEmailTemplateConstants.ALERT_RETURNED)) {
toAddress = new EmailAddress(borrowerEntered.getTitle(), borrowerEntered.getEmail());
parameters.add("returnDate" + EmailToSend.PARAMETER_SEPARATOR + formatDateToParameter(returnDate));
} else if (template.equals(RMEmailTemplateConstants.ALERT_BORROWING_EXTENTED)) {
toAddress = new EmailAddress(borrowerEntered.getTitle(), borrowerEntered.getEmail());
parameters.add("extensionDate" + EmailToSend.PARAMETER_SEPARATOR + formatDateToParameter(LocalDate.now()));
parameters.add("returnDate" + EmailToSend.PARAMETER_SEPARATOR + formatDateToParameter(returnDate));
}
LocalDateTime sendDate = TimeProvider.getLocalDateTime();
emailToSend.setTo(toAddress);
emailToSend.setSendOn(sendDate);
emailToSend.setSubject(subject);
String fullTemplate = isAccepted? template+RMEmailTemplateConstants.ACCEPTED: template+RMEmailTemplateConstants.DENIED;
emailToSend.setTemplate(fullTemplate);
parameters.add("subject" + EmailToSend.PARAMETER_SEPARATOR + subject);
String recordTitle = record.getTitle();
parameters.add("title" + EmailToSend.PARAMETER_SEPARATOR + recordTitle);
parameters.add("currentUser" + EmailToSend.PARAMETER_SEPARATOR + currentUser);
String constellioUrl = eimConfigs.getConstellioUrl();
parameters.add("constellioURL" + EmailToSend.PARAMETER_SEPARATOR + constellioUrl);
parameters.add("recordURL" + EmailToSend.PARAMETER_SEPARATOR + constellioUrl + "#!" + displayURL + "/" + record.getId());
parameters.add("recordType" + EmailToSend.PARAMETER_SEPARATOR + $(schemaType).toLowerCase());
parameters.add("isAccepted" + EmailToSend.PARAMETER_SEPARATOR + $(String.valueOf(isAccepted)));
emailToSend.setParameters(parameters);
transaction.add(emailToSend);
recordServices.execute(transaction);
} catch (RecordServicesException e) {
LOGGER.error("Cannot alert user", e);
}
}
private String formatDateToParameter(LocalDate date) {
if (date == null) {
return "";
}
return date.toString("yyyy-MM-dd");
}
private EmailToSend newEmailToSend() {
MetadataSchemaTypes types = metadataSchemasManager.getSchemaTypes(collection);
MetadataSchema schema = types.getSchemaType(EmailToSend.SCHEMA_TYPE).getDefaultSchema();
Record emailToSendRecord = recordServices.newRecordWithSchema(schema);
return new EmailToSend(emailToSendRecord, types);
}
}