AdjustLotAction.java

package com.mycim.webapp.actions.lot.adjustlot;

import com.fa.sesa.exception.Assert;
import com.fa.sesa.exception.Errors;
import com.fa.sesa.threadlocal.LocalContext;
import com.mycim.framework.utils.MiscUtils;
import com.mycim.framework.utils.beans.BeanUtils;
import com.mycim.framework.utils.beans.PropertyUtils;
import com.mycim.framework.utils.lang.ObjectUtils;
import com.mycim.framework.utils.lang.StringUtils;
import com.mycim.framework.utils.lang.collections.MapUtils;
import com.mycim.framework.utils.lang.math.NumberUtils;
import com.mycim.framework.utils.lang.time.DateUtils;
import com.mycim.framework.utils.msg.JsonUtils;
import com.mycim.valueobject.LocationNames;
import com.mycim.valueobject.MessageIdList;
import com.mycim.valueobject.ObjectList;
import com.mycim.valueobject.consts.EventName;
import com.mycim.valueobject.consts.ReferenceDetailNames;
import com.mycim.valueobject.ems.Entity;
import com.mycim.valueobject.ems.Equipment;
import com.mycim.valueobject.prp.ContextValue;
import com.mycim.valueobject.sys.ReferenceFile;
import com.mycim.valueobject.sys.ReferenceFileDetail;
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.actions.WipSetupAction;
import com.mycim.webapp.forms.lot.LotInfoForm;
import org.apache.commons.compress.utils.Sets;
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 Luopeng.Wang
 * @version 6.0.0
 * @date 2019/10/13
 **/
public class AdjustLotAction extends WipSetupAction {
    @Override
    public ActionForward init(ActionMapping mapping, ActionForm form, HttpServletRequest request,
                              HttpServletResponse response) throws Exception {
        LotInfoForm theform = (LotInfoForm) form;

        Lot lot = initLotBaseInfoForJsp(request, true, null, null);
        String lotStatus = lot.getLotStatus();
        Assert.isFalse(
                LotStatus.DISPATCH.equalsIgnoreCase(lotStatus) || LotStatus.PROCESSED.equalsIgnoreCase(lotStatus),
                Errors.create().content("Lot Status {} Not Allowed!").args(lotStatus).build());


        super.checkCstRemoved(Sets.newHashSet(lot.getLotRrn()));

        //        当carrierId为空事,视图渲染为N/A ;
        PropertyUtils.copyProperties(theform, lot);
        theform.setRecipePhysicalId(getRecipePhysicalId(lot));
        theform.setDueDateS(DateUtils.formatDate(lot.getDueDate(), DateUtils.DATE_FORMAT4DAY));
        request.setAttribute("DATE_FORMAT_KEY", DateUtils.DATE_FORMAT4DAY);
        theform.setWaitTime(lot.getwaitTime());

        //为确保sort与manual的数据一致性,当sort创建以后将不允许Adjust
        this.checkWaitJobs(lot.getCarrierRrn(), 0L, 0L, null);

        String carrierId = getInstanceId(MiscUtils.parseSQL(lot.getCarrierRrn()));
        String productId = getInstanceId(MiscUtils.parseSQL(lot.getProductRrn()));
        theform.setCarrierId(carrierId == null || carrierId.trim().equals("") ? "N/A" : carrierId);
        theform.setProductId(productId);
        theform.setLotComments(lot.getLotComments());
        theform.setQty1toInt(theform.getQty1().intValue());
        String createType = lot.getCreateCategory().toUpperCase();
        // String cassetteCreateType= carrierService.getCarrier(lot.getCarrierRrn()).getFlagType();//将cassette type传到前台,用于比对lot的createType能否被修改
        if ("C".equalsIgnoreCase(createType) || "D".equalsIgnoreCase(createType)) {
            //该字段只用于页面区分批次类型
            theform.setLotPlanType("1");
        } else {
            theform.setLotPlanType("0");
        }
        // request.setAttribute("cassetteCreateType",cassetteCreateType);
        request.setAttribute("createType", createType);
        request.setAttribute("currentLotType", lot.getLotType().toUpperCase());
        ContextValue reticleFamilyContext = ctxExecService
                .getReticleFamilyContext(lot.getProductRrn(), lot.getProductVersion(), lot.getProcessRrn(),
                                         lot.getProcessVersion(), lot.getRouteRrn(), lot.getOperationRrn());
        if (reticleFamilyContext != null) {
            theform.setReticleGroupId(reticleFamilyContext.getResultValue1());
        }
        String location = lot.getLocation();
        String pLocation = lot.getpLocation();
        theform.setLocation(location);
        theform.setpLocation(pLocation);
        return mapping.findForward(Constants.INIT_KEY);
    }

    public ActionForward modifyLotLocation(ActionMapping mapping, ActionForm form, HttpServletRequest request,
                                           HttpServletResponse response) throws Exception {
        LotInfoForm theform = (LotInfoForm) form;
        String user = LocalContext.getUserId();
        Long facilityRrn = LocalContext.getFacilityRrn();
        // List<Lot> lockLots = new ArrayList<>();
        Map transInfo = new HashMap();
        transInfo.put("user", user);

        Assert.isFalse(theform.getLotOwner() == null || theform.getLotOwner().trim().length() < 1,
                       Errors.create().content("Lot Owner is require").build());

        long lotOwnerRrn = this.getInstanceRrn(theform.getLotOwner().toUpperCase().trim(),
                                               this.getNamedSpace(ObjectList.USER_KEY, facilityRrn),
                                               ObjectList.USER_KEY);
        Assert.isFalse(lotOwnerRrn == 0, Errors.create().content("Owner not found").build());

        if (StringUtils.isNotBlank(theform.getReticleGroupId())) {
            theform.setReticleGroupRrn(
                    getInstanceRrn(theform.getReticleGroupId(), facilityRrn, ObjectList.RETICLE_GROUP));
        }

        Lot oldLot = lotQueryService.getLot(theform.getLotId(), facilityRrn);
        transInfo.put("lotRrn", oldLot.getLotRrn());
        //需求40590,此处取消卡控,卡控内容:修改后的lot create category 必须与cassette create category保持一致
        // Assert.isFalse(!StringUtils.equalsIgnoreCase(theform.getCreateCategory(),carrierService.getCarrier(oldLot.getCarrierRrn()).getFlagType()),
        //                Errors.create().key(MessageIdList.CARRIER_CATEGORY_IS_NOT_CONSISTENT).build());
        //卡控post future hold被hold住的lot

        //需求40590,在running/hold/waiting状态下均可修改
        //checkPostFutureHold(oldLot.getLotRrn());
        // Assert.isFalse(!(LotStatus.WAITING.equalsIgnoreCase(oldLot.getLotStatus()) ||
        //                        LotStatus.HOLD.equalsIgnoreCase(oldLot.getLotStatus()) ||
        //                        LotStatus.RUNNING.equalsIgnoreCase(oldLot.getLotStatus()))
        //         ,Errors.create().content("Lot Status {} Not Allowed!").args(oldLot.getLotStatus()).build());

        //Lot Status为hold、WAITING、RUNNING、RUNNINGHOLD、RUNCARDHOLD、OCAPHOLD、BANKED 时可以修改
        if(ObjectUtils.isNotEmpty(oldLot)){
            List<String> stastusWhiteList=new ArrayList(Arrays.asList(LotStatus.WAITING,LotStatus.RUNNING,LotStatus.RUNNINGHOLD,LotStatus.RUNCARD_HOLD,LotStatus.BANKED,LotStatus.HOLD));

            Assert.state(stastusWhiteList.contains(oldLot.getLotStatus().toUpperCase()),
                         Errors.create().content(MessageIdList.LOT_STATUS_NOT_ALLOW_ADJUST_LOT).build());

            //Lot Status为WAITING、RUNNING、RUNNINGHOLD、RUNCARDHOLD、OCAPHOLD、BANKED 时不可以修改Create Category、Lot Type
            stastusWhiteList.remove(LotStatus.HOLD);
            if(stastusWhiteList.contains(oldLot.getLotStatus())){
                Assert.state(StringUtils.equalsIgnoreCase(oldLot.getCreateCategory(),theform.getCreateCategory()) &&
                                     StringUtils.equalsIgnoreCase(oldLot.getLotType(),theform.getLotType()),
                             Errors.create().content(MessageIdList.LOT_STATUS_NOT_ALLOW_ADJUST_LOT_CREATE_CATEGORY_AND_TYPE).build());
            }
        }


        // Assert.isFalse(LotStatus.DISPATCH.equalsIgnoreCase(oldLot.getLotStatus()) ||
        //                        LotStatus.PROCESSED.equalsIgnoreCase(oldLot.getLotStatus()),
        //                Errors.create().content("Lot Status {} Not Allowed!").args(oldLot.getLotStatus()).build());
        /*
        if (!LotStatus.HOLD.equalsIgnoreCase(oldLot.getLotStatus())) {
            throw new WebException("Cannot be modified without holding!");
        }
        */
        // check lot  update location
        String newLocationId = theform.getLocation();
        /*if (StringUtils.isNotEmpty(newLocationId)) {
            String refId = ReferenceDetailNames.LOT_LOCATION_REF;
            long refRrn = getInstanceRrn(refId, LocalContext.getFacilityRrn(), ObjectList.REFERENCE_FILE_KEY);
            Assert.isFalse(refRrn <= 0, Errors.create().content("The {} dose not exist!").args(refId).build());

            Assert.isFalse(NumberUtils.toLong(newLocationId) <= 0,
                           Errors.create().content("The key1value of the {} must be a " + "number greater than 0!")
                                 .args(refId).build());

            String data1 = sysService.getReferenceFileData1ValueByKey1Value(refId, newLocationId);
            //当未查到,getReferenceFileData1ValueByKey1Value会直接返回key1Value,所以这里用==判断
            Assert.isFalse(data1 == newLocationId, Errors.create().content("The value {} dose not belong to {}!")
                                                         .args(theform.getLocation(),
                                                               ReferenceDetailNames.LOT_LOCATION_REF).build());
            newLocationId = data1;
        }*/
        if (!StringUtils.equals(oldLot.getLocation(), newLocationId)) {
            if (StringUtils.isNotEmpty(theform.getLocation())) {
                long locationRrn = -Math.abs(NumberUtils.toLong(theform.getLocation()));//以负数保存到db,方便区分查询
                transInfo.put("locationRrn", locationRrn);
            }

            ////需求40590,在running/hold/waiting状态下均可修改
            // Assert.isTrue(StringUtils.equals(oldLot.getLotStatus(), LotStatus.HOLD),
            //               Errors.create().content("Cannot be modified without holding!").build());

            transInfo.put("location", theform.getLocation());
            transInfo.put("changeLocationFlag", true);
        } else {
            transInfo.put("changeLocationFlag", false);
        }

        transInfo.put("reticleGroupRrn", new Long(theform.getReticleGroupRrn()));
        transInfo.put("lotOwner", StringUtils.trim(theform.getLotOwner()));
        transInfo.put("lotId", theform.getLotId());
        transInfo.put("currOperation", theform.getOperationId());

        transInfo.put("operationId", theform.getOperationId());
        transInfo.put("qty", "" + theform.getQty1());
        transInfo.put("productId", theform.getProductId());
        transInfo.put("route", "");

        transInfo.put("hotFlag", theform.getHotFlag());

        transInfo.put("priority", theform.getPriority());
        String createCategoryDesc = sysService
                .referenceDetailExchangeNull("$LOT_CREATE_CATEGORY", theform.getCreateCategory(), "data_1_value");
        transInfo.put("lotType", theform.getLotType());
        transInfo.put("createCategory", theform.getCreateCategory());

        transInfo.put("qty1", theform.getQty1());
        transInfo.put("qty2", theform.getQty2());

        if (!theform.getDueDateS().trim().equalsIgnoreCase("")) {
            transInfo.put("dueDateS", DateUtils.stringToTimestamp(theform.getDueDateS() + " 00:00:00"));
            transInfo.put("dueDate", DateUtils.stringToTimestamp(theform.getDueDateS() + " 00:00:00"));

        } else {
            transInfo.put("dueDateS", null);
            transInfo.put("dueDate", null);
        }

        transInfo.put("lotComments", theform.getLotComments());
        transInfo.put("customerId", theform.getCustomerId());
        transInfo.put("shippingCode", theform.getShippingCode());
        transInfo.put("outerOrderNO", theform.getOuterOrderNO());
        transInfo.put("outOrderType", theform.getOutOrderType());
        transInfo.put("facilityRrn", facilityRrn);
        transInfo.put("customerLotId", theform.getCustomerLotId());

        transInfo.put("transId", "ADJUST");

        String splitMergeFlag = theform.getSplitMergeFlag();
        Assert.isFalse(StringUtils.isNotBlank(splitMergeFlag) && !LocationNames.checkLotFlagName(splitMergeFlag),
                       Errors.create().content("flag not match").build());

        transInfo.put("splitMergeFlag", theform.getSplitMergeFlag());
        transInfo.put("pollutionLevel", theform.getPollutionLevel());
        String userRRN = theform.getUserId().trim();
        String userName = securityService.getUserName(Long.parseLong(userRRN));
        String reason = theform.getReasonCode() + " " + theform.getDeptExt().trim().toUpperCase() + " " +
                userName.toUpperCase() + " " + theform.getReason();

        // String oldPriority = String.valueOf(oldLot.getPriority());
        // String oldDueDateS = DateUtils.formatDate(oldLot.getDueDate(), DateUtils.DATE_FORMAT4DAY);
        // String newPriority = String.valueOf(transInfo.get("priority"));
        // String newDueDateS = DateUtils.formatDate((Date) transInfo.get("dueDateS"), DateUtils.DATE_FORMAT4DAY);
        // String oldPollutionLevel = String.valueOf(oldLot.getPollutionLevel());
        // String newPollutionLevel = MapUtils.getString(transInfo, "pollutionLevel");

        if (theform.getHotFlag() == null) {
            transInfo.put("hotFlag", oldLot.getHotFlag());
        }

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

        transReason.setTransQty1(oldLot.getQty1());
        transReason.setTransQty2(oldLot.getQty2());
        transReason.setResponsibility(user);
        transInfo.put("transReason", transReason);

        //污染等级只能为数字
        Assert.isTrue(NumberUtils.isCreatable(theform.getPollutionLevel()),
                      Errors.create().key(MessageIdList.LOT_POLLUTIONLEVEL_MUST_BE_NUMBER)
                            .content("Contamination Level " + "can only be number").build());
        transInfo.put("pollutionLevel", theform.getPollutionLevel());


        Map transBefore = BeanUtils.copyBeanToMap(oldLot);

        Map before = new HashMap();
        Map after = new HashMap();

        for (String key : ADJUST_LOT_FIELDS) {
            before.put(key, MapUtils.getString(transBefore, key));
            after.put(key, MapUtils.getString(transInfo, key));
        }

        transInfo.put("adjustBeforeJson", JsonUtils.toString(before));
        transInfo.put("adjustAfterJson", JsonUtils.toString(after));
        // lockLots.add(oldLot);
        // checkAndCreateLotsTransLock(LocalContext.getUserRrn(), TransactionNames.LOCK_ADJUST_LOT, lockLots,
        //                             "Adjust lot in AdjustLotAction by " + user);
        lotService.adjustLot(transInfo);

        request.setAttribute("transId", "adjustlot");
        request.setAttribute("returnlocation", "true");
        return init(mapping, form, request, response);
    }

    public Map getLotTypes(Map map) {
        long facilityRrn = LocalContext.getFacilityRrn();
        Map options = new LinkedHashMap();
        String categoryId = MapUtils.getString(map, "categoryId");
        String type = "$LOT_TYPE";
        if (!"PE".equalsIgnoreCase(categoryId)) {
            type = "$LOT_TYPE2";
        }
        String namedSpace = baseService.getNamedSpace(facilityRrn, ObjectList.REFERENCE_FILE_KEY);
        ReferenceFile rf = new ReferenceFile(type, namedSpace, ObjectList.REFERENCE_FILE_KEY);
        rf = sysService.getReferenceFile(rf);
        if (rf.getInstanceRrn() > 0) {
            List<ReferenceFileDetail> coll = (List<ReferenceFileDetail>) rf.getValuesItems();
            if (coll != null && coll.size() > 0) {
                for (ReferenceFileDetail rfd : coll) {
                    options.put(rfd.getData1Value(), rfd.getKey1Value());
                }
            }
        }
        return options;
    }

    private Map buildEquipInfoForLot(Lot lot) {
        Map<String, Object> equipmentInfo = new HashMap<>();
        if (lot.getEqptRrn() != null) {
            String lotStatus = lot.getLotStatus();
            long equipmenRrn = lot.getEqptRrn();
            Entity equipment = new Equipment();
            equipment.setInstanceRrn(equipmenRrn);
            equipment = emsService.getEntity(equipment);
            String equipmentId = equipment.getInstanceId();
            equipmentInfo.put("equipmentId", equipmentId);
            // check equipment status
            String equipmenStatus = emsService.getEntityCurrentStatus(equipmenRrn);
            equipmentInfo.put("equipmentStatus", equipmenStatus);
            if (equipmenStatus != null &&
                    (equipmenStatus.equals(EventName.DOWN) || equipmenStatus.equals(EventName.OFF) ||
                            equipmenStatus.equals(EventName.FACD)) &&
                    !((StringUtils.equals(lotStatus, LotStatus.RUNNING) ||
                            StringUtils.equals(lotStatus, LotStatus.DISPATCH) ||
                            StringUtils.equals(lotStatus, LotStatus.PROCESSED)) &&
                            StringUtils.equalsIgnoreCase(equipmenStatus, EventName.DOWN))) {
                equipmentInfo.put("equipmentAvailable", "NOT_AVAILABLE");
            } else {
                equipmentInfo.put("equipmentAvailable", "AVAILABLE");
            }
        }
        return equipmentInfo;
    }

}