All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.netgrif.application.engine.orgstructure.groups.NextGroupService Maven / Gradle / Ivy

Go to download

System provides workflow management functions including user, role and data management.

There is a newer version: 6.3.3
Show newest version
package com.netgrif.application.engine.orgstructure.groups;

import com.netgrif.application.engine.auth.domain.IUser;
import com.netgrif.application.engine.auth.domain.RegisteredUser;
import com.netgrif.application.engine.auth.service.interfaces.IRegistrationService;
import com.netgrif.application.engine.auth.service.interfaces.IUserService;
import com.netgrif.application.engine.auth.web.requestbodies.NewUserRequest;
import com.netgrif.application.engine.elastic.service.interfaces.IElasticCaseService;
import com.netgrif.application.engine.elastic.web.requestbodies.CaseSearchRequest;
import com.netgrif.application.engine.mail.interfaces.IMailAttemptService;
import com.netgrif.application.engine.mail.interfaces.IMailService;
import com.netgrif.application.engine.orgstructure.groups.interfaces.INextGroupService;
import com.netgrif.application.engine.petrinet.domain.I18nString;
import com.netgrif.application.engine.petrinet.domain.throwable.TransitionNotExecutableException;
import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService;
import com.netgrif.application.engine.security.service.ISecurityContextService;
import com.netgrif.application.engine.startup.ImportHelper;
import com.netgrif.application.engine.workflow.domain.Case;
import com.netgrif.application.engine.workflow.domain.QCase;
import com.netgrif.application.engine.workflow.domain.Task;
import com.netgrif.application.engine.workflow.domain.eventoutcomes.caseoutcomes.CreateCaseEventOutcome;
import com.netgrif.application.engine.workflow.service.interfaces.IDataService;
import com.netgrif.application.engine.workflow.service.interfaces.ITaskService;
import com.netgrif.application.engine.workflow.service.interfaces.IWorkflowService;
import com.netgrif.application.engine.workflow.web.responsebodies.TaskReference;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.dsl.BooleanExpression;
import freemarker.template.TemplateException;
import lombok.extern.slf4j.Slf4j;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import com.netgrif.application.engine.petrinet.domain.PetriNet;

import javax.mail.MessagingException;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class NextGroupService implements INextGroupService {

    @Autowired
    protected IWorkflowService workflowService;

    @Autowired
    protected IMailService mailService;

    @Autowired
    protected IMailAttemptService mailAttemptService;

    @Autowired
    protected IUserService userService;

    @Autowired
    protected IDataService dataService;

    @Autowired
    protected IRegistrationService registrationService;

    @Autowired
    protected IPetriNetService petriNetService;

    @Autowired
    protected ITaskService taskService;

    @Autowired
    protected IElasticCaseService elasticCaseService;

    @Autowired
    protected ISecurityContextService securityContextService;


    protected final static String GROUP_NET_IDENTIFIER = "org_group";
    protected final static String GROUP_INIT_TASK_ID = "2";

    protected final static String GROUP_CASE_IDENTIFIER = "org_group";
    protected final static String GROUP_MEMBERS_FIELD = "members";
    protected final static String GROUP_AUTHOR_FIELD = "author";
    protected final static String GROUP_TITLE_FIELD = "group_name";

    @Override
    public CreateCaseEventOutcome createDefaultSystemGroup(IUser author){
        if(findDefaultGroup() != null) {
            log.info("Default system group has already been created.");
            return null;
        }
        return createGroup("Default system group", author);
    }

    @Override
    public CreateCaseEventOutcome createGroup(IUser author){
        return createGroup(author.getFullName(), author);
    }

    @Override
    public CreateCaseEventOutcome createGroup(String title, IUser author){
        Case userDefaultGroup = findUserDefaultGroup(author);
        if (userDefaultGroup != null && userDefaultGroup.getTitle().equals(title)) {
            return null;
        }
        PetriNet orgGroupNet = petriNetService.getNewestVersionByIdentifier(GROUP_NET_IDENTIFIER);
        CreateCaseEventOutcome outcome = workflowService.createCase(orgGroupNet.getStringId(), title, "", author.transformToLoggedUser());

        Map> taskData = getInitialGroupData(author, title, outcome.getCase());
        Task initTask = getGroupInitTask(outcome.getCase());
        dataService.setData(initTask.getStringId(), ImportHelper.populateDataset(taskData));

        try {
            taskService.assignTask(author.transformToLoggedUser(), initTask.getStringId());
            taskService.finishTask(author.transformToLoggedUser(), initTask.getStringId());
        } catch (TransitionNotExecutableException e) {
            log.error(e.getMessage());
        }
        author.addGroup(outcome.getCase().getStringId());
        userService.save(author);
        return outcome;
    }

    @Override
    public Case findGroup(String groupID) {
        Case result = workflowService.searchOne(groupCase().and(QCase.case$._id.eq(new ObjectId(groupID))));
        if (!isGroupCase(result)) {
            return null;
        }
        return result;
    }

    @Override
    public Case findDefaultGroup() {
        return findByName("Default system group");
    }

    @Override
    public Case findByName(String name) {
        CaseSearchRequest request = new CaseSearchRequest();
        request.query = "title.keyword:\"" + name + "\"";
        List result = elasticCaseService.search(Collections.singletonList(request), userService.getSystem().transformToLoggedUser(), PageRequest.of(0, 1), LocaleContextHolder.getLocale(), false).getContent();
        return !result.isEmpty() ? result.get(0) : null;
    }

    @Override
    public List findByPredicate(Predicate predicate) {
        return workflowService.searchAll(predicate).getContent();
    }

    @Override
    public List findByIds(Collection groupIds) {
        List groupQueries = groupIds.stream().map(ObjectId::new).map(QCase.case$._id::eq).collect(Collectors.toList());
        BooleanBuilder builder = new BooleanBuilder();
        groupQueries.forEach(builder::or);
        return this.workflowService.searchAll(groupCase().and(builder)).getContent();
    }

    @Override
    public List findAllGroups() {
        return workflowService.searchAll(groupCase()).getContent();
    }

    @Override
    public Map inviteUser(String email, Map existingUsers, Case groupCase) {
        if (!isGroupCase(groupCase)) {
            return null;
        }
        IUser user = userService.findByEmail(email, true);
        if (user != null && user.isActive()) {
            log.info("User [" + user.getFullName() + "] has already been registered.");
            user.addGroup(groupCase.getStringId());
            userService.save(user);
            return addUser(user, existingUsers);
        } else {
            log.info("Inviting new user to group.");
            NewUserRequest newUserRequest = new NewUserRequest();
            newUserRequest.email = email;
            RegisteredUser regUser = registrationService.createNewUser(newUserRequest);
            regUser.addGroup(groupCase.getStringId());
            userService.save(regUser);

            try {
                mailService.sendRegistrationEmail(regUser);
                mailAttemptService.mailAttempt(newUserRequest.email);
            } catch (MessagingException | IOException | TemplateException e) {
                log.error(e.getMessage());
            }
            return addUser(regUser, existingUsers);
        }
    }

    @Override
    public void addUserToDefaultGroup(IUser user) {
        addUser(user, findDefaultGroup());
    }

    @Override
    public void addUser(IUser user, String groupId){
        Case groupCase = this.findGroup(groupId);
        if(groupCase != null){
            this.addUser(user, groupCase);
        }
    }

    @Override
    public void addUser(IUser user, Case groupCase) {
        Map existingUsers = groupCase.getDataField(GROUP_MEMBERS_FIELD).getOptions();
        if (existingUsers == null) {
            existingUsers = new HashMap<>();
        }
        groupCase.getDataField(GROUP_MEMBERS_FIELD).setOptions(addUser(user, existingUsers));
        workflowService.save(groupCase);
        user.addGroup(groupCase.getStringId());
        userService.save(user);
        securityContextService.saveToken(user.getStringId());
    }

    @Override
    public Map addUser(IUser user, Map existingUsers) {
        existingUsers.put(user.getStringId(), new I18nString(user.getEmail()));
        return existingUsers;
    }

    @Override
    public void removeUser(IUser user, Case groupCase){
        HashSet userIds = new HashSet<>();
        Map existingUsers = groupCase.getDataField(GROUP_MEMBERS_FIELD).getOptions();

        userIds.add(user.getStringId());
        groupCase.getDataField(GROUP_MEMBERS_FIELD).setOptions(removeUser(userIds, existingUsers, groupCase));
        workflowService.save(groupCase);
    }

    @Override
    public Map removeUser(HashSet usersToRemove, Map existingUsers, Case groupCase) {
        String authorId = this.getGroupOwnerId(groupCase);
        usersToRemove.forEach(user -> {
            if (user.equals(authorId)) {
                log.error("Author with id [" + authorId + "] cannot be removed from group with ID [" + groupCase.get_id().toString() + "]");
            } else {
                existingUsers.remove(user);
                securityContextService.saveToken(user);
            }
        });
        userService.findAllByIds(usersToRemove, false).forEach(user -> {
            if (!user.getStringId().equals(authorId)) {
                user.getNextGroups().remove(groupCase.getStringId());
                userService.save(user);
            }
        });
        return existingUsers;
    }

    @Override
    public Set getAllCoMembers(IUser user) {
        Set users = workflowService.searchAll(
                groupCase().and(QCase.case$.dataSet.get(GROUP_MEMBERS_FIELD).options.containsKey(user.getStringId())))
                .map(it -> it.getDataSet().get(GROUP_MEMBERS_FIELD).getOptions().keySet()).stream()
                .collect(HashSet::new, Set::addAll, Set::addAll);
        users.remove(user.getStringId());
        users.remove(userService.getSystem().getStringId());
        return users;
    }


    @Override
    public List getMembers(Case groupCase) {
        if (!isGroupCase(groupCase)) {
            return null;
        }
        Set userIds = groupCase.getDataSet().get(GROUP_MEMBERS_FIELD).getOptions().keySet();
        List resultList = new ArrayList<>();
        userIds.forEach(id -> resultList.add(userService.resolveById(id, true)));
        return resultList;
    }

    @Override
    public Set getAllGroupsOfUser(IUser groupUser) {
        List groupList = workflowService.searchAll(groupCase().and(QCase.case$.dataSet.get(GROUP_MEMBERS_FIELD).options.containsKey(groupUser.getStringId())))
                .map(aCase -> aCase.get_id().toString()).getContent();
        return new HashSet<>(groupList);
    }

    @Override
    public String getGroupOwnerId(String groupId) {
        return this.getGroupOwnerId(this.findGroup(groupId));
    }

    @Override
    public Collection getGroupsOwnerIds(Collection groupIds) {
        return this.findByIds(groupIds).stream().map(this::getGroupOwnerId).collect(Collectors.toList());
    }

    @Override
    public String getGroupOwnerEmail(String groupId) {
        return this.getGroupOwnerEmail(this.findGroup(groupId));
    }

    @Override
    public Collection getGroupsOwnerEmails(Collection groupIds) {
        return this.findByIds(groupIds).stream().map(this::getGroupOwnerEmail).collect(Collectors.toList());
    }

    protected static BooleanExpression groupCase() {
        return QCase.case$.processIdentifier.eq(GROUP_CASE_IDENTIFIER);
    }

    protected boolean isGroupCase(Case aCase) {
        if (aCase == null) {
            log.error("The input case is a null object.");
            return false;
        } else if (!aCase.getProcessIdentifier().equals(GROUP_CASE_IDENTIFIER)) {
            log.error("Case [" + aCase.getTitle() + "] is not an organization group case.");
            return false;
        }
        return true;
    }

    protected boolean authorHasDefaultGroup(IUser author) {
        List allGroups = findAllGroups();
        for (Case group : allGroups){
            if(group.getAuthor().getId().equals(author.getStringId())) {
                return true;
            }
        }
        return false;
    }

    protected String getGroupOwnerId(Case groupCase) {
        return groupCase.getAuthor().getId();
    }

    protected Case findUserDefaultGroup(IUser author) {
        return workflowService.searchOne(QCase.case$.author.id.eq(author.getStringId()).and(QCase.case$.title.eq(author.getFullName())));
    }

    protected Task getGroupInitTask(Case groupCase) {
        List taskList = taskService.findAllByCase(groupCase.getStringId(), LocaleContextHolder.getLocale());
        Optional initTaskReference = taskList.stream().filter(taskReference ->
                taskReference.getTransitionId().equals(GROUP_INIT_TASK_ID))
                .findFirst();

        if (initTaskReference.isEmpty()) {
            log.error("Initial task of group case is not present!");
            return null;
        }

        String initTaskId = initTaskReference.get().getStringId();
        return taskService.findById(initTaskId);
    }

    protected Map> getInitialGroupData(IUser author, String title, Case groupCase) {
        Map> taskData = new HashMap<>();

        groupCase.getDataField(GROUP_MEMBERS_FIELD).setOptions(addUser(author, new HashMap<>()));
        workflowService.save(groupCase);

        Map authorData = new HashMap<>();
        authorData.put("type", "user");
        authorData.put("value", author.getStringId());

        Map titleData = new HashMap<>();
        titleData.put("type", "text");
        titleData.put("value", title);

        taskData.put(GROUP_TITLE_FIELD, titleData);
        taskData.put(GROUP_AUTHOR_FIELD, authorData);
        return taskData;
    }

    protected String getGroupOwnerEmail(Case groupCase) {
        return groupCase.getAuthor().getEmail();
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy