AutoMonitorLotHoldReleaseAction.java

package com.mycim.webapp.actions;

import com.fa.sesa.exception.Assert;
import com.fa.sesa.exception.Errors;
import com.fa.sesa.exception.SystemIllegalArgumentException;
import com.fa.sesa.threadlocal.LocalContext;
import com.mycim.framework.context.spring.SpringContext;
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.server.carrier.service.CarrierService;
import com.mycim.server.wip.service.DiffBatchQueryService;
import com.mycim.valueobject.MessageIdList;
import com.mycim.valueobject.automonitor.entity.LotAutoMonitorInfo;
import com.mycim.valueobject.consts.HoldCodeNames;
import com.mycim.valueobject.security.User;
import com.mycim.valueobject.wip.Lot;
import com.mycim.valueobject.wip.LotStatus;
import com.mycim.valueobject.wip.TransReason;
import com.mycim.webapp.Constants;
import com.mycim.webapp.WebUtils;
import com.mycim.webapp.forms.LotInfoFormAutoMonitor;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.springframework.beans.factory.annotation.Autowired;

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

/**
 * @author finatice.yang
 * @date 2021/9/2
 **/
public class AutoMonitorLotHoldReleaseAction extends AutoMonitorAction {

    @Override
    public ActionForward init(ActionMapping mapping, ActionForm form, HttpServletRequest request,
                              HttpServletResponse response) {
        return initHoldOrRelease(mapping, form, request, response);
    }

    public ActionForward initHoldOrRelease(ActionMapping mapping, ActionForm form, HttpServletRequest request,
                                           HttpServletResponse response) {
        LotInfoFormAutoMonitor theform = (LotInfoFormAutoMonitor) form;
        Lot lot = lotInqService.getLot(theform.getLotId());
        theform.setProductId(lot.getProductId());
        theform.setCarrierId(lot.getCarrierId());
        LotAutoMonitorInfo monitorLotInfo = lotAutoMonitorInqService.getLotActiveAutoMonitorInfo(lot.getLotRrn());
        Assert.state(Objects.nonNull(monitorLotInfo), Errors.create().content("Monitor lot not exist!").build());

        Map<String, Object> lotMapInfo = builidlotMapInfo(lot, monitorLotInfo);
        request.setAttribute("lotInfo", lotMapInfo);
        List holdInfos = new ArrayList<>();
        if (lot != null && lot.getLotRrn() > 0) {
            holdInfos = wipQueryService.getHoldReasons(lot.getLotRrn());
            request.setAttribute("lotId", lot.getLotId());
        }
        request.setAttribute("holdReasons", holdInfos);
        theform.setCacheCollection(WebUtils.getCacheObj2String(holdInfos));
        String flag = WebUtils.getParameter("flag", request);
        if (StringUtils.equalsIgnoreCase(Constants.HOLD_KEY, flag)) {
            if (LotStatus.isCanHold(lot.getLotStatus())) {
                return mapping.findForward(Constants.HOLD_KEY);
            } else if (LotStatus.isCanRunningHold(lot.getLotStatus())) {
                return mapping.findForward(Constants.RUNNING_HOLD_KEY);
            } else {
                throw new SystemIllegalArgumentException(
                        Errors.create().key(MessageIdList.LOT_STATUS_NOT_ALLOW).content("Lot status not allow!")
                              .build());
            }
        } else if (StringUtils.equalsIgnoreCase(Constants.RELEASE_KEY, flag)) {
            if (LotStatus.isHold(lot.getLotStatus())) {
                return mapping.findForward(Constants.RELEASE_KEY);
            } else if (LotStatus.isRunningHold(lot.getLotStatus())) {
                return mapping.findForward(Constants.RUNNING_RELEASE_KEY);
            } else {
                throw new SystemIllegalArgumentException(
                        Errors.create().key(MessageIdList.LOT_STATUS_NOT_ALLOW).content("Lot status not allow!")
                              .build());
            }
        } else {
            return mapping.findForward(Constants.INIT_KEY);
        }
    }

    public ActionForward hold(ActionMapping mapping, ActionForm form, HttpServletRequest request) throws Exception {
        LotInfoFormAutoMonitor theform = (LotInfoFormAutoMonitor) form;
        String lotId = theform.getLotId();

        Lot lot = lotInqService.getLot(lotId);
        Assert.state(Objects.nonNull(lot) && lot.getLotRrn() > 0,
                     Errors.create().key(MessageIdList.LOT_LOTRRN_NOT_FOUND).content("Cannot Find Lot!").build());

        Assert.state(StringUtils.isNotBlank(theform.getReason()),
                     Errors.create().key(MessageIdList.ERROR_REASON_IS_EMPTY).content("Reason is empty!").build());

        List<Lot> holdLotList = new ArrayList<>();
        List<Lot> batchLotList = diffBatchQueryService.getBatchLotList(lot.getLotRrn());
        if(CollectionUtils.isNotEmpty(batchLotList)) {
            for(Lot batchLot:batchLotList) {
                Assert.state(LotStatus.isCanHold(batchLot.getLotStatus()),
                             Errors.create().key(MessageIdList.LOT_STATUS_CANT_NOT_BE_HOLD)
                                   .content("Lot status must be 'HOLD' or 'WAITING'!").build());
                holdLotList.add(batchLot);
            }
        } else {
            Assert.state(LotStatus.isCanHold(lot.getLotStatus()),
                         Errors.create().key(MessageIdList.LOT_STATUS_CANT_NOT_BE_HOLD)
                               .content("Lot status must be 'HOLD' or 'WAITING'!").build());
            holdLotList.add(lot);
        }
        List<String> lockLotRrns = holdLotList.stream().map(holdLot -> StringUtils.toString(holdLot.getLotRrn()))
                                              .collect(Collectors.toList());

        User user = securityService.getUser(LocalContext.getUserId(), LocalContext.getFacilityRrn());
        TransReason transReason = buildHoldTransReason(theform);
        lotService.holdLot(holdLotList, user, transReason, lockLotRrns);

        return mapping.findForward("toInit");
    }

    public ActionForward runningHold(ActionMapping mapping, ActionForm form,
                                     HttpServletRequest request) throws Exception {
        LotInfoFormAutoMonitor theform = (LotInfoFormAutoMonitor) form;

        String lotId = theform.getLotId();

        Lot lot = lotInqService.getLot(lotId);
        Assert.state(Objects.nonNull(lot) && lot.getLotRrn() > 0,
                     Errors.create().key(MessageIdList.LOT_LOTRRN_NOT_FOUND).content("Cannot Find Lot!").build());

        Assert.state(StringUtils.isNotBlank(theform.getReason()),
                     Errors.create().key(MessageIdList.ERROR_REASON_IS_EMPTY).content("Reason is empty!").build());

        List<Lot> holdLotList = new ArrayList<>();
        List<Lot> batchLotList = diffBatchQueryService.getBatchLotList(lot.getLotRrn());
        if(CollectionUtils.isNotEmpty(batchLotList)) {
            for(Lot batchLot:batchLotList) {
                Assert.state(LotStatus.isCanRunningHold(batchLot.getLotStatus()),
                             Errors.create().key(MessageIdList.LOT_STATUS_CANT_NOT_BE_HOLD)
                                   .content("Lot status must be 'RUNNING' or 'RUNNINGHOLD'!").build());
                holdLotList.add(batchLot);
            }
        } else {
            Assert.state(LotStatus.isCanRunningHold(lot.getLotStatus()),
                         Errors.create().key(MessageIdList.LOT_STATUS_CANT_NOT_BE_HOLD)
                               .content("Lot status must be 'RUNNING' or 'RUNNINGHOLD'!").build());
            holdLotList.add(lot);
        }
        List<String> lockLotRrns = holdLotList.stream().map(holdLot -> StringUtils.toString(holdLot.getLotRrn()))
                                              .collect(Collectors.toList());

        User user = securityService.getUser(LocalContext.getUserId(), LocalContext.getFacilityRrn());
        TransReason transReason = buildHoldTransReason(theform);
        lotService.holdRunningLot(holdLotList, user, transReason, lockLotRrns);

        return mapping.findForward("toInit");

    }

    public ActionForward release(ActionMapping mapping, ActionForm form, HttpServletRequest request,
                                 HttpServletResponse response) throws Exception {
        LotInfoFormAutoMonitor theform = (LotInfoFormAutoMonitor) form;

        String lotId = theform.getLotId();
        String fieldFlag = request.getParameter("fieldFlags");
        String[] fieldFlags = fieldFlag.split(",");

        Lot lot = lotInqService.getLot(lotId);
        Assert.state(Objects.nonNull(lot) && lot.getLotRrn() > 0,
                     Errors.create().key(MessageIdList.LOT_LOTRRN_NOT_FOUND).content("Cannot Find Lot!").build());

        Assert.state(LotStatus.isHold(lot.getLotStatus()),
                     Errors.create().key(MessageIdList.LOT_STATUS_NOT_ALLOW).content("Lot status not allow!").build());

        List<Map> holdReasons = wipQueryService.getHoldReasons(lot.getLotRrn());
        List<Map> releaseReasons = new ArrayList();
        List<Map> unReleaseReasons = new ArrayList();

        // 是否存在trackOutHold释放
        boolean trackOutHoldExisted = false;
        for (int i = 0; i < holdReasons.size(); i++) {
            Map holdReason = holdReasons.get(i);
            String reasonCode = MapUtils.getString(holdReason, "reasonCode");

            if (StringUtils.equals("0", fieldFlags[i])) {
                releaseReasons.add(holdReason);
            } else {
                unReleaseReasons.add(holdReason);
            }
        }

        Assert.state(CollectionUtils.isNotEmpty(releaseReasons),
                     Errors.create().key(MessageIdList.LOT_RELEASE_HOLD_EMPTY).content("please select release hold!")
                           .build());

        Map<String, Object> releaseInfo = buildReleaseInfo(theform, lot, releaseReasons);

        lotService.releaseLot(releaseInfo);

        return mapping.findForward("toInit");
    }

    public ActionForward runningRelease(ActionMapping mapping, ActionForm form, HttpServletRequest request,
                                        HttpServletResponse response) throws Exception {
        LotInfoFormAutoMonitor theform = (LotInfoFormAutoMonitor) form;

        String lotId = theform.getLotId();
        String fieldFlag = request.getParameter("fieldFlags");
        String[] fieldFlags = fieldFlag.split(",");

        Lot lot = lotInqService.getLot(lotId);
        Assert.state(Objects.nonNull(lot) && lot.getLotRrn() > 0,
                     Errors.create().key(MessageIdList.LOT_LOTRRN_NOT_FOUND).content("Cannot Find Lot!").build());

        Assert.state(LotStatus.isRunningHold(lot.getLotStatus()),
                     Errors.create().key(MessageIdList.LOT_STATUS_NOT_ALLOW).content("Lot status not allow!").build());

        List<Map> holdReasons = wipQueryService.getHoldReasons(lot.getLotRrn());
        List<Map> releaseReasons = new ArrayList();
        List<Map> unReleaseReasons = new ArrayList();

        // 是否存在trackOutHold释放
        boolean trackOutHoldExisted = false;
        for (int i = 0; i < holdReasons.size(); i++) {
            Map holdReason = holdReasons.get(i);
            String reasonCode = MapUtils.getString(holdReason, "reasonCode");

            if (StringUtils.equals("0", fieldFlags[i])) {
                releaseReasons.add(holdReason);
            } else {
                unReleaseReasons.add(holdReason);
            }
        }

        Assert.state(CollectionUtils.isNotEmpty(releaseReasons),
                     Errors.create().key(MessageIdList.LOT_RELEASE_HOLD_EMPTY).content("please select release hold!")
                           .build());

        Map<String, Object> releaseInfo = buildReleaseInfo(theform, lot, releaseReasons);

        lotService.releaseRunningLot(releaseInfo);
        return mapping.findForward("toInit");
    }

    private Map<String, Object> buildHoldInfo(LotInfoFormAutoMonitor theform, Lot lot) {
        String reason = theform.getDepartment() + " Reason: Holdcode is " + theform.getReasonCode() + ". " +
                theform.getReason();
        TransReason transReason = new TransReason();
        transReason.setReasonCode(theform.getReasonCode());
        transReason.setReason(reason);
        transReason.setTransQty1(lot.getQty1());
        transReason.setTransQty2(lot.getQty2());
        transReason.setResponsibility(LocalContext.getUserId());
        Map<String, Object> holdInfo = MapUtils.newHashMap();
        holdInfo.put("lotRrn", new Long(lot.getLotRrn()).toString());
        holdInfo.put("lotId", lot.getLotId());
        holdInfo.put("lotStatus", lot.getLotStatus());
        holdInfo.put("transPerformedBy", LocalContext.getUserId());
        holdInfo.put("holdBy", LocalContext.getUserRrn() + "");
        holdInfo.put("transComments", reason);
        holdInfo.put("operation", lot.getOperationId());
        holdInfo.put("holdcode", theform.getReasonCode());
        holdInfo.put("transReason", transReason);
        return holdInfo;
    }

    private TransReason buildHoldTransReason(LotInfoFormAutoMonitor theform) {
        String reason = theform.getDepartment() + " Reason: Holdcode is " + theform.getReasonCode() + ". " +
                theform.getReason();
        TransReason transReason = new TransReason();
        transReason.setReasonCode(theform.getReasonCode());
        transReason.setReason(reason);
        transReason.setResponsibility(LocalContext.getUserId());
        return transReason;
    }

    private Map<String, Object> buildReleaseInfo(LotInfoFormAutoMonitor theform, Lot lot, List<Map> releaseReasons) {
        Map<String, Object> releaseInfo = MapUtils.newHashMap();
        releaseInfo.put("lotRrn", new Long(lot.getLotRrn()).toString());
        releaseInfo.put("lotId", lot.getLotId());
        releaseInfo.put("releaseReasons", releaseReasons);
        releaseInfo.put("transPerformedBy", LocalContext.getUserId());
        releaseInfo.put("transComments", theform.getLotComments());
        releaseInfo.put("operation", lot.getOperationId());

        TransReason transReason = new TransReason();
        transReason.setReasonCode(theform.getReasonCode());

        transReason.setReason(theform.getLotComments());
        transReason.setTransQty1(lot.getQty1());
        transReason.setTransQty2(lot.getQty2());
        transReason.setResponsibility(LocalContext.getUserId());
        transReason.setReason(theform.getReason());

        releaseInfo.put("transReason", transReason);
        releaseInfo.put("superFlag", "0");
        return releaseInfo;
    }

}