package com.constellio.app.modules.rm.ui.pages.folder;
import static com.constellio.app.ui.i18n.i18n.$;
import static com.constellio.model.services.search.query.logical.LogicalSearchQueryOperators.from;
import static java.util.Arrays.asList;
import static org.apache.commons.lang.StringUtils.isNotBlank;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
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 com.constellio.app.api.extensions.taxonomies.FolderDeletionEvent;
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.model.enums.DefaultTabInFolderDisplay;
import com.constellio.app.modules.rm.model.labelTemplate.LabelTemplate;
import com.constellio.app.modules.rm.navigation.RMViews;
import com.constellio.app.modules.rm.services.RMSchemasRecordsServices;
import com.constellio.app.modules.rm.services.borrowingServices.BorrowingServices;
import com.constellio.app.modules.rm.services.borrowingServices.BorrowingType;
import com.constellio.app.modules.rm.services.decommissioning.DecommissioningService;
import com.constellio.app.modules.rm.services.events.RMEventsSearchServices;
import com.constellio.app.modules.rm.ui.builders.DocumentToVOBuilder;
import com.constellio.app.modules.rm.ui.builders.FolderToVOBuilder;
import com.constellio.app.modules.rm.ui.components.breadcrumb.FolderDocumentBreadcrumbTrail;
import com.constellio.app.modules.rm.ui.components.content.ConstellioAgentClickHandler;
import com.constellio.app.modules.rm.ui.entities.DocumentVO;
import com.constellio.app.modules.rm.ui.entities.FolderVO;
import com.constellio.app.modules.rm.ui.util.ConstellioAgentUtils;
import com.constellio.app.modules.rm.wrappers.Cart;
import com.constellio.app.modules.rm.wrappers.ContainerRecord;
import com.constellio.app.modules.rm.wrappers.Document;
import com.constellio.app.modules.rm.wrappers.Folder;
import com.constellio.app.modules.rm.wrappers.RMTask;
import com.constellio.app.modules.tasks.TasksPermissionsTo;
import com.constellio.app.modules.tasks.model.wrappers.Task;
import com.constellio.app.modules.tasks.model.wrappers.Workflow;
import com.constellio.app.modules.tasks.navigation.TaskViews;
import com.constellio.app.modules.tasks.services.TasksSchemasRecordsServices;
import com.constellio.app.modules.tasks.services.WorkflowServices;
import com.constellio.app.services.factories.ConstellioFactories;
import com.constellio.app.ui.entities.ContentVersionVO;
import com.constellio.app.ui.entities.ContentVersionVO.InputStreamProvider;
import com.constellio.app.ui.entities.MetadataSchemaVO;
import com.constellio.app.ui.entities.RecordVO;
import com.constellio.app.ui.entities.RecordVO.VIEW_MODE;
import com.constellio.app.ui.framework.builders.EventToVOBuilder;
import com.constellio.app.ui.framework.builders.MetadataSchemaToVOBuilder;
import com.constellio.app.ui.framework.builders.RecordToVOBuilder;
import com.constellio.app.ui.framework.components.ComponentState;
import com.constellio.app.ui.framework.data.RecordVODataProvider;
import com.constellio.app.ui.pages.base.SchemaPresenterUtils;
import com.constellio.app.ui.pages.base.SessionContext;
import com.constellio.app.ui.pages.base.SingleSchemaBasePresenter;
import com.constellio.data.utils.TimeProvider;
import com.constellio.model.entities.CorePermissions;
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.schemas.Metadata;
import com.constellio.model.entities.schemas.MetadataSchema;
import com.constellio.model.entities.schemas.MetadataSchemaType;
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.services.configs.SystemConfigurationsManager;
import com.constellio.model.services.contents.icap.IcapException;
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.logical.LogicalSearchQuery;
import com.constellio.model.services.search.query.logical.condition.LogicalSearchCondition;
import com.constellio.model.services.security.AuthorizationsServices;
public class DisplayFolderPresenter extends SingleSchemaBasePresenter<DisplayFolderView> {
private static Logger LOGGER = LoggerFactory.getLogger(DisplayFolderPresenter.class);
private RecordVODataProvider documentsDataProvider;
private RecordVODataProvider tasksDataProvider;
private RecordVODataProvider subFoldersDataProvider;
private RecordVODataProvider eventsDataProvider;
private MetadataSchemaToVOBuilder schemaVOBuilder = new MetadataSchemaToVOBuilder();
private FolderToVOBuilder folderVOBuilder;
private DocumentToVOBuilder documentVOBuilder;
private SchemaPresenterUtils schemaPresenterUtils;
private FolderVO folderVO;
private transient RMConfigs rmConfigs;
private transient RMSchemasRecordsServices rmSchemasRecordsServices;
private transient BorrowingServices borrowingServices;
private transient MetadataSchemasManager metadataSchemasManager;
private transient RecordServices recordServices;
private transient ModelLayerCollectionExtensions extensions;
Boolean allItemsSelected = false;
Boolean allItemsDeselected = false;
public DisplayFolderPresenter(DisplayFolderView view) {
super(view, Folder.DEFAULT_SCHEMA);
ConstellioFactories constellioFactories = view.getConstellioFactories();
SessionContext sessionContext = view.getSessionContext();
schemaPresenterUtils = new SchemaPresenterUtils(Folder.DEFAULT_SCHEMA, constellioFactories, sessionContext);
initTransientObjects();
}
private void readObject(java.io.ObjectInputStream stream)
throws IOException, ClassNotFoundException {
stream.defaultReadObject();
initTransientObjects();
}
private void initTransientObjects() {
rmSchemasRecordsServices = new RMSchemasRecordsServices(collection, appLayerFactory);
borrowingServices = new BorrowingServices(collection, modelLayerFactory);
folderVOBuilder = new FolderToVOBuilder();
documentVOBuilder = new DocumentToVOBuilder(modelLayerFactory);
metadataSchemasManager = modelLayerFactory.getMetadataSchemasManager();
recordServices = modelLayerFactory.newRecordServices();
extensions = modelLayerFactory.getExtensions().forCollection(collection);
rmConfigs = new RMConfigs(modelLayerFactory.getSystemConfigurationsManager());
}
@Override
protected boolean hasPageAccess(String params, User user) {
return true;
}
public void forParams(String params) {
String id = params;
String taxonomyCode = view.getUIContext().getAttribute(FolderDocumentBreadcrumbTrail.TAXONOMY_CODE);
view.setTaxonomyCode(taxonomyCode);
Record record = getRecord(id);
this.folderVO = folderVOBuilder.build(record, VIEW_MODE.DISPLAY, view.getSessionContext());
setSchemaCode(record.getSchemaCode());
view.setRecord(folderVO);
MetadataSchema documentsSchema = getDocumentsSchema();
MetadataSchemaVO documentsSchemaVO = schemaVOBuilder.build(documentsSchema, VIEW_MODE.TABLE, view.getSessionContext());
documentsDataProvider = new RecordVODataProvider(
documentsSchemaVO, documentVOBuilder, modelLayerFactory, view.getSessionContext()) {
@Override
protected LogicalSearchQuery getQuery() {
return getDocumentsQuery();
}
};
MetadataSchemaVO foldersSchemaVO = schemaVOBuilder.build(defaultSchema(), VIEW_MODE.TABLE, view.getSessionContext());
subFoldersDataProvider = new RecordVODataProvider(
foldersSchemaVO, folderVOBuilder, modelLayerFactory, view.getSessionContext()) {
@Override
protected LogicalSearchQuery getQuery() {
return getSubFoldersQuery();
}
};
MetadataSchemaVO tasksSchemaVO = schemaVOBuilder.build(getTasksSchema(), VIEW_MODE.TABLE, view.getSessionContext());
tasksDataProvider = new RecordVODataProvider(
tasksSchemaVO, folderVOBuilder, modelLayerFactory, view.getSessionContext()) {
@Override
protected LogicalSearchQuery getQuery() {
return getTasksQuery();
}
};
eventsDataProvider = getEventsDataProvider();
computeAllItemsSelected();
}
private LogicalSearchQuery getDocumentsQuery() {
Record record = getRecord(folderVO.getId());
MetadataSchemaType documentsSchemaType = getDocumentsSchemaType();
MetadataSchema documentsSchema = getDocumentsSchema();
Metadata folderMetadata = documentsSchema.getMetadata(Document.FOLDER);
LogicalSearchQuery query = new LogicalSearchQuery();
LogicalSearchCondition condition = from(documentsSchemaType).where(folderMetadata).is(record);
query.setCondition(condition);
query.filteredWithUser(getCurrentUser());
query.filteredByStatus(StatusFilter.ACTIVES);
query.sortAsc(Schemas.TITLE);
return query;
}
private LogicalSearchQuery getSubFoldersQuery() {
Record record = getRecord(folderVO.getId());
MetadataSchemaType foldersSchemaType = getFoldersSchemaType();
MetadataSchema foldersSchema = getFoldersSchema();
Metadata parentFolderMetadata = foldersSchema.getMetadata(Folder.PARENT_FOLDER);
LogicalSearchQuery query = new LogicalSearchQuery();
query.setCondition(from(foldersSchemaType).where(parentFolderMetadata).is(record));
query.filteredWithUser(getCurrentUser());
query.filteredByStatus(StatusFilter.ACTIVES);
query.sortAsc(Schemas.TITLE);
return query;
}
private LogicalSearchQuery getTasksQuery() {
TasksSchemasRecordsServices tasks = new TasksSchemasRecordsServices(collection, appLayerFactory);
Metadata taskFolderMetadata = tasks.userTask.schema().getMetadata(RMTask.LINKED_FOLDERS);
LogicalSearchQuery query = new LogicalSearchQuery();
query.setCondition(from(tasks.userTask.schemaType()).where(taskFolderMetadata).is(folderVO.getId()));
query.filteredByStatus(StatusFilter.ACTIVES);
query.filteredWithUser(getCurrentUser());
query.sortDesc(Schemas.MODIFIED_ON);
return query;
}
public void selectInitialTabForUser() {
SystemConfigurationsManager systemConfigurationsManager = modelLayerFactory.getSystemConfigurationsManager();
RMConfigs rmConfigs = new RMConfigs(systemConfigurationsManager);
String userDefaultTabInFolderDisplayCode = getCurrentUser().getDefaultTabInFolderDisplay();
String configDefaultTabInFolderDisplayCode = rmConfigs.getDefaultTabInFolderDisplay();
String defaultTabInFolderDisplayCode = StringUtils.isNotBlank(userDefaultTabInFolderDisplayCode) ?
userDefaultTabInFolderDisplayCode :
configDefaultTabInFolderDisplayCode;
if (isNotBlank(defaultTabInFolderDisplayCode)) {
if (DefaultTabInFolderDisplay.METADATA.getCode().equals(defaultTabInFolderDisplayCode)) {
view.selectMetadataTab();
} else if (DefaultTabInFolderDisplay.CONTENT.getCode().equals(defaultTabInFolderDisplayCode)) {
view.selectFolderContentTab();
}
}
}
public int getFolderContentCount() {
return subFoldersDataProvider.size() + documentsDataProvider.size();
}
public int getTaskCount() {
return tasksDataProvider.size();
}
public RecordVODataProvider getWorkflows() {
MetadataSchemaVO schemaVO = new MetadataSchemaToVOBuilder().build(
schema(Workflow.DEFAULT_SCHEMA), VIEW_MODE.TABLE, view.getSessionContext());
return new RecordVODataProvider(schemaVO, new RecordToVOBuilder(), modelLayerFactory, view.getSessionContext()) {
@Override
protected LogicalSearchQuery getQuery() {
return new WorkflowServices(view.getCollection(), appLayerFactory).getWorkflowsQuery();
}
};
}
public void workflowStartRequested(RecordVO record) {
Map<String, List<String>> parameters = new HashMap<>();
parameters.put(RMTask.LINKED_FOLDERS, asList(folderVO.getId()));
Workflow workflow = new TasksSchemasRecordsServices(view.getCollection(), appLayerFactory).getWorkflow(record.getId());
new WorkflowServices(view.getCollection(), appLayerFactory).start(workflow, getCurrentUser(), parameters);
}
@Override
protected boolean hasRestrictedRecordAccess(String params, User user, Record restrictedRecord) {
return user.hasReadAccess().on(restrictedRecord);
}
@Override
protected List<String> getRestrictedRecordIds(String params) {
return asList(folderVO.getId());
}
private void disableMenuItems(Folder folder) {
RMConfigs rmConfigs = new RMConfigs(modelLayerFactory.getSystemConfigurationsManager());
User user = getCurrentUser();
view.setLogicallyDeletable(getDeleteButtonState(user, folder));
view.setEditButtonState(getEditButtonState(user, folder));
view.setMoveInFolderState(getMoveInFolderButtonState(user, folder));
view.setAddSubFolderButtonState(getAddFolderButtonState(user, folder));
view.setAddDocumentButtonState(getAddDocumentButtonState(user, folder));
view.setDuplicateFolderButtonState(getDuplicateFolderButtonState(user, folder));
view.setAuthorizationButtonState(getAuthorizationButtonState(user, folder));
view.setShareFolderButtonState(getShareButtonState(user, folder));
view.setPrintButtonState(getPrintButtonState(user, folder));
view.setBorrowButtonState(getBorrowButtonState(user, folder));
view.setReturnFolderButtonState(getReturnFolderButtonState(user, folder));
view.setReminderReturnFolderButtonState(getReminderReturnFolderButtonState(user, folder));
view.setAlertWhenAvailableButtonState(getAlertWhenAvailableButtonState(user, folder));
view.setBorrowedMessage(getBorrowMessageState(folder));
view.setStartWorkflowButtonState(ComponentState.visibleIf(rmConfigs.areWorkflowsEnabled()));
}
String getBorrowMessageState(Folder folder) {
String borrowedMessage = null;
if (folder.getBorrowed() != null && folder.getBorrowed()) {
String borrowUserEntered = folder.getBorrowUserEntered();
if (borrowUserEntered != null) {
String userTitle = rmSchemasRecordsServices.getUser(borrowUserEntered).getTitle();
LocalDateTime borrowDateTime = folder.getBorrowDate();
LocalDate borrowDate = borrowDateTime != null ? borrowDateTime.toLocalDate() : null;
borrowedMessage = $("DisplayFolderView.borrowedFolder", userTitle, borrowDate);
} else {
borrowedMessage = $("DisplayFolderView.borrowedByNullUserFolder");
}
} else if (folder.getContainer() != null) {
try {
ContainerRecord containerRecord = rmSchemasRecordsServices.getContainerRecord(folder.getContainer());
boolean borrowed = Boolean.TRUE.equals(containerRecord.getBorrowed());
String borrower = containerRecord.getBorrower();
if (borrowed && borrower != null) {
String userTitle = rmSchemasRecordsServices.getUser(borrower).getTitle();
LocalDate borrowDate = containerRecord.getBorrowDate();
borrowedMessage = $("DisplayFolderView.borrowedContainer", userTitle, borrowDate);
} else if (borrowed) {
borrowedMessage = $("DisplayFolderView.borrowedByNullUserContainer");
}
} catch (Exception e) {
LOGGER.error("Could not find linked container");
}
}
return borrowedMessage;
}
protected ComponentState getBorrowButtonState(User user, Folder folder) {
try {
borrowingServices.validateCanBorrow(user, folder, null);
return ComponentState
.visibleIf(user.hasAll(RMPermissionsTo.BORROW_FOLDER, RMPermissionsTo.BORROWING_FOLDER_DIRECTLY).on(folder));
} catch (Exception e) {
return ComponentState.INVISIBLE;
}
}
private ComponentState getReturnFolderButtonState(User user, Folder folder) {
try {
borrowingServices.validateCanReturnFolder(user, folder);
return ComponentState
.visibleIf(user.hasAll(RMPermissionsTo.BORROW_FOLDER, RMPermissionsTo.BORROWING_FOLDER_DIRECTLY).on(folder));
} catch (Exception e) {
return ComponentState.INVISIBLE;
}
}
protected ComponentState getReminderReturnFolderButtonState(User user, Folder folder) {
return isBorrowedByOtherUser(user, folder);
}
protected ComponentState getAlertWhenAvailableButtonState(User user, Folder folder) {
return isBorrowedByOtherUser(user, folder);
}
private ComponentState isBorrowedByOtherUser(User currentUser, Folder folder) {
Boolean borrowed = folder.getBorrowed();
if ((borrowed != null && borrowed) && borrowed && !isCurrentUserBorrower(currentUser, folder)) {
return ComponentState.ENABLED;
} else {
return ComponentState.INVISIBLE;
}
}
private boolean isCurrentUserBorrower(User currentUser, Folder folder) {
return currentUser.getId().equals(folder.getBorrowUserEntered());
}
ComponentState getPrintButtonState(User user, Folder folder) {
AuthorizationsServices authorizationsServices = modelLayerFactory.newAuthorizationsServices();
if (authorizationsServices.canRead(user, folder.getWrappedRecord())) {
if (folder.getPermissionStatus().isInactive()) {
if (folder.getBorrowed() != null && folder.getBorrowed()) {
return ComponentState.visibleIf(user.has(RMPermissionsTo.MODIFY_INACTIVE_BORROWED_FOLDER).on(folder) && user
.has(RMPermissionsTo.MODIFY_INACTIVE_FOLDERS).on(folder));
}
return ComponentState.visibleIf(user.has(RMPermissionsTo.MODIFY_INACTIVE_FOLDERS).on(folder));
}
if (folder.getPermissionStatus().isSemiActive()) {
if (folder.getBorrowed() != null && folder.getBorrowed()) {
return ComponentState.visibleIf(user.has(RMPermissionsTo.MODIFY_SEMIACTIVE_BORROWED_FOLDER).on(folder) && user
.has(RMPermissionsTo.MODIFY_SEMIACTIVE_FOLDERS).on(folder));
}
return ComponentState.visibleIf(user.has(RMPermissionsTo.MODIFY_SEMIACTIVE_FOLDERS).on(folder));
}
return ComponentState.ENABLED;
}
return ComponentState.INVISIBLE;
}
private ComponentState getDuplicateFolderButtonState(User user, Folder folder) {
AuthorizationsServices authorizationsServices = modelLayerFactory.newAuthorizationsServices();
if (authorizationsServices.canWrite(user, folder.getWrappedRecord())) {
if (folder.getPermissionStatus().isInactive()) {
return ComponentState.visibleIf(user.has(RMPermissionsTo.DUPLICATE_INACTIVE_FOLDER).on(folder));
}
if (folder.getPermissionStatus().isSemiActive()) {
return ComponentState.visibleIf(user.has(RMPermissionsTo.DUPLICATE_SEMIACTIVE_FOLDER).on(folder));
}
return ComponentState.ENABLED;
}
return ComponentState.INVISIBLE;
}
private ComponentState getAuthorizationButtonState(User user, Folder folder) {
return ComponentState.visibleIf(user.has(RMPermissionsTo.MANAGE_FOLDER_AUTHORIZATIONS).on(folder));
}
ComponentState getShareButtonState(User user, Folder folder) {
if (user.has(RMPermissionsTo.SHARE_FOLDER).on(folder)) {
if (folder.getPermissionStatus().isInactive()) {
return ComponentState.visibleIf(user.has(RMPermissionsTo.SHARE_A_INACTIVE_FOLDER).on(folder));
}
if (folder.getPermissionStatus().isSemiActive()) {
return ComponentState.visibleIf(user.has(RMPermissionsTo.SHARE_A_SEMIACTIVE_FOLDER).on(folder));
}
if (isNotBlank(folder.getLegacyId())) {
return ComponentState.visibleIf(user.has(RMPermissionsTo.SHARE_A_IMPORTED_FOLDER).on(folder));
}
return ComponentState.ENABLED;
}
return ComponentState.INVISIBLE;
}
ComponentState getDeleteButtonState(User user, Folder folder) {
if (user.hasDeleteAccess().on(folder)) {
if (folder.getPermissionStatus().isInactive()) {
if (folder.getBorrowed() != null && folder.getBorrowed()) {
return ComponentState.visibleIf(user.has(RMPermissionsTo.MODIFY_INACTIVE_BORROWED_FOLDER).on(folder) && user
.has(RMPermissionsTo.DELETE_INACTIVE_FOLDERS).on(folder));
}
return ComponentState.visibleIf(user.has(RMPermissionsTo.DELETE_INACTIVE_FOLDERS).on(folder));
}
if (folder.getPermissionStatus().isSemiActive()) {
if (folder.getBorrowed() != null && folder.getBorrowed()) {
return ComponentState.visibleIf(user.has(RMPermissionsTo.MODIFY_SEMIACTIVE_BORROWED_FOLDER).on(folder) && user
.has(RMPermissionsTo.DELETE_SEMIACTIVE_FOLDERS).on(folder));
}
return ComponentState.visibleIf(user.has(RMPermissionsTo.DELETE_SEMIACTIVE_FOLDERS).on(folder));
}
return ComponentState.ENABLED;
}
return ComponentState.INVISIBLE;
}
ComponentState getMoveInFolderButtonState(User user, Folder folder) {
// return getEditButtonState(user, folder);
return ComponentState.INVISIBLE;
}
ComponentState getEditButtonState(User user, Folder folder) {
if (isNotBlank(folder.getLegacyId()) && !user.has(RMPermissionsTo.MODIFY_IMPORTED_FOLDERS).on(folder)) {
return ComponentState.INVISIBLE;
}
return ComponentState.visibleIf(user.hasWriteAccess().on(folder)
&& extensions.isRecordModifiableBy(folder.getWrappedRecord(), user));
}
ComponentState getAddFolderButtonState(User user, Folder folder) {
if (user.hasWriteAccess().on(folder) &&
user.hasAll(RMPermissionsTo.CREATE_SUB_FOLDERS, RMPermissionsTo.CREATE_FOLDERS).on(folder)) {
if (folder.getPermissionStatus().isInactive()) {
if (folder.getBorrowed() != null && folder.getBorrowed()) {
return ComponentState.visibleIf(user.has(RMPermissionsTo.MODIFY_INACTIVE_BORROWED_FOLDER).on(folder) && user
.has(RMPermissionsTo.CREATE_SUB_FOLDERS_IN_INACTIVE_FOLDERS).on(folder));
}
return ComponentState.visibleIf(user.has(RMPermissionsTo.CREATE_SUB_FOLDERS_IN_INACTIVE_FOLDERS).on(folder));
}
if (folder.getPermissionStatus().isSemiActive()) {
if (folder.getBorrowed() != null && folder.getBorrowed()) {
return ComponentState.visibleIf(user.has(RMPermissionsTo.MODIFY_SEMIACTIVE_BORROWED_FOLDER).on(folder) && user
.has(RMPermissionsTo.CREATE_SUB_FOLDERS_IN_SEMIACTIVE_FOLDERS).on(folder));
}
return ComponentState.visibleIf(user.has(RMPermissionsTo.CREATE_SUB_FOLDERS_IN_SEMIACTIVE_FOLDERS).on(folder));
}
return ComponentState.ENABLED;
}
return ComponentState.INVISIBLE;
}
ComponentState getAddDocumentButtonState(User user, Folder folder) {
if (user.hasWriteAccess().on(folder) &&
user.has(RMPermissionsTo.CREATE_DOCUMENTS).on(folder)) {
if (folder.getPermissionStatus().isInactive()) {
if (folder.getBorrowed() != null && folder.getBorrowed()) {
return ComponentState.visibleIf(user.has(RMPermissionsTo.MODIFY_INACTIVE_BORROWED_FOLDER).on(folder) && user
.has(RMPermissionsTo.CREATE_INACTIVE_DOCUMENT).on(folder));
}
return ComponentState.visibleIf(user.has(RMPermissionsTo.CREATE_INACTIVE_DOCUMENT).on(folder));
}
if (folder.getPermissionStatus().isSemiActive()) {
if (folder.getBorrowed() != null && folder.getBorrowed()) {
return ComponentState.visibleIf(user.has(RMPermissionsTo.MODIFY_SEMIACTIVE_BORROWED_FOLDER).on(folder) && user
.has(RMPermissionsTo.CREATE_SEMIACTIVE_DOCUMENT).on(folder));
}
return ComponentState.visibleIf(user.has(RMPermissionsTo.CREATE_SEMIACTIVE_DOCUMENT).on(folder));
}
return ComponentState.ENABLED;
}
return ComponentState.INVISIBLE;
}
private MetadataSchemaType getFoldersSchemaType() {
return schemaType(Folder.SCHEMA_TYPE);
}
private MetadataSchemaType getDocumentsSchemaType() {
return schemaType(Document.SCHEMA_TYPE);
}
private MetadataSchema getFoldersSchema() {
return schema(Folder.DEFAULT_SCHEMA);
}
private MetadataSchema getDocumentsSchema() {
return schema(Document.DEFAULT_SCHEMA);
}
private MetadataSchema getTasksSchema() {
return schema(Task.DEFAULT_SCHEMA);
}
public void viewAssembled() {
view.setFolderContent(Arrays.asList(subFoldersDataProvider, documentsDataProvider));
view.setTasks(tasksDataProvider);
view.setEvents(eventsDataProvider);
RMSchemasRecordsServices schemas = new RMSchemasRecordsServices(collection, appLayerFactory);
Folder folder = schemas.wrapFolder(toRecord(folderVO));
disableMenuItems(folder);
modelLayerFactory.newLoggingServices().logRecordView(folder.getWrappedRecord(), getCurrentUser());
}
public void backButtonClicked() {
view.navigate().to().previousView();
}
public void addDocumentButtonClicked() {
view.navigate().to(RMViews.class).addDocument(folderVO.getId());
}
public void addSubFolderButtonClicked() {
view.navigate().to(RMViews.class).addFolder(folderVO.getId());
}
public void editFolderButtonClicked() {
view.navigate().to(RMViews.class).editFolder(folderVO.getId());
}
public void deleteFolderButtonClicked(String reason) {
String parentId = folderVO.get(Folder.PARENT_FOLDER);
Record record = toRecord(folderVO);
if (recordServices.isLogicallyDeletable(record, getCurrentUser())) {
appLayerFactory.getExtensions().forCollection(collection)
.notifyFolderDeletion(new FolderDeletionEvent(rmSchemasRecordsServices.wrapFolder(record)));
delete(record, reason, false);
if (parentId != null) {
view.navigate().to(RMViews.class).displayFolder(parentId);
} else {
view.navigate().to().home();
}
} else {
view.showErrorMessage($("ListSchemaRecordsView.cannotDelete"));
}
}
public void duplicateFolderButtonClicked() {
Folder folder = rmSchemasRecordsServices().getFolder(folderVO.getId());
view.navigate().to(RMViews.class).duplicateFolder(folder.getId(), false);
}
public void duplicateStructureButtonClicked() {
Folder folder = rmSchemasRecordsServices().getFolder(folderVO.getId());
view.navigate().to(RMViews.class).duplicateFolder(folder.getId(), true);
}
public void linkToFolderButtonClicked() {
// TODO ZeroClipboardComponent
view.showMessage("Clipboard integration TODO!");
}
public void addAuthorizationButtonClicked() {
view.navigate().to().listObjectAccessAuthorizations(folderVO.getId());
}
public void shareFolderButtonClicked() {
view.navigate().to().shareContent(folderVO.getId());
}
public void editDocumentButtonClicked(RecordVO recordVO) {
view.navigate().to(RMViews.class).editDocument(recordVO.getId());
}
public void downloadDocumentButtonClicked(RecordVO recordVO) {
ContentVersionVO contentVersionVO = recordVO.get(Document.CONTENT);
view.downloadContentVersion(recordVO, contentVersionVO);
}
public void displayDocumentButtonClicked(RecordVO record) {
view.navigate().to(RMViews.class).displayDocument(record.getId());
}
public void documentClicked(RecordVO recordVO) {
ContentVersionVO contentVersionVO = recordVO.get(Document.CONTENT);
if (contentVersionVO == null) {
view.navigate().to(RMViews.class).displayDocument(recordVO.getId());
return;
}
String agentURL = ConstellioAgentUtils.getAgentURL(recordVO, contentVersionVO);
if (agentURL != null) {
// view.openAgentURL(agentURL);
new ConstellioAgentClickHandler().handleClick(agentURL, recordVO, contentVersionVO);
} else {
view.navigate().to(RMViews.class).displayDocument(recordVO.getId());
}
}
public void subFolderClicked(RecordVO subFolderVO) {
view.navigate().to(RMViews.class).displayFolder(subFolderVO.getId());
}
public void taskClicked(RecordVO taskVO) {
view.navigate().to(TaskViews.class).displayTask(taskVO.getId());
}
private DecommissioningService decommissioningService() {
return new DecommissioningService(getCurrentUser().getCollection(), appLayerFactory);
}
private RMSchemasRecordsServices rmSchemasRecordsServices() {
return new RMSchemasRecordsServices(getCurrentUser().getCollection(), appLayerFactory);
}
private boolean documentExists(String fileName) {
Record record = getRecord(folderVO.getId());
MetadataSchemaType documentsSchemaType = getDocumentsSchemaType();
MetadataSchema documentsSchema = getDocumentsSchema();
Metadata folderMetadata = documentsSchema.getMetadata(Document.FOLDER);
Metadata titleMetadata = documentsSchema.getMetadata(Schemas.TITLE.getCode());
LogicalSearchQuery query = new LogicalSearchQuery();
LogicalSearchCondition parentCondition = from(documentsSchemaType).where(folderMetadata).is(record)
.andWhere(Schemas.LOGICALLY_DELETED_STATUS).isFalseOrNull();
query.setCondition(parentCondition.andWhere(titleMetadata).is(fileName));
SearchServices searchServices = modelLayerFactory.newSearchServices();
return searchServices.query(query).getNumFound() > 0;
}
public void contentVersionUploaded(ContentVersionVO uploadedContentVO) {
view.selectFolderContentTab();
String fileName = uploadedContentVO.getFileName();
if (!documentExists(fileName)) {
try {
uploadedContentVO.setMajorVersion(true);
Record newRecord;
if (rmSchemasRecordsServices().isEmail(fileName)) {
InputStreamProvider inputStreamProvider = uploadedContentVO.getInputStreamProvider();
InputStream in = inputStreamProvider.getInputStream(DisplayFolderPresenter.class + ".contentVersionUploaded");
Document document = rmSchemasRecordsServices.newEmail(fileName, in);
newRecord = document.getWrappedRecord();
} else {
Document document = rmSchemasRecordsServices.newDocument();
newRecord = document.getWrappedRecord();
}
DocumentVO documentVO = documentVOBuilder.build(newRecord, VIEW_MODE.FORM, view.getSessionContext());
documentVO.setFolder(folderVO);
documentVO.setTitle(fileName);
documentVO.setContent(uploadedContentVO);
schemaPresenterUtils.setSchemaCode(newRecord.getSchemaCode());
newRecord = schemaPresenterUtils.toRecord(documentVO);
schemaPresenterUtils.addOrUpdate(newRecord);
documentsDataProvider.fireDataRefreshEvent();
view.refreshFolderContentTab();
} catch (final IcapException e) {
view.showErrorMessage(e.getMessage());
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
} finally {
view.clearUploadField();
}
}
}
public boolean borrowFolder(LocalDate borrowingDate, LocalDate previewReturnDate, String userId, BorrowingType borrowingType,
LocalDate returnDate) {
boolean borrowed;
String errorMessage = borrowingServices
.validateBorrowingInfos(userId, borrowingDate, previewReturnDate, borrowingType, returnDate);
if (errorMessage != null) {
view.showErrorMessage($(errorMessage));
borrowed = false;
} else {
Record record = recordServices().getDocumentById(userId);
User borrowerEntered = wrapUser(record);
try {
borrowingServices
.borrowFolder(folderVO.getId(), borrowingDate, previewReturnDate, getCurrentUser(), borrowerEntered,
borrowingType, true);
view.navigate().to(RMViews.class).displayFolder(folderVO.getId());
borrowed = true;
} catch (RecordServicesException e) {
LOGGER.error(e.getMessage(), e);
view.showErrorMessage($("DisplayFolderView.cannotBorrowFolder"));
borrowed = false;
}
}
if (returnDate != null) {
return returnFolder(returnDate, borrowingDate);
}
return borrowed;
}
public boolean returnFolder(LocalDate returnDate) {
LocalDateTime borrowDateTime = folderVO.getBorrowDate();
LocalDate borrowDate = borrowDateTime != null ? borrowDateTime.toLocalDate() : null;
return returnFolder(returnDate, borrowDate);
}
protected boolean returnFolder(LocalDate returnDate, LocalDate borrowingDate) {
String errorMessage = borrowingServices.validateReturnDate(returnDate, borrowingDate);
if (errorMessage != null) {
view.showErrorMessage($(errorMessage));
return false;
}
try {
borrowingServices.returnFolder(folderVO.getId(), getCurrentUser(), returnDate, true);
view.navigate().to(RMViews.class).displayFolder(folderVO.getId());
return true;
} catch (RecordServicesException e) {
view.showErrorMessage($("DisplayFolderView.cannotReturnFolder"));
return false;
}
}
private EmailToSend newEmailToSend() {
MetadataSchemaTypes types = metadataSchemasManager.getSchemaTypes(getCurrentUser().getCollection());
MetadataSchema schema = types.getSchemaType(EmailToSend.SCHEMA_TYPE).getDefaultSchema();
Record emailToSendRecord = recordServices.newRecordWithSchema(schema);
return new EmailToSend(emailToSendRecord, types);
}
public void reminderReturnFolder() {
try {
EmailToSend emailToSend = newEmailToSend();
User borrower = rmSchemasRecordsServices.getUser(folderVO.getBorrowUserId());
EmailAddress borrowerAddress = new EmailAddress(borrower.getTitle(), borrower.getEmail());
emailToSend.setTo(Arrays.asList(borrowerAddress));
emailToSend.setSendOn(TimeProvider.getLocalDateTime());
emailToSend.setSubject($("DisplayFolderView.returnFolderReminder") + folderVO.getTitle());
emailToSend.setTemplate(RMEmailTemplateConstants.REMIND_BORROW_TEMPLATE_ID);
List<String> parameters = new ArrayList<>();
String previewReturnDate = folderVO.getPreviewReturnDate().toString();
parameters.add("previewReturnDate" + EmailToSend.PARAMETER_SEPARATOR + previewReturnDate);
parameters.add("borrower" + EmailToSend.PARAMETER_SEPARATOR + borrower.getUsername());
String borrowedFolderTitle = folderVO.getTitle();
parameters.add("borrowedFolderTitle" + EmailToSend.PARAMETER_SEPARATOR + borrowedFolderTitle);
parameters.add("title" + EmailToSend.PARAMETER_SEPARATOR + $("DisplayFolderView.returnFolderReminder") + " \""
+ folderVO.getTitle() + "\"");
emailToSend.setParameters(parameters);
recordServices.add(emailToSend);
view.showMessage($("DisplayFolderView.reminderEmailSent"));
} catch (RecordServicesException e) {
LOGGER.error("DisplayFolderView.cannotSendEmail", e);
view.showMessage($("DisplayFolderView.cannotSendEmail"));
}
}
public void alertWhenAvailable() {
try {
RMSchemasRecordsServices schemas = new RMSchemasRecordsServices(view.getCollection(), appLayerFactory);
Folder folder = schemas.getFolder(folderVO.getId());
List<String> usersToAlert = folder.getAlertUsersWhenAvailable();
String currentUserId = getCurrentUser().getId();
if (!currentUserId.equals(folder.getBorrowUser()) && !currentUserId.equals(folder.getBorrowUserEntered())) {
List<String> newUsersToAlert = new ArrayList<>();
newUsersToAlert.addAll(usersToAlert);
if (!newUsersToAlert.contains(currentUserId)) {
newUsersToAlert.add(currentUserId);
folder.setAlertUsersWhenAvailable(newUsersToAlert);
addOrUpdate(folder.getWrappedRecord());
}
}
view.showMessage($("RMObject.createAlert"));
} catch (Exception e) {
LOGGER.error("RMObject.cannotCreateAlert", e);
view.showErrorMessage($("RMObject.cannotCreateAlert"));
}
}
public List<LabelTemplate> getCustomTemplates() {
return appLayerFactory.getLabelTemplateManager().listExtensionTemplates(Folder.SCHEMA_TYPE);
}
public List<LabelTemplate> getDefaultTemplates() {
return appLayerFactory.getLabelTemplateManager().listTemplates(Folder.SCHEMA_TYPE);
}
public Date getPreviewReturnDate(Date borrowDate, Object borrowingTypeValue) {
BorrowingType borrowingType;
Date previewReturnDate = TimeProvider.getLocalDate().toDate();
if (borrowDate != null && borrowingTypeValue != null) {
borrowingType = (BorrowingType) borrowingTypeValue;
if (borrowingType == BorrowingType.BORROW) {
int addDays = rmConfigs.getBorrowingDurationDays();
previewReturnDate = LocalDate.fromDateFields(borrowDate).plusDays(addDays).toDate();
} else {
previewReturnDate = borrowDate;
}
}
return previewReturnDate;
}
boolean isDocument(RecordVO record) {
return record.getSchema().getCode().startsWith("document");
}
public boolean canModifyDocument(RecordVO record) {
boolean hasContent = record.get(Document.CONTENT) != null;
boolean hasAccess = getCurrentUser().hasWriteAccess().on(getRecord(record.getId()));
return hasContent && hasAccess;
}
public void addToCartRequested(RecordVO recordVO) {
Cart cart = rmSchemasRecordsServices.getCart(recordVO.getId()).addFolders(Arrays.asList(folderVO.getId()));
addOrUpdate(cart.getWrappedRecord());
view.showMessage($("DisplayFolderView.addedToCart"));
}
public RecordVODataProvider getOwnedCartsDataProvider() {
final MetadataSchemaVO cartSchemaVO = schemaVOBuilder
.build(rmSchemasRecordsServices.cartSchema(), VIEW_MODE.TABLE, view.getSessionContext());
return new RecordVODataProvider(cartSchemaVO, new RecordToVOBuilder(), modelLayerFactory, view.getSessionContext()) {
@Override
protected LogicalSearchQuery getQuery() {
return new LogicalSearchQuery(
from(rmSchemasRecordsServices.cartSchema()).where(rmSchemasRecordsServices.cartOwner())
.isEqualTo(getCurrentUser().getId())).sortAsc(Schemas.TITLE);
}
};
}
public RecordVODataProvider getSharedCartsDataProvider() {
final MetadataSchemaVO cartSchemaVO = schemaVOBuilder
.build(rmSchemasRecordsServices.cartSchema(), VIEW_MODE.TABLE, view.getSessionContext());
return new RecordVODataProvider(cartSchemaVO, new RecordToVOBuilder(), modelLayerFactory, view.getSessionContext()) {
@Override
protected LogicalSearchQuery getQuery() {
return new LogicalSearchQuery(
from(rmSchemasRecordsServices.cartSchema()).where(rmSchemasRecordsServices.cartSharedWithUsers())
.isContaining(asList(getCurrentUser().getId()))).sortAsc(Schemas.TITLE);
}
};
}
public void parentFolderButtonClicked(String parentId)
throws RecordServicesException {
RMSchemasRecordsServices rmSchemas = new RMSchemasRecordsServices(collection, appLayerFactory);
String currentFolderId = folderVO.getId();
if (isNotBlank(parentId)) {
try {
recordServices.update(rmSchemas.getFolder(currentFolderId).setParentFolder(parentId));
view.navigate().to(RMViews.class).displayFolder(currentFolderId);
} catch (RecordServicesException.ValidationException e) {
view.showErrorMessage($(e.getErrors()));
}
}
}
public void createNewCartAndAddToItRequested(String title) {
Cart cart = rmSchemasRecordsServices.newCart();
cart.setTitle(title);
cart.setOwner(getCurrentUser());
try {
cart.addFolders(Arrays.asList(folderVO.getId()));
recordServices().execute(new Transaction(cart.getWrappedRecord()).setUser(getCurrentUser()));
view.showMessage($("DisplayFolderView.addedToCart"));
} catch (RecordServicesException e) {
e.printStackTrace();
}
}
public RecordVODataProvider getEventsDataProvider() {
final MetadataSchemaVO eventSchemaVO = schemaVOBuilder
.build(rmSchemasRecordsServices.eventSchema(), VIEW_MODE.TABLE, view.getSessionContext());
return new RecordVODataProvider(eventSchemaVO, new EventToVOBuilder(), modelLayerFactory, view.getSessionContext()) {
@Override
protected LogicalSearchQuery getQuery() {
RMEventsSearchServices rmEventsSearchServices = new RMEventsSearchServices(modelLayerFactory, collection);
return rmEventsSearchServices.newFindEventByRecordIDQuery(getCurrentUser(), folderVO.getId());
}
};
}
protected boolean hasCurrentUserPermissionToViewEvents() {
return getCurrentUser().has(CorePermissions.VIEW_EVENTS).on(toRecord(folderVO));
}
public void refreshEvents() {
modelLayerFactory.getDataLayerFactory().newEventsDao().flush();
view.setEvents(getEventsDataProvider());
}
public boolean hasCurrentUserPermissionToUseCart() {
return getCurrentUser().has(RMPermissionsTo.USE_CART).globally();
}
public boolean hasPermissionToStartWorkflow() {
return getCurrentUser().has(TasksPermissionsTo.START_WORKFLOWS).globally();
}
public boolean isSelected(RecordVO recordVO) {
String recordId = recordVO.getId();
SessionContext sessionContext = view.getSessionContext();
return sessionContext.getSelectedRecordIds().contains(recordId);
}
public void recordSelectionChanged(RecordVO recordVO, Boolean selected) {
String recordId = recordVO.getId();
SessionContext sessionContext = view.getSessionContext();
if (selected) {
sessionContext.addSelectedRecordId(recordId, recordVO.getSchema().getTypeCode());
} else {
sessionContext.removeSelectedRecordId(recordId, recordVO.getSchema().getTypeCode());
}
}
void computeAllItemsSelected() {
SessionContext sessionContext = view.getSessionContext();
List<String> selectedRecordIds = sessionContext.getSelectedRecordIds();
SearchServices searchServices = modelLayerFactory.newSearchServices();
List<String> subFolderIds = searchServices.searchRecordIds(getSubFoldersQuery());
for (String subFolderId : subFolderIds) {
if (!selectedRecordIds.contains(subFolderId)) {
allItemsSelected = false;
return;
}
}
List<String> documentIds = searchServices.searchRecordIds(getDocumentsQuery());
for (String documentId : documentIds) {
if (!selectedRecordIds.contains(documentId)) {
allItemsSelected = false;
return;
}
}
allItemsSelected = !subFolderIds.isEmpty() || !documentIds.isEmpty();
}
boolean isAllItemsSelected() {
return allItemsSelected;
}
boolean isAllItemsDeselected() {
return allItemsDeselected;
}
void selectAllClicked() {
allItemsSelected = true;
allItemsDeselected = false;
SessionContext sessionContext = view.getSessionContext();
SearchServices searchServices = modelLayerFactory.newSearchServices();
List<String> subFolderIds = searchServices.searchRecordIds(getSubFoldersQuery());
for (String subFolderId : subFolderIds) {
sessionContext.addSelectedRecordId(subFolderId, Folder.SCHEMA_TYPE);
}
List<String> documentIds = searchServices.searchRecordIds(getDocumentsQuery());
for (String documentId : documentIds) {
sessionContext.addSelectedRecordId(documentId, Document.SCHEMA_TYPE);
}
}
void deselectAllClicked() {
allItemsSelected = false;
allItemsDeselected = true;
SessionContext sessionContext = view.getSessionContext();
SearchServices searchServices = modelLayerFactory.newSearchServices();
List<String> subFolderIds = searchServices.searchRecordIds(getSubFoldersQuery());
for (String subFolderId : subFolderIds) {
sessionContext.removeSelectedRecordId(subFolderId, Folder.SCHEMA_TYPE);
}
List<String> documentIds = searchServices.searchRecordIds(getDocumentsQuery());
for (String documentId : documentIds) {
sessionContext.removeSelectedRecordId(documentId, Document.SCHEMA_TYPE);
}
}
}