public OrderManagementService(IPreactor preactor) { _preactor = preactor; shtRepo = new ShortagesRepo(_preactor); ignShtRepo = new IgnoreShortagesRepo(_preactor); ordRepo = new OrderRepo(_preactor); prdRepo = new ProductRepo(_preactor); resSqlRepo = new ResourceRepoSql(_preactor); resList = resSqlRepo.getAll(); }
public IEnumerable <IGrouping <dynamic, OrderDTO> > SetOperationsStartTimeByLast2(IEnumerable <IGrouping <dynamic, OrderDTO> > list) { //обход по подгруппам (resource-rank) DateTime tTime = _preactor.PlanningBoard.TerminatorTime; DateTime prevMaxEndDate = default(DateTime); ResourceRepoSql resSqlRepo = new ResourceRepoSql(_preactor); int resId = -1; IEnumerable <OrderDTO> opListTemp = new List <OrderDTO>(); IEnumerable <OrderDTO> opListTempBuffer = new List <OrderDTO>(); PlannerService _plannerService = new PlannerService(_preactor); foreach (var gr in list) { //Если меняется ранк, то идет вычисление предыдущей макс даты //Если меняется ресурс, макс дата сбрасывается. DateTime st1 = default(DateTime); DateTime et1 = default(DateTime); OrderDTO lastOp = getLastOperationOnResource(gr.ToList()); if (lastOp != null) { st1 = lastOp.SetupStart; et1 = lastOp.EndTime; } if (gr.Select(x => x.ResourceId).First() != resId) { _plannerService.UnallocateOpOnResources(gr.Select(x => x.ResourceId).First(), true); if (lastOp != null) { prevMaxEndDate = st1; } else { prevMaxEndDate = tTime; } opListTempBuffer = new List <OrderDTO>();//обнуляем буфер уже запланированых операций на ресурсе } else { if (opListTempBuffer.Count() > 0) { List <OrderDTO> testIntervalList = opListTempBuffer.Where(x => { return(IsDayIntervalIntersected(st1, et1, x.SetupStart, x.EndTime)); }).ToList(); if (testIntervalList.Count() == 0) { prevMaxEndDate = st1; } else { prevMaxEndDate = opListTempBuffer.Max(x => x.EndTime); } } } opListTemp = gr.ToList(); resId = gr.Select(x => x.ResourceId).First(); int resNumber = _preactor.GetRecordNumber("Resources", new PrimaryKey(resId)); while (opListTemp.Count() > 0) { lastOp = getLastOperationOnResource(opListTemp); if (lastOp == null) { //оставшееся подмножество операций больше не удовлетворяет условиям break; } DateTime setupStart = lastOp.SetupStart; DateTime startTime = lastOp.StartTime; DateTime endTime = lastOp.EndTime; int opNumber = _preactor.GetRecordNumber("Orders", new PrimaryKey(lastOp.Id)); prevMaxEndDate = tTime; //Проверяем на пересечение текущего штабеля операций с уже запланироваными if (opListTempBuffer.Count() > 0) { List <OrderDTO> testIntervalList = opListTempBuffer.Where(x => { return(IsDayIntervalIntersected(lastOp.SetupStart, lastOp.EndTime, x.SetupStart, x.EndTime)); }).ToList(); if (testIntervalList.Count() == 0) { prevMaxEndDate = lastOp.SetupStart; } else { //если текущий штабель пересекает запланированые, выясняем время тестированием от терминатора prevMaxEndDate = tTime; OperationTimes?times1 = _preactor.PlanningBoard.TestOperationOnResource(opNumber, resNumber, prevMaxEndDate); if (times1 != null) { testIntervalList = opListTempBuffer.Where(x => { return(IsDayIntervalIntersected(times1.Value.ChangeStart, times1.Value.ProcessEnd, x.SetupStart, x.EndTime)); }).ToList(); } if (testIntervalList.Count() == 0) { prevMaxEndDate = times1.Value.ChangeStart; } else { prevMaxEndDate = opListTempBuffer.Max(x => x.EndTime);//как последний вариант ставим в конец всех операций } } } //------------------------------------- OperationTimes?times = _preactor.PlanningBoard.TestOperationOnResource(opNumber, resNumber, prevMaxEndDate); //При подсчете разницы, учитываем на тестовое время,что есть периоды недоступности ресурсов if (times.HasValue) { DateTime testTimeStart = times.Value.ProcessStart; DateTime testTimeSetup = times.Value.ChangeStart; DateTime testTimeEnd = times.Value.ProcessEnd; startTime = testTimeStart; setupStart = testTimeSetup; endTime = testTimeEnd; } else { times = _preactor.PlanningBoard.QueryOperationOnResource(opNumber, resNumber, prevMaxEndDate); DateTime testTimeStart = times.Value.ProcessStart; DateTime testTimeSetup = times.Value.ChangeStart; DateTime testTimeEnd = times.Value.ProcessEnd; startTime = testTimeStart; setupStart = testTimeSetup; endTime = testTimeEnd; } var subListOp = opListTemp.Where(x => x.StartTime <= lastOp.StartTime).ToList(); opListTemp = opListTemp.Except(subListOp).ToList(); foreach (var el in subListOp) { if (el.SetupStart < tTime) { continue; } el.SetupStart = setupStart; el.StartTime = startTime; TimeSpan tsStart = endTime - el.StartTime; TimeSpan tsSetup = endTime - el.SetupStart; el.EndTime = el.StartTime.Add(tsStart); el.Scheduled = true; } prevMaxEndDate = subListOp.Max(x => x.EndTime); opListTempBuffer = opListTempBuffer.Concat(subListOp);//постепенно заполняем буфер запланированых операций }//while }//foreach return(list); }