NpwMergeLotAction.java

package com.mycim.webapp.actions.npwmerge;

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.lang.StringUtils;
import com.mycim.framework.utils.lang.collections.MapUtils;
import com.mycim.framework.utils.msg.JsonUtils;
import com.mycim.valueobject.MessageIdList;
import com.mycim.valueobject.wip.Lot;
import com.mycim.valueobject.wip.TransReason;
import com.mycim.webapp.Constants;
import com.mycim.webapp.WebUtils;
import com.mycim.webapp.actions.NpwSetupAction;
import com.mycim.webapp.forms.NpwSplitMergeInfoForm;
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 shijie.deng
 * @version 6.0.0
 * @date 2019/11/19
 **/
public class NpwMergeLotAction extends NpwSetupAction {

    @Override
    public ActionForward init(ActionMapping mapping, ActionForm form, HttpServletRequest request,
                              HttpServletResponse response) throws Exception {
        NpwSplitMergeInfoForm theform = (NpwSplitMergeInfoForm) form;
        theform.setSourceListValues(initEmptyCarrier());
        return (mapping.findForward(Constants.INIT_KEY));
    }


    public ActionForward getChildLot(ActionMapping mapping, NpwSplitMergeInfoForm theform, HttpServletRequest request,
                                     HttpServletResponse response) {
        theform.setSourceListValues(initEmptyCarrier());
        String carrierId = theform.getCarrierId();
        Assert.isFalse(StringUtils.isBlank(carrierId),
                       Errors.create().key(MessageIdList.CARRIER_CASSETTE_EMPTY).content("Carrier Id can't be empty!")
                             .build());
        carrierId = StringUtils.trimToUpperCase(carrierId);
        Lot lot = lotQueryService.getLotByCarrierId(theform.getCarrierId(), LocalContext.getFacilityRrn());
        theform.setLotId(lot.getLotId());
        return (mapping.findForward(Constants.INIT_KEY));
    }

    public ActionForward getParentLot(ActionMapping mapping, NpwSplitMergeInfoForm theform, HttpServletRequest request,
                                      HttpServletResponse response) {
        List buildChildLots = new ArrayList();
        Assert.isFalse(StringUtils.isBlank(theform.getBaseCarrierId()),
                       Errors.create().key(MessageIdList.CARRIER_CASSETTE_EMPTY).content("Carrier Id can't be empty!")
                             .build());
        Lot paLot = lotQueryService
                .getLotByCarrierId(theform.getBaseCarrierId().trim().toUpperCase(), LocalContext.getFacilityRrn());
        Lot lot = paLot;
        Assert.notNull(lot.getQty1(),
                       Errors.create().key(MessageIdList.LOT_QTY_NULL).content("This Lot's qty1 is null").build());
        theform.setTransId(Constants.MODIFY_KEY);
        paLot.setTrackUnitFlag("1");
        theform.setBaseLotId(paLot.getLotId());
        Lot child_Lot = lotQueryService.getLot(theform.getLotId(), LocalContext.getFacilityRrn());
        child_Lot.setTrackUnitFlag("1");
        // 判断是否可以合批
        Assert.isTrue(dmmService.checkMergeAvailableNpw(paLot.getLotRrn(), child_Lot.getLotRrn()),
                      Errors.create().key(MessageIdList.NPW_MERGE_VERIFY_FAILED).content("Failed to verify in merge!")
                            .build());
        HashMap childLot = getLotInfo(child_Lot);
        List childUnitList = dmmLotService.getNpwMergeLotUnitList(paLot.getLotRrn(), child_Lot.getLotRrn());
        childLot.put("qty1", new Double(childUnitList.size()));
        childLot.put("units", childUnitList);
        List<Map> childLots = new ArrayList();
        childLots.add(childLot);

        // check if available slot count enough
        Long availableSlotCount = carrierService.getCarrier(LocalContext.getFacilityRrn(), paLot.getCarrierId())
                                                .getAvailableSlotCount();

        Assert.isFalse(MiscUtils.parseSQL((Double) childLot.get("qty1")) > availableSlotCount.longValue(),
                       Errors.create().key(MessageIdList.UNSCRAP_SLOT_NOT_ENOUGH)
                             .content("This Carrier available slot is not enough!").build());

        buildChildLots.add(childLot);
        this.rebuildTheFormSourceList(theform, lot, buildChildLots);
        request.setAttribute("showCarrierFlag", "1");
        theform.setChildLotsCache(WebUtils.getCacheObj2String(childLots));
        return (mapping.findForward(Constants.INIT_KEY));
    }

    public ActionForward saveMergeLots(ActionMapping mapping, NpwSplitMergeInfoForm theform, HttpServletRequest request,
                                       HttpServletResponse response) {
        List<Map> childLots = (List<Map>) WebUtils.getCacheString2Obj(request.getParameter("childLotsCache"));
        List<Map> buildChildUnits = null;
        List<Map> buildChildLots = new ArrayList();
        List<Map<String, Object>> sourceListValues = parseJsonStrAndRemoveIdlePostion(theform.getSourceListValues());


        Lot lot = lotQueryService
                .getLotByCarrierId(theform.getBaseCarrierId().trim().toUpperCase(), LocalContext.getFacilityRrn());

        for (Iterator iterator2 = childLots.iterator(); iterator2.hasNext(); ) {
            Map childMap = (HashMap) iterator2.next();
            Map buildChildMap = childMap;
            Collection childUnits = (Collection) MapUtils.getObject(childMap, "units");
            buildChildUnits = new ArrayList();
            for (Iterator iterator3 = childUnits.iterator(); iterator3.hasNext(); ) {
                Map unitsMap = (HashMap) iterator3.next();
                Map buildUnitsMap = unitsMap;
                String childUnitRrn = MapUtils.getString(unitsMap, "unitRrn");
                for (Iterator iterator = sourceListValues.iterator(); iterator.hasNext(); ) {
                    Map sourceMap = (HashMap) iterator.next();
                    String sourceUnitRrn = MapUtils.getString(sourceMap, "unitRrn");
                    if (StringUtils.equals(childUnitRrn, sourceUnitRrn)) {
                        buildUnitsMap.put("position", MapUtils.getString(sourceMap, "position"));
                        buildChildUnits.add(buildUnitsMap);
                    }
                }
            }
            if (buildChildUnits.size() > 0) {
                buildChildMap.put("units", buildChildUnits);
                buildChildLots.add(buildChildMap);
            }
        }
        if (childLots.size() == buildChildLots.size()) {
            childLots = buildChildLots;
        }
        this.mergeLot(lot, childLots, theform);
        request.setAttribute("mergeOver", "1");
        return (mapping.findForward(Constants.INIT_KEY));
    }

    private void mergeLot(Lot lot, List<Map> childLots, NpwSplitMergeInfoForm theform) {
        Assert.isFalse(childLots.size() <= 0, Errors.create().key(MessageIdList.MERGELOT_NO_LOT_SELECTED_FOR_MERGE)
                                                    .content("No lot selected for merge").build());

        lot.setTransPerformedby(LocalContext.getUserId());
        HashMap valueMap = new HashMap();
        valueMap.put("lot", lot);
        valueMap.put("childLots", childLots);
        valueMap.put("unitOfParent", wipQueryService.getUnitListByLot(lot.getLotRrn()));
        valueMap.put("comment", theform.getComment());
        valueMap.put("newUnits", parseJsonStrAndRemoveIdlePostion(theform.getSourceListValues()));
        valueMap.put("user", LocalContext.getUserId());
        valueMap.put("userRrn", LocalContext.getUserRrn());

        TransReason transReason = new TransReason();
        String reason = theform.getReason();
        transReason.setReasonCode("");
        transReason.setResponsibility(LocalContext.getUserId());
        transReason.setReason(reason);

        valueMap.put("transReason", transReason);
        dmmLotService.npwMergeLot(valueMap);
    }

    private void rebuildTheFormSourceList(NpwSplitMergeInfoForm theform, Lot lot, List<Map> childLots) {
        theform.setSourceListValues(parseToJsonString(wipQueryService.getUnitListByLot(lot.getLotRrn())));
        theform.setTargetListValues("合批信息");
        List<Map> source = JsonUtils.toObject(theform.getSourceListValues(), List.class);

        for (Iterator it = childLots.iterator(); it.hasNext(); ) {
            Map item = (Map) it.next();
            sourceAndChidUnits(source, item);
        } // end of while

        Collections.sort((List) source, new Comparator() {

            @Override
            public int compare(Object paramObject1, Object paramObject2) {
                Map info1 = (Map) paramObject1;
                Map info2 = (Map) paramObject2;
                int seq1 = MapUtils.getIntValue(info1, "position");
                int seq2 = MapUtils.getIntValue(info2, "position");
                return (seq1 - seq2);
            }
        });

        theform.setSourceListValues(this.parseToJsonString(source));
    }

    private void sourceAndChidUnits(List<Map> source, Map item) {
        List<Map> childUnits = new ArrayList<Map>((List<Map>) item.get("units"));

        Map childUnitsMap = buildChildUnitsPositionMap(childUnits);

        List<Map> alreadyAddUnits = new ArrayList();
        //1.子批晶圆放在原有的slot上
        for (Map map : source) {
            String unitId = MapUtils.getString(map, "unitId");
            String unitRrn = MapUtils.getString(map, "unitRrn");
            String position = MapUtils.getString(map, "position");
            if (StringUtils.isBlank(unitId) && StringUtils.isBlank(unitRrn)) {
                //该位置未放置晶圆,则将子批的放进来(放到分批前所在位置)
                Map childUnit = (Map) childUnitsMap.get(position);
                if (childUnit != null) {
                    map.put("unitRrn", childUnit.get("unitRrn"));
                    map.put("unitId", childUnit.get("unitId"));
                    map.put("lotid", childUnit.get("lotid"));
                    alreadyAddUnits.add(childUnit);
                }

            }
        }
        //2.移除已经找到位置的晶圆
        childUnits.removeAll(alreadyAddUnits);

        //3.剩余找不到位置的,有空位就放
        int remainSize = childUnits.size();
        int addIndex = 0;
        for (Map map : source) {
            String unitId = MapUtils.getString(map, "unitId");
            String unitRrn = MapUtils.getString(map, "unitRrn");
            if (StringUtils.isBlank(unitId) && StringUtils.isBlank(unitRrn)) {
                //该位置未放置晶圆,则将子批的放进来
                if (addIndex < remainSize) {
                    Map childUnit = childUnits.get(addIndex);
                    map.put("unitRrn", childUnit.get("unitRrn"));
                    map.put("unitId", childUnit.get("unitId"));
                    map.put("lotid", childUnit.get("lotid"));
                    addIndex++;
                } else {
                    //子批晶圆已经放置完毕,跳出循环
                    break;
                }
            }
        }
    }

    private Map buildChildUnitsPositionMap(List<Map> childUnits) {
        Map positionMap = new HashMap();
        for (Map childUnit : childUnits) {
            String sourcePosition = MapUtils.getString(childUnit, "sourcePosition");
            //将来源位置当Key  unitMap为Value
            positionMap.put(sourcePosition, childUnit);
        }
        return positionMap;
    }

    private HashMap getLotInfo(Lot childLot) {
        HashMap item = new HashMap();
        item.put("childLotId", childLot.getLotId());
        item.put("childLotRrn", childLot.getLotRrn());
        item.put("carrierId", childLot.getCarrierId());
        item.put("qty1", childLot.getQty1());
        item.put("qty2", childLot.getQty2());
        item.put("productId", childLot.getProductId());
        item.put("processId", childLot.getProcessId());
        item.put("operationId", childLot.getOperationId());
        return item;
    }

}