private void _addCapitalTracking(ProductForWareshousingCreationDto product, Guid storageId, Guid warehousingId, ProductStorageEntity productStorage)
        {
            // create capital price tracking
            productStorage.CapitalPrice = ProductStorageHelper.CalculateCapitalPrice(
                productStorage.Inventory, productStorage.CapitalPrice, product.InputAmount, product.InputPrice
                );

            productStorage.Inventory += product.InputAmount;

            CapitalPriceTrackingDto capitalPriceTracking = new CapitalPriceTrackingDto
            {
                WarehousingId = warehousingId,
                Amount        = product.InputAmount,
                InputPrice    = product.InputPrice,
                CapitalPrice  = productStorage.CapitalPrice,
                Inventory     = productStorage.Inventory
            };

            productStorage.CapitalPriceTrackings = productStorage.CapitalPriceTrackings ?? "[]";

            var capitalPriceTrackings = JsonConvert.DeserializeObject <List <CapitalPriceTrackingDto> >(productStorage.CapitalPriceTrackings);

            capitalPriceTrackings.Add(capitalPriceTracking);
            productStorage.CapitalPriceTrackings = JsonConvert.SerializeObject(capitalPriceTrackings);
            _context.ProductStorages.Update(productStorage);
        }
        private async Task _removeCapitalTracking(ProductForWareshousingCreationDto product, Guid storageId, Guid warehousingId)
        {
            var productStorages = await _context.ProductStorages.Where(ps => ps.StorageId == storageId && ps.ProductId == product.Id).ToListAsync();

            foreach (var productStorage in productStorages)
            {
                if (productStorage.Inventory >= product.InputAmount || setting.IsAllowNegativeInventoryBill)
                {
                    var    capitalPriceTrackings = JsonConvert.DeserializeObject <List <CapitalPriceTrackingDto> >(productStorage.CapitalPriceTrackings);
                    int    index          = capitalPriceTrackings.FindIndex(c => c.WarehousingId == warehousingId);
                    double deltaInventory = -1 * product.InputAmount;

                    var result = ChangeCapitalPriceTrackingsResultHelper.ChangeCapitalPriceTrackings(index,
                                                                                                     deltaInventory, product.InputPrice, capitalPriceTrackings, true);

                    productStorage.Inventory             = result.Inventory;
                    productStorage.CapitalPrice          = result.CapitalPrice;
                    productStorage.CapitalPriceTrackings = result.CapitalPriceTrackingsJson;

                    // remove detail inventory
                    var oldProductProductionList = (productStorage.ProductProductionDateList == null) ? new List <ProductProductionDateDto>() : JsonConvert.DeserializeObject <List <ProductProductionDateDto> >(productStorage.ProductProductionDateList);
                    var detailInputAmountList    = product.DetailInputAmountList;
                    foreach (var detailInputAmount in detailInputAmountList)
                    {
                        if (detailInputAmount.InputAmount > product.InputAmount)
                        {
                            throw new Exception("Detail InputAmount is greater than product InputAmount");
                        }

                        var oldProductProduction = oldProductProductionList.SingleOrDefault(p => p.ProductionWeekYear == detailInputAmount.ProductionWeekYear);
                        if (oldProductProduction != null)
                        {
                            oldProductProduction.Inventory -= detailInputAmount.InputAmount;
                        }
                        else
                        {
                            oldProductProductionList.Add(new ProductProductionDateDto()
                            {
                                ProductionWeekYear = detailInputAmount.ProductionWeekYear,
                                ProductionDate     = DateTimeHelper.ConvertWeekYearToDateTime(detailInputAmount.ProductionWeekYear),
                                Inventory          = detailInputAmount.InputAmount
                            });
                        }
                    }
                    productStorage.ProductProductionDateList = JsonConvert.SerializeObject(oldProductProductionList);
                }
                else
                {
                    throw new Exception("change_warehousing_make_negative_inventory");
                }
                _context.ProductStorages.Update(productStorage);
            }
        }
        private void _updateInventoryDetail(ProductForWareshousingCreationDto editedProduct, ProductForWareshousingCreationDto oldProduct, ProductStorageEntity productStorage)
        {
            // update detail inventory for each product
            var oldProductProductionList = (productStorage.ProductProductionDateList == null) ? new List <ProductProductionDateDto>() : JsonConvert.DeserializeObject <List <ProductProductionDateDto> >(productStorage.ProductProductionDateList);
            var detailInputAmountList    = editedProduct.DetailInputAmountList;

            if (detailInputAmountList != null && detailInputAmountList.Count > 0)
            {
                foreach (var detailInputAmount in detailInputAmountList)
                {
                    if (detailInputAmount.InputAmount > editedProduct.InputAmount)
                    {
                        throw new Exception("Detail InputAmount is greater than product InputAmount");
                    }

                    var oldProductProduction = oldProductProductionList.SingleOrDefault(p => p.ProductionWeekYear == detailInputAmount.ProductionWeekYear);
                    if (oldProductProduction != null)
                    {
                        if (oldProduct == null)
                        {
                            oldProductProduction.Inventory += (detailInputAmount.InputAmount);
                        }
                        else
                        {
                            var    beforeAddedProductDetailInputAmount = oldProduct.DetailInputAmountList.SingleOrDefault(p => p.ProductionWeekYear == detailInputAmount.ProductionWeekYear);
                            double beforeInputAmount = (beforeAddedProductDetailInputAmount == null) ? 0 : beforeAddedProductDetailInputAmount.InputAmount;
                            oldProductProduction.Inventory += (detailInputAmount.InputAmount - beforeInputAmount);
                        }
                    }
                    else
                    {
                        oldProductProductionList.Add(new ProductProductionDateDto()
                        {
                            ProductionWeekYear = detailInputAmount.ProductionWeekYear,
                            ProductionDate     = DateTimeHelper.ConvertWeekYearToDateTime(detailInputAmount.ProductionWeekYear),
                            Inventory          = detailInputAmount.InputAmount
                        });
                    }
                }
                productStorage.ProductProductionDateList = JsonConvert.SerializeObject(oldProductProductionList);
                //_context.ProductStorages.Update(productStorage);
            }
        }