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);
        }
Пример #2
0
        private void _removeCapitalTrackingAndUpdateCapitalPriceInventory(ProductStorageEntity productStorage, ProductForBillCreationDto product, Guid billId)
        {
            // update capital price with average
            if (productStorage.CapitalPriceTrackings == null)
            {
                throw new Exception("CapitalPriceTrackings is NULL with ProductStorage.Id=" + productStorage.Id);
            }
            var capitalPriceTrackings = JsonConvert.DeserializeObject <List <CapitalPriceTrackingDto> >(productStorage.CapitalPriceTrackings);

            var startedIndex = capitalPriceTrackings.FindIndex(c => c.BillId == billId);

            capitalPriceTrackings.RemoveAt(startedIndex);

            for (int i = startedIndex; i < capitalPriceTrackings.Count; i++)
            {
                capitalPriceTrackings[i].Inventory = capitalPriceTrackings[i - 1].Inventory + capitalPriceTrackings[i].Amount;

                capitalPriceTrackings[i].CapitalPrice =
                    ProductStorageHelper.CalculateCapitalPrice(
                        capitalPriceTrackings[i - 1].Inventory,
                        capitalPriceTrackings[i - 1].CapitalPrice,
                        capitalPriceTrackings[i].Amount,
                        capitalPriceTrackings[i].InputPrice
                        );
            }

            productStorage.CapitalPriceTrackings = JsonConvert.SerializeObject(capitalPriceTrackings);
            productStorage.CapitalPrice          = capitalPriceTrackings[capitalPriceTrackings.Count - 1].CapitalPrice;
            productStorage.Inventory             = capitalPriceTrackings[capitalPriceTrackings.Count - 1].Inventory;

            _context.ProductStorages.Update(productStorage);
        }
Пример #3
0
        private void _updateCapitalTrackingCapitalPriceAndInventory(ProductStorageEntity productStorage, ProductForBillCreationDto product, double newAmount, Guid billId)
        {
            // update capital price with average
            if (productStorage.CapitalPriceTrackings == null)
            {
                throw new Exception("CapitalPriceTrackings is NULL with ProductStorage.Id=" + productStorage.Id);
            }
            var capitalPriceTrackings = JsonConvert.DeserializeObject <List <CapitalPriceTrackingDto> >(productStorage.CapitalPriceTrackings);

            var startedIndex = capitalPriceTrackings.FindIndex(c => c.BillId == billId);

            if (startedIndex < 0) // product is new on bill, we need to create a new tracking
            {
                var newCapitalPriceTrackingDto = new CapitalPriceTrackingDto()
                {
                    BillId       = billId,
                    Amount       = newAmount,
                    CapitalPrice = productStorage.CapitalPrice,
                    Inventory    = productStorage.Inventory - newAmount
                };
                capitalPriceTrackings.Add(newCapitalPriceTrackingDto);
            }
            else
            {
                capitalPriceTrackings[startedIndex].Amount = newAmount;

                for (int i = startedIndex; i < capitalPriceTrackings.Count; i++)
                {
                    if (capitalPriceTrackings[i].BillId != Guid.Empty) // this is a bill. we need to decrease the invetory
                    {
                        capitalPriceTrackings[i].Inventory = capitalPriceTrackings[i - 1].Inventory - capitalPriceTrackings[i].Amount;
                    }
                    else
                    {
                        capitalPriceTrackings[i].Inventory = capitalPriceTrackings[i - 1].Inventory + capitalPriceTrackings[i].Amount;
                    }

                    if (capitalPriceTrackings[i].BillId == Guid.Empty) // this is not a bill. we only update capital price for warehousing and inventory
                    {
                        capitalPriceTrackings[i].CapitalPrice =
                            ProductStorageHelper.CalculateCapitalPrice(
                                capitalPriceTrackings[i - 1].Inventory,
                                capitalPriceTrackings[i - 1].CapitalPrice,
                                capitalPriceTrackings[i].Amount,
                                capitalPriceTrackings[i].InputPrice
                                );
                    }
                    else
                    {
                        capitalPriceTrackings[i].CapitalPrice = capitalPriceTrackings[i - 1].CapitalPrice;
                    }
                }
            }

            productStorage.CapitalPriceTrackings = JsonConvert.SerializeObject(capitalPriceTrackings);
            productStorage.CapitalPrice          = capitalPriceTrackings[capitalPriceTrackings.Count - 1].CapitalPrice;
            productStorage.Inventory             = capitalPriceTrackings[capitalPriceTrackings.Count - 1].Inventory;
            _context.ProductStorages.Update(productStorage);
        }
        public async Task <bool> FixAllCapitalPriceTracking()
        {
            bool finished = false;

            var bills = await _context.Bills.Where(b => b.IsActive == true).ToListAsync();

            foreach (var bill in bills)
            {
                var productList = JsonConvert.DeserializeObject <List <ProductForBillCreationDto> >(bill.ProductList);
                foreach (var product in productList)
                {
                    var productStorage = await _context.ProductStorages.SingleOrDefaultAsync(ps => ps.ProductId == product.Id && ps.StorageId == bill.StorageId);

                    var capitalPriceTrackings = (productStorage.CapitalPriceTrackings == null) ?
                                                new List <CapitalPriceTrackingDto>() : JsonConvert.DeserializeObject <List <CapitalPriceTrackingDto> >(productStorage.CapitalPriceTrackings);

                    CapitalPriceTrackingDto defaultRecord = new CapitalPriceTrackingDto();

                    if (capitalPriceTrackings.Count == 0)
                    {
                        capitalPriceTrackings.Add(defaultRecord);
                    }
                    else if (capitalPriceTrackings[0].WarehousingId != Guid.Empty && capitalPriceTrackings[0].BillId != Guid.Empty)
                    {
                        capitalPriceTrackings.Add(defaultRecord);
                    }

                    var existed = capitalPriceTrackings.Find(c => c.BillId == bill.Id);
                    if (existed == null)
                    {
                        capitalPriceTrackings.Add(new CapitalPriceTrackingDto {
                            BillId       = bill.Id,
                            InputPrice   = 0,
                            Amount       = product.Amount,
                            CapitalPrice = capitalPriceTrackings[capitalPriceTrackings.Count - 1].CapitalPrice,
                            Inventory    = capitalPriceTrackings[capitalPriceTrackings.Count - 1].Inventory + product.Amount
                        });
                    }
                    productStorage.CapitalPriceTrackings = JsonConvert.SerializeObject(capitalPriceTrackings);
                    _context.ProductStorages.Update(productStorage);
                }
            }
            ;
            await _context.SaveChangesAsync();

            var warehousings = await _context.Warehousings.Where(b => b.IsActive == true).ToListAsync();

            foreach (var warehousing in warehousings)
            {
                var productList = JsonConvert.DeserializeObject <List <ProductForWareshousingCreationDto> >(warehousing.ProductList);
                foreach (var product in productList)
                {
                    var productStorage = await _context.ProductStorages.SingleOrDefaultAsync(ps => ps.ProductId == product.Id && ps.StorageId == warehousing.StorageId);

                    var capitalPriceTrackings = (productStorage.CapitalPriceTrackings == null) ?
                                                new List <CapitalPriceTrackingDto>() : JsonConvert.DeserializeObject <List <CapitalPriceTrackingDto> >(productStorage.CapitalPriceTrackings);

                    CapitalPriceTrackingDto defaultRecord = new CapitalPriceTrackingDto();

                    if (capitalPriceTrackings.Count == 0)
                    {
                        capitalPriceTrackings.Add(defaultRecord);
                    }
                    else if (capitalPriceTrackings[0].WarehousingId != Guid.Empty && capitalPriceTrackings[0].BillId != Guid.Empty)
                    {
                        capitalPriceTrackings.Add(defaultRecord);
                    }

                    var existed = capitalPriceTrackings.Find(c => c.WarehousingId == warehousing.Id);
                    if (existed == null)
                    {
                        var lastestRecord = capitalPriceTrackings[capitalPriceTrackings.Count - 1];
                        capitalPriceTrackings.Add(new CapitalPriceTrackingDto
                        {
                            BillId       = warehousing.Id,
                            InputPrice   = product.InputPrice,
                            Amount       = product.InputAmount,
                            CapitalPrice = ProductStorageHelper.CalculateCapitalPrice(lastestRecord.Inventory, lastestRecord.CapitalPrice, product.InputAmount, product.InputPrice),
                            Inventory    = lastestRecord.Inventory + product.InputAmount
                        });
                    }
                    productStorage.CapitalPriceTrackings = JsonConvert.SerializeObject(capitalPriceTrackings);
                    _context.ProductStorages.Update(productStorage);
                }
            }
            ;
            await _context.SaveChangesAsync();

            var productStorages = await _context.ProductStorages.ToListAsync();

            foreach (var productStorage in productStorages)
            {
                var capitalPriceTrackings = (productStorage.CapitalPriceTrackings == null) ?
                                            new List <CapitalPriceTrackingDto>() : JsonConvert.DeserializeObject <List <CapitalPriceTrackingDto> >(productStorage.CapitalPriceTrackings);

                CapitalPriceTrackingDto defaultRecord = new CapitalPriceTrackingDto();

                if (capitalPriceTrackings.Count == 0 || !_isDefaultRecord(capitalPriceTrackings[0]))
                {
                    capitalPriceTrackings.Insert(0, defaultRecord);
                }



                List <int> removeIndexs = new List <int>();

                for (int i = 1; i < capitalPriceTrackings.Count; i++)
                {
                    if (_isDefaultRecord(capitalPriceTrackings[i]))
                    {
                        removeIndexs.Add(i);
                    }
                    else if (capitalPriceTrackings[i].BillId != Guid.Empty)
                    {
                        capitalPriceTrackings[i].InputPrice   = 0;
                        capitalPriceTrackings[i].CapitalPrice = capitalPriceTrackings[i - 1].CapitalPrice;
                        capitalPriceTrackings[i].Inventory    = capitalPriceTrackings[i - 1].Inventory - capitalPriceTrackings[i].Amount;
                    }
                    else if (capitalPriceTrackings[i].WarehousingId != Guid.Empty)
                    {
                        capitalPriceTrackings[i].CapitalPrice = ProductStorageHelper
                                                                .CalculateCapitalPrice(
                            capitalPriceTrackings[i - 1].Inventory,
                            capitalPriceTrackings[i - 1].CapitalPrice,
                            capitalPriceTrackings[i].Amount,
                            capitalPriceTrackings[i].InputPrice);

                        capitalPriceTrackings[i].Inventory = capitalPriceTrackings[i - 1].Inventory
                                                             + capitalPriceTrackings[i].Amount;
                    }
                }
                foreach (int index in removeIndexs)
                {
                    capitalPriceTrackings.RemoveAt(index);
                }
                productStorage.Inventory             = capitalPriceTrackings[capitalPriceTrackings.Count - 1].Inventory;
                productStorage.CapitalPrice          = capitalPriceTrackings[capitalPriceTrackings.Count - 1].CapitalPrice;
                productStorage.CapitalPriceTrackings = JsonConvert.SerializeObject(capitalPriceTrackings);
                _context.ProductStorages.Update(productStorage);
            }
            await _context.SaveChangesAsync();

            finished = true;

            return(finished);
        }
        new public async Task <Guid> EditAsync(Guid id, WarehousingForCreationDto updationDto)
        {
            var warehousing = await _entity.SingleOrDefaultAsync(w => w.Id == id);

            if (warehousing == null)
            {
                throw new Exception("Can not find warehousing with id = " + id);
            }
            if (!warehousing.IsActive)
            {
                throw new Exception("The destroyed warehousing can not be edited");
            }

            var oldProducts    = JsonConvert.DeserializeObject <List <ProductForWareshousingCreationDto> >(warehousing.ProductList);
            var editedProducts = updationDto.ProductList;

            double productMoney = 0;

            // when a old product is removed in new product list, we remove inventory
            foreach (var oldProduct in oldProducts)
            {
                var editedProduct = editedProducts.SingleOrDefault(p => p.Id == oldProduct.Id);
                if (editedProduct == null)
                {
                    await _removeCapitalTracking(oldProduct, updationDto.StorageId, id);
                }
            }

            foreach (var editedProduct in editedProducts)
            {
                // calculate product money
                productMoney += editedProduct.InputAmount * editedProduct.InputPrice;

                /* when not finding edited product on old product list, let add a new cappital tracking into
                 * ProductStorage of edited product */

                var oldProduct = oldProducts.SingleOrDefault(p => p.Id == editedProduct.Id);
                if (oldProduct == null)
                {
                    var productStorage = await _context.ProductStorages.SingleOrDefaultAsync(p => p.ProductId == editedProduct.Id &&
                                                                                             p.StorageId == warehousing.StorageId);

                    _addCapitalTracking(editedProduct, updationDto.StorageId, id, productStorage);
                }
                else
                {
                    var productStorage = await _context.ProductStorages.SingleOrDefaultAsync(p => p.ProductId == editedProduct.Id &&
                                                                                             p.StorageId == warehousing.StorageId);

                    // if we find a old product is same with edited product, we need to to update ProductProductionDate
                    if (editedProduct.DetailInputAmountList != null && editedProduct.DetailInputAmountList.Count > 0)
                    {
                        _updateInventoryDetail(editedProduct, oldProduct, productStorage);
                    }

                    // if we find old product is same with edited product, we need to update capital tracking of product storage


                    var capitalPriceTrackings = JsonConvert.DeserializeObject <List <CapitalPriceTrackingDto> >(productStorage.CapitalPriceTrackings);
                    int index = capitalPriceTrackings.FindIndex(c => c.WarehousingId == id);
                    if (index == -1) // hot fix, this shit. duplicate warehousing when create cause error on destroy, it remove all warehousing
                    {
                        var lastestRecord = capitalPriceTrackings[capitalPriceTrackings.Count - 1];

                        CapitalPriceTrackingDto capitalPriceTrackingDto = new CapitalPriceTrackingDto()
                        {
                            WarehousingId = id,
                            BillId        = Guid.Empty,
                            InventoryId   = Guid.Empty,
                            Amount        = editedProduct.InputAmount,
                            Inventory     = lastestRecord.Inventory + editedProduct.InputAmount,
                            CapitalPrice  = ProductStorageHelper.CalculateCapitalPrice(
                                lastestRecord.Inventory,
                                lastestRecord.CapitalPrice,
                                editedProduct.InputAmount,
                                editedProduct.InputPrice
                                )
                        };
                        capitalPriceTrackings.Add(capitalPriceTrackingDto);

                        index = capitalPriceTrackings.Count - 1;
                    }


                    double deltaInventory = editedProduct.InputAmount - oldProduct.InputAmount;

                    var result = ChangeCapitalPriceTrackingsResultHelper.ChangeCapitalPriceTrackings(index,
                                                                                                     deltaInventory, editedProduct.InputPrice, capitalPriceTrackings, false);

                    if (!setting.IsAllowNegativeInventoryBill && result.Inventory < 0)
                    {
                        throw new Exception("change_warehousing_make_negative_inventory");
                    }
                    // remove tracking record
                    capitalPriceTrackings.RemoveAt(index);
                    // save new information
                    productStorage.Inventory             = result.Inventory;
                    productStorage.CapitalPrice          = result.CapitalPrice;
                    productStorage.CapitalPriceTrackings = result.CapitalPriceTrackingsJson;

                    _context.Update(productStorage);
                }
            }

            foreach (PropertyInfo propertyInfo in updationDto.GetType().GetProperties())
            {
                if (warehousing.GetType().GetProperty(propertyInfo.Name) != null &&
                    propertyInfo.Name != "ProductList" &&
                    propertyInfo.Name != "SupplierBillList" &&
                    propertyInfo.Name != "InputDate"
                    )
                {
                    warehousing.GetType().GetProperty(propertyInfo.Name).SetValue(warehousing, propertyInfo.GetValue(updationDto, null));
                }
            }

            warehousing.SupplierBillList = JsonConvert.SerializeObject(updationDto.SupplierBillList);
            warehousing.UpdatedDateTime  = DateTime.Now;

            var user = await _userManager.GetUserAsync(_httpContextAccessor.HttpContext.User);

            warehousing.UpdatedUserId = user.Id;
            warehousing.ProductList   = JsonConvert.SerializeObject(updationDto.ProductList);


            warehousing.ProductMoney = productMoney;
            warehousing.SummaryMoney = warehousing.ProductMoney + warehousing.TaxMoney;
            warehousing.DebtMoney    = warehousing.SummaryMoney - updationDto.PaymentMoney;

            _entity.Update(warehousing);

            var created = await _context.SaveChangesAsync();

            if (created < 1)
            {
                throw new InvalidOperationException("Database context could not create Warehousing.");
            }

            return(warehousing.Id);
        }
Пример #6
0
        public async Task <Guid> DestroyAsync(Guid id)
        {
            var bill = await _entity.SingleOrDefaultAsync(r => r.Id == id);

            if (bill == null)
            {
                throw new Exception("Can not find object with this Id.");
            }
            if (!bill.IsActive)
            {
                throw new Exception("The bill has destroyed status. We can only destroy active bill.");
            }
            bill.IsActive = false;

            // descrease accumulation points
            var customer = await _context.Customers.SingleOrDefaultAsync(c => c.Id == bill.CustomerId);

            if (customer == null)
            {
                throw new Exception("Can not find customer with id=" + bill.CustomerId);
            }
            customer.AccumulationPoint = customer.AccumulationPoint - bill.PointEarning + bill.UsedPoints;
            _context.Customers.Update(customer);

            ProductForBillCreationDto[] products = JsonConvert.DeserializeObject <ProductForBillCreationDto[]>(bill.ProductList);

            foreach (var product in products)
            {
                if (product.IsService)
                {
                    continue;
                }
                var productStorages = await _context.ProductStorages.Where(ps => ps.StorageId == bill.StorageId && ps.ProductId == product.Id).ToListAsync();

                foreach (var productStorage in productStorages)
                {
                    // remove tracking record of capital
                    var capitalPriceTrackings = JsonConvert.DeserializeObject <List <CapitalPriceTrackingDto> >(productStorage.CapitalPriceTrackings);

                    int removedIndex = -1;

                    for (var i = 0; i < capitalPriceTrackings.Count; i++)
                    {
                        if (capitalPriceTrackings[i].BillId != Guid.Empty && capitalPriceTrackings[i].BillId == id)
                        {
                            removedIndex = i;
                            break;
                        }
                    }
                    if (removedIndex > -1)
                    {
                        var removedTracking = capitalPriceTrackings[removedIndex];

                        capitalPriceTrackings.RemoveAt(removedIndex);

                        for (var i = removedIndex; i < capitalPriceTrackings.Count; i++)
                        {
                            capitalPriceTrackings[i].Inventory = capitalPriceTrackings[i].Inventory + removedTracking.Amount;

                            if (capitalPriceTrackings[i].WarehousingId != Guid.Empty)
                            {
                                // calculate capital price after remove position for warehousing

                                capitalPriceTrackings[i].CapitalPrice =
                                    ProductStorageHelper.CalculateCapitalPrice(
                                        capitalPriceTrackings[i - 1].Inventory,
                                        capitalPriceTrackings[i - 1].CapitalPrice,
                                        capitalPriceTrackings[i].Amount,
                                        capitalPriceTrackings[i].InputPrice
                                        );
                            }
                        }
                    }

                    // calculate capital price again
                    productStorage.Inventory             = capitalPriceTrackings[capitalPriceTrackings.Count - 1].Inventory;
                    productStorage.CapitalPrice          = capitalPriceTrackings[capitalPriceTrackings.Count - 1].CapitalPrice;
                    productStorage.CapitalPriceTrackings = JsonConvert.SerializeObject(capitalPriceTrackings);
                    // update detail output amount
                    _addOrUpdateProductProductionDate(productStorage, product, false);
                    _context.ProductStorages.Update(productStorage);
                }
            }

            await _context.SaveChangesAsync();

            return(bill.Id);
        }