ProcessSaveAction.java

package com.mycim.webapp.actions.process;

import com.fa.sesa.exception.Assert;
import com.fa.sesa.exception.Errors;
import com.fa.sesa.i18n.I18nUtils;
import com.fa.sesa.threadlocal.LocalContext;
import com.mycim.framework.utils.beans.PropertyUtils;
import com.mycim.framework.utils.lang.StringUtils;
import com.mycim.framework.utils.lang.collections.CollectionUtils;
import com.mycim.framework.utils.lang.collections.MapUtils;
import com.mycim.framework.utils.lang.math.NumberUtils;
import com.mycim.valueobject.MessageIdList;
import com.mycim.valueobject.ObjectList;
import com.mycim.valueobject.bas.Relation;
import com.mycim.valueobject.consts.LinkTypeList;
import com.mycim.valueobject.consts.SessionNames;
import com.mycim.valueobject.prp.Item;
import com.mycim.valueobject.prp.ProcessPlanning;
import com.mycim.valueobject.prp.ProcessVersion;
import com.mycim.valueobject.security.UserGroup;
import com.mycim.webapp.Constants;
import com.mycim.webapp.WebUtils;
import com.mycim.webapp.actions.PrpSetupAction;
import com.mycim.webapp.forms.TechnologyVersionInfoForm;
import com.mycim.webapp.secutiry.jwt.JwtUtils;
import com.mycim.webapp.secutiry.jwt.token.JwtToken;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

/**
 * 流程定义
 *
 * @author Johnson.Wang
 * @version 6.0.0
 * @date 2019/8/31
 **/
public class ProcessSaveAction extends PrpSetupAction {

    private static final String MONITOR_PROCESS_FLAG = "MONITOR";

    private static final String PROCESS_RRN_KEY = "PROCESSRRN";

    @Override
    public ActionForward init(ActionMapping mapping, ActionForm form, HttpServletRequest request,
                              HttpServletResponse response) throws Exception {
        TechnologyVersionInfoForm infoForm = (TechnologyVersionInfoForm) form;

        String id = (String) request.getAttribute("instanceId");
        if (StringUtils.isEmpty(id)) {
            id = infoForm.getInstanceId();
        }

        id = StringUtils.isEmpty(id) ? "" : id.trim().toUpperCase();
        ProcessPlanning processPlanning = new ProcessPlanning(id, getNamedSpace(ObjectList.WFL_KEY,
                                                                                LocalContext.getFacilityRrn()),
                                                              ObjectList.WFL_KEY);

        processPlanning = (ProcessPlanning) getInstance(processPlanning);
        Assert.isFalse(processPlanning != null &&
                               StringUtils.equalsIgnoreCase(processPlanning.getFlagType(), MONITOR_PROCESS_FLAG),
                       Errors.create().key(MessageIdList.PROCESS_DUMMY).content("process:{} is Dummy process!")
                             .args(processPlanning.getInstanceId()).build());


        PropertyUtils.copyProperties(infoForm, processPlanning);

        infoForm.setTransId(Constants.CREATE_KEY);
        long processRrn = getInstanceRrn(id, LocalContext.getFacilityRrn(), ObjectList.WFL_KEY);
        if (processPlanning.getInstanceRrn() > 0 || processRrn > 0) {
            //检查是否有权限查看该process
            Assert.isFalse((processPlanning == null || processPlanning.getInstanceRrn() <=0) &&  processRrn> 0,
                           Errors.create().key(MessageIdList.PROCESS_NO_PERMISSION).content("No permission to view the process!").build());

            Assert.isFalse(processPlanning.getObjectType() == null ||
                                   !processPlanning.getObjectType().equalsIgnoreCase(ObjectList.ROUTE_KEY),
                           Errors.create().key(MessageIdList.ROUTE_VALIDATE_TYPE).content("It is not subPlan!")
                                 .build());

            Assert.isFalse(processPlanning.getObjectSubtype() == null ||
                                   !processPlanning.getObjectSubtype().equalsIgnoreCase(ObjectList.PROCESS_KEY),
                           Errors.create().key(MessageIdList.ROUTE_VALIDATE_TYPE).content("It is not Process!")
                                 .build());
            // //检查是否有权限查看该process
            // checkProcessPermission(processPlanning.getInstanceId());
            infoForm.setTransId(Constants.MODIFY_KEY);
            //处理是否是从基本信息界面发起的请求,而不是其他 tab
            if (!WebUtils.getParameterBoolean("homePage", request)) {
                infoForm.setNpwType(processPlanning.getAttribute3());
            }
            //判断NPWproduct 和 普通 product 是否对应菜单
            if ((StringUtils.isBlank(processPlanning.getAttribute3()) &&
                    StringUtils.equalsIgnoreCase(infoForm.getNpwType(), Constants.NPW_TYPE)) ||
                    (StringUtils.isBlank(infoForm.getNpwType()) &&
                            StringUtils.equalsIgnoreCase(processPlanning.getAttribute3(), Constants.NPW_TYPE))) {
                infoForm.setInstanceId("");
                request.setAttribute("errorMsgAlert", I18nUtils.getMessage("process.cant_edit_this_menu",
                                                                           "Process:{} not allowed to edit " + "in " +
                                                                                   "this menu! ",
                                                                           processPlanning.getInstanceId()));
                return init(mapping, form, request, response);
            }
            List<Relation> fullRelations = baseService
                    .getFullRelations(LinkTypeList.PROCESS_TO_PERMISSIONS_GROUP, processPlanning.getInstanceRrn(), 0L);
            StringBuilder processPermissionsGroupRrns = new StringBuilder();
            StringBuilder processPermissionsGroupIds = new StringBuilder();
            int i = 0;
            for (Relation relation : fullRelations) {
                processPermissionsGroupRrns.append(relation.getToRrn());
                processPermissionsGroupIds.append(baseService.getNamedObjectId(relation.getToRrn()));
                i++;
                if (i < fullRelations.size()) {
                    processPermissionsGroupRrns.append(",");
                    processPermissionsGroupIds.append(",");
                }
            }
            infoForm.setProcessPermissionsGroupRrns(processPermissionsGroupRrns.toString());
            infoForm.setProcessPermissionsGroupIds(processPermissionsGroupIds.toString());
            request.setAttribute("permissionsGroup", processPermissionsGroupRrns.toString());
        }

        List<ProcessVersion> versions = prpService.getProcessVersions(processPlanning);
        infoForm.setVersionEditEnable(String.valueOf(checkVersionEditEnable(versions)));
        infoForm.setObjectDeleteEnable(checkObjectDeleteEnable(versions));
        infoForm.setDisableFlag(baseService.getNamedObjectDisableFlag(processPlanning.getInstanceRrn()));
        infoForm.setFlagType(processPlanning.getFlagType());
        infoForm.setReworkFlag(baseService.getProcessReworkFlag(processPlanning.getInstanceRrn()));

        request.setAttribute(SessionNames.PROCESSPLANNING_KEY, processPlanning);
        request.setAttribute("versionForm", infoForm);
        return (mapping.findForward(Constants.MODIFY_KEY));
    }

    public ActionForward create(ActionMapping mapping, TechnologyVersionInfoForm form, HttpServletRequest request,
                                HttpServletResponse response) throws Exception {
        ProcessPlanning processPlanning = new ProcessPlanning(form.getInstanceId(), getNamedSpace(ObjectList.WFL_KEY,
                                                                                                  LocalContext
                                                                                                          .getFacilityRrn()),
                                                              ObjectList.WFL_KEY);

        Assert.isFalse(StringUtils.isEmpty(form.getInstanceId()),
                       Errors.create().key(MessageIdList.PROCESS_EMPTY_ID).content("process id empty").build());
        ProcessPlanning pp = prpService.getProcessPlanning(processPlanning);
        long processRrn = getInstanceRrn(form.getInstanceId(), LocalContext.getFacilityRrn(), ObjectList.WFL_KEY);
        Assert.isFalse((pp == null || pp.getInstanceRrn() <=0) &&  processRrn> 0,
                       Errors.create().key(MessageIdList.PROCESS_NO_PERMISSION)
                             .content("No permission to view the process!").build());

        Assert.isFalse(processRrn > 0,
                       Errors.create().key(MessageIdList.PROCESS_INVALID_SAME).content("流程已存在").build());

        Assert.isFalse(NumberUtils.isCreatable(form.getInstanceId()) && form.getInstanceId().matches("^[0-9]*$"),
                       Errors.create().key(MessageIdList.PROCESS_PURE_NUMBER).content("流程不能为纯数字").build());

        form.setInstanceId(StringUtils.trimToUpperCase(form.getInstanceId()));

        PropertyUtils.copyProperties(processPlanning, form);

        processPlanning.setTransPerformedby(LocalContext.getUserId());
        processPlanning.setDisableFlag(form.getDisableFlag());
        processPlanning.setTransId(Constants.CREATE_KEY);

        processPlanning.setObjectType(ObjectList.ROUTE_KEY);
        processPlanning.setObjectSubtype(ObjectList.PROCESS_KEY);
        processPlanning.setFlagType(form.getFlagType());
        processPlanning.setReworkFlag(form.getReworkFlag());
        processPlanning.setAttribute3(form.getNpwType());
        String processPermissionsGroupRrns = form.getProcessPermissionsGroupRrns();
        String[] groupRrnArray = StringUtils.split(processPermissionsGroupRrns, ',');
        StringBuilder processPermissionsGroupIds = new StringBuilder();
        int i = 0;
        for (String groupRrn : groupRrnArray) {
            i++;
            processPermissionsGroupIds.append(getInstanceId(new Long(groupRrn)));
            if (i < groupRrnArray.length) {
                processPermissionsGroupIds.append(",");
            }
        }
        //用于回显下拉框的值
        form.setProcessPermissionsGroupIds(processPermissionsGroupIds.toString());

        String processPermissionsGroup = form.getProcessPermissionsGroupRrns();
        String[] groups = StringUtils.split(processPermissionsGroup, ',');
        boolean hasUserFlag = false;
        for (String group : groups) {
            List<Map> userGroupGrantUserList = securityService
                    .getHasGrantUserAll(new Long(group), LocalContext.getUserId());
            for (Map map : userGroupGrantUserList) {
                String instanceId = MapUtils.getString(map, "instanceId");
                if (StringUtils.isEqual(instanceId, LocalContext.getUserId())) {
                    hasUserFlag = true;
                }
            }
        }
        //如果所选用户组中都不包含当前用户,则不允许添加该流程
        Assert.isTrue(hasUserFlag, Errors.create().key(MessageIdList.PROCESS_USERGROUP_NO_USER).content(
                "Please select at least one User Group containing the current " + "user!").build());

        prpService.insertProcessPlanning(processPlanning, groups);

        updateLocalContext(response);
        //重定向刷新Localcontext
        response.sendRedirect("technologysave.do?instanceId=" + processPlanning.getInstanceId());
        return null;
    }

    public ActionForward copy(ActionMapping mapping, TechnologyVersionInfoForm form, HttpServletRequest request,
                              HttpServletResponse response) throws Exception {
        ProcessPlanning processPlanning = new ProcessPlanning(request.getParameter(Constants.COPY_KEY),
                                                              getNamedSpace(ObjectList.WFL_KEY,
                                                                            LocalContext.getFacilityRrn()),
                                                              ObjectList.WFL_KEY);

        String origId = form.getInstanceId();

        Assert.isFalse(StringUtils.isEmpty(origId), Errors.create().key(MessageIdList.PROCESS_ENTER_PROCESS_ID)
                                                          .content("Please enter the process id first!").build());

        processPlanning = (ProcessPlanning) getInstance(processPlanning);
        // populate the new information thru the new instance id
        PropertyUtils.copyProperties(form, processPlanning);

        // and restore the original Id
        form.setInstanceId(origId);

        form.setTransId(Constants.CREATE_KEY);

        form.setDisableFlag(baseService.getNamedObjectDisableFlag(processPlanning.getInstanceRrn()));
        form.setFlagType(processPlanning.getFlagType());

        List<Relation> fullRelations = baseService
                .getFullRelations(LinkTypeList.PROCESS_TO_PERMISSIONS_GROUP, processPlanning.getInstanceRrn(), 0L);
        StringBuilder processPermissionsGroupRrns = new StringBuilder();
        StringBuilder processPermissionsGroupIds = new StringBuilder();
        int i = 0;
        for (Relation relation : fullRelations) {
            processPermissionsGroupRrns.append(relation.getToRrn());
            processPermissionsGroupIds.append(baseService.getNamedObjectId(relation.getToRrn()));
            i++;
            if (i < fullRelations.size()) {
                processPermissionsGroupRrns.append(",");
                processPermissionsGroupIds.append(",");
            }
        }
        form.setProcessPermissionsGroupRrns(processPermissionsGroupRrns.toString());
        form.setProcessPermissionsGroupIds(processPermissionsGroupIds.toString());

        request.setAttribute(SessionNames.PROCESSPLANNING_KEY, processPlanning);
        request.setAttribute("versionForm", form);
        return (mapping.findForward(Constants.MODIFY_KEY));
    }

    public ActionForward update(ActionMapping mapping, TechnologyVersionInfoForm form, HttpServletRequest request,
                                HttpServletResponse response) throws Exception {
        ProcessPlanning processPlanning = new ProcessPlanning(form.getInstanceId(), getNamedSpace(ObjectList.WFL_KEY,
                                                                                                  LocalContext
                                                                                                          .getFacilityRrn()),
                                                              ObjectList.WFL_KEY);
        processPlanning = (ProcessPlanning) getInstance(processPlanning);

        checkPermissionForOperateProcess(processPlanning.getInstanceRrn());

        PropertyUtils.copyProperties(processPlanning, form);

        processPlanning.setObjectType(ObjectList.ROUTE_KEY);
        processPlanning.setObjectSubtype(ObjectList.PROCESS_KEY);
        processPlanning.setFlagType(form.getFlagType());
        processPlanning.setTransId(Constants.MODIFY_KEY);
        processPlanning.setTransPerformedby(LocalContext.getUserId());
        processPlanning.setDisableFlag(form.getDisableFlag());
        processPlanning.setReworkFlag(form.getReworkFlag());

        prpService.updateProcessPlanning(processPlanning, form.getProcessPermissionsGroupRrns());

        updateLocalContext(response);
        //重新请求刷新Localcontext
        request.getRequestDispatcher("technologysave.do?action=init").forward(request, response);
        return WebUtils.NULLActionForward;
    }

    public ActionForward delete(ActionMapping mapping, TechnologyVersionInfoForm form, HttpServletRequest request,
                                HttpServletResponse response) throws Exception {
        ProcessPlanning processPlanning = new ProcessPlanning(form.getInstanceId(), getNamedSpace(ObjectList.WFL_KEY,
                                                                                                  LocalContext
                                                                                                          .getFacilityRrn()),
                                                              ObjectList.WFL_KEY);

        long processPlanningRrn = baseService.getNamedObjectRrn(processPlanning);

        checkPermissionForOperateProcess(processPlanningRrn);

        prpService.deleteProcessPlanning(processPlanningRrn);

        form.setInstanceId(null);
        updateLocalContext(response);
        return init(mapping, form, request, response);
    }

    public ActionForward useInfo(ActionMapping mapping, TechnologyVersionInfoForm versionInfo,
                                 HttpServletRequest request) {
        long processRrn = this
                .getInstanceRrn(versionInfo.getInstanceId(), LocalContext.getFacilityRrn(), ObjectList.WFL_KEY);

        List<Item> usedProducts = prpService.getUsedByProducts(processRrn);
        if (CollectionUtils.isNotEmpty(usedProducts)) {
            List<Map> wflLists = new ArrayList<>();
            for (Item product : usedProducts) {
                Map<String, Object> wfl = new HashMap<>(4);
                wfl.put("productId", product.getInstanceId());
                wfl.put("productDesc", product.getInstanceDesc());
                wfl.put("productRrn", product.getInstanceRrn());
                wflLists.add(wfl);
            }
            request.setAttribute("productLists", wflLists);
        }
        return mapping.findForward("processwheretouse");
    }

    /**
     * 更新LocalContext中的processRrns
     *
     * @param response response对象
     */
    private void updateLocalContext(HttpServletResponse response) {
        String dataPermissionFlag = sysService.getDataPermissionFlag(LocalContext.getFacilityRrn());
        String processRrns = getProcessRrns(LocalContext.getUserRrn());
        JwtToken jwtToken = new JwtToken(LocalContext.getFacilityRrn(), LocalContext.getUserRrn(),
                                         LocalContext.getUserId(), I18nUtils.getCurrentLanguage().toString(),
                                         processRrns, dataPermissionFlag);
        JwtUtils.setTokenToCookie(response, JwtUtils.sign(jwtToken));
    }

    private String getProcessRrns(long userRrn) {
        Set<Long> processRrns = new HashSet<>();
        List<UserGroup> userGroups = securityService.getUserGroupByUserRrn(userRrn);
        for (UserGroup userGroup : userGroups) {
            List<Relation> relations = baseService
                    .getRelationsUseToRrn(userGroup.getInstanceRrn(), LinkTypeList.PROCESS_TO_PERMISSIONS_GROUP);
            for (Relation relation : relations) {
                processRrns.add(relation.getFromRrn());
            }
        }
        return StringUtils.join(processRrns, ",");
    }

}