MergeLotAction.java
package com.mycim.webapp.actions.lot.merge;
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.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.msg.JsonUtils;
import com.mycim.valueobject.MessageIdList;
import com.mycim.valueobject.ObjectList;
import com.mycim.valueobject.consts.ContextNames;
import com.mycim.valueobject.consts.SessionNames;
import com.mycim.valueobject.ems.Carrier;
import com.mycim.valueobject.wip.*;
import com.mycim.webapp.Constants;
import com.mycim.webapp.WebUtils;
import com.mycim.webapp.actions.lot.ManualAndSortCheckAction;
import com.mycim.webapp.forms.lot.LotInfoForm;
import com.mycim.webapp.forms.lot.SplitMergeInfoForm;
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 shijie.deng
* @version 6.0.0
* @date 2019/10/6
**/
public class MergeLotAction extends ManualAndSortCheckAction {
@Override
public ActionForward init(ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) throws Exception {
SplitMergeInfoForm theform = (SplitMergeInfoForm) form;
if (StringUtils.isNotBlank((String) request.getAttribute("target"))) {
theform.setCacheTarget((String) request.getAttribute("target"));
}
theform.setPages(1);
// reset increment element
Lot lot = initLotBaseInfoForJsp(request, true, null, null);
/*if (!lot.getLotStatus().equalsIgnoreCase(LotStatus.HOLD)) {
throw new WebException("lot.merge_not_hold", "lot status must be hold!");
}*/
//卡控post future hold被hold住的lot
checkPostFutureHold(lot.getLotRrn());
super.checkCstRemoved(Sets.newHashSet(lot.getLotRrn()));
Assert.isTrue(LotStatus.isWaitingOrHold(lot.getLotStatus()),
Errors.create().content("This lot status must be in " + "WAITING、HOLD !").build());
if (this.isTrackUnitFlag(lot)) {
lot.setTrackUnitFlag(TRUE);
} else {
lot.setTrackUnitFlag(FALSE);
} // end of if
LotInfoForm lotInfoForm = new LotInfoForm();
PropertyUtils.copyProperties(lotInfoForm, lot);
Map conditionMap = BeanUtils.copyBeanToMap(lot);
lotInfoForm.setRecipePhysicalId(getRecipePhysicalId(lot));
Assert.isFalse(lot.getQty1() == null, Errors.create().content("This Lot's qty1 is null").build());
wipQueryService.checkActiveInlineOcapId(lot.getLotRrn());
//check sortJob
checkWaitJobs(lot.getCarrierRrn(), 0L, 0L, null);
theform.setSourceListValues(parseToJsonString(wipQueryService.getUnitListByLot(lot.getLotRrn())));
Collection collection = parseToSimplifyCollection(theform.getSourceListValues());
request.setAttribute(SessionNames.COLLECTION2_KEY, collection);
theform.setCacheCollection2(WebUtils.getCacheObj2String(collection));
lotInfoForm.setRemainQty(lot.getQty1());
theform.setLotInfoForm(lotInfoForm);
theform.setLotId(null);
Carrier parentCarrier = carrierService.getCarrier(lot.getCarrierRrn());
request.setAttribute("parentCSTslotCount", parentCarrier.getSlotCount());
Boolean canDropTarget = parentCarrier.getSlotCount() == 13;// cst13 的晶周可以拖动
request.setAttribute("canDropTarget", canDropTarget);
theform.setTransId(Constants.MODIFY_KEY);
List childLotView = buildChildLotMap(lotQueryService.getChildLotsForMerge(lot));
request.setAttribute(SessionNames.LOT_KEY, lot);
request.setAttribute(SessionNames.COLLECTION_KEY, childLotView);
request.setAttribute(SessionNames.LOT_INFO_FORM_KEY, lotInfoForm);
theform.setCacheLotInfo(WebUtils.getCacheObj2String(lotInfoForm));
theform.setCacheLot(WebUtils.getCacheObj2String(lot));
theform.setCacheChildLots(WebUtils.getCacheObj2String(new ArrayList()));
theform.setCacheChildLotsView(WebUtils.getCacheObj2String(childLotView));
return mapping.findForward(Constants.INIT_KEY);
}
public ActionForward addChildLot(ActionMapping mapping, SplitMergeInfoForm theform, HttpServletRequest request) {
long facilityRrn = LocalContext.getFacilityRrn();
LotInfoForm lotInfoForm = (LotInfoForm) WebUtils.getCacheString2Obj(theform.getCacheLotInfo());
List childLots = (List) WebUtils.getCacheString2Obj(theform.getCacheChildLots());
List childLotsView = (List) WebUtils.getCacheString2Obj(theform.getCacheChildLotsView());
Lot lot = (Lot) WebUtils.getCacheString2Obj(theform.getCacheLot());
initLotBaseInfoForJsp(request, true, null, null);
Carrier parentCarrier = carrierService.getCarrier(lot.getCarrierRrn());
request.setAttribute("parentCSTslotCount", parentCarrier.getSlotCount());
Boolean canDropTarget = parentCarrier.getSlotCount() == 13;// cst13 的晶周可以拖动
request.setAttribute("canDropTarget", canDropTarget);
List buildChildLots = new ArrayList();
Boolean confirmFlag = WebUtils.getParameterBoolean("confirmFlag", request);
// check if valid lot selected
Assert.isFalse((theform.getChildLotId() == null) || theform.getChildLotId().equalsIgnoreCase(""),
Errors.create().key(MessageIdList.LOT_LOTID_OR_CASSETTEID_EMPTY)
.content("Lot Id and Cassette Id can't be Empty!").build());
Assert.isFalse(theform.getChildLotId().equals(lot.getLotId()),
Errors.create().content("Please select different lot to merge!").build());
Lot paLot = lotQueryService.getLot(lot.getLotId(), facilityRrn);
theform.setChildLotId(StringUtils.trimToUpperCase(theform.getChildLotId()));
Lot child_Lot = lotQueryService.getLot(theform.getChildLotId(), facilityRrn);
Assert.isFalse(child_Lot.getLotRrn() <= 0, Errors.create().content("No such Lot!").build());
//Check flip for childLot and parentLot
this.checkFlip4ChildAndParentLot(paLot, child_Lot);
//TODO : merge lot really need it?
// String qtimeErrorMsg = buidldQtimeErrorMsg(paLot, child_Lot);
// StringBuilder confirmMsg = new StringBuilder();
StringBuilder loopErrorMsg = new StringBuilder();
// this.buidldLoopErrorMsg(paLot, child_Lot, confirmMsg, loopErrorMsg);
// loopErrorMsg.append(qtimeErrorMsg);
Assert.isFalse(loopErrorMsg.length() > 0, Errors.create().content(loopErrorMsg.toString()).build());
Carrier childCarrier = carrierService.getCarrier(child_Lot.getCarrierRrn());
Assert.isFalse(!StringUtils.equalsIgnoreCase(parentCarrier.getFlagType(), childCarrier.getFlagType()) ||
!StringUtils.equalsIgnoreCase(parentCarrier.getObjectSubtype(),
childCarrier.getObjectSubtype()),
Errors.create().content("Parent and child lot Cassette info not consistent!").build());
//child lot若正被post future hold状态则无法合批
checkPostFutureHold(child_Lot.getLotRrn());
//child lot和lot必须都bond或都未bond才允许合批
this.checkBond(lot, child_Lot);
//check contamination level
this.checkContaminationLevel(lot, child_Lot);
HashMap item = null;
for (Iterator it = childLots.iterator(); it.hasNext(); ) {
item = (HashMap) it.next();
Assert.isFalse(item.get("childLotId").equals(theform.getChildLotId()),
Errors.create().content("Please Select different lot to merge!").build());
}
// 判断是否可以合批
checkMergeAvailable(paLot, child_Lot);
HashMap childLot = getLotInfo(theform, lot);
theform.setChildLotId(StringUtils.EMPTY);
lotInfoForm.setMergedQty(MiscUtils.parseSQL(lotInfoForm.getMergedQty()) + MiscUtils.parseSQL((Double) childLot.get("qty1")));
lotInfoForm.setMergedQty2(MiscUtils.parseSQL(lotInfoForm.getMergedQty2()) + MiscUtils.parseSQL((Double) childLot.get("qty2")));
theform.setLotInfoForm(lotInfoForm);
buildChildLots.add(childLot);
childLots.add(childLot);
buildChildLotMap(childLotsView, child_Lot, true);
this.rebuildTheFormSourceList(theform, lot, buildChildLots,
(List) WebUtils.getCacheString2Obj(theform.getCacheCollection2()), parentCarrier);
request.setAttribute(SessionNames.LOT_KEY, lot);
request.setAttribute(SessionNames.COLLECTION_KEY, childLotsView);
request.setAttribute(SessionNames.LOT_INFO_FORM_KEY, lotInfoForm);
theform.setCacheChildLots(WebUtils.getCacheObj2String(childLots));
theform.setCacheChildLotsView(WebUtils.getCacheObj2String(childLotsView));
theform.setCacheLotInfo(WebUtils.getCacheObj2String(lotInfoForm));
theform.setCacheLot(WebUtils.getCacheObj2String(lot));
return mapping.findForward(Constants.INIT_KEY);
}
public Map checkFutureHold(Map map) {
Map result = new HashMap();
String lotId = MapUtils.getString(map, "lotId");
/**
* 是否有futureHold
*/
Lot lot = lotQueryService.getLot(lotId, LocalContext.getFacilityRrn());
long refRrn = getInstanceRrn(ContextNames.EEN_CONTEXT_HOLDLOT,
getNamedSpace(ObjectList.CONTEXT_KEY, LocalContext.getFacilityRrn()),
ObjectList.CONTEXT_KEY);
List<Map> futureHoldInfoByLot = ctxExecService.getFutureHoldListByLot(refRrn, lot.getLotRrn());
refRrn = getInstanceRrn(ContextNames.EEN_CONTEXT_HOLDPRODUCT, LocalContext.getFacilityRrn(),
ObjectList.CONTEXT_KEY);
List<Map> futureHoldInfoByProduct = ctxExecService
.getFutureHoldListByProduct(refRrn, lot.getProductRrn(), lot.getProcessRrn(), lot.getLotRrn());
if (futureHoldInfoByLot != null && futureHoldInfoByLot.size() > 0) {
result.put("futureHoldInfoByLot", futureHoldInfoByLot);
}
if (futureHoldInfoByProduct != null && futureHoldInfoByProduct.size() > 0) {
result.put("futureHoldInfoByProduct", futureHoldInfoByProduct);
}
return result;
}
public ActionForward delChildLot(ActionMapping mapping, SplitMergeInfoForm theform, HttpServletRequest request) {
initLotBaseInfoForJsp(request, true, null, null);
LotInfoForm lotInfoForm = (LotInfoForm) WebUtils.getCacheString2Obj(theform.getCacheLotInfo());
List childLots = (List) WebUtils.getCacheString2Obj(theform.getCacheChildLots());
List childLotsView = (List) WebUtils.getCacheString2Obj(theform.getCacheChildLotsView());
Lot lot = (Lot) WebUtils.getCacheString2Obj(theform.getCacheLot());
Iterator it = childLots.iterator();
String record = request.getParameter(Constants.ITEM_KEY);
List source = JsonUtils.toObject(theform.getSourceListValues(), List.class);
List buildSource = new ArrayList();
while (it.hasNext()) {
HashMap item = (HashMap) it.next();
String childLotId = (String) item.get("childLotId");
if (childLotId.equals(record)) {
lotInfoForm.setMergedQty(new Double(MiscUtils.parseSQL(lotInfoForm.getMergedQty()) -
MiscUtils.parseSQL((Double) item.get("qty1"))));
lotInfoForm.setMergedQty2(new Double(MiscUtils.parseSQL(lotInfoForm.getMergedQty2()) -
MiscUtils.parseSQL((Double) item.get("qty2"))));
for (Iterator iterator = source.iterator(); iterator.hasNext(); ) {
boolean sourceB = true;
Map sourceMap = (Map) iterator.next();
String sourceUnitId = MapUtils.getString(sourceMap, "unitId");
List childUnits = (List) MapUtils.getObject(item, "units");
for (Iterator iterator2 = childUnits.iterator(); iterator2.hasNext(); ) {
Map childUnit = (Map) iterator2.next();
String childUnitId = MapUtils.getString(childUnit, "unitId");
if (StringUtils.equals(sourceUnitId, childUnitId)) {
sourceB = false;
}
}
if (sourceB) {
buildSource.add(sourceMap);
}
}
childLots.remove(item);
break;
}
}
Lot tempLot = new Lot();
tempLot.setLotId(record);
buildChildLotMap(childLotsView, tempLot, false);
theform.setLotInfoForm(lotInfoForm);
theform.setSourceListValues(this.parseToJsonString(buildSource));
request.setAttribute(SessionNames.LOT_KEY, lot);
request.setAttribute(SessionNames.COLLECTION_KEY, childLotsView);
request.setAttribute(SessionNames.LOT_INFO_FORM_KEY, lotInfoForm);
theform.setCacheChildLots(WebUtils.getCacheObj2String(childLots));
theform.setCacheChildLotsView(WebUtils.getCacheObj2String(childLotsView));
theform.setCacheLotInfo(WebUtils.getCacheObj2String(lotInfoForm));
theform.setCacheLot(WebUtils.getCacheObj2String(lot));
return mapping.findForward(Constants.INIT_KEY);
}
public ActionForward saveMergeLots(ActionMapping mapping, SplitMergeInfoForm theform, HttpServletRequest request) {
String user = LocalContext.getUserId();
LotInfoForm lotInfoForm = (LotInfoForm) WebUtils.getCacheString2Obj(theform.getCacheLotInfo());
List childLots = (List) WebUtils.getCacheString2Obj(theform.getCacheChildLots());
Lot lot = (Lot) WebUtils.getCacheString2Obj(theform.getCacheLot());
lot.setTransPerformedby(user);
List buildChildUnits = null;
List buildChildLots = new ArrayList();
List sourceListValues = this.parseJsonStrAndRemoveIdlePostion(theform.getSourceListValues());
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;
}
childLotsBeforeIntoServiceCheck(childLots);
lotBeforeIntoServiceCheck(lot, "SO");
//check sortJob
checkWaitJobs(lot.getCarrierRrn(), 0L, 0L, null);
mergeLot(lot, childLots, theform, user);
// if (StringUtils.equalsIgnoreCase("_merge", theform.getCacheTarget())) {
// request.getRequestDispatcher("/lotLocation4CSECAction.do?qry=lotlocation&lotId=" +
// String.valueOf(
// lot.getLotId())).forward(request, response);
// return null;
// }
// request.setAttribute(SessionNames.LOT_KEY, lot);
// request.setAttribute(SessionNames.COLLECTION_KEY, childLots);
// request.setAttribute(SessionNames.LOT_INFO_FORM_KEY, lotInfoForm);
// theform.setCacheChildLots(WebUtils.getCacheObj2String(childLots));
// theform.setCacheLotInfo(WebUtils.getCacheObj2String(lotInfoForm));
// theform.setCacheLot(WebUtils.getCacheObj2String(lot));
return mapping.findForward(Constants.LOTLOCATION_KEY);
}
public Map checkMergeInfo(Map requestMap) {
long facilityRrn = LocalContext.getFacilityRrn();
List childLots = (List) WebUtils.getCacheString2Obj(MapUtils.getString(requestMap, "cacheChildLots"));
Lot lot = (Lot) WebUtils.getCacheString2Obj(MapUtils.getString(requestMap, "cacheLot"));
String childLotId = MapUtils.getStringCheckNull(requestMap, "childLotId");
Double mergedQty = MapUtils.getDouble(requestMap, "mergedQty");
Lot paLot = lotQueryService.getLot(lot.getLotId(), facilityRrn);
Carrier parentCarrier = carrierService.getCarrier(lot.getCarrierRrn());
Lot childLot = lotQueryService.getLot(childLotId, facilityRrn);
Assert.isFalse(childLot == null || childLot.getLotRrn() <= 0, Errors.create().content("No such Lot!").build());
//TODO:
// String qtimeErrorMsg = buidldQtimeErrorMsg(paLot, childLot);
StringBuilder confirmMsg = new StringBuilder();
StringBuilder loopErrorMsg = new StringBuilder();
// this.buidldLoopErrorMsg(paLot, childLot, confirmMsg, loopErrorMsg);
// loopErrorMsg.append(qtimeErrorMsg);
Map<String, String> result = new HashMap<String, String>();
result.put("confirmMsg", confirmMsg.toString());
result.put("loopErrorMsg", loopErrorMsg.toString());
HashMap item = null;
for (Iterator it = childLots.iterator(); it.hasNext(); ) {
item = (HashMap) it.next();
Assert.isFalse(item.get("childLotId").equals(childLotId),
Errors.create().content("Please Select different lot to merge!").build());
}
Carrier childCarrier = carrierService.getCarrier(childLot.getCarrierRrn());
Assert.isFalse(!StringUtils.equalsIgnoreCase(parentCarrier.getFlagType(), childCarrier.getFlagType()) ||
!StringUtils.equalsIgnoreCase(parentCarrier.getObjectSubtype(),
childCarrier.getObjectSubtype()),
Errors.create().content("Parent and child " + "lot " + "Cassette " + "info not " + "consistent!")
.build());
// 获取计算后的母批,比验证母批晶舟槽位数是否够用
Lot tmpParentLot = this.rebuidMergeLotInfo(lot, childLots);
Lot temChildLot = childLot;
int index = StringUtils.indexOf(childLot.getLotId(), ".");
int childLotnumber = NumberUtils.toInt(childLot.getLotId().substring(index + 1));
index = StringUtils.indexOf(lot.getLotId(), ".");
int parentLotnumber = NumberUtils.toInt(lot.getLotId().substring(index + 1));
if (childLotnumber < parentLotnumber) {
tmpParentLot = childLot;
temChildLot = lot;
}
Long availableSlotCount = carrierService.getCarrier(tmpParentLot.getCarrierRrn()).getAvailableSlotCount();
Assert.isFalse((MiscUtils.parseSQL(mergedQty) + MiscUtils.parseSQL(temChildLot.getQty1())) >
availableSlotCount.longValue(),
Errors.create().content("This Carrier available slot " + "is not enough!").build());
return result;
}
public List<Map> buildChildLotMap(List<Lot> lots) {
List list = new ArrayList();
for (Lot lot : lots) {
HashMap item = new HashMap();
item.put("childLotId", lot.getLotId());
item.put("carrierId", lot.getCarrierId());
item.put("qty1", lot.getQty1());
item.put("qty2", lot.getQty2());
item.put("productId", getInstanceId(lot.getProductRrn()));
item.put("processId", getInstanceId(lot.getProcessRrn()));
item.put("operationId", getInstanceId(lot.getOperationRrn()));
item.put("mergeSelectFlag", lot.getMergeSelectFlag());
list.add(item);
}
return list;
}
public void buildChildLotMap(List<Map> lots, Lot lot, Boolean mergeSelectFlag) {
for (Map map : lots) {
if (StringUtils.equalsIgnoreCase(lot.getLotId(), (String) map.get("childLotId"))) {
if (mergeSelectFlag) {
map.put("mergeSelectFlag", "true");
} else {
map.put("mergeSelectFlag", null);
}
}
}
}
private HashMap getLotInfo(SplitMergeInfoForm theform, Lot lot) {
long facilityRrn = LocalContext.getFacilityRrn();
// check if child lot valid
Lot childLot = lotQueryService.getLot(theform.getChildLotId(), facilityRrn);
Assert.isFalse(childLot.getLotRrn() <= 0, Errors.create().content("No such Lot!").build());
Assert.isFalse((childLot.getLotStatus() != null) && (childLot.getLotStatus().equals(LotStatus.LOSSED) ||
childLot.getLotStatus().equals(LotStatus.SCRAPPED) ||
childLot.getLotStatus().equals(LotStatus.TERMINATED)),
Errors.create().content("Invalid child lot status!").build());
// check if lots in same operation
this.checkLotStepForMerge(lot, childLot);
HashMap item = new HashMap();
item.put("childLotId", theform.getChildLotId());
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());
if (this.isTrackUnitFlag(lot)) {
Assert.isTrue(this.isTrackUnitFlag(childLot),
Errors.create().content("Different track unit flag!").build());
item.put("units", this.parseToSimplifyCollection(
this.parseToString(wipQueryService.getUnitListByLot(childLot.getLotRrn()))));
}
return item;
}
/**
* @param theform
* @param lot
* @param childLots
* @param parentLotUnits
*/
private void rebuildTheFormSourceList(SplitMergeInfoForm theform, Lot lot, List childLots, List parentLotUnits,
Carrier parentCarrier) {
Boolean canDropTarget = parentCarrier.getSlotCount() == 13;// cst13 的晶周可以拖动
double remainQty = lot.getQty1().doubleValue();
List source = null;
if ((lot.getTrackUnitFlag() != null) && lot.getTrackUnitFlag().equalsIgnoreCase(TRUE)) {
source = JsonUtils.toObject(theform.getSourceListValues(), List.class);
}
for (Iterator it = childLots.iterator(); it.hasNext(); ) {
Map item = (Map) it.next();
if (lot.getTrackUnitFlag().equalsIgnoreCase(TRUE)) {
List<Map> childUnits = (List<Map>) item.get("units");
source = addUnitsInDifferenceFoupForMergeLot(source, childUnits, lot.getLotId());
}
} // end of while
if (lot.getTrackUnitFlag().equalsIgnoreCase(TRUE)) {
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));
}
}
/**
* @param foupUnits
* @param childUnits
* @return List<Map < String, Object>>
* @Description 将其他foup的子批wafer添加到母批foup内, 并返回母批所在foup的wafer集合(包含空槽位position)
*/
private List<Map> addUnitsInDifferenceFoupForMergeLot(List<Map> foupUnits, List<Map> childUnits,
String parentLotId) {
List<Map> tempChildUnits = new ArrayList<Map>();
tempChildUnits.addAll(childUnits);
List<Map> alreadyAddUnits = new ArrayList<Map>();
// 1.放入对应的空位
for (Map lotUnitMap : tempChildUnits) {
lotUnitMap.put("lotid", parentLotId);
String lotUnitPosition = MapUtils.getString(lotUnitMap, "position");
String lotUnitId = MapUtils.getString(lotUnitMap, "unitId");
String lotUnitRrn = MapUtils.getString(lotUnitMap, "unitRrn");
String lotUnitDummyflag = MapUtils.getString(lotUnitMap, "dummyflag");
String lotUnitAvailable = MapUtils.getString(lotUnitMap, "available");
String lotUnitLotid = MapUtils.getString(lotUnitMap, "lotid");
for (Map carrierUnitMap : foupUnits) {
String carrierUnitPosition = MapUtils.getString(carrierUnitMap, "position");
String carrierUnitId = MapUtils.getString(carrierUnitMap, "unitId");
String carrierUnitRrn = MapUtils.getString(carrierUnitMap, "unitRrn");
if (lotUnitPosition.equals(carrierUnitPosition) && StringUtils.isBlank(carrierUnitId) &&
StringUtils.isBlank(carrierUnitRrn)) {// 同位置下是空位
carrierUnitMap.put("unitId", lotUnitId);
carrierUnitMap.put("unitRrn", lotUnitRrn);
carrierUnitMap.put("dummyflag", lotUnitDummyflag);
carrierUnitMap.put("available", lotUnitAvailable);
carrierUnitMap.put("lotid", lotUnitLotid);
alreadyAddUnits.add(lotUnitMap);
break;
}
}
}
tempChildUnits.removeAll(alreadyAddUnits);// 移除已添加到对应位置的unit
// 2.有空位就放入
for (Map lotUnitMap : tempChildUnits) {
String lotUnitId = MapUtils.getString(lotUnitMap, "unitId");
String lotUnitRrn = MapUtils.getString(lotUnitMap, "unitRrn");
String lotUnitDummyflag = MapUtils.getString(lotUnitMap, "dummyflag");
String lotUnitAvailable = MapUtils.getString(lotUnitMap, "available");
String lotUnitLotid = MapUtils.getString(lotUnitMap, "lotid");
for (Map carrierUnitMap : foupUnits) {
String carrierUnitId = MapUtils.getString(carrierUnitMap, "unitId");
String carrierUnitRrn = MapUtils.getString(carrierUnitMap, "unitRrn");
if (StringUtils.isBlank(carrierUnitId) && StringUtils.isBlank(carrierUnitRrn)) {// 空位
carrierUnitMap.put("unitId", lotUnitId);
carrierUnitMap.put("unitRrn", lotUnitRrn);
carrierUnitMap.put("dummyflag", lotUnitDummyflag);
carrierUnitMap.put("available", lotUnitAvailable);
carrierUnitMap.put("lotid", lotUnitLotid);
break;
}
}
}
return foupUnits;
}
private Lot rebuidMergeLotInfo(Lot lot, Collection childLots) {
long facilityRrn = LocalContext.getFacilityRrn();
int parIndex = StringUtils.indexOf(lot.getLotId(), ".");
int parLotnumber = NumberUtils.toInt(lot.getLotId().substring(parIndex + 1));
String minestLotId = StringUtils.EMPTY;
int minestLotnumber = parLotnumber;
Map leftLot = new HashMap();
Iterator it = childLots.iterator();
while (it.hasNext()) {
Map item = (HashMap) it.next();
String childLotId = MapUtils.getString(item, "childLotId", StringUtils.EMPTY);
int index = StringUtils.indexOf(childLotId, ".");
int childLotnumber = NumberUtils.toInt(childLotId.substring(index + 1));
if (minestLotnumber > childLotnumber) {
minestLotnumber = childLotnumber;
minestLotId = childLotId;
leftLot = item;
}
}
if (minestLotnumber != parLotnumber) {
Lot realParentLot = lotQueryService.getLot(minestLotId, facilityRrn);
childLots.remove(leftLot);
HashMap item = new HashMap();
item.put("childLotId", lot.getLotId());
item.put("carrierId", lot.getCarrierId());
item.put("qty1", lot.getQty1());
item.put("qty2", lot.getQty2());
item.put("productId", lot.getProductId());
item.put("processId", lot.getProcessId());
item.put("operationId", lot.getOperationId());
if (this.isTrackUnitFlag(realParentLot)) {
Assert.isTrue(this.isTrackUnitFlag(lot), Errors.create().content("Different track unit flag!").build());
item.put("units", this.parseToSimplifyCollection(
this.parseToString(wipQueryService.getUnitListByLot(lot.getLotRrn()))));
}
childLots.add(item);
lot = realParentLot;
}
return lot;
}
private void mergeLot(Lot lot, List childLots, SplitMergeInfoForm theform, String user) {
long facilityRrn = LocalContext.getFacilityRrn();
Assert.isFalse(childLots.size() <= 0, Errors.create().key(MessageIdList.MERGELOT_NO_LOT_SELECTED_FOR_MERGE)
.content("No lot selected for merge").build());
lot = this.rebuidMergeLotInfo(lot, childLots);
Carrier parentCarrier = carrierService.getCarrier(lot.getCarrierRrn());
Boolean canDropTarget = parentCarrier.getSlotCount() == 13;// cst13 的晶周可以拖动
List newUnits = null;
List sourceListValues = wipQueryService.getUnitListByLot(lot.getLotRrn());
//创建需要上锁的 rrn arry
List<String> needLockLotRrns=new ArrayList<>();
//添加 父 lot rrn
needLockLotRrns.add(StringUtils.toString(lot.getLotRrn()));
List<Map> masterLotRunCardCreatedTimeList = lotRunCardQueryService
.getSumbitAndActiveRunCardCreateTime(lot.getLotRrn());
for (Iterator it = childLots.iterator(); it.hasNext(); ) {
Map item = (Map) it.next();
Lot child_Lot = lotQueryService
.getLot(MapUtils.getString(item, "childLotId"), LocalContext.getFacilityRrn());
// 再次判断是否可以合批
checkMergeAvailable(lot, child_Lot);
sourceAndChidUnits(sourceListValues, item, masterLotRunCardCreatedTimeList);
//经过上述判断后 将子批次 加入上锁集合
needLockLotRrns.add(StringUtils.toString(child_Lot.getLotRrn()));
// check process version
checkProcessVersionForMerge(lot, child_Lot);
// check product version
checkProductVersionForMerge(lot, child_Lot);
// check Contamination
this.checkContaminationLevel(lot, child_Lot);
//Check flip for childLot and parentLot
this.checkFlip4ChildAndParentLot(lot, child_Lot);
}
Collections.sort((List) sourceListValues, 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);
}
});
List buildChildUnits = new ArrayList();
for (Iterator iterator2 = sourceListValues.iterator(); iterator2.hasNext(); ) {
Map childMap = (HashMap) iterator2.next();
Map buildChildMap = childMap;
String childUnitRrn = MapUtils.getString(childMap, "unitRrn");
for (Iterator iterator = sourceListValues.iterator(); iterator.hasNext(); ) {
Map sourceMap = (HashMap) iterator.next();
String sourceUnitRrn = MapUtils.getString(sourceMap, "unitRrn");
if (StringUtils.equals(childUnitRrn, sourceUnitRrn)) {
buildChildMap.put("position", MapUtils.getString(sourceMap, "position"));
buildChildUnits.add(buildChildMap);
}
}
}
if (buildChildUnits.size() == buildChildUnits.size()) {
sourceListValues = buildChildUnits;
}
newUnits = this.parseJsonStrAndRemoveIdlePostion(theform.getSourceListValues());
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", newUnits);
Assert.isFalse(checkMergeBeforeUpdateDB(valueMap), Errors.create().content("Merge Lot info is error!").build());
// add for FMI reason Code
TransReason transReason = new TransReason();
String reason = theform.getReason();
transReason.setReasonCode("");
transReason.setResponsibility(user);
transReason.setReason(reason);
valueMap.put("transReason", transReason);
checkLotPriority(valueMap, lot, childLots);
// end
// String childLotIds = "";
// List<Lot> lockLots = new ArrayList<Lot>();
// lockLots.add(lot);
// for (Iterator iterator = childLots.iterator(); iterator.hasNext(); ) {
// Map map = (Map) iterator.next();
// Lot _lot = lotQueryService.getLot(MapUtils.getString(map, "childLotId"), facilityRrn);
// // lockLots.add(_lot);
// childLotIds += _lot.getLotId() + ",";
// }
// Long userRrn = LocalContext.getUserRrn();
// checkAndCreateLotsTransLock(userRrn, TransactionNames.LOCK_MERGE, lockLots,
// "The lot: " + lot.getLotId() + " merge: " + childLotIds + " in MergeLotAction
// by:" +
// " " + user);
lotService.mergeLot(valueMap,needLockLotRrns);
}
private void checkLotPriority(HashMap valueMap, Lot lot, Collection childLots) {
// Check the priority size of sub-lot and lot
Integer tempHotFlag = NumberUtils.toInt(lot.getHotFlag(), Integer.MAX_VALUE);
Integer tempProirity = Optional.ofNullable(lot.getPriority()).orElse(Integer.MAX_VALUE);
boolean changeFlag = false;
for (Iterator it = childLots.iterator(); it.hasNext(); ) {
HashMap subLotMap = (HashMap) it.next();
Lot subLot = lotQueryService.getLot(MapUtils.getString(subLotMap, "childLotId"), lot.getFacilityRrn());
Integer hotFlag = NumberUtils.toInt(subLot.getHotFlag(), Integer.MAX_VALUE);
Integer priority = Optional.ofNullable(subLot.getPriority()).orElse(Integer.MAX_VALUE);
if (hotFlag < tempHotFlag || (hotFlag.equals(tempHotFlag) && priority < tempProirity)) {
changeFlag = true;
tempHotFlag = hotFlag;
tempProirity = priority;
}
}
if (changeFlag) {
valueMap.put("hotFlag", tempHotFlag);
valueMap.put("priority", tempProirity);
}
}
}