private static bool IsLoadableDummy(FabAoEquipment eqp, FabLot dummy, decimal inflowHours) { var now = eqp.NowDT; var last = eqp.GetLastPlan(); //eqp.LastPlan as FabPlanInfo; if (last == null) { return(false); } //M제약에 의해 진행 중인 last의 Arrange가 없어진 경우 if (EqpArrangeMaster.IsLoadable(eqp, dummy) == false) { return(false); } var currEA = dummy.CurrentEqpArrange; if (currEA == null || currEA.IsLoableByProductVersion(last.ProductVersion) == false) { return(false); } string reason = string.Empty; if (FilterMaster.IsEqpRecipeTime(eqp, dummy, now.AddHours((double)inflowHours), ref reason) == false) { return(false); } //Dummy Mask 확인 if (FilterMaster.IsLoadableToolArrange(eqp, dummy, false) == false) { return(false); } //MixRun(ParallelChamber) if (eqp.IsParallelChamber) { var subEqp = eqp.TriggerSubEqp; if (subEqp != null) { if (subEqp.IsLoadable(last.FabStep, now) == false) { return(false); } } } return(true); }
internal static IList <IHandlingBatch> Revaluate(AoEquipment eqp, List <IHandlingBatch> wips) { if (eqp.Dispatcher is FifoDispatcher) { return(wips); } for (int i = wips.Count - 1; i >= 0; i--) { var hb = wips[i]; var lot = hb.ToFabLot(); bool isRevaluate = false; //ALLOW_SMALL_LOT_FILTER 기준으로 소량인 경우만 Revaluate 시킴 if (lot.DispatchFilterInfo.FilterType == DispatchFilter.Setup) { if (FilterMaster.IsStepSmallLot(eqp, lot)) { isRevaluate = true; } } if (lot.DispatchFilterInfo.FilterType == DispatchFilter.NewEqpAssign) { if (lot.DispatchFilterInfo.NewAssignNeedCount > 0) { isRevaluate = true; } } if (isRevaluate) { lot.CurrentFabPlan.AddLotFilteredInfo("Revaluate", DispatchFilter.Revaluate); } else { wips.RemoveAt(i); WriteFilterInfo(hb, eqp); } } return(wips); }
public static bool IsEqpRecipeTime(AoEquipment aeqp, FabLot lot, Time inTime, ref string reason) { if (InputMart.Instance.GlobalParameters.ApplyRecipeTime == false) { return(true); } var eqp = aeqp.ToFabAoEquipment(); List <EqpRecipeInfo> list = FilterMaster.GetRecipeMatchList(eqp, lot); if (list == null || list.Count == 0) { return(true); } EqpRecipeInfo info = list[0]; //M 무조건 투입방지 (Matching에서 활용가능한 M만 가져왔음) if (info.Flag == RecipeFlag.M) { reason = string.Format("M:{0}≤{1}", info.MaxCount, info.TrackInCount); return(false); } //TestLot 하나 흘림. 그동안 해당 제품은 흘릴 수 없음. else if (info.Flag == RecipeFlag.X) { if (info.ActiveEndTime == Time.MaxValue) { FilterMaster.AddCurrentEqpRecipeInfo(lot, info); return(true); } if (info.ActiveStartTime != DateTime.MinValue) { if (inTime < info.ActiveEndTime) { Time remain = info.ActiveEndTime - inTime; reason = string.Format("X:Remain {0}Hour", remain.TotalHours.ToRound(1)); return(false); } } } //DueDate까지만 흘릴 수 있음. (DueDate 이내에 Lot이 들어가지 않을 경우 X처럼동작 else if (info.Flag == RecipeFlag.Y) { if (info.ChangeYtoX) { if (info.ActiveStartTime != DateTime.MinValue) { if (inTime < info.ActiveEndTime) { Time remain = info.ActiveEndTime - inTime; reason = string.Format("Y:Remain {0}Hour", remain.TotalHours.ToRound(1)); return(false); } } } else { FilterMaster.AddCurrentEqpRecipeInfo(lot, info); } } return(true); }