public async Task <IActionResult> CreateProductionOrder(ProdOrderHeaderForDetailDto prodOrderHeaderForDetailDto)
        {
            if (prodOrderHeaderForDetailDto == null)
            {
                return(BadRequest("Empty Body"));
            }

            var prodOrderHeaderToCreate = _mapper.Map <ProductionOrderHeader>(prodOrderHeaderForDetailDto);

            prodOrderHeaderToCreate.BusinessPlace = await _repository.Get <BusinessPlace>(prodOrderHeaderForDetailDto.BusinessPlaceId);

            prodOrderHeaderToCreate.Session = await _repository.Get <ProductionSession>(prodOrderHeaderForDetailDto.SessionId);

            prodOrderHeaderToCreate.User = await _repository.Get <User>(prodOrderHeaderForDetailDto.UserId);

            await _repository.CreateProductionOrder(prodOrderHeaderToCreate);

            if (await _repository.SaveAll())
            {
                var prodOrderHeaderToReturn = _mapper.Map <ProdOrderHeaderForDetailDto>(prodOrderHeaderToCreate);
                return(CreatedAtRoute(nameof(GetProductionOrder), new { prodOrderHeaderToCreate.Id }, prodOrderHeaderToReturn));
            }

            return(BadRequest("Could not create production Order"));
        }
        public async Task <IActionResult> UpdateProductionOrder(int id, ProdOrderHeaderForDetailDto prodOrderHeaderForDetailDto)
        {
            if (prodOrderHeaderForDetailDto == null)
            {
                return(BadRequest("Empty Body"));
            }

            var prodOrderHeaderFromRepository = await _repository.GetProductionOrder(id);

            if (prodOrderHeaderFromRepository == null)
            {
                return(BadRequest("Production Order not available"));
            }

            prodOrderHeaderFromRepository.UserId = prodOrderHeaderForDetailDto.UserId;

            prodOrderHeaderFromRepository.BusinessPlace = await _repository.Get <BusinessPlace>(prodOrderHeaderForDetailDto.BusinessPlaceId);

            prodOrderHeaderFromRepository.Session = await _repository.Get <ProductionSession>(prodOrderHeaderForDetailDto.SessionId);

            prodOrderHeaderFromRepository.User = await _repository.Get <User>(prodOrderHeaderForDetailDto.UserId);

            prodOrderHeaderFromRepository.RequiredDate  = DateTime.Parse(prodOrderHeaderForDetailDto.RequiredDate);
            prodOrderHeaderFromRepository.EnteredDate   = DateTime.Parse(prodOrderHeaderForDetailDto.EnteredDate);
            prodOrderHeaderFromRepository.IsNotEditable = false;

            foreach (var pod in prodOrderHeaderFromRepository.ProductionOrderDetails)
            {
                _repository.Delete(pod);
            }

            prodOrderHeaderFromRepository.ProductionOrderDetails.Clear();

            foreach (var pod in prodOrderHeaderForDetailDto.ProductionOrderDetails)
            {
                prodOrderHeaderFromRepository.ProductionOrderDetails.Add(new ProductionOrderDetail
                {
                    ItemId      = pod.ItemId,
                    Quantity    = (decimal)pod.Quantity,
                    Description = pod.Description
                });
            }

            if (await _repository.SaveAll())
            {
                return(NoContent());
            }


            throw new System.Exception($"Updating production Order {id} failed on save");
        }
        public async Task <IActionResult> AcceptItems([FromQuery] int planId, [FromBody] ProdOrderHeaderForDetailDto prodOrderHeaderForDetailDto)
        {
            if (prodOrderHeaderForDetailDto == null)
            {
                return(BadRequest(new ErrorModel(1, 400, "Empty Body")));
            }

            if (planId == 0)
            {
                return(BadRequest(new ErrorModel(2, 400, "Invalid Plan")));
            }
            var plan = await _repository.GetProductionPlan(planId);

            if (plan == null)
            {
                return(BadRequest(new ErrorModel(2, 400, "Invalid Plan")));
            }

            if (prodOrderHeaderForDetailDto.Id == 0)
            {
                return(BadRequest(new ErrorModel(3, 400, "Valid Prod order Id required")));
            }
            var prodOrder = await _repository.GetProductionOrder(prodOrderHeaderForDetailDto.Id);

            if (prodOrder == null)
            {
                return(BadRequest(new ErrorModel(3, 400, "Valid Prod order Id required")));
            }

            if (prodOrderHeaderForDetailDto.ProductionOrderDetails == null)
            {
                return(BadRequest(new ErrorModel(4, 400, "Items required")));
            }


            var prodItems = await _context.ProductionItems
                            .Where(a => a.CurrentPlace == prodOrder.BusinessPlace && a.BatchNo == planId).ToListAsync();

            var itemCost = await GetCostOfPlan(plan, 10);//changes

            foreach (var item in prodOrderHeaderForDetailDto.ProductionOrderDetails)
            {
                var itemFromPITEMSList = prodItems.FirstOrDefault(a => a.ItemId == item.ItemId);

                if (itemFromPITEMSList == null)
                {
                    ProductionItem pItem = new ProductionItem();
                    pItem.Id                = 0;
                    pItem.Item              = null;
                    pItem.ItemId            = item.ItemId;
                    pItem.BatchNo           = planId;
                    pItem.StockedQuantity   = item.Quantity;
                    pItem.AvailableQuantity = item.Quantity;
                    pItem.UsedQuantity      = 0;
                    pItem.CostPrice         = itemCost.FirstOrDefault(a => a.ItemID == item.ItemId).CostPerUnit;//changes
                    pItem.CurrentPlace      = prodOrder.BusinessPlace;
                    pItem.ManufacturedDate  = DateTime.Now;

                    var expiryDays = prodOrder.ProductionOrderDetails.FirstOrDefault(a => a.ItemId == item.ItemId).Item.ExpireDays;
                    expiryDays       = expiryDays == null ? 0 : expiryDays;
                    pItem.ExpireDate = DateTime.Now.AddDays(expiryDays.Value);

                    prodItems.Add(pItem);
                }
                else
                {
                    var existingQty = itemFromPITEMSList.StockedQuantity;

                    prodItems.FirstOrDefault(a => a.ItemId == item.ItemId).StockedQuantity    = existingQty + item.Quantity;
                    prodItems.FirstOrDefault(a => a.ItemId == item.ItemId).AvailableQuantity += item.Quantity;
                }
            }

            _context.UpdateRange(prodItems);

            prodOrder.isProcessed = 1;
            _context.Update(prodOrder);

            Notification noti = new Notification
            {
                Title    = "Items Sent for prod order " + prodOrder.ProductionOrderNo,
                Message  = "Items for production order No - " + prodOrder.ProductionOrderNo + "  has been sent from " + plan.BusinessPlace.Name,
                DateTime = DateTime.Now,
                UserId   = prodOrder.UserId,
                Status   = 0
            };

            _context.Add(noti);

            if (await _context.SaveChangesAsync() > 0)
            {
                var prods = await _context.ProductionOrderHeaders.Where(a => a.PlanId == planId && (a.isProcessed == 0 || a.isProcessed == null)).ToListAsync();

                if (prods == null || prods.Count == 0)
                {
                    //changes
                    var availableRawMaterials = await _context.RawItems.Where(a => a.CurrentPlace == plan.BusinessPlace && a.AvailableQuantity > 0).ToListAsync();

                    //need more
                    foreach (var recipeitem in plan.ProductionPlanRecipes)
                    {
                        var quantityToUpdate = recipeitem.Quantity;
                        foreach (var item in availableRawMaterials.Where(a => a.ItemId == recipeitem.ItemId))
                        {
                            if (quantityToUpdate == 0)
                            {
                                break;
                            }

                            if (item.AvailableQuantity > quantityToUpdate)
                            {
                                item.UsedQuantity      = item.UsedQuantity + quantityToUpdate;
                                item.AvailableQuantity = item.AvailableQuantity - quantityToUpdate;
                                quantityToUpdate       = 0;
                            }
                            else
                            {
                                item.UsedQuantity      = item.UsedQuantity + item.AvailableQuantity;
                                item.AvailableQuantity = item.AvailableQuantity - item.AvailableQuantity;
                                quantityToUpdate       = quantityToUpdate - item.AvailableQuantity;
                            }
                        }
                    }

                    var planToUpdate = await _context.ProductionPlanHeaders.FirstOrDefaultAsync(a => a.Id == planId);

                    planToUpdate.IsNotEditable = true;
                    await _context.SaveChangesAsync();
                }
                return(Ok());
            }

            return(BadRequest(new ErrorModel(5, 400, "Couldn't Accept, Some error occured")));
        }