AssignCSTAction.java

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

import com.fa.sesa.exception.Assert;
import com.fa.sesa.exception.Errors;
import com.fa.sesa.threadlocal.LocalContext;
import com.mycim.framework.utils.beans.BeanUtils;
import com.mycim.framework.utils.lang.StringUtils;
import com.mycim.valueobject.MessageIdList;
import com.mycim.valueobject.consts.*;
import com.mycim.valueobject.ems.Carrier;
import com.mycim.valueobject.security.User;
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.actions.WipSetupAction;
import com.mycim.webapp.forms.lot.LotInfoForm;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.collections.MapUtils;
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.HashMap;
import java.util.List;
import java.util.Map;


public class AssignCSTAction extends WipSetupAction {

    @Override
    public ActionForward init(ActionMapping mapping, ActionForm form, HttpServletRequest request,
                              HttpServletResponse response) throws Exception {
        Long facilityRrn = LocalContext.getFacilityRrn();
        Lot lot = initLotBaseInfoForJsp(request, true, null, null);
        String lotId = lot.getLotId();
        if (StringUtils.isEmpty(lotId)) {
            Assert.isFalse(request.getParameter("byCarrierId") != null,
                           Errors.create().key(MessageIdList.CARRIER_CASSETTE_ID_NOT_EXIST)
                                 .content("carrier id not exist").build());
            Assert.isTrue(request.getParameter("byCarrierId") != null,
                          Errors.create().key(MessageIdList.LOT_ENTER_CORRECT_LOTID)
                                .content("please enter correct lot id").build());
        }


        Assert.isTrue(LotStatus.isWaitingOrHold(lot.getLotStatus()),
                      Errors.create().content("The lot status must be in " + "WAITING、HOLD. ").build());
        
        //卡控post future hold被hold住的lot
        checkPostFutureHold(lot.getLotRrn());

        Assert.isFalse(diffBatchQueryService.checkLotInBatch(lot.getLotRrn()),
                       Errors.create().key(MessageIdList.LOT_IN_BATCH).content("Lot in batch!").build());
        LotInfoForm lotInfoForm = new LotInfoForm();

        PropertyUtils.copyProperties(lotInfoForm, lot);
        lotInfoForm.setRecipePhysicalId(getRecipePhysicalId(lot));
        Map<String, Object> conditionMap = BeanUtils.copyBeanToMap(lot);
        lotInfoForm.setFlowSeq(ctxExecService.getFlowSeqByProcessInfo(conditionMap));
        lotInfoForm.setOperationDesc(ctxExecService.getOperationDescByProcessInfo(conditionMap));

        Carrier carrier = carrierService.getCarrier(lot.getCarrierRrn());
        Assert.isFalse(carrier == null || carrier.getInstanceRrn() <= 0,
                       Errors.create().content("Can not find this cassette of" + " Lot.").build());
        wipQueryService.checkActiveInlineOcapId(lot.getLotRrn());

        request.setAttribute("lotId", lotId);
        request.setAttribute("carrierType", carrier.getDmmType());
        request.setAttribute("processLocation", lot.getProcessLocation());
        request.setAttribute("carrierCategory", carrier.getFlagType());
        request.setAttribute("lotLocation", StringUtils.trimToEmpty(request.getParameter("lotLocation")));
        request.setAttribute(SessionNames.LOT_KEY, lot);
        request.setAttribute(SessionNames.LOT_INFO_FORM_KEY, lotInfoForm);

        Assert.isTrue(StringUtils.equalsIgnoreCase(carrier.getObjectSubtype(), CarrierType.DUMMY), Errors.create()
         .content(
                 "This Lot has a cassette and cannot be installed another one. Try using the " +
                         "exchange cassette.")
         .build());
        return mapping.findForward("install");
    }

    public void installCSTForLot(Map map) {
        Long facilityRrn = LocalContext.getFacilityRrn();
        String userId = LocalContext.getUserId();
        String department = map.get("department").toString().toUpperCase();
        String responsibilityUserId = map.get("responsibilityUserId").toString().toUpperCase();
        Long responsibilityUserRrn = new Long(map.get("responsibilityUserRrn").toString());
        String deptExt = map.get("deptExt").toString().toUpperCase();
        String reason = map.get("reason").toString().toUpperCase();
        String targetCarrierId = map.get("targetCarrierId").toString();
        String lotId = map.get("lotId").toString().toUpperCase();

        Assert.isFalse(StringUtils.isEmpty(targetCarrierId),
                       Errors.create().content("Target cassette ID cannot be empty!").build());
        checkParameters(department, responsibilityUserId, responsibilityUserRrn, reason);

        Map<String, Object> operatorTransInfo = new HashMap<>();

        operatorTransInfo.put("department", department);
        operatorTransInfo.put("deptExt", deptExt);
        operatorTransInfo.put("responsibilityUserId", responsibilityUserId);
        operatorTransInfo.put("responsibilityUserRrn", responsibilityUserRrn);
        operatorTransInfo.put("reason", reason);

        Lot lot = lotQueryService.getLot(lotQueryService.getLotRrn(lotId));

        Assert.isTrue(LotStatus.isWaitingOrHold(lot.getLotStatus()),
                      Errors.create().content("The lot status must be in " + "WAITING、HOLD. ").build());


        User responsibilityUser = getResponsibilityUser(responsibilityUserRrn);

        this.compareRealAndDummyCarrierAndCheckRealCarrierAvailabile(facilityRrn, lot.getCarrierId(), targetCarrierId,lot);
        Long targetCarrierRrn = getCarrierRrnForLot(facilityRrn, lot.getQty1(), targetCarrierId);

        //check sortJob
        checkWaitJobs(targetCarrierRrn, 0L, 0L, null);

        TransReason transReason = new TransReason();
        transReason.setReasonCategory(TransactionNames.INSTALL_CST_KEY);
        transReason.setReasonCode(department);
        transReason.setReason(buildReasonDetail(department, deptExt, reason, responsibilityUser.getUserName()));
        transReason.setResponsibility(responsibilityUser.getInstanceId());
        transReason.setTransQty1(lot.getQty1());
        transReason.setTransQty2(lot.getQty2());

        Map<String, Object> transInfo = new HashMap<>();

        transInfo.put("facilityRrn", facilityRrn);
        transInfo.put("targetCarrierRrn", targetCarrierRrn);
        transInfo.put("transReason", transReason);
        transInfo.put("transPerformedBy", userId);
        transInfo.put("transComments", reason);
        // List<Lot> lockLots = new ArrayList<>();
        // lockLots.add(lot);
        // checkAndCreateLotsTransLock(LocalContext.getUserRrn(), TransactionNames.LOCK_ASSIGN_CST, lockLots,
        //                             "Assign CST in AssignCSTAction by: " + userId);
        lotService.installCSTForLot(lot, transInfo);
    }

    public Long getCarrierRrnForLot(Long facilityRrn, Double lotQty, String carrierId) {
        carrierId = StringUtils.trimToUpperCase(carrierId);
        Assert.isFalse(StringUtils.isEmpty(carrierId), Errors.create().content("carrier is required!!").build());
        Carrier carrier = carrierService.getCarrier(facilityRrn, carrierId);

        Assert.isFalse(StringUtils.equalsIgnoreCase(carrier.getObjectSubtype(), Carrier.CarrierType.DUMMY.toString()),
                       Errors.create().content("The carrier: {} is a  dummy carrier!").args(carrier.getInstanceId())
                             .build());
        Assert.isFalse(carrier.getAvailableSlotCount() < lotQty,
                       Errors.create().content("The AvailableSlot is not enough!!").build());

        Assert.isFalse(!StringUtils.equalsIgnoreCase(carrier.getCarrierStatus(), PcdStatus.FREE_KEY) &&
                               !StringUtils.equalsIgnoreCase(carrier.getCarrierStatus(), PcdStatus.ASSEMBLY_KEY),
                       Errors.create().content("Invalid carrier status!").build());

        Assert.isFalse((carrierService.isAssseblyNeed(carrier.getObjectSubtype())) &&
                               !StringUtils.equalsIgnoreCase(carrier.getCarrierStatus(), PcdStatus.ASSEMBLY_KEY),
                       Errors.create().content("{} type carrier needed assembled " + "first!")
                             .args(carrier.getObjectSubtype()).build());
        carrierService.checkPcdIsValid(carrier.getInstanceRrn(), facilityRrn);

        return carrierService.getAvailableCarrierRrnById(facilityRrn, carrierId);

    }

    private void checkParameters(String department, String responsibilityUserId, Long responsibilityUserRrn,
                                 String reason) {
        Assert.isFalse(StringUtils.isEmpty(department),
                       Errors.create().content("Department can not be empty!").build());
        Assert.isFalse(StringUtils.isEmpty(responsibilityUserId) || responsibilityUserRrn <= 0,
                       Errors.create().content("User Id can not be empty!").build());
        Assert.isFalse(StringUtils.isEmpty(reason), Errors.create().content("Reason can not be empty!").build());
    }

    private User getResponsibilityUser(long responsibilityUserRrn) {
        User responsibilityUser = securityService.getUser(responsibilityUserRrn);
        Assert.isFalse(responsibilityUser == null || responsibilityUser.getInstanceRrn() <= 0,
                       Errors.create().content("User not exist, Please check!").build());
        return responsibilityUser;
    }

    private String buildReasonDetail(String department, String deptExt, String reason, String userName) {
        return department + " " + deptExt + " " + userName + " " + reason;
    }


    /**
     * 比较一个虚拟晶舟和一个真实晶舟的类型、类别,以及验证真实晶舟状态
     *
     * @param dummyCarrierId 虚拟晶舟id
     * @param realCarrierId  真实晶舟id
     */
    //添加lot参数
    private void compareRealAndDummyCarrierAndCheckRealCarrierAvailabile(Long facilityRrn, String dummyCarrierId,
                                                                         String realCarrierId,Lot lot) {
        Carrier dummyCarrier = carrierService.getCarrier(facilityRrn, dummyCarrierId);
        Carrier realCarrier = carrierService.getCarrier(facilityRrn, realCarrierId);

        //不比较两个晶舟的类别了 #25888

        if (carrierService.isAssseblyNeed(realCarrier.getObjectSubtype())) {
            Assert.isTrue(StringUtils.equals(realCarrier.getCarrierStatus(), PcdStatus.ASSEMBLY_KEY),
                          Errors.create().key(MessageIdList.CARRIER_INVALID_CASSETTE_STATUS)
                                .content("carrier status invalid").build());
        } else {
            Assert.isTrue(StringUtils.equals(realCarrier.getCarrierStatus(), PcdStatus.FREE_KEY),
                          Errors.create().key(MessageIdList.CARRIER_INVALID_CASSETTE_STATUS)
                                .content("carrier status invalid").build());
        }
        //需求#40592 原晶舟与目标晶舟type的比较 改为 原晶舟所在批次与目标晶舟类型的比较,在ajust lot改变lot type后重新分配cassette
        Assert.isTrue(StringUtils.equalsIgnoreCase(realCarrier.getFlagType(), lot.getCreateCategory()),
                      Errors.create().key(MessageIdList.CARRIER_CATEGORY_IS_NOT_CONSISTENT)
                            .content("carrier category is not consistent").build());
        //需求#40592 增补更新 卡控lot和cassette的$$PROCESS_LOCARION_CARRIER_TYPE
        //判断lot的processLocation进行是不是"xx TO xx"的格式
        int toIndex=-1;
        if((toIndex =lot.getProcessLocation().indexOf(com.mycim.valueobject.Constants.PROCESS_LOCATION_CARRIER.CONCAT_STR))!=-1)lot.setProcessLocation(lot.getProcessLocation().substring(0,toIndex).trim());
        ReferenceFileDetail referenceFileDetail = getReferenceFileDetail(ReferenceDetailNames.PROCESS_LOCARION_CARRIER_TYPE, lot.getProcessLocation(), facilityRrn);
        if (referenceFileDetail!=null) {
            Assert.isTrue(StringUtils.equalsIgnoreCase(referenceFileDetail.getData1Value(),realCarrier.getObjectSubtype()),
                          Errors.create().key(MessageIdList.CARRIER_TYPE_IS_NOT_CONSISTENT).content("carrier type is " + "not consistent").build());
        }
        carrierService.checkPcdIsValid(realCarrier.getInstanceRrn(), facilityRrn);
    }

    public List<String> getCarrierProcessLocation(Map map){
        String carrierType = MapUtils.getString(map, "carrierType");
        List<String> processLocation = sysService
                .getRefFileKey(ReferenceDetailNames.PROCESS_LOCARION_CARRIER_TYPE, carrierType);
        return processLocation;

    }

}