Example #1
0
        /// <summary>
        /// Run requirements planning and backward/forward termination.
        /// </summary>
        /// <param name="demand"></param>
        /// <param name="task"></param>
        /// <param name="simulationId"></param>
        public void RunRequirementsAndTermination(IDemandToProvider demand, MrpTask task, int simulationId)
        {
            if (demand.State == State.Created)
            {
                ExecutePlanning(demand, task, simulationId);
                if (demand.State != State.Finished)
                {
                    demand.State = State.ProviderExist;
                }
                _context.Update(demand);
                _context.SaveChanges();
                _messageHub.SendToAllClients("Requirements planning completed.");
            }

            if (task == MrpTask.All || task == MrpTask.Backward)
            {
                _scheduling.BackwardScheduling(demand);
                demand.State = State.BackwardScheduleExists;
                _context.Update(demand);
                _context.SaveChanges();
                _messageHub.SendToAllClients("Backward schedule exists.");
            }

            if (task == MrpTask.All && CheckNeedForward(demand, simulationId) || task == MrpTask.Forward)
            {
                //schedules forward and then backward again with the finish of the forward algorithm
                _scheduling.ForwardScheduling(demand);
                demand.State = State.ForwardScheduleExists;
                _context.Update(demand);
                _context.SaveChanges();
                _scheduling.BackwardScheduling(demand);
                _messageHub.SendToAllClients("Forward schedule exists.");
            }
            _context.SaveChanges();
        }
Example #2
0
        /// <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));
            });
        }
Example #3
0
        public void ExecutePlanning(IDemandToProvider demand, MrpTask task, int simulationId)
        {
            //creates Provider for the needs
            var productionOrders = _demandForecast.NetRequirement(demand, task, simulationId);

            if (demand.State != State.Finished)
            {
                demand.State = State.ProviderExist;
            }

            var articleBoms = _context.ArticleBoms
                              .Include(a => a.ArticleChild)
                              .ThenInclude(a => a.ArticleBoms)
                              .ToList();

            //If there was enough in stock this does not have to be produced
            if (!productionOrders.Any())
            {
                return;
            }
            foreach (var productionOrder in productionOrders)
            {
                //if the ProductionOrder was just created, initialize concrete WorkSchedules for the ProductionOrders
                if (productionOrder.ProductionOrderWorkSchedule == null ||
                    !productionOrder.ProductionOrderWorkSchedule.Any())
                {
                    _context.CreateProductionOrderWorkSchedules(productionOrder);
                }

                var children = articleBoms.Where(a => a.ArticleParentId == productionOrder.ArticleId)
                               .ToList();

                if (!children.Any())
                {
                    return;
                }
                foreach (var child in children)
                {
                    //create Requester
                    var dpob = _context.CreateDemandProductionOrderBom(child.ArticleChildId, productionOrder.Quantity * (int)child.Quantity);
                    //create Production-BOM
                    _context.TryCreateProductionOrderBoms(dpob, productionOrder, simulationId);
                    //call this method recursively for a depth-first search
                    ExecutePlanning(dpob, task, simulationId);
                }
            }
        }
Example #4
0
        /// <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();
            });
        }
Example #5
0
        /// <summary>
        /// Plans capacities for all demands which are either already planned or just finished with MRP.
        /// </summary>
        /// <param name="task"></param>
        /// <param name="newOrdersAdded"></param>
        public void PlanCapacities(MrpTask task, bool newOrdersAdded, int simulationId, ProductionDomainContext evaluationContext)
        {
            var timer   = _context.SimulationConfigurations.Single(a => a.Id == simulationId).Time;
            var demands = _context.Demands.Where(a =>
                                                 a.State == State.BackwardScheduleExists ||
                                                 a.State == State.ForwardScheduleExists ||
                                                 a.State == State.ExistsInCapacityPlan ||
                                                 (timer > 0 && a.State == State.Injected)).ToList();

            List <MachineGroupProductionOrderWorkSchedule> machineList = null;

            /*if (newOrdersAdded)
             * {
             *  _rebuildNets.Rebuild(simulationId, evaluationContext);
             *  _messageHub.SendToAllClients("RebuildNets completed");
             * }*/

            if (timer == 0 && (task == MrpTask.All || task == MrpTask.Capacity))
            {
                //creates a list with the needed capacities to follow the terminated schedules
                machineList = _capacityScheduling.CapacityRequirementsPlanning(simulationId);
            }

            if (timer != 0 || (task == MrpTask.GifflerThompson || (_capacityScheduling.CapacityLevelingCheck(machineList) && task == MrpTask.All)))
            {
                _capacityScheduling.GifflerThompsonScheduling(simulationId);
            }
            else
            {
                foreach (var demand in demands)
                {
                    SetStartEndFromTermination(demand);
                }

                _capacityScheduling.SetMachines(simulationId);
            }
            foreach (var demand in demands)
            {
                demand.State = State.ExistsInCapacityPlan;
            }
            _context.Demands.UpdateRange(demands);
            _context.SaveChanges();
        }
Example #6
0
        /// <summary>
        /// Creates providers for the demands through stock, productionOrders or purchases
        /// </summary>
        /// <param name="demand"></param>
        /// <param name="task"></param>
        /// <param name="simulationId"></param>
        /// <returns>ProductionOrder to fulfill the demand, ProductionOrder is null if there was enough in stock</returns>
        public List <ProductionOrder> NetRequirement(IDemandToProvider demand, MrpTask task, int simulationId)
        {
            //Todo: search for available POs
            var stock = _context.Stocks.Include(a => a.DemandStocks)
                        .Single(a => a.ArticleForeignKey == demand.ArticleId);
            var plannedStock     = _context.GetPlannedStock(stock, demand);
            var productionOrders = new List <ProductionOrder>();
            var stockProvider    = _context.TryCreateStockReservation(demand);
            var time             = _context.SimulationConfigurations.Single(a => a.Id == simulationId).Time;
            //if the article has no children it has to be purchased
            var children = _context.ArticleBoms.Where(a => a.ArticleParentId == demand.ArticleId).ToList();

            if (children.Any())
            {
                //if the plannedStock is below zero, articles have to be produced for its negative amount
                if (plannedStock < 0)
                {
                    var fittingProductionOrders = _context.CheckForProductionOrders(demand, -plannedStock, _context.SimulationConfigurations.Single(a => a.Id == simulationId).Time);
                    var amount = -plannedStock;
                    if (fittingProductionOrders != null)
                    {
                        foreach (var fittingProductionOrder in fittingProductionOrders)
                        {
                            var availableAmount = _context.GetAvailableAmountFromProductionOrder(fittingProductionOrder);
                            var provider        = _context.CreateDemandProviderProductionOrder(demand, fittingProductionOrder,
                                                                                               availableAmount < -plannedStock ? availableAmount : -plannedStock);
                            //productionOrders.Add(fittingProductionOrder);
                            _context.AssignProductionOrderToDemandProvider(fittingProductionOrder, provider);
                            amount -= availableAmount < -plannedStock ? availableAmount : -plannedStock;
                            if (amount == 0)
                            {
                                return(productionOrders);
                            }
                        }
                    }
                    if (amount > 0)
                    {
                        var pos = _context.CreateChildProductionOrders(demand, amount, simulationId);
                        productionOrders.AddRange(pos);
                    }
                }
            }
            else if (plannedStock < stock.Min)
            {
                _context.CreatePurchaseDemand(demand, stock.Max - stock.Min, _context.SimulationConfigurations.Single(a => a.Id == simulationId).Time);
            }
            if (stock.Min <= 0 || plannedStock >= stock.Min || demand.GetType() == typeof(DemandStock))
            {
                return(productionOrders);
            }

            if (_context.Demands.OfType <DemandStock>()
                .Any(a => a.ArticleId == demand.ArticleId &&
                     a.State != State.Finished))
            {
                return(productionOrders);
            }

            var demandStock = plannedStock < 0 ? _context.CreateStockDemand(demand, stock, stock.Min) : _context.CreateStockDemand(demand, stock, stock.Min - plannedStock);

            //call processMrp to plan and schedule the stockDemand
            _processMrp.RunRequirementsAndTermination(demandStock, task, simulationId);
            return(productionOrders);
        }
Example #7
0
        private void FillSimulationWorkSchedules(List <PowsSimulationItem> items, int simulationId, int simulationNumber, MrpTask task)
        {
            foreach (var item in items)
            {
                var po   = _context.ProductionOrders.Include(b => b.Article).Single(a => a.Id == item.ProductionOrderId);
                var pows = _context.ProductionOrderWorkSchedules.Single(a => a.Id == item.ProductionOrderWorkScheduleId);

                if (task == MrpTask.None)
                {
                    var schedule = new SimulationWorkschedule()
                    {
                        ParentId          = JsonConvert.SerializeObject(from parent in _context.GetParents(pows) select parent.Id),
                        ProductionOrderId = "[" + po.Id.ToString() + "]",
                        Article           = po.Article.Name,
                        DueTime           = po.Duetime,
                        End                       = pows.EndSimulation,
                        EstimatedEnd              = pows.End,
                        EstimatedStart            = pows.Start,
                        HierarchyNumber           = pows.HierarchyNumber,
                        Machine                   = pows.MachineId == null ? null : _context.Machines.Single(a => a.Id == pows.MachineId).Name,
                        Start                     = pows.StartSimulation,
                        OrderId                   = JsonConvert.SerializeObject(_context.GetOrderIdsFromProductionOrder(po)),
                        SimulationConfigurationId = simulationId,
                        WorkScheduleId            = pows.Id.ToString(),
                        WorkScheduleName          = pows.Name,
                        SimulationType            = SimulationType.Central,
                        SimulationNumber          = simulationNumber,
                    };
                    _context.Add(schedule);
                    //_evaluationContext.Add(schedule.CopyDbPropertiesWithoutId());
                }

                if (task == MrpTask.Backward || task == MrpTask.All)
                {
                    var backward = new SimulationWorkschedule()
                    {
                        ParentId          = JsonConvert.SerializeObject(from parent in _context.GetParents(pows) select parent.ProductionOrderId),
                        ProductionOrderId = "[" + po.Id.ToString() + "]",
                        Article           = po.Article.Name,
                        DueTime           = po.Duetime,
                        End                       = pows.EndBackward,
                        HierarchyNumber           = pows.HierarchyNumber,
                        Start                     = pows.StartBackward,
                        OrderId                   = JsonConvert.SerializeObject(_context.GetOrderIdsFromProductionOrder(po)),
                        SimulationConfigurationId = simulationId,
                        WorkScheduleId            = pows.Id.ToString(),
                        WorkScheduleName          = pows.Name,
                        SimulationType            = SimulationType.BackwardPlanning,
                        SimulationNumber          = simulationNumber,
                        Machine                   = pows.MachineGroupId.ToString()
                    };
                    _context.Add(backward);
                    _evaluationContext.Add(backward.CopyDbPropertiesWithoutId());
                }
                if (task == MrpTask.Forward || task == MrpTask.All)
                {
                    var forward = new SimulationWorkschedule()
                    {
                        ParentId          = JsonConvert.SerializeObject(from parent in _context.GetParents(pows) select parent.ProductionOrderId),
                        ProductionOrderId = "[" + po.Id.ToString() + "]",
                        Article           = po.Article.Name,
                        DueTime           = po.Duetime,
                        End                       = pows.EndForward,
                        HierarchyNumber           = pows.HierarchyNumber,
                        Start                     = pows.StartForward,
                        OrderId                   = JsonConvert.SerializeObject(_context.GetOrderIdsFromProductionOrder(po)),
                        SimulationConfigurationId = simulationId,
                        WorkScheduleId            = pows.Id.ToString(),
                        WorkScheduleName          = pows.Name,
                        SimulationType            = SimulationType.ForwardPlanning,
                        SimulationNumber          = simulationNumber,
                        Machine                   = pows.MachineGroupId.ToString()
                    };
                    _context.Add(forward);
                    _evaluationContext.Add(forward.CopyDbPropertiesWithoutId());
                }
            }
            _context.SaveChanges();
            _evaluationContext.SaveChanges();
        }