public async Task <List <AgentStatistic> > RunSim(int simulationId, int simulationNumber) { AgentStatistic.Log = new List <string>(); Debug.WriteLine("Simulation Starts"); _messageHub.SendToAllClients("Simulation starts..."); using (var context = new SimulationContext(isDefaultContextForProcess: true)) { // initialise the model var system = await CreateModel(context : context, simulationId : simulationId, simNr : simulationNumber); // instantate a new simulator var simulator = new Simulator(); // run the simulation await simulator.SimulateAsync(0); // Debug Debuglog(simulationContext: context, productionDomainContextContext: _productionDomainContext, simNr: simulationNumber, simId: simulationId); var simulationNr = _productionDomainContext.GetSimulationNumber(simulationId, SimulationType.Decentral); Statistics.UpdateSimulationId(simulationId, SimulationType.Decentral, simulationNumber); _productionDomainContext.SimulationWorkschedules.AddRange(SimulationWorkschedules); _productionDomainContext.SaveChanges(); SaveStockExchanges(simulationId, simulationNr, context); //UpdateStockExchanges(simulationId, simulationNr); } return(Agent.AgentStatistics); }
/// <summary> /// Set Start- and Endtime for ProductionOrderWorkSchedules for the given OrderPart excluding capacities in a backward schedule /// </summary> /// <param name="demand"></param> public void BackwardScheduling(IDemandToProvider demand) { var productionOrderWorkSchedules = new List <ProductionOrderWorkSchedule>(); _context.GetWorkSchedulesFromDemand(demand, ref productionOrderWorkSchedules); productionOrderWorkSchedules = productionOrderWorkSchedules.OrderBy(a => a.ProductionOrderId).ThenByDescending(b => b.HierarchyNumber).ToList(); foreach (var workSchedule in productionOrderWorkSchedules) { // set transition time relating to machine group. var transitionTime = Calculations.GetTransitionTimeForWorkSchedule(workSchedule); //Set hierarchy to something high that every workSchedule found will overwrite this value var hierarchyParent = _context.GetHierarchyParent(workSchedule); //if no hierarchy has been found if (hierarchyParent == null) { if (demand.State == State.ForwardScheduleExists) { workSchedule.EndForward = SetBackwardTimeFromParent(workSchedule, demand.State); } else { workSchedule.EndBackward = SetBackwardTimeFromParent(workSchedule, demand.State); } } else { if (demand.State == State.ForwardScheduleExists) { workSchedule.EndForward = _context.ProductionOrderWorkSchedules.Single(a => (a.HierarchyNumber == hierarchyParent.HierarchyNumber) && (a.ProductionOrderId == workSchedule.ProductionOrderId)).StartForward; } else { workSchedule.EndBackward = _context.ProductionOrderWorkSchedules.Single(a => (a.HierarchyNumber == hierarchyParent.HierarchyNumber) && (a.ProductionOrderId == workSchedule.ProductionOrderId)).StartBackward; } } if (demand.State == State.ForwardScheduleExists) { workSchedule.StartForward = workSchedule.EndForward - workSchedule.Duration - transitionTime; workSchedule.EndForward = workSchedule.StartForward + workSchedule.Duration; } else { workSchedule.StartBackward = workSchedule.EndBackward - workSchedule.Duration - transitionTime; workSchedule.EndBackward = workSchedule.StartBackward + workSchedule.Duration; } } _context.ProductionOrderWorkSchedules.UpdateRange(productionOrderWorkSchedules); _context.SaveChanges(); }
public Task PrepareSimulationContext() { return(Task.Run(() => { _processMrp = new ProcessMrpSim(_context, _messageHub); _context.SaveChanges(); })); }
private static void ExtractStockExchanges(MasterDBContext inMemmoryContext, ProductionDomainContext productionDomainContext) { var se = inMemmoryContext.StockExchanges.AsNoTracking().ToList().Select(x => { x.Id = 0; return(x); }).ToList(); productionDomainContext.StockExchanges.AddRange(se); productionDomainContext.SaveChanges(); }
private static void ExtractWorkSchedules(MasterDBContext inMemmoryContext, ProductionDomainContext productionDomainContext) { var sw = inMemmoryContext.SimulationWorkschedules.AsNoTracking().ToList().Select(x => { x.Id = 0; return(x); }).ToList(); productionDomainContext.SimulationWorkschedules.AddRange(sw); productionDomainContext.SaveChanges(); }
/// <summary> /// An algorithm for capacity-leveling. Writes Start/End in ProductionOrderWorkSchedule. /// </summary> public void GifflerThompsonScheduling(int simulationId) { var notplanned = new List <ProductionOrderWorkSchedule>(); // Datenbank.Collection.Methode(collection => collection.field == parameter).Field //.Single Return an Object instead of an Collection of that requested Object. var currentTime = _context.SimulationConfigurations.Single(a => a.Id == simulationId).Time; //var productionOrderWorkSchedules = GetProductionSchedules(simulationId); var productionOrderWorkSchedules = _context.ProductionOrderWorkSchedules.Where(a => a.ProducingState == ProducingState.Created).ToList(); productionOrderWorkSchedules = ResetStartEnd(productionOrderWorkSchedules); productionOrderWorkSchedules = CalculateWorkTimeWithParents(productionOrderWorkSchedules); var plannableSchedules = new List <ProductionOrderWorkSchedule>(); var plannedSchedules = new List <ProductionOrderWorkSchedule>(); GetInitialPlannables(productionOrderWorkSchedules, plannedSchedules, plannableSchedules); while (plannableSchedules.Any()) { //find next element by using the activity slack rule //Todo: Remove after testing //var shortest = GetHighestPriority(plannableSchedules); CalculateActivitySlack(plannableSchedules, currentTime); var shortest = GetShortest(plannableSchedules); plannableSchedules.Remove(shortest); //Add a fix spot on a machine with start/end AddMachine(plannedSchedules, shortest, currentTime); plannedSchedules.Add(shortest); //search for parents and if available and allowed add it to the schedule var parents = _context.GetParents(shortest); foreach (var parent in parents) { if (!plannableSchedules.Contains(parent) && IsTechnologicallyAllowed(parent, plannedSchedules)) { plannableSchedules.Add(parent); } _context.SaveChanges(); } } if (productionOrderWorkSchedules.Count() != plannedSchedules.Count()) { notplanned = productionOrderWorkSchedules.Where(pows => !plannedSchedules.Contains(pows)).ToList(); } }
/// <summary> /// Call this method for a single run without simulation. /// </summary> /// <param name="task"></param> /// <param name="simulationId"></param> /// <returns></returns> public async Task InitializeMrp(MrpTask task, int simulationId) { await Task.Run(async() => { _messageHub.SendToAllClients("Prepare InMemory Tables...", MessageType.info); rebuildNets = new RebuildNets(_context); capacityScheduling = new CapacityScheduling(_context); _context = InMemoryContext.CreateInMemoryContext(); InMemoryContext.LoadData(_evaluationContext, _context); await PrepareSimulationContext(); var simConfig = _context.SimulationConfigurations.Single(x => x.Id == simulationId); await OrderGenerator.GenerateOrders(_context, simConfig, simulationId); var simulationNumber = _context.GetSimulationNumber(simulationId, SimulationType.Central); //call initial central MRP-run await _processMrp.CreateAndProcessOrderDemand(task, _context, simulationId, _evaluationContext); if (task == MrpTask.Backward || task == MrpTask.Forward || task == MrpTask.GifflerThompson) { var list = _context.ProductionOrderWorkSchedules.Select(schedule => new PowsSimulationItem(_context) { End = (task == MrpTask.Backward) ? schedule.EndBackward : (task == MrpTask.Forward) ? schedule.EndForward : schedule.End, Start = (task == MrpTask.Backward) ? schedule.StartBackward : (task == MrpTask.Forward) ? schedule.StartForward : schedule.Start, ProductionOrderId = schedule.ProductionOrderId, ProductionOrderWorkScheduleId = schedule.Id, SimulationId = simulationId }) .ToList(); _evaluationContext.SaveChanges(); FillSimulationWorkSchedules(list, simulationId, simulationNumber, task); } SimulationType simType = SimulationType.Central; switch (task) { case MrpTask.Forward: simType = SimulationType.ForwardPlanning; break; case MrpTask.Backward: simType = SimulationType.BackwardPlanning; break; } CopyResults.ExtractSimulationOrders(_context, _evaluationContext, simulationId, simulationNumber, simType); _messageHub.EndScheduler(); }); }
/// <summary> /// /// </summary> /// <param name="context"></param> /// <param name="simulationId"></param> /// <param name="simulationType"></param> /// <param name="simulationNumber"></param> /// <param name="final"></param> /// <param name="time"></param> public static void CalculateTimeliness(ProductionDomainContext context, int simulationId, SimulationType simulationType, int simulationNumber, bool final, int time) { var simConfig = context.SimulationConfigurations.Single(a => a.Id == simulationId); /*var orderTimeliness = final ? context.SimulationOrders.Where(a => a.State == State.Finished * && a.CreationTime > simConfig.SettlingStart * && a.CreationTime < simConfig.SimulationEndTime * && a.SimulationType == simulationType) * .Select(x => new { x.Name, x.FinishingTime, x.DueTime }).ToList() : * context.SimulationOrders.Where(a => a.State == State.Finished * && a.FinishingTime >= time - simConfig.DynamicKpiTimeSpan * && a.SimulationType == simulationType) * .Select(x => new { x.Name, x.FinishingTime, x.DueTime }).ToList(); * * */ var orderTimeliness = final ? //then context.SimulationOrders .Where(x => x.SimulationConfigurationId == simulationId && x.SimulationType == simulationType) .Where(a => a.State == State.Finished && a.CreationTime >= simConfig.SettlingStart && a.FinishingTime <= simConfig.SimulationEndTime && a.CreationTime < simConfig.SimulationEndTime) .Select(x => new { x.Name, x.FinishingTime, x.DueTime }).ToList() // Else : context.SimulationOrders .Where(x => x.SimulationConfigurationId == simulationId && x.SimulationType == simulationType) .Where(a => a.State == State.Finished && a.FinishingTime >= time - simConfig.DynamicKpiTimeSpan) .Select(x => new { x.Name, x.FinishingTime, x.DueTime }).ToList(); if (!orderTimeliness.Any()) { return; } var kpis = orderTimeliness.GroupBy(g => g.Name).Select(o => new Kpi() { Name = o.Key, Value = Math.Round((o.Count(x => (x.DueTime - x.FinishingTime) >= 0) / (double)o.Count()), 2), ValueMin = Math.Round((double)o.Min(m => m.FinishingTime - m.DueTime), 2), ValueMax = Math.Round((double)o.Max(n => n.FinishingTime - n.DueTime), 2), Count = o.Count(c => c.Name == o.Key), IsKpi = final, KpiType = KpiType.Timeliness, SimulationConfigurationId = simulationId, SimulationType = simulationType, SimulationNumber = simulationNumber, Time = time, IsFinal = final }).ToList(); context.Kpis.AddRange(kpis); context.SaveChanges(); }
internal void PersistDbCache() { // TODO: performance issue: Batch insert // first collect all T_* entities List <T_ProductionOrderBom> tProductionOrderBoms = _productionOrderBoms.GetAllAs <T_ProductionOrderBom>(); List <T_StockExchange> tStockExchangeDemands = _stockExchangeDemands.GetAllAs <T_StockExchange>(); List <T_StockExchange> tStockExchangesProviders = _stockExchangeProviders.GetAllAs <T_StockExchange>(); List <T_ProductionOrder> tProductionOrders = _productionOrders.GetAllAs <T_ProductionOrder>(); List <T_ProductionOrderOperation> tProductionOrderOperations = _productionOrderOperations.GetAllAsT_ProductionOrderOperation(); List <T_PurchaseOrderPart> tPurchaseOrderParts = _purchaseOrderParts.GetAllAs <T_PurchaseOrderPart>(); List <T_CustomerOrderPart> tCustomerOrderParts = _customerOrderParts.GetAllAs <T_CustomerOrderPart>(); List <T_CustomerOrder> tCustomerOrders = _customerOrders.GetAllAsTCustomerOrders(); // Insert all T_* entities InsertOrUpdateRange(tProductionOrders, _productionDomainContext.ProductionOrders, _productionDomainContext); InsertOrUpdateRange(tProductionOrderOperations, _productionDomainContext.ProductionOrderOperations, _productionDomainContext); InsertOrUpdateRange(tProductionOrderBoms, _productionDomainContext.ProductionOrderBoms, _productionDomainContext); InsertOrUpdateRange(tStockExchangeDemands, _productionDomainContext.StockExchanges, _productionDomainContext); InsertOrUpdateRange(tCustomerOrders, _productionDomainContext.CustomerOrders, _productionDomainContext); InsertOrUpdateRange(tCustomerOrderParts, _productionDomainContext.CustomerOrderParts, _productionDomainContext); // providers InsertOrUpdateRange(tStockExchangesProviders, _productionDomainContext.StockExchanges, _productionDomainContext); InsertOrUpdateRange(tPurchaseOrderParts, _productionDomainContext.PurchaseOrderParts, _productionDomainContext); InsertOrUpdateRange(_purchaseOrders, _productionDomainContext.PurchaseOrders, _productionDomainContext); // at the end: T_DemandToProvider & T_ProviderToDemand InsertOrUpdateRange(DemandToProviderGetAll().Select(x => (T_DemandToProvider)x), _productionDomainContext.DemandToProviders, _productionDomainContext); if (ProviderToDemandGetAll().Any()) { InsertOrUpdateRange(ProviderToDemandGetAll().Select(x => (T_ProviderToDemand)x), _productionDomainContext.ProviderToDemand, _productionDomainContext); } _productionDomainContext.SaveChanges(); }
private static void ExtractKpis(MasterDBContext inMemmoryContext, ProductionDomainContext productionDomainContext) { //List<Kpi> kpis = new List<Kpi>(); //inMemmoryContext.Kpis.AsNoTracking().ToList(); // foreach (var item in inMemmoryContext.Kpis.ToList()) // { // kpis.Add(item.CopyDbPropertiesWithoutId()); // } var kpis = inMemmoryContext.Kpis.AsNoTracking().ToList().Select(x => { x.Id = 0; return(x); }).ToList(); productionDomainContext.Kpis.AddRange(kpis); productionDomainContext.SaveChanges(); }
private void SaveContext(ProductionDomainContext _evaluationContext) { foreach (var stockexchange in _context.StockExchanges) { stockexchange.SimulationConfigurationId = 1; stockexchange.SimulationNumber = _context.GetSimulationNumber(stockexchange.SimulationConfigurationId, SimulationType.Central); stockexchange.SimulationType = SimulationType.Central; var name = _context.Stocks.Single(b => b.Id == stockexchange.StockId).Name; stockexchange.StockId = _evaluationContext.Stocks.Single(a => a.Name.Equals(name)).Id; var exchange = new StockExchange(); stockexchange.CopyDbPropertiesTo(exchange); _evaluationContext.StockExchanges.Add(exchange); } _evaluationContext.SaveChanges(); }
private void OrderProvided(InstructionSet instructionSet) { if (!(instructionSet.ObjectToProcess is RequestItem requestItem)) { throw new InvalidCastException(this.Name + " Cast to RequestItem Failed"); } var order = _productionDomainContext.Orders .Include(x => x.OrderParts) .Single(x => x.Id == _productionDomainContext.OrderParts.Single(s => s.Id == requestItem.OrderId).OrderId); order.FinishingTime = (int)Context.TimePeriod; order.State = State.Finished; _productionDomainContext.SaveChanges(); _messageHub.SendToAllClients("Oder No:" + order.Id + " finished at " + Context.TimePeriod); _messageHub.ProcessingUpdate(_simConfig.Id, orderCount++, SimulationType.Decentral, _simConfig.OrderQuantity); }
public static void ExtractSimulationOrders(MasterDBContext inMemmoryContext, ProductionDomainContext productionDomainContext, int simId, int simNo, SimulationType simType) { List <SimulationOrder> so = new List <SimulationOrder>(); foreach (var item in inMemmoryContext.Orders.ToList()) { SimulationOrder set = new SimulationOrder(); item.CopyPropertiesTo <IOrder>(set); set.SimulationConfigurationId = simId; set.SimulationNumber = simNo; set.SimulationType = simType; set.OriginId = item.Id; so.Add(set); } productionDomainContext.SimulationOrders.AddRange(so); productionDomainContext.SaveChanges(); }
//[InlineData(SimulationType.Decentral, 2)] //[InlineData(SimulationType.Decentral, 3)] //[InlineData(SimulationType.Central, 6)] // [InlineData(SimulationType.Central, 4)] // [InlineData(SimulationType.Central, 5)] // [InlineData(SimulationType.Central, 6)] // [InlineData(SimulationType.Central, 7)] public async Task TestKpiCalculation(SimulationType simType, int simId) { var toRemove = await _productionDomainContext.Kpis.Where(x => x.SimulationType == simType && x.SimulationConfigurationId == 1 && x.KpiType == KpiType.MeanTimeToStart) .ToListAsync(); _productionDomainContext.Kpis.RemoveRange(toRemove); _productionDomainContext.SaveChanges(); //var simConfig = _productionDomainContext.SimulationConfigurations.Where(x => x.Id == 1); CalculateKpis.CalculateMeanStartTime(_productionDomainContext , 1 , simType , 1 , true , 20160); // var toRemove2 = await _productionDomainContext.Kpis.Where(x => x.SimulationType == simType // && x.SimulationConfigurationId == simId // && x.KpiType == KpiType.StockEvolution) // .ToListAsync(); // _productionDomainContext.Kpis.RemoveRange(toRemove2); // _productionDomainContext.SaveChanges(); // // CalculateKpis.ArticleStockEvolution(_productionDomainContext // , simId // , simType // , 1 // , true // , 20160); // // CalculateKpis.CalculateAllKpis( //CalculateKpis.CalculateMachineUtilization( //context: _productionDomainContext, // simulationId: 1, // simulationType: simType, // simulationNumber: 1, // final: true, // time: 20000); }
public static void Copy(MasterDBContext inMemmoryContext, ProductionDomainContext productionDomainContext, int simId, int simNo, SimulationType simType) { ExtractKpis(inMemmoryContext, productionDomainContext); ExtractWorkSchedules(inMemmoryContext, productionDomainContext); ExtractStockExchanges(inMemmoryContext, productionDomainContext); ExtractSimulationOrders(inMemmoryContext, productionDomainContext, simId, simNo, simType); var simConfig = productionDomainContext.SimulationConfigurations.Single(s => s.Id == simId); if (simType == SimulationType.Central) { simConfig.CentralRuns += 1; simConfig.CentralIsRunning = false; } else { simConfig.DecentralRuns += 1; simConfig.DecentralIsRunning = false; } productionDomainContext.SaveChanges(); }
public Task <bool> DoAtEnd <T>(List <TimeTable <T> .MachineStatus> listMachineStatus, int time) where T : ISimulationItem { var purchasePart = _context.PurchaseParts.Single(a => a.Id == PurchasePartId); var stock = _context.Stocks.Single(a => a.ArticleForeignKey == purchasePart.ArticleId); stock.Current += purchasePart.Quantity; _context.StockExchanges.Add(new StockExchange() { ExchangeType = ExchangeType.Insert, Quantity = purchasePart.Quantity, StockId = stock.Id, RequiredOnTime = purchasePart.Purchase.DueTime, Time = time }); purchasePart.State = State.Finished; _context.SaveChanges(); var provider = _context.UpdateStateDemandProviderPurchaseParts(); _context.UpdateStateDemandRequester(provider); return(null); }
internal void Clone(ProductionDomainContext productionDomainContext) { DbTransactionData.InsertRange(_articles.GetAll(), productionDomainContext.Articles, productionDomainContext); DbTransactionData.InsertRange(_articleBoms.GetAll(), productionDomainContext.ArticleBoms, productionDomainContext); DbTransactionData.InsertRange(_articleToBusinessPartners.GetAll(), productionDomainContext.ArticleToBusinessPartners, productionDomainContext); DbTransactionData.InsertRange(_articleTypes.GetAll(), productionDomainContext.ArticleTypes, productionDomainContext); DbTransactionData.InsertRange(_businessPartners.GetAll(), productionDomainContext.BusinessPartners, productionDomainContext); DbTransactionData.InsertRange(_resources.GetAll(), productionDomainContext.Resources, productionDomainContext); DbTransactionData.InsertRange(_resourceSkills.GetAll(), productionDomainContext.ResourceSkills, productionDomainContext); DbTransactionData.InsertRange(_resourceTools.GetAll(), productionDomainContext.ResourceTools, productionDomainContext); DbTransactionData.InsertRange(_resourceSetups.GetAll(), productionDomainContext.ResourceSetups, productionDomainContext); DbTransactionData.InsertRange(_operations.GetAll(), productionDomainContext.Operations, productionDomainContext); DbTransactionData.InsertRange(_stocks.GetAll(), productionDomainContext.Stocks, productionDomainContext); DbTransactionData.InsertRange(_units.GetAll(), productionDomainContext.Units, productionDomainContext); productionDomainContext.SaveChanges(); }
/* * public void SqlBulkCopy() * { * // Establishing connection * SqlConnectionStringBuilder cb = new SqlConnectionStringBuilder(); * cb.DataSource = * "Server=(localdb)\\mssqllocaldb;Database=Master40;Trusted_Connection=True;MultipleActiveResultSets=true"; * cb.InitialCatalog = "Master40"; * cb.IntegratedSecurity = true; * SqlConnection cnn = new SqlConnection(cb.ConnectionString); * * // Getting source data * SqlCommand cmd = new SqlCommand("SELECT * FROM PendingOrders", cnn); * cnn.Open(); * SqlDataReader rdr = cmd.ExecuteReader(); * * // Initializing an SqlBulkCopy object * SqlBulkCopy sbc = new SqlBulkCopy("server=.;database=ProductionTest;Integrated Security=SSPI"); * * // Copying data to destination * sbc.DestinationTableName = "Temp"; * sbc.WriteToServer(rdr); * * // Closing connection and the others * sbc.Close(); * cnn.Close(); * } */ public static void CopyAllTables(this ProductionDomainContext sourceContext, ProductionDomainContext targetContext) { // basic Set targetContext.ArticleTypes.AddRange(sourceContext.ArticleTypes); targetContext.Units.AddRange(sourceContext.Units); targetContext.Machines.AddRange(sourceContext.Machines); targetContext.MachineGroups.AddRange(sourceContext.MachineGroups); targetContext.MachineTools.AddRange(sourceContext.MachineTools); targetContext.Articles.AddRange(sourceContext.Articles); targetContext.Stocks.AddRange(sourceContext.Stocks); targetContext.StockExchanges.AddRange(sourceContext.StockExchanges); targetContext.WorkSchedules.AddRange(sourceContext.WorkSchedules); targetContext.ArticleBoms.AddRange(sourceContext.ArticleBoms); targetContext.BusinessPartners.AddRange(sourceContext.BusinessPartners); targetContext.ArticleToBusinessPartners.AddRange(sourceContext.ArticleToBusinessPartners); targetContext.Orders.AddRange(sourceContext.Orders); targetContext.OrderParts.AddRange(sourceContext.OrderParts); targetContext.SimulationConfigurations.AddRange(sourceContext.SimulationConfigurations); targetContext.SaveChanges(); }
public void Rebuild(int simulationId, ProductionDomainContext evaluationContext) { //delete all demands but the head-demands _context.Demands.RemoveRange(_context.Demands.Where(a => (a.DemandRequesterId != null || a.GetType() == typeof(DemandProductionOrderBom)) && a.State != State.Finished).ToList()); _context.ProductionOrderBoms.RemoveRange(_context.ProductionOrderBoms.Where(a => a.State != State.Finished)); _context.SaveChanges(); var requester = _context.Demands.Where(a => null == a.DemandRequesterId && a.State != State.Finished).ToList(); requester = (from req in requester where req.GetType() == typeof(DemandStock) || _context.GetDueTimeByOrder(req) < _context.SimulationConfigurations.Single(a => a.Id == simulationId).Time + _context.SimulationConfigurations.Single(a => a.Id == simulationId).MaxCalculationTime select req).ToList(); //rebuild by using activity-slack to order demands while (requester.Any()) { var nextRequester = GetNextByActivitySlack(requester, simulationId); SatisfyRequest(nextRequester, simulationId, evaluationContext); requester.Remove(requester.Find(a => a.Id == nextRequester.Id)); } }
/// <summary> /// /// </summary> /// <param name="context"></param> /// <param name="simulationId"></param> /// <param name="simulationType"></param> /// <param name="simulationNumber"></param> /// <param name="final"></param> /// <param name="time"></param> public static void CalculateMachineUtilization(ProductionDomainContext context, int simulationId, SimulationType simulationType, int simulationNumber, bool final, int time) { var simConfig = context.SimulationConfigurations.Single(a => a.Id == simulationId); //get working time var content = final ? context.SimulationWorkschedules.Where(a => a.Start >= simConfig.SettlingStart && a.End <= simConfig.SimulationEndTime && a.End >= simConfig.SettlingStart && a.SimulationNumber == simulationNumber && a.SimulationType == simulationType && a.SimulationConfigurationId == simulationId) .Select(x => new { x.Start, x.End, x.Machine }).Distinct().ToList() : context.SimulationWorkschedules.Where(a => a.Start >= time - simConfig.DynamicKpiTimeSpan && a.End <= time && a.SimulationNumber == simulationNumber && a.SimulationType == simulationType && a.SimulationConfigurationId == simulationId) .Select(x => new { x.Start, x.End, x.Machine }).Distinct().ToList(); //get SimulationTime var simulationTime = final ? simConfig.SimulationEndTime - simConfig.SettlingStart : simConfig.DynamicKpiTimeSpan; var kpis = content.GroupBy(x => x.Machine).Select(g => new Kpi() { Value = Math.Round((double)(g.Sum(x => x.End) - g.Sum(x => x.Start)) / simulationTime, 2), Name = g.Key, IsKpi = final, KpiType = KpiType.MachineUtilization, SimulationConfigurationId = simulationId, SimulationType = simulationType, SimulationNumber = simulationNumber, Time = time, IsFinal = final }).ToList(); context.Kpis.AddRange(kpis); context.SaveChanges(); if (!final) { return; } var allKpis = context.Kpis.Where(a => a.KpiType == KpiType.MachineUtilization && a.SimulationConfigurationId == simulationId && a.SimulationNumber == simulationNumber && a.SimulationType == simulationType && !a.IsFinal && a.Time > simConfig.SettlingStart && a.Time < simConfig.SimulationEndTime).ToList(); //for each machine for (var i = 0; i < kpis.Count(); i++) { var list = allKpis.Where(a => a.Name == kpis[i].Name).ToList(); if (list.Count == 0 || list.Count == 1) { continue; } kpis[i].Count = list.Sum(item => Math.Pow(item.Value - kpis[i].Value, 2)) / (list.Count - 1.00); kpis[i].ValueMin = kpis[i].Count / list.Count; } context.UpdateRange(kpis); context.SaveChanges(); }
public Task <bool> DoAtStart(int time) { var pows = _context.ProductionOrderWorkSchedules.Single(a => a.Id == ProductionOrderWorkScheduleId); pows.ProducingState = ProducingState.Producing; var demandProvider = _context.ProductionOrderWorkSchedules.Single(a => a.Id == ProductionOrderWorkScheduleId).ProductionOrder .DemandProviderProductionOrders; if (demandProvider != null && demandProvider.Any()) { foreach (var provider in demandProvider) { provider.State = State.Producing; } _context.ProductionOrderWorkSchedules.Update(pows); } if (HasHierarchyChildren(pows)) { _context.SaveChanges(); return(null); } //set bom to be finished var boms = _context.ProductionOrderBoms.Where(a => a.ProductionOrderParentId == ProductionOrderId); foreach (var bom in boms) { bom.State = State.Finished; var requester = bom.DemandProductionOrderBoms; foreach (var req in requester.Where(a => a.State != State.Finished)) { //find DemandProviderStock to set them ready foreach (var provider in req.DemandProvider.OfType <DemandProviderStock>()) { provider.State = State.Finished; } req.State = State.Finished; } } _context.UpdateRange(boms); var pobs = _context.ProductionOrderBoms.Where(a => a.ProductionOrderParentId == ProductionOrderId); foreach (var pob in pobs) { foreach (var dpob in pob.DemandProductionOrderBoms) { var stock = _context.Stocks.Single(a => a.ArticleForeignKey == dpob.ArticleId); stock.Current -= dpob.Quantity; _context.StockExchanges.Add(new StockExchange() { ExchangeType = ExchangeType.Withdrawal, Quantity = dpob.Quantity, StockId = stock.Id, RequiredOnTime = _context.ProductionOrders.Single(a => a.Id == ProductionOrderId).Duetime, Time = time }); _context.Stocks.Update(stock); _context.SaveChanges(); } } _context.SaveChanges(); return(null); }
/// <summary> /// Plans all unplanned Orders with MRP I + II /// </summary> /// <param name="task"></param> /// <returns></returns> public async Task CreateAndProcessOrderDemand(MrpTask task, ProductionDomainContext context, int simulationId, ProductionDomainContext evaluationContext) { await Task.Run(() => { if (context != null) { _context = context; } var newOrdersAdded = false; _messageHub.SendToAllClients("Start full MRP cycle...", MessageType.info); //get all unplanned orderparts and iterate through them for MRP var simConfig = _context.SimulationConfigurations.Single(a => a.Id == simulationId); var maxAllowedTime = simConfig.Time + simConfig.MaxCalculationTime; //Todo: put together if problem is solved var orderParts3 = _context.OrderParts.Include(a => a.Order).Where(a => a.IsPlanned == false); var orderParts2 = orderParts3.Where(a => a.Order.CreationTime <= simConfig.Time); var orderParts = orderParts2.Where(a => a.Order.DueTime < maxAllowedTime).Include(a => a.Article).ToList(); if (orderParts.Any()) { newOrdersAdded = true; } foreach (var orderPart in orderParts.ToList()) { var demand = GetDemand(orderPart); _messageHub.SendToAllClients("running requirements for orderpart " + orderPart.Id); //run the requirements planning and backward/forward termination algorithm RunRequirementsAndTermination(demand, task, simulationId); } if (task == MrpTask.All || task == MrpTask.GifflerThompson || task == MrpTask.Capacity) { //run the capacity algorithm PlanCapacities(task, newOrdersAdded, simulationId, evaluationContext); _messageHub.SendToAllClients("Capacities are planned"); } //set all orderparts to be planned foreach (var orderPart in orderParts) { if (task == MrpTask.All || task == MrpTask.GifflerThompson) { orderPart.IsPlanned = true; } } _context.SaveChanges(); _messageHub.SendToAllClients("End of the latest calculated order: " + _context.ProductionOrderWorkSchedules?.Max(a => a.End)); }); }
public static void DbInitialize(ProductionDomainContext productionDomainContext) { productionDomainContext.Database.EnsureCreated(); // Article Types var articleTypes = CreateArticleTypes(); productionDomainContext.ArticleTypes.AddRange(articleTypes); productionDomainContext.SaveChanges(); // Units var units = CreateUnits(); productionDomainContext.Units.AddRange(units); productionDomainContext.SaveChanges(); // resource skills var resourceSkills = CreateResourceSkills(); productionDomainContext.ResourceSkills.AddRange(resourceSkills); productionDomainContext.SaveChanges(); // resource Tools var resourceTools = CreateResourceTools(); productionDomainContext.ResourceTools.AddRange(resourceTools); productionDomainContext.SaveChanges(); // resources var resources = CreateResources(resourceSkills, resourceTools); productionDomainContext.Resources.AddRange(resources); productionDomainContext.SaveChanges(); // resource Setups var resourceSetups = CreateResourceSetups(resourceTools, resources, resourceSkills); productionDomainContext.ResourceSetups.AddRange(resourceSetups); productionDomainContext.SaveChanges(); // Articles var articles = CreateArticles(articleTypes, units); productionDomainContext.Articles.AddRange(articles); productionDomainContext.SaveChanges(); // get the name -> id mappings var dbArticles = productionDomainContext.Articles.ToDictionary(p => p.Name, p => p.Id); // create Stock entrys for each Article foreach (var article in dbArticles) { var stocks = new M_Stock[] { new M_Stock { ArticleForeignKey = article.Value, Name = "Stock: " + article.Key, Min = (article.Key == ARTICLE_SCREWS) ? 50 : 0, Max = 1000, Current = (article.Key == ARTICLE_SCREWS) ? 100 : 0 } }; productionDomainContext.Stocks.AddRange(stocks); productionDomainContext.SaveChanges(); } var operations = CreateOperations(resourceTools, articles, resourceSkills); productionDomainContext.Operations.AddRange(operations); productionDomainContext.SaveChanges(); var articleBom = CreateArticleBoms(articles, operations); productionDomainContext.ArticleBoms.AddRange(articleBom); productionDomainContext.SaveChanges(); var businessPartners = CreateBusinessPartners(); productionDomainContext.BusinessPartners.AddRange(businessPartners); productionDomainContext.SaveChanges(); var articleToBusinessPartner = CreateArticleToBusinessPartners(articles, businessPartners); productionDomainContext.ArticleToBusinessPartners.AddRange(articleToBusinessPartner); productionDomainContext.SaveChanges(); }
public void GanttPlanInsertConfirmationAndReplan() { ProductionDomainContext master40Context = ProductionDomainContext.GetContext(masterCtxString); master40Context.CustomerOrders.RemoveRange(master40Context.CustomerOrders); master40Context.CustomerOrderParts.RemoveRange(master40Context.CustomerOrderParts); master40Context.SaveChanges(); master40Context.CreateNewOrder(10115, 1, 0, 250); master40Context.SaveChanges(); GanttPlanDBContext ganttPlanContext = GanttPlanDBContext.GetContext(GanttPlanCtxString); ganttPlanContext.Database.ExecuteSqlRaw("EXEC sp_MSforeachtable 'DELETE FROM ? '"); GanttPlanOptRunner.RunOptAndExport("Init"); Assert.True(ganttPlanContext.GptblProductionorder.Any()); ganttPlanContext.GptblConfirmation.RemoveRange(ganttPlanContext.GptblConfirmation); var productionorder = ganttPlanContext.GptblProductionorder.Single(x => x.ProductionorderId.Equals("000004")); ganttPlanContext.GptblConfirmation.RemoveRange(ganttPlanContext.GptblConfirmation); var activities = ganttPlanContext.GptblProductionorderOperationActivity.Where(x => x.ProductionorderId.Equals(productionorder.ProductionorderId)); var activity = activities.Single(x => x.OperationId.Equals("10") && x.ActivityId.Equals(2)); var confirmation = CreateConfirmation(activity, productionorder, 1); ganttPlanContext.GptblConfirmation.Add(confirmation); ganttPlanContext.SaveChanges(); GanttPlanOptRunner.RunOptAndExport("Continuous"); Assert.True(ganttPlanContext.GptblConfirmation.Any()); confirmation = ganttPlanContext.GptblConfirmation.SingleOrDefault(x => x.ConfirmationId.Equals(confirmation.ConfirmationId)); //ganttPlanContext.GptblConfirmation.Remove(confirmation); var finishConfirmation = CreateConfirmation(activity, productionorder, 16); ganttPlanContext.SaveChanges(); ganttPlanContext.GptblConfirmation.Add(finishConfirmation); activity = activities.Single(x => x.OperationId.Equals("10") && x.ActivityId.Equals(3)); confirmation = CreateConfirmation(activity, productionorder, 16); ganttPlanContext.GptblConfirmation.Add(confirmation); activity = activities.Single(x => x.OperationId.Equals("20") && x.ActivityId.Equals(2)); confirmation = CreateConfirmation(activity, productionorder, 16); ganttPlanContext.GptblConfirmation.Add(confirmation); ganttPlanContext.SaveChanges(); GanttPlanOptRunner.RunOptAndExport("Continuous"); Assert.True(ganttPlanContext.GptblProductionorder.Count().Equals(10)); }
/// <summary> /// /// </summary> /// <param name="context"></param> /// <param name="simulationId"></param> /// <param name="simulationType"></param> /// <param name="simulationNumber"></param> /// <param name="final"></param> /// <param name="time"></param> public static void ArticleStockEvolution(ProductionDomainContext context, int simulationId, SimulationType simulationType, int simulationNumber, bool final, int time) { var simConfig = context.SimulationConfigurations.Single(a => a.Id == simulationId); var stockEvoLutionsContext = context.StockExchanges .Where(x => x.SimulationConfigurationId == simulationId && x.SimulationType == simulationType) .Where(a => a.Time < simConfig.SimulationEndTime) .Where(t => t.State == State.Finished) .Include(x => x.Stock).ThenInclude(x => x.Article).ToList(); //.Where(x => x.SimulationType == simulationType && x.SimulationConfigurationId == simulationId && x.SimulationNumber == simulationNumber); if (!final) { stockEvoLutionsContext = stockEvoLutionsContext .Where(a => a.Time >= time - simConfig.DynamicKpiTimeSpan).ToList(); } var stockEvoLutions = stockEvoLutionsContext.Select(x => new { x.ExchangeType, x.Time, x.Stock.Article.Name, x.Stock.Article.Price, x.Stock.StartValue, x.Quantity }).OrderBy(x => x.Time).ThenByDescending(x => x.ExchangeType); var articles = stockEvoLutions.Select(x => new { x.Name }).Distinct(); var kpis = new List <Kpi>(); var globalValue = 0.0; var lastGlobal = new Kpi(); foreach (var articleEvolution in stockEvoLutions) { globalValue = (articleEvolution.ExchangeType == ExchangeType.Insert) ? globalValue + Math.Round(Convert.ToDouble(articleEvolution.Quantity) * articleEvolution.Price, 2) : globalValue - Math.Round(Convert.ToDouble(articleEvolution.Quantity) * articleEvolution.Price, 2); if ((int)lastGlobal.Count == articleEvolution.Time) { lastGlobal.ValueMin = globalValue; } else { lastGlobal = new Kpi { Name = "Stock Total", Value = 0, // Math.Round(Convert.ToDouble(globalValue.value), 2), ValueMin = globalValue, ValueMax = 0, Count = Convert.ToDouble(articleEvolution.Time), IsKpi = final, KpiType = KpiType.StockEvolution, SimulationConfigurationId = simulationId, SimulationType = simulationType, SimulationNumber = simulationNumber, Time = time, IsFinal = final }; kpis.Add(lastGlobal); } } foreach (var item in articles) { var value = 0.0; var lastKpi = new Kpi(); var articleEvolutions = stockEvoLutions.Where(x => x.Name.Equals(item.Name)); foreach (var articleEvolution in articleEvolutions) { value = (articleEvolution.ExchangeType == ExchangeType.Insert) ? value + (double)articleEvolution.Quantity : value - (double)articleEvolution.Quantity; if ((int)lastKpi.Count == articleEvolution.Time) { lastKpi.Value = value; } else { lastKpi = new Kpi { Name = articleEvolution.Name, Value = Math.Round(Convert.ToDouble(value), 2), ValueMin = Math.Round(Convert.ToDouble(value * articleEvolution.Price), 2), ValueMax = 0, Count = Convert.ToDouble(articleEvolution.Time), IsKpi = final, KpiType = KpiType.StockEvolution, SimulationConfigurationId = simulationId, SimulationType = simulationType, SimulationNumber = simulationNumber, Time = time, IsFinal = final }; kpis.Add(lastKpi); } } } context.Kpis.AddRange(kpis); context.SaveChanges(); }
/// <summary> /// must be called only after filling SimulationSchedules! /// </summary> /// <param name="context"></param> /// <param name="simulationId"></param> /// <param name="simulationType"></param> /// <param name="simulationNumber"></param> /// <param name="final"></param> /// <param name="time"></param> public static void CalculateMeanStartTime(ProductionDomainContext context, int simulationId, SimulationType simulationType, int simulationNumber, bool final, int time) { var simConfig = context.SimulationConfigurations.Single(a => a.Id == simulationId); //calculate lead times for each product var finishedProducts = final ? context.SimulationWorkschedules .Where(x => x.SimulationConfigurationId == simulationId && x.SimulationType == simulationType) .Where(a => a.ParentId.Equals("[]") && a.Start > simConfig.SettlingStart && a.HierarchyNumber == 20 && a.End <= simConfig.SimulationEndTime).ToList() : context.SimulationWorkschedules .Where(x => x.SimulationConfigurationId == simulationId && x.SimulationType == simulationType).Where(a => a.ParentId.Equals("[]") && a.Start >= time - simConfig.DynamicKpiTimeSpan && a.HierarchyNumber == 20 && a.End <= time - simConfig.DynamicKpiTimeSpan).ToList(); var leadTimes = new List <Kpi>(); var simulationWorkSchedules = context.SimulationWorkschedules.Where( x => x.SimulationConfigurationId == simulationId && x.SimulationType == simulationType && x.SimulationNumber == simulationNumber).ToList(); var simOrders = context.SimulationOrders.Where(x => x.SimulationConfigurationId == simulationId && x.SimulationType == simulationType && x.CreationTime <= time && x.State == State.Finished).AsNoTracking().ToList(); foreach (var product in finishedProducts) { var id = Convert.ToInt32(product.OrderId.Replace("[", "").Replace("]", "")); var start = simulationWorkSchedules.Where(x => x.OrderId == product.OrderId).Min(x => x.Start); var insert = simOrders.SingleOrDefault(x => x.OriginId == id); if (insert != null) { leadTimes.Add(new Kpi { Value = start - insert.CreationTime, Name = product.Article, IsFinal = final }); } } var products = leadTimes.Where(a => a.Name.Contains("-Truck")).Select(x => x.Name).Distinct(); var leadTimesBoxPlot = new List <Kpi>(); //calculate Average per article foreach (var product in products) { var relevantItems = leadTimes.Where(x => x.Name.Equals(product)).Select(x => x.Value); // BoxPlot: without bounderys var enumerable = relevantItems as double[] ?? relevantItems.ToArray(); var stat = enumerable.FiveNumberSummary(); leadTimesBoxPlot.Add(new Kpi() { Name = product, Value = Math.Round(stat[2], 2), ValueMin = Math.Round(stat[0], 2), ValueMax = Math.Round(stat[4], 2), IsKpi = final, KpiType = KpiType.MeanTimeToStart, SimulationConfigurationId = simulationId, SimulationType = simulationType, SimulationNumber = simulationNumber, Time = time, IsFinal = final }); if (double.IsNaN(leadTimesBoxPlot.Last().Value)) { leadTimesBoxPlot.Last().Value = 0; } if (double.IsNaN(leadTimesBoxPlot.Last().ValueMin)) { leadTimesBoxPlot.Last().ValueMin = 0; } if (double.IsNaN(leadTimesBoxPlot.Last().ValueMax)) { leadTimesBoxPlot.Last().ValueMax = 0; } // Recalculation for Diagram with cut of outliners // calculate bounderies using lower mild fence (1,5) -> source: http://www.statisticshowto.com/upper-and-lower-fences/ var interQuantileRange = stat[3] - stat[1]; var uperFence = stat[3] + 1.5 * interQuantileRange; var lowerFence = stat[1] - 1.5 * interQuantileRange; // cut them from the sample relevantItems = enumerable.Where(x => x > lowerFence && x < uperFence); // BoxPlot: without bounderys stat = relevantItems.FiveNumberSummary(); // Drop to Database foreach (var item in stat) { leadTimesBoxPlot.Add(new Kpi() { Name = product, Value = Math.Round(item, 2), ValueMin = 0, ValueMax = 0, IsKpi = false, KpiType = KpiType.MeanTimeToStart, SimulationConfigurationId = simulationId, SimulationType = simulationType, SimulationNumber = simulationNumber, IsFinal = final }); if (double.IsNaN(leadTimesBoxPlot.Last().Value)) { leadTimesBoxPlot.Last().Value = 0; } } } context.Kpis.AddRange(leadTimesBoxPlot); context.SaveChanges(); }
public static void CalculateLayTimes(ProductionDomainContext context, int simulationId, SimulationType simulationType, int simulationNumber, bool final, int time) { var simConfig = context.SimulationConfigurations.Single(a => a.Id == simulationId); var stockEvoLutionsContext = context.StockExchanges.Include(x => x.Stock).ThenInclude(x => x.Article) .Where(x => x.SimulationConfigurationId == simulationId && x.SimulationType == simulationType) .Where(t => t.State == State.Finished && t.Stock.Article.ToBuild).AsQueryable(); //.Where(x => x.SimulationType == simulationType && x.SimulationConfigurationId == simulationId && x.SimulationNumber == simulationNumber); if (!final) { stockEvoLutionsContext = stockEvoLutionsContext .Where(a => a.Time >= time - simConfig.DynamicKpiTimeSpan); } var stockEvoLutions = stockEvoLutionsContext.Select(x => new { x.ExchangeType, x.Time, x.Stock.Article.Name, x.Stock.Article.Price, x.Quantity }) .OrderBy(x => x.Time).ThenByDescending(x => x.ExchangeType).ToList(); var articles = context.Articles.Include(a => a.Stock).ToList(); foreach (var article in articles) //.Where(x => x.Name.Equals("Dump-Truck"))) { var laytimeList = new List <double>(); Queue <dynamic> inserts = new Queue <dynamic>(stockEvoLutions .Where(a => a.ExchangeType == ExchangeType.Insert && a.Name == article.Name && a.Quantity != 0) .OrderBy(t => t.Time).ToList()); Queue <dynamic> withdrawls = new Queue <dynamic>(stockEvoLutions .Where(a => a.ExchangeType == ExchangeType.Withdrawal && a.Name == article.Name) .OrderBy(t => t.Time).ToList()); decimal restCount = 0, insertAmount = 0, withdrawlAmount = 0; int withdrawlTime = 0; while (inserts.Any()) { var insert = inserts.Dequeue(); insertAmount = insert.Quantity; while (insertAmount > 0 && (withdrawls.Any() || restCount != 0)) { if (restCount == 0) { dynamic withdrawl = withdrawls.Dequeue(); withdrawlAmount = withdrawl.Quantity; withdrawlTime = withdrawl.Time; } restCount = insertAmount - withdrawlAmount; if (restCount >= 0) { for (int i = 0; i < withdrawlAmount; i++) { //if (insert.Time > simConfig.SettlingStart) laytimeList.Add(withdrawlTime - insert.Time); insertAmount--; withdrawlAmount--; } restCount = 0; } else { for (int i = 0; i < insertAmount; i++) { //if (insert.Time > simConfig.SettlingStart) laytimeList.Add(withdrawlTime - insert.Time); insertAmount--; withdrawlAmount--; } } } } if (!laytimeList.Any()) { continue; } var stat = laytimeList.FiveNumberSummary(); context.Kpis.Add(new Kpi() { Name = article.Name, Value = Math.Round(stat[2], 2), ValueMin = Math.Round(stat[0], 2), ValueMax = Math.Round(stat[4], 2), IsKpi = true, KpiType = KpiType.LayTime, SimulationConfigurationId = simulationId, SimulationType = simulationType, SimulationNumber = simulationNumber, Time = time, IsFinal = final }); var interQuantileRange = stat[3] - stat[1]; var upperFence = stat[3] + 1.5 * interQuantileRange; var lowerFence = stat[1] - 1.5 * interQuantileRange; // cut them from the sample var relevantItems = stat.Where(x => x >= lowerFence && x <= upperFence); // BoxPlot: without bounderys stat = relevantItems.FiveNumberSummary(); foreach (var item in stat) { context.Kpis.Add(new Kpi() { Name = article.Name, Value = Math.Round(item, 2), ValueMin = 0, ValueMax = 0, IsKpi = false, KpiType = KpiType.LayTime, SimulationConfigurationId = simulationId, SimulationType = simulationType, SimulationNumber = simulationNumber, IsFinal = final }); } } context.SaveChanges(); }