LotPlanErpAction.java

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

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.jdbc.Page;
import com.mycim.framework.utils.beans.BeanUtils;
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.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.ReferenceDetailNames;
import com.mycim.valueobject.consts.ReferenceFileConst;
import com.mycim.valueobject.ems.Carrier;
import com.mycim.valueobject.erp.workOrder.WorkOrderImpSourceWafer;
import com.mycim.valueobject.erp.workOrder.WorkOrderImpSourceWaferDb;
import com.mycim.valueobject.inv.LotInventoryDO;
import com.mycim.valueobject.inv.MaterialDO;
import com.mycim.valueobject.prp.Operation;
import com.mycim.valueobject.prp.WorkOrder;
import com.mycim.valueobject.security.User;
import com.mycim.valueobject.sys.ReferenceFileDetail;
import com.mycim.valueobject.wip.Lot;
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.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.*;

public class LotPlanErpAction extends LotWaferStartAction {
    private static final String SEPARATOR = "#";

    private static final String DEFAULT_WAFER_BANK = "WAFER_BANK";

    @Override
    public ActionForward init(ActionMapping mapping, ActionForm form, HttpServletRequest request,
                              HttpServletResponse response) {
        return mapping.findForward("init");

    }

    //树菜单显示
    public Map<String, Object> queryWorkOrderTree(Map<String, String> theform, HttpServletRequest request) {
        Map<String, Object> condi = new HashMap<String, Object>();
        condi.put("workOrderId", MapUtils.getString(theform, "workOrderId"));
        condi.put("status", MapUtils.getString(theform, "status"));
        if (StringUtils.isNotEmpty(MapUtils.getString(theform, "startDay"))) {
            condi.put("startDay", DateUtils.parse(MapUtils.getString(theform, "startDay"), DateUtils.DATE_FORMAT4DAY));
        }

        List<WorkOrder> workOrderByStatus = workOrderService.getWorkOrderByCondition(condi);
        List<Map<String, Object>> retList = new ArrayList<Map<String, Object>>();
        for (WorkOrder wo : workOrderByStatus) {
            Map<String, Object> condition = new HashMap<>();
            condition.put("iconCls", "task");
            condition.put("leaf", "true");
            condition.put("workOrderId", wo.getWorkorderId());
            condition.put("workOrderRrn", wo.getWorkorderRrn());
            condition.put("productId", wo.getProductId());
            condition.put("workorderPriority", wo.getWorkorderPriority());
            condition.put("orderDieQty", wo.getOrderDieQty());
            condition.put("startDay", wo.getStartDay());
            condition.put("requireDay", wo.getRequireDay());
            condition.put("dayDay", wo.getDayDay());
            condition.put("dueDate", wo.getDueDate());
            long facilityRrn = LocalContext.getFacilityRrn();
            if (StringUtils.isNotEmpty(wo.getProductId())) {
                ReferenceFileDetail refDetail = getReferenceFileDetail(ReferenceDetailNames.WORKORDER_PROPERTY,
                                                                       wo.getProductId(), facilityRrn);
                if (refDetail != null) {
                    WorkOrderPriorityReF checkWorkOrderPriorityReF = checkWorkOrderPriorityReF(wo.getProductId(),
                                                                                               refDetail, facilityRrn);
                    condition.put("lotType", checkWorkOrderPriorityReF.getLotType());
                    condition.put("substrate", checkWorkOrderPriorityReF.getSubstrate());
                    condition.put("project", checkWorkOrderPriorityReF.getProject());
                    condition.put("createCategory", checkWorkOrderPriorityReF.getCreateCategory());
                    condition.put("createCategoryShow", checkWorkOrderPriorityReF.getCreateCategoryShow());
                    condition.put("lotOwner", checkWorkOrderPriorityReF.getLotOwnerId());
                }
            }
            int shipCount = workOrderService.getPackageDieCount(wo.getWorkorderRrn(), "SHIP");
            int scraptCount = workOrderService.getPackageDieCount(wo.getWorkorderRrn(), "SCRAP");
            condition.put("finishDieQty", shipCount);
            condition.put("scrapDieQty", scraptCount);
            condition.put("operatingDieQty", wo.getOrderDieQty() - shipCount - scraptCount);

            condition.put("leaf", "true");
            retList.add(condition);
        }
        Map<String, Object> result = new HashMap<>();
        result.put("dataList", retList);
        return result;
    }

    // 列表展示
    public Page queryImportWafer(Map<String, Object> map) {
        long facilityRrn = LocalContext.getFacilityRrn();
        WorkOrder wo = workOrderService.getWorkOrderByRrn(MapUtils.getLong(map, "workOrderRrn"));

        Page page = new Page(MapUtils.getIntValue(map, "page"), MapUtils.getIntValue(map, "limit"));
        Page selectPage = workOrderService.getWorkOrderImpDBByOrderRrn(page, MapUtils.getLong(map, "workOrderRrn"));

        List<Map<String, Object>> retList = new ArrayList<Map<String, Object>>();
        Assert.notNull(wo.getProductId(), Errors.create().content("WorkOrder need Mes Product").build());
        ReferenceFileDetail refDetail = getReferenceFileDetail(ReferenceDetailNames.WORKORDER_PROPERTY,
                                                               wo.getProductId(), facilityRrn);
        WorkOrderPriorityReF checkWorkOrderPriorityReF = checkWorkOrderPriorityReF(wo.getProductId(), refDetail,
                                                                                   facilityRrn);
        List<WorkOrderImpSourceWaferDb> results = (List<WorkOrderImpSourceWaferDb>) selectPage.getResults();
        for (WorkOrderImpSourceWaferDb workOrderImpDB : results) {
            Map copyBeanToMap = BeanUtils.copyBeanToMap(workOrderImpDB);
            if (refDetail != null) {
                copyBeanToMap.put("lotType", checkWorkOrderPriorityReF.getLotType());
                copyBeanToMap.put("lotTypeShow", checkWorkOrderPriorityReF.getLotTypeShow());
                copyBeanToMap.put("substrate", checkWorkOrderPriorityReF.getSubstrate());
                copyBeanToMap.put("substrateShow", checkWorkOrderPriorityReF.getSubstrateShow());
                copyBeanToMap.put("project", checkWorkOrderPriorityReF.getProject());
                copyBeanToMap.put("createCategory", checkWorkOrderPriorityReF.getCreateCategory());
                copyBeanToMap.put("createCategoryShow", checkWorkOrderPriorityReF.getCreateCategoryShow());
            }
            retList.add(copyBeanToMap);
        }
        selectPage.setResults(retList);
        return selectPage;
    }

    public Map<String, List<ReferenceFileDetail>> loadComboxData() {
        List<ReferenceFileDetail> holtFlag = getReferenceFileDetails("$$LOT_HOTFLAG");
        List<ReferenceFileDetail> priority = getReferenceFileDetails("$$LOT_PRIORITY");
        List<ReferenceFileDetail> startHold = getReferenceFileDetails("$$YES_OR_NO");
        Map<String, List<ReferenceFileDetail>> ret = new HashMap<String, List<ReferenceFileDetail>>();
        ret.put("hotFlag", holtFlag);
        ret.put("priority", priority);
        ret.put("startHold", startHold);
        return ret;
    }

    public Map<String, String> generateLotId(Map map) {
        WorkOrder wo = workOrderService.getWorkOrderByRrn(MapUtils.getLong(map, "workOrderRrn"));
        long facilityRrn = LocalContext.getFacilityRrn();
        ReferenceFileDetail refDetail = getReferenceFileDetail(ReferenceDetailNames.WORKORDER_PROPERTY,
                                                               wo.getProductId(), facilityRrn);
        Assert.notNull(refDetail,
                       Errors.create().key(MessageIdList.LOTPLANERP_WORKORDERPRIORITY).content("Check ReferenceFile:{}")
                             .args("$$WORKORDER_PROPERTY").build());
        String lotType = refDetail.getData1Value();
        String substrate = refDetail.getData2Value();
        String projectCode = refDetail.getData3Value();
        String projectId = "";
        if (StringUtils.isNotBlank(projectCode)) {
            projectId = getReferenceFileDetail(ReferenceDetailNames.PROJECT_TYPE, projectCode, facilityRrn)
                    .getData2Value();
        }
        String year = (new SimpleDateFormat("yyyy")).format(new Date());
        String lotIdPrefix =
                projectId + projectCode + substrate + lotType + year.substring(year.length() - 1, year.length());
        int serialLength = 4;
        List<String> lotIds = baseService.generateLotIdbyLotIdPrefix(lotIdPrefix, serialLength, 1);
        String lotId = CollectionUtils.isEmpty(lotIds) ? "" : lotIds.get(0);

        String carrierType = getCarrierType(wo, facilityRrn);

        Map<String, String> retMap = new HashMap<String, String>();
        retMap.put("lotId", lotId);
        retMap.put("carrierType", carrierType);
        return retMap;
    }

    //投批
    public void createLotByErp(Map map) {
        long workOrderRrn = MapUtils.getLong(map, "workOrderRrn");
        String waferArr = MapUtils.getString(map, "waferArr");
        Lot lot = new Lot();
        WorkOrder wk = workOrderService.getWorkOrderByRrn(workOrderRrn);
        lot.setCarrierId(MapUtils.getString(map, "startCarrierId"));
        lot.setLotId(MapUtils.getString(map, "lotId"));
        lot.setLotOwner(MapUtils.getString(map, "lotOwner"));
        Assert.isFalse(StringUtils.isEmpty(MapUtils.getString(map, "hotFlag")),
                       Errors.create().key(MessageIdList.LOTPLAN_HOTFLAGEMPTY).content("HotFlag is empty!").build());
        Assert.isFalse(StringUtils.isEmpty(MapUtils.getString(map, "priority")),
                       Errors.create().key(MessageIdList.LOTPLAN_PRIORITYEMPTY).content("Priority is empty!").build());
        Assert.isFalse(StringUtils.isEmpty(MapUtils.getString(map, "startHold")),
                       Errors.create().key(MessageIdList.LOTPLAN_STARTHOLD).content("StartHold is empty!").build());
        setLotPlanProperties(lot, wk, waferArr, map);
        creatLotByErp(lot, waferArr, workOrderRrn);
    }

    private WorkOrderPriorityReF checkWorkOrderPriorityReF(String proId, ReferenceFileDetail refDetail,
                                                           long facilityRrn) {
        WorkOrderPriorityReF ref = new WorkOrderPriorityReF();
        Assert.notNull(refDetail, Errors.create().key(MessageIdList.WORKORDERPROPERTY_NEEDCONF)
                                        .content("$$WORKORDER_PROPERTY need configer: {}").args(proId).build());
        ReferenceFileDetail lotTypeDetail = getWorkOrderPriorityReferenceFileDetail(ReferenceDetailNames.LOT_TYPE,
                                                                                    refDetail.getData1Value(),
                                                                                    facilityRrn);
        Assert.notNull(lotTypeDetail, Errors.create().key(MessageIdList.WORKORDERPROPERTY_LOTTYPE)
                                            .content("$$WORKORDER_PROPERTY LOT_TYPE error: {}").args(proId).build());
        ref.setLotType(refDetail.getData1Value());
        ref.setLotTypeShow(lotTypeDetail.getData1Value());

        ReferenceFileDetail substrateDetail = getWorkOrderPriorityReferenceFileDetail("$$LOT_SUBSTRATE",
                                                                                      refDetail.getData2Value(),
                                                                                      facilityRrn);
        Assert.notNull(substrateDetail, Errors.create().key(MessageIdList.WORKORDERPROPERTY_SUBSTRATE)
                                              .content("$$WORKORDER_PROPERTY LOT_SUBSTRATE error: {}").args(proId)
                                              .build());
        ref.setSubstrate(refDetail.getData2Value());
        ref.setSubstrateShow(substrateDetail.getData1Value());

        ReferenceFileDetail projectDetail = getWorkOrderPriorityReferenceFileDetail(ReferenceDetailNames.PROJECT_TYPE,
                                                                                    refDetail.getData3Value(),
                                                                                    facilityRrn);
        Assert.notNull(projectDetail, Errors.create().key(MessageIdList.WORKORDERPROPERTY_PROJECT)
                                            .content("$$WORKORDER_PROPERTY PROJECT_TYPE error: {}").args(proId)
                                            .build());
        ref.setProject(projectDetail.getData1Value());

        ReferenceFileDetail createCategoryDetail = getWorkOrderPriorityReferenceFileDetail(
                ReferenceDetailNames.LOT_CREATE_CATEGORY, refDetail.getData4Value(), facilityRrn);
        Assert.notNull(createCategoryDetail, Errors.create().key(MessageIdList.WORKORDERPROPERTY_CREATECATEGORY)
                                                   .content("$$WORKORDER_PROPERTY LOT_CREATE_CATEGORY error: {}")
                                                   .args(proId).build());
        ref.setCreateCategory(refDetail.getData4Value());
        ref.setCreateCategoryShow(createCategoryDetail.getData1Value());

        String lotOwnerId = refDetail.getData5Value();
        try {
            User user = securityService.getUser(lotOwnerId, facilityRrn);
            ref.setLotOwnerId(user.getInstanceId());
        } catch (Exception e) {
            throw new SystemIllegalArgumentException(Errors.create().key(MessageIdList.WORKORDERPROPERTY_LOTOWNER)
                                                           .content("$$WORKORDER_PROPERTY LOT_OWNER error: {}")
                                                           .args(proId).build());
        }
        return ref;
    }

    private ReferenceFileDetail getWorkOrderPriorityReferenceFileDetail(String referenceFileId, String key1Value,
                                                                        Long facilityRrn) {
        key1Value = key1Value == null ? "" : key1Value;
        return getReferenceFileDetail(referenceFileId, key1Value, " ", facilityRrn);
    }

    private void creatLotByErp(Lot lotPlan, String waferArr, long workOrderRrn) {
        String lotId = lotPlan.getLotId();
        Long facilityRrn = lotPlan.getFacilityRrn();
        String user = lotPlan.getLotOwner();

        List<Map<String, Object>> rawMaterials = makeRawMaterials(waferArr, facilityRrn);

        Map lotMapInfo;
        lotMapInfo = buildLotMap(lotPlan);
        Lot lot = (Lot) lotMapInfo.get("lot");

        String carrierId = lot.getCarrierId();
        Long carrierRrn = carrierService.getCarrierRrnForLot(facilityRrn, lot, carrierId);

        lotMapInfo.put("carrierId", carrierId);
        lotMapInfo.put("lotPlanTypeMenu", lot.getLotPlanType());
        lot.setCarrierRrn(carrierRrn);
        // cassette与lot的绑定需要判断category
        Carrier carrier = carrierService.getCarrier(carrierRrn);
        String targetCarrierType = carrierService.getTargetCarrierTypeByStatus(lot);

        Assert.isTrue(StringUtils.equalsIgnoreCase(targetCarrierType, carrier.getObjectSubtype()),
                      Errors.create().key(MessageIdList.LOT_CASSETTE_TYPE_PROCESS_LOCATION)
                            .content("Cassette type is different from process location!").build());
        Assert.isFalse(lotQueryService.getLotRrn(lot.getLotId()) > 0,
                       Errors.create().content("THIS LOT ID ALREADY EXISTED!").build());
        Assert.isTrue(StringUtils.equalsIgnoreCase(lot.getCreateCategory(), carrier.getFlagType()),
                      Errors.create().key(MessageIdList.LOT_CASSETTE_TYPE_MUST_SAME)
                            .content("Lot and cassette must be same category!").build());

        String[] units = parseUnitListString(rawMaterials, lot.getLotId());
        Assert.isTrue(validateUniqueUnit(units),
                      Errors.create().key(MessageIdList.UNIT_ID_MUST_UNIQUE).content("Unit ID must be Unique!")
                            .build());

        lot.setCustomerWaferId(
                Arrays.asList(units).toString().replace('[', ' ').replace(']', ' ').trim().toUpperCase());

        int i = 0;
        for (Iterator it = rawMaterials.iterator(); it.hasNext(); ) {
            HashMap item = (HashMap) it.next();
            Assert.isTrue((units[i] != null) && !"".equals(units[i]),
                          Errors.create().key(MessageIdList.UNIT_ID_MUST_SPECIFIED).content("Units must be specified!")
                                .build());
            item.put("unitList", units[i++].toUpperCase());
        }

        HashMap transInfo = new HashMap();
        transInfo.put("startFlag", lot.getStartedFlag());
        lot.setSplitMergeFlag(LocationNames.initLotFlagName(lot.getProcessId()));
        transInfo.put("lot", lot);
        transInfo.put("lotid", lot.getLotId());
        transInfo.put("qty", lot.getQty1() + "");
        transInfo.put("productRrn", lot.getProductRrn());

        transInfo.put("transPerformedby", user);
        transInfo.put("keepUnitHistoryFlag", "false");
        transInfo.put("unitList", units);

        transInfo.put("positionList", getPositionList(lot.getQty1()));
        transInfo.put("rawMaterials", rawMaterials);

        transInfo.put("lotComments", "");
        transInfo.put("trackUnitFlag", "1");
        transInfo.put("erpSWaferArr", JsonUtils.toList(waferArr, WorkOrderImpSourceWaferDb.class));
        transInfo.put("workOrderRrn", workOrderRrn);

        Map resultsInfo = lotService.createLotAndMoveNext(transInfo);
        Lot currentLot = lotQueryService.getLot(lotId, facilityRrn);
        saveLotSeqAttribute(((Long) resultsInfo.get("lotRrn")).longValue(), currentLot.getProductRrn());
    }

    private List<Map<String, Object>> makeRawMaterials(String waferArr, Long facilityRrn) {
        //[{"materialLotNum":"MATERIAL-001","qty":6,"materialId":"MATERIAL-001","waferBank":"WAFER_BANK"}]

        //[{offset=0, lotBox=();();(), unitList="", wareHouseRrn=5396732, lotNumber=MATERIAL-001,
        //specifiedQty=25.0, confirmFlag=false, itemId=MATERIAL-001, onHandQty=2941.0,
        //		itemRrn=5412879, wareHouseId=WAFER_BANK, int_specifiedQty=25.0}]

        //把物料做归类(qty,sourceWaferId问题),不同物料混投
        List<WorkOrderImpSourceWaferDb> list = JsonUtils.toList(waferArr, WorkOrderImpSourceWaferDb.class);
        Set<MaterialLotInner> set = new HashSet<LotPlanErpAction.MaterialLotInner>();
        for (WorkOrderImpSourceWaferDb wf : list) {
            MaterialLotInner inner = new MaterialLotInner();
            BeanUtils.copyProperties(wf, inner);
            if (set.contains(inner)) {
                for (MaterialLotInner innerSet : set) {
                    if (innerSet.equals(inner)) {
                        innerSet.setQty(innerSet.getQty() + 1);
                        Map<String, String> winner = new HashMap<String, String>();
                        winner.put("uniqueNum", wf.getUniqueNum());
                        winner.put("sourceWaferId", wf.getSourceWaferId());
                        winner.put("sourceWaferDieQty", Integer.valueOf(wf.getSourceWaferDieQty()).toString());
                        innerSet.getUniqueNumList().add(winner);
                        break;
                    }
                }
            } else {
                Map<String, String> winner = new HashMap<String, String>();
                winner.put("uniqueNum", wf.getUniqueNum());
                winner.put("sourceWaferId", wf.getSourceWaferId());
                winner.put("sourceWaferDieQty", Integer.valueOf(wf.getSourceWaferDieQty()).toString());
                inner.getUniqueNumList().add(winner);
                set.add(inner);
            }
        }

        List<Map<String, Object>> returnList = new ArrayList<Map<String, Object>>();
        for (MaterialLotInner sWafer : set) {
            Map<String, Object> map = new HashMap<String, Object>();
            Operation warehouse = warehouseService.getWarehouse(facilityRrn, "WAFER_BANK");
            map.put("offset", 0);
            map.put("lotBox", "();();()");
            map.put("wareHouseId", "WAFER_BANK");
            map.put("lotNumber", sWafer.getMaterialLotNum());
            map.put("itemId", sWafer.getMaterialId());
            //查找物料号
            MaterialDO material = asmService.getMaterial(facilityRrn, sWafer.getMaterialId());
            Assert.isFalse(material == null || material.getItemRrn() == 0,
                           Errors.create().key(MessageIdList.MATERIAL_MATERIALNOTEXIST)
                                 .content("Material Id not " + "exist" + ":{}").args(sWafer.getMaterialId()).build());
            LotInventoryDO lotInventory = warehouseService
                    .getLotInventory(sWafer.getMaterialLotNum(), material.getItemRrn(), warehouse.getInstanceRrn());
            Assert.isFalse(lotInventory == null || lotInventory.getItemRrn() == 0,
                           Errors.create().key(MessageIdList.MATERIALLOT_MATERIALNOTEXIST)
                                 .content("materialLot " + "Id" + " not " + "exist:{}").args(sWafer.getMaterialLotNum())
                                 .build());
            Assert.isFalse(lotInventory.getReceiptQty() - lotInventory.getIssueQty() - lotInventory.getAdjustQty() <
                                   sWafer.getQty(), Errors.create().key(MessageIdList.MATERIALLOT_OUTOFSTOCK)
                                                          .content("materialLot out of stock:{}")
                                                          .args(sWafer.getMaterialLotNum()).build());
            map.put("wareHouseRrn", warehouse.getInstanceRrn());
            map.put("specifiedQty", sWafer.getQty());
            map.put("confirmFlag", "false");
            map.put("itemRrn", material.getItemRrn());
            map.put("int_specifiedQty", (int) sWafer.getQty());
            map.put("uniqueNumList", sWafer.getUniqueNumList());
            returnList.add(map);
        }

        return returnList;
    }

    private void setLotPlanProperties(Lot lot, WorkOrder workOrder, String waferArr, Map<String, Object> lotProp) {
        //facilityRrn
        long facilityRrn = LocalContext.getFacilityRrn();
        lot.setFacilityRrn(facilityRrn);

        String carrierId = lot.getCarrierId();
        Carrier carrier = carrierService.getCarrier(facilityRrn, carrierId);
        Assert.isFalse(carrier == null || carrier.getInstanceRrn() == 0L,
                       Errors.create().key(MessageIdList.CARRIER_CARRIERNOTEXISTS).content("Carrier Not Exists:{}")
                             .args(carrierId).build());
        lot.setCarrierRrn(carrier.getInstanceRrn());

        //workOrderId
        lot.setInnerOrderNO(workOrder.getWorkorderId());
        //HOT_FLAG
        lot.setHotFlag(MapUtils.getString(lotProp, "hotFlag"));
        //PRIVERITY
        lot.setPriority(MapUtils.getInteger(lotProp, "priority", 1));
        //PO type
        lot.setOutOrderType(MapUtils.getString(lotProp, "outOrderType"));
        //PO num
        lot.setOuterOrderNO(MapUtils.getString(lotProp, "outerOrderNO"));
        //CustomerLotId
        lot.setCustomerLotId(MapUtils.getString(lotProp, "customerLotId"));
        //CustomerId
        lot.setCustomerId(MapUtils.getString(lotProp, "customerId"));
        //START_FLAG
        lot.setStartedFlag(TRUE);

        ReferenceFileDetail refDetail = getReferenceFileDetail(ReferenceDetailNames.WORKORDER_PROPERTY,
                                                               workOrder.getProductId(), facilityRrn);
        Assert.notNull(refDetail,
                       Errors.create().key(MessageIdList.LOTPLANERP_WORKORDERPRIORITY).content("Check ReferenceFile:{}")
                             .args("$$WORKORDER_PROPERTY").build());
        String lotType = refDetail.getData1Value();
        String createCategory = refDetail.getData4Value();
        //CREATE_CATEGORY
        //lot.setCreateCategory(getKey1ValueFromData1Value(facilityRrn,"$LOT_CREATE_CATEGORY",
        // workOrderImp
        // .getCreateCategory()));
        lot.setCreateCategory(createCategory);

        //CREATED_TIMESTAMP
        lot.setCreatedTimestamp(new Timestamp(System.currentTimeMillis()));

        //DUE_DATE
        lot.setDueDate(workOrder.getDueDate());

        //DUMMY_FLAG
        lot.setDummyFlag("0");

        //LOT_TYPE
        lot.setLotType(lotType);

        //qty1
        List<WorkOrderImpSourceWafer> list = JsonUtils.toList(waferArr, WorkOrderImpSourceWafer.class);
        lot.setQty1((double) list.size());
        lot.setQty2(0D);

        //INPUT_QTY1
        lot.setInputQty1((double) list.size());
        lot.setInputQty2(0D);

        //STEP_SEQUENCE
        lot.setStepSequence(new Long(TRUE));

        //STATUS
        lot.setLotStatus("WAITING");

        //startHold
        lot.setStartHold(MapUtils.getString(lotProp, "startHold"));

        //QUEUE_TIMESTAMP
        lot.setQueueTimestamp(new Timestamp(System.currentTimeMillis()));

        //PRODUCT_RRN
        long productRrn = baseService.getNamedObjectRrn(workOrder.getProductId(),
                                                        baseService.getNamedSpace(facilityRrn, ObjectList.PRODUCT_KEY),
                                                        ObjectList.PRODUCT_KEY);
        lot.setProductRrn(productRrn);

        //PROCESS_RRN
        Long processRrn = getDefaultTechnology(productRrn);
        lot.setProcessRrn(processRrn);
        int processVersion = prpService.getLastAvaliableProcessVersion(productRrn, processRrn);
        lot.setProcessVersion(processVersion);

        //PROCESS_STEP_VERSION
        buildLotProcessStepinfo(lot);
    }

    private String getKey1ValueFromData1Value(long facilityRrn, String RefFileId, String data1Value) {
        String ret = "";
        List<ReferenceFileDetail> refFileValues = sysService.getRefFileValues(RefFileId, facilityRrn);
        for (ReferenceFileDetail detail : refFileValues) {
            if (StringUtils.equalsIgnoreCase(detail.getData1Value(), data1Value)) {
                ret = detail.getKey1Value();
                break;
            }
        }
        Assert.isFalse(StringUtils.isEmpty(ret),
                       Errors.create().key(MessageIdList.LOT_CREATECATEGORYERROR).content("Create Category Error:{}")
                             .args(data1Value).build());
        return ret;
    }

    private WorkOrderImpSourceWaferDb getImportWkByImpRrn(String importRrn) {
        return workOrderService.getImportWkByImpRrn(importRrn);
    }


    private void buildLotProcessStepinfo(Lot lot) {
        String stageId = "";
        String layerId = "";
        Long borRrn = new Long(0);
        Long operationRrn = new Long(0);
        Integer operationVer = new Integer(0);
        Long executionRrn = new Long(0);
        String processStepVersion = null;
        String processStepIdVersion = null;
        String processStepVersion4wfl = null;

        Map tempInfo = getStepsInfoByVersion(lot, lot.getProcessRrn(), lot.getProcessVersion(), "");
        operationRrn = MapUtils.getLong(tempInfo, "operationRrn");

        executionRrn = (Long) tempInfo.get("executionRrn");

        Assert.isTrue(checkOperationInFacility(operationRrn, lot.getFacilityRrn()),
                      Errors.create().content("The Lot's first " + "step is " + "not in " + "current " + "facility!")
                            .build());

        operationVer = (Integer) tempInfo.get("operationVer");
        stageId = (String) tempInfo.get("stageId");
        layerId = (String) tempInfo.get("layerId");
        processStepVersion = (String) tempInfo.get("processStepVersion");
        processStepIdVersion = (String) tempInfo.get("processStepIdVersion");
        processStepVersion4wfl = (String) tempInfo.get("processStepVersion4wfl");

        lot.setNextOperationRrn1((Long) tempInfo.get("nextoperationRrn1"));

        if ((lot.getNextOperationRrn1() != null) && (lot.getNextOperationRrn1().compareTo(new Long(0)) > 0)) {
            lot.setNextOperationId1(getInstanceId(lot.getNextOperationRrn1().longValue()));
        }

        lot.setNextStepVersion1((String) tempInfo.get("nextprocessStepVersion1"));
        lot.setNextStepIdVersion1((String) tempInfo.get("nextprocessStepIdVersion1"));

        lot.setNextOperationRrn2((Long) tempInfo.get("nextoperationRrn2"));

        if ((lot.getNextOperationRrn2() != null) && (lot.getNextOperationRrn2().compareTo(new Long(0)) > 0)) {
            lot.setNextOperationId2(getInstanceId(lot.getNextOperationRrn2().longValue()));
        }

        lot.setNextStepVersion2((String) tempInfo.get("nextprocessStepVersion2"));
        lot.setNextStepIdVersion2((String) tempInfo.get("nextprocessStepIdVersion2"));

        if ((lot.getScheduleDueDate() != null) && (lot.getDueDate() != null) &&
                lot.getScheduleDueDate().after(lot.getDueDate())) {
            lot.setLastScheduleFlag(TRUE);
        }

        lot.setProcessStepVersion(processStepVersion.toString());
        lot.setProcessStepIdVersion(processStepIdVersion.toString());
        lot.setWflStepPath(processStepVersion4wfl);
        lot.setExecutionRrn(executionRrn);
        lot.setOperationRrn(operationRrn);
        lot.setOperationVersion(operationVer);
        lot.setOperationId(this.getInstanceId(operationRrn.longValue()));
        lot.setStageId(stageId);
        lot.setLayerId(layerId);
        lot.setBorRrn(borRrn);
        lot.setBeforeStatus("");
    }

    private Map buildLotMap(Lot lot) {
        String lotCategoryCode = lot.getCreateCategory();
        String createCategory = sysService
                .referenceDetailExchangeNull(ReferenceDetailNames.LOT_CREATE_CATEGORY, lot.getCreateCategory(), null,
                                             ReferenceFileConst.DATA_1_VALUE);

        Map lotMapInfo = BeanUtils.copyBeanToMap(lot);
        lotMapInfo.put("lotCategoryCode", lotCategoryCode);
        lotMapInfo.put("createCategory", createCategory);
        lotMapInfo.put("workArea", lotQueryService.getWorkArea(lot));
        lotMapInfo.put("operation_rrn", lot.getOperationRrn());
        String nextOperationDesc1 = getNextStepDesc(lot);
        lotMapInfo.put("nextOperationDesc1", nextOperationDesc1 == null ? "" : nextOperationDesc1);

        lotMapInfo.put("splitMergeFlag", StringUtils.nullToStr(lot.getSplitMergeFlag()));
        lotMapInfo.put("pollutionLevel", lot.getPollutionLevel());
        String pollutionLevelColor = sysService
                .getRefFileValue("$$LOT_POLUTIONLEVEL", lot.getPollutionLevel(), ReferenceFileConst.DATA_2_VALUE);
        if (StringUtils.isNotBlank(pollutionLevelColor)) {
            String plBgColor = StringUtils.substringBefore(pollutionLevelColor, "$");
            String plColor = StringUtils.substringAfter(pollutionLevelColor, "$");
            lotMapInfo.put("plBgColor", plBgColor);
            lotMapInfo.put("plColor", plColor);
        }

        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        String duedate = df.format(lot.getDueDate());
        lotMapInfo.put("duedate", duedate);
        lotMapInfo.put("qty1", lot.getQty1().intValue());
        lotMapInfo.put("routeDesc", getInstanceDesc(lot.getRouteRrn()));
        lotMapInfo.put("carrierType", carrierService.getTargetCarrierTypeByStatus(lot));
        String hotFlagString = "";
        if (StringUtils.isNotBlank(lot.getHotFlag()) && StringUtils.isNotBlank(lot.getPriority().toString())) {
            hotFlagString = getHotflagSplicingPriority(lot);
        }
        lotMapInfo.put("hotFlagString", hotFlagString);
        lotMapInfo.put("flowSeq", ctxExecService.getFlowSeqByProcessInfo(lotMapInfo));
        lotMapInfo.put("operationDesc", ctxExecService.getOperationDescByProcessInfo(lotMapInfo));
        lotMapInfo.put("stageId", ctxExecService.getStageByProcessInfo(lotMapInfo));
        lotMapInfo.put("allMaterial", this.getMaterials4lot(lot.getProductRrn()));
        lotMapInfo.put("defaultBank", DEFAULT_WAFER_BANK);
        lotMapInfo.put("planStartDateS", DateUtils.formatDate(lot.getPlanStartDate(), DateUtils.DATE_FORMAT4DAY));
        lotMapInfo.put("lot", lot);

        return lotMapInfo;
    }

    private String getMaterials4lot(Long productRrn) {
        long facilityRrn = LocalContext.getFacilityRrn();
        Operation warehouse = prpService
                .getOperation(getInstanceRrn(DEFAULT_WAFER_BANK, facilityRrn, ObjectList.OPERATION_KEY));
        Assert.isFalse(warehouse == null || warehouse.getInstanceRrn() <= 0,
                       Errors.create().key(MessageIdList.ASM_MISSING_WAREHOUSE).content("Warehouse is not exist!")
                             .build());

        return asmService.getMaterials4lot(warehouse.getInstanceRrn(), productRrn);
    }

    private String[] parseUnitListString(Collection rawMaterials, String lotId) {
        String[] units = new String[rawMaterials.size()];
        for (int i = 0; i < rawMaterials.size(); i++) {
            units[i] = "";
        }
        String unitListString = "";
        for (int i = 0; i < units.length; i++) {
            unitListString += units[i];
        }

        List raw = (List) rawMaterials;
        int num = 0;
        for (int i = 0; i < units.length; i++) {
            Map map = (Map) raw.get(i);
            int qty = MapUtils.getIntValue(map, "int_specifiedQty");
            if (StringUtils.isBlank(units[i]) || StringUtils.equals("$", units[i])) {
                String unitList = "";
                for (int j = 0; j < qty; j++) {
                    String unitId = "";
                    while (true) {
                        unitId = lotId + SEPARATOR + String.format("%02d", ++num);
                        if (!StringUtils.contains(unitListString, unitId)) {
                            break;
                        }
                    }
                    unitList = unitList + unitId + "|" + "0" + "$";
                }
                units[i] = unitList;
            }
        }
        return units;
    }

    private String getCarrierType(WorkOrder wo, long facilityRrn) {
        long productRrn = baseService
                .getNamedObjectRrn(wo.getProductId(), baseService.getNamedSpace(facilityRrn, ObjectList.PRODUCT_KEY),
                                   ObjectList.PRODUCT_KEY);
        Long processRrn = getDefaultTechnology(productRrn);
        int processVersion = prpService.getLastAvaliableProcessVersion(productRrn, processRrn);
        Assert.isFalse(processVersion == 0, Errors.create().key(MessageIdList.PRODUCT_HAVA_NOT_AVALIABLE_VERSION)
                                                  .content("Have not avaliable process version, please check!")
                                                  .build());
        String processLocation = "";
        if (productRrn > 0 && processRrn != null && processRrn > 0) {
            // 获取流程树
            Map<String, Object> matchingRules = new HashMap<String, Object>();
            matchingRules.put("productRrn", productRrn);
            matchingRules.put("processRrn", processRrn);
            List wflTree = prpService.getWorkFlowTree(processRrn, matchingRules);

            Map<String, Object> contextValueInfoMap = new HashMap<>();
            if (wflTree != null && wflTree.size() > 0) {
                contextValueInfoMap.putAll(matchingRules);
                String[] treeRouteNodes = (String[]) wflTree.get(0);
                String[] treeOperNodes = (String[]) wflTree.get(1);

                contextValueInfoMap.put("routeRrn", NumberUtils.createLong(treeRouteNodes[4]));
                contextValueInfoMap.put("operationRrn", NumberUtils.createLong(treeOperNodes[4]));
                contextValueInfoMap.put("processVersion", processVersion);

                processLocation = ctxExecService.getProcessLocation(contextValueInfoMap);
            }
        }
        ReferenceFileDetail referenceFileDetail = getReferenceFileDetail(
                ReferenceDetailNames.PROCESS_LOCARION_CARRIER_TYPE, processLocation, facilityRrn);
        return referenceFileDetail.getData1Value();
    }

    public class MaterialLotInner {
        private String materialId;

        private String materialLotNum;

        private List<Map<String, String>> uniqueNumList = new ArrayList<Map<String, String>>();

        private double qty = 1;

        public double getQty() {
            return qty;
        }

        public void setQty(double qty) {
            this.qty = qty;
        }

        public String getMaterialId() {
            return materialId;
        }

        public void setMaterialId(String materialId) {
            this.materialId = materialId;
        }

        public String getMaterialLotNum() {
            return materialLotNum;
        }

        public void setMaterialLotNum(String materialLotNum) {
            this.materialLotNum = materialLotNum;
        }

        public List<Map<String, String>> getUniqueNumList() {
            return uniqueNumList;
        }

        public void setUniqueNumList(List<Map<String, String>> uniqueNumList) {
            this.uniqueNumList = uniqueNumList;
        }

        @Override
        public int hashCode() {
            return new String(materialId + materialLotNum).hashCode();
        }

        @Override
        public boolean equals(Object obj) {
            if (obj instanceof MaterialLotInner) {
                MaterialLotInner objw = (MaterialLotInner) obj;
                if (StringUtils.equals(objw.getMaterialId(), this.getMaterialId()) &&
                        StringUtils.equals(objw.getMaterialLotNum(), this.getMaterialLotNum())) {
                    return true;
                } else {
                    return false;
                }
            } else {
                return false;
            }
        }

    }

    class WorkOrderPriorityReF {
        private String lotType;

        private String lotTypeShow;

        private String substrate;

        private String substrateShow;

        private String project;

        private String createCategory;

        private String createCategoryShow;

        private String lotOwnerId;

        public String getLotType() {
            return lotType;
        }

        public void setLotType(String lotType) {
            this.lotType = lotType;
        }

        public String getLotTypeShow() {
            return lotTypeShow;
        }

        public void setLotTypeShow(String lotTypeShow) {
            this.lotTypeShow = lotTypeShow;
        }

        public String getSubstrate() {
            return substrate;
        }

        public void setSubstrate(String substrate) {
            this.substrate = substrate;
        }

        public String getSubstrateShow() {
            return substrateShow;
        }

        public void setSubstrateShow(String substrateShow) {
            this.substrateShow = substrateShow;
        }

        public String getProject() {
            return project;
        }

        public void setProject(String project) {
            this.project = project;
        }

        public String getCreateCategory() {
            return createCategory;
        }

        public void setCreateCategory(String createCategory) {
            this.createCategory = createCategory;
        }

        public String getCreateCategoryShow() {
            return createCategoryShow;
        }

        public void setCreateCategoryShow(String createCategoryShow) {
            this.createCategoryShow = createCategoryShow;
        }

        public String getLotOwnerId() {
            return lotOwnerId;
        }

        public void setLotOwnerId(String lotOwnerId) {
            this.lotOwnerId = lotOwnerId;
        }

    }

}