Exemple #1
0
        public async Task <DbResponse> DeleteBillAsync(int id, IUnitOfWork db)
        {
            var response = new DbResponse();

            try
            {
                var selling = Context.Selling
                              .Include(s => s.SellingList)
                              .Include(s => s.SellingPaymentList)
                              .FirstOrDefault(s => s.SellingId == id);

                if (selling == null)
                {
                    response.IsSuccess = false;
                    response.Message   = "Not found";
                    return(response);
                }

                if (selling.SellingPaymentList.Count > 0)
                {
                    response.IsSuccess = false;
                    response.Message   = "Payment Exist";
                    return(response);
                }


                var stocks = selling.SellingList.SelectMany(s => s.ProductStock).Select(sp =>
                {
                    sp.IsSold = false;
                    return(sp);
                }).ToList();

                Context.ProductStock.UpdateRange(stocks);
                Context.Selling.Remove(selling);
                await Context.SaveChangesAsync();

                db.Customers.UpdatePaidDue(selling.CustomerId);
            }
            catch (Exception e)
            {
                response.IsSuccess = false;
                response.Message   = e.Message;
                return(response);
            }

            response.IsSuccess = true;
            response.Message   = "Success";
            return(response);
        }
        public async Task <DbResponse <ProductCatalogViewModel> > AddCustomAsync(ProductCatalogViewModel model)
        {
            var response = new DbResponse <ProductCatalogViewModel>();

            if (Context.ProductCatalog.Any(c => c.ParentId == model.ParentId && c.CatalogName == model.CatalogName))
            {
                response.Message   = "Name already exists";
                response.IsSuccess = false;
                return(response);
            }

            var level = 0;

            if (model.ParentId != null)
            {
                level = Context.ProductCatalog.Find(model.ParentId).CatalogLevel + 1;
            }

            var catalog = new ProductCatalog
            {
                CatalogTypeId = model.CatalogTypeId,
                CatalogName   = model.CatalogName,
                CatalogLevel  = level,
                ParentId      = model.ParentId
            };



            await Context.ProductCatalog.AddAsync(catalog).ConfigureAwait(false);

            try
            {
                await Context.SaveChangesAsync().ConfigureAwait(false);

                model.ProductCatalogId = catalog.ProductCatalogId;
                response.IsSuccess     = true;
                response.Message       = "Success";
                response.Data          = model;
            }
            catch (DbUpdateException e)
            {
                response.Message   = e.Message;
                response.IsSuccess = false;
            }

            return(response);
        }
Exemple #3
0
        public DbResponse <ProductViewModel> ProductWithCodes(int productId)
        {
            var response = new DbResponse <ProductViewModel>();

            try
            {
                var product = Context.Product.Include(p => p.ProductCatalog).Include(p => p.ProductStock).Select(p => new ProductViewModel
                {
                    ProductId     = p.ProductId,
                    Description   = p.Description,
                    Warranty      = p.Warranty,
                    Note          = p.Note,
                    SellingPrice  = p.SellingPrice,
                    PurchasePrice = p.SellingPrice,
                    ProductStocks = p.ProductStock.Where(s => !s.IsSold).Select(s => new ProductStockViewModel
                    {
                        ProductCode = s.ProductCode
                    }).ToList(),
                    ProductName        = p.ProductName,
                    ProductCatalogId   = p.ProductCatalogId,
                    ProductCatalogName = p.ProductCatalog.CatalogName
                }).FirstOrDefault(p => p.ProductId == productId);

                if (product == null)
                {
                    response.Message   = "No data Found";
                    response.IsSuccess = false;
                    return(response);
                }

                response.IsSuccess = true;
                response.Message   = "Success";
                response.Data      = product;
                return(response);
            }
            catch (Exception e)
            {
                response.Message   = e.Message;
                response.IsSuccess = false;
                return(response);
            }
        }
Exemple #4
0
        public async Task <DbResponse <ProductCatalogTypeViewModel> > AddCustomAsync(ProductCatalogTypeViewModel model)
        {
            var response = new DbResponse <ProductCatalogTypeViewModel>();

            if (await Context.ProductCatalogType.AnyAsync(c => c.CatalogType == model.CatalogType).ConfigureAwait(false))
            {
                response.Message   = "This category type already exist";
                response.IsSuccess = false;
                return(response);
            }


            var catalogType = new ProductCatalogType
            {
                CatalogType = model.CatalogType
            };


            await Context.ProductCatalogType.AddAsync(catalogType).ConfigureAwait(false);

            try
            {
                await Context.SaveChangesAsync().ConfigureAwait(false);

                model.CatalogTypeId = catalogType.CatalogTypeId;
                response.IsSuccess  = true;
                response.Message    = "Success";
                response.Data       = model;
                return(response);
            }
            catch (DbUpdateException e)
            {
                response.Message   = e.Message;
                response.IsSuccess = false;
                return(response);
            }
        }
        public async Task <DbResponse> UpdateMemoNumberAsync(int purchaseId, string newMemoNumber)
        {
            var response = new DbResponse();

            try
            {
                var purchase = await Context.Purchase.FindAsync(purchaseId).ConfigureAwait(false);

                purchase.MemoNumber = newMemoNumber;

                Context.Purchase.Update(purchase);
                await Context.SaveChangesAsync().ConfigureAwait(false);

                response.IsSuccess = true;
                response.Message   = "Success";
            }
            catch (DbUpdateException e)
            {
                response.Message   = e.Message;
                response.IsSuccess = false;
            }

            return(response);
        }
        public async Task <DbResponse> DuePaySingleAsync(PurchaseDuePaySingleModel model, IUnitOfWork db)
        {
            var response = new DbResponse();

            try
            {
                var Sn = await db.PurchasePayments.GetNewSnAsync().ConfigureAwait(false);

                var purchase = await Context.Purchase.FindAsync(model.PurchaseId).ConfigureAwait(false);



                var due = (purchase.PurchaseTotalPrice + purchase.PurchaseReturnAmount) -
                          (purchase.PurchaseDiscountAmount + purchase.PurchasePaidAmount);
                if (model.PaidAmount > due)
                {
                    response.IsSuccess = false;
                    response.Message   = "Paid amount is greater than due";
                    return(response);
                }

                if (model.PaidAmount > 0)
                {
                    var PurchasePayment = new PurchasePayment
                    {
                        RegistrationId = model.RegistrationId,
                        VendorId       = model.VendorId,
                        ReceiptSn      = Sn,
                        PaidAmount     = model.PaidAmount,
                        PaymentMethod  = model.PaymentMethod,
                        PaidDate       = model.PaidDate.BdTime().Date,
                        AccountId      = model.AccountId,

                        PurchasePaymentList = new List <PurchasePaymentList>
                        {
                            new PurchasePaymentList
                            {
                                PurchaseId         = model.PurchaseId,
                                PurchasePaidAmount = model.PaidAmount
                            }
                        }
                    };
                    await Context.PurchasePayment.AddAsync(PurchasePayment).ConfigureAwait(false);
                }

                purchase.PurchasePaidAmount += model.PaidAmount;

                Context.Purchase.Update(purchase);

                //Account substract balance
                if (model.PaidAmount > 0 && model.AccountId != null)
                {
                    db.Account.BalanceSubtract(model.AccountId.Value, model.PaidAmount);
                }

                await db.SaveChangesAsync().ConfigureAwait(false);

                db.Vendors.UpdatePaidDue(model.VendorId);

                response.IsSuccess = true;
                response.Message   = "Success";
                return(response);
            }
            catch (Exception e)
            {
                response.Message   = e.Message;
                response.IsSuccess = false;
                return(response);
            }
        }
        public async Task <DbResponse <int> > DuePayMultipleAsync(PurchaseDuePayMultipleModel model, IUnitOfWork db)
        {
            var response = new DbResponse <int>();

            try
            {
                var purchases = await Context.Purchase.Where(s => model.Bills.Select(i => i.PurchaseId).Contains(s.PurchaseId)).ToListAsync().ConfigureAwait(false);

                foreach (var invoice in model.Bills)
                {
                    var purchase = purchases.FirstOrDefault(s => s.PurchaseId == invoice.PurchaseId);

                    if (purchase != null)
                    {
                        var due = purchase.PurchaseDueAmount;

                        if (invoice.PurchasePaidAmount > due)
                        {
                            response.IsSuccess = false;
                            response.Message   = $"{invoice.PurchasePaidAmount} Paid amount is greater than due";
                            return(response);
                        }
                    }

                    if (purchase != null)
                    {
                        purchase.PurchasePaidAmount += invoice.PurchasePaidAmount;
                    }
                }

                var sn = await db.PurchasePayments.GetNewSnAsync().ConfigureAwait(false);

                var purchasePayment = new PurchasePayment
                {
                    RegistrationId      = model.RegistrationId,
                    VendorId            = model.VendorId,
                    ReceiptSn           = sn,
                    PaidAmount          = model.PaidAmount,
                    PaymentMethod       = model.PaymentMethod,
                    PaidDate            = model.PaidDate.BdTime().Date,
                    AccountId           = model.AccountId,
                    PurchasePaymentList = model.Bills.Select(i => new PurchasePaymentList
                    {
                        PurchaseId         = i.PurchaseId,
                        PurchasePaidAmount = i.PurchasePaidAmount
                    }).ToList()
                };

                await Context.PurchasePayment.AddAsync(purchasePayment).ConfigureAwait(false);

                Context.Purchase.UpdateRange(purchases);

                //Account subtract balance
                if (model.PaidAmount > 0 && model.AccountId != null)
                {
                    db.Account.BalanceSubtract(model.AccountId.Value, model.PaidAmount);
                }

                await db.SaveChangesAsync().ConfigureAwait(false);

                db.Vendors.UpdatePaidDue(model.VendorId);

                response.IsSuccess = true;
                response.Message   = "Success";
                response.Data      = purchasePayment.PurchasePaymentId;
                return(response);
            }
            catch (Exception e)
            {
                response.Message   = e.Message;
                response.IsSuccess = false;
                return(response);
            }
        }
Exemple #8
0
        public async Task <DbResponse> DuePaySingleAsync(SellingDuePaySingleModel model, IUnitOfWork db)
        {
            var response = new DbResponse();

            try
            {
                var Sn = await db.SellingPayments.GetNewSnAsync().ConfigureAwait(false);

                var selling = await Context.Selling.FindAsync(model.SellingId).ConfigureAwait(false);

                var accountCostPercentage = db.Account.GetCostPercentage(model.AccountId.GetValueOrDefault());

                var due = (selling.SellingTotalPrice + selling.ServiceCharge + selling.SellingReturnAmount + selling.AccountTransactionCharge) -
                          (model.SellingDiscountAmount + selling.SellingPaidAmount);
                if (model.PaidAmount > due)
                {
                    response.IsSuccess = false;
                    response.Message   = "Paid amount is greater than due";
                }

                if (model.PaidAmount > 0)
                {
                    var sellingPayment = new SellingPayment
                    {
                        RegistrationId           = model.RegistrationId,
                        CustomerId               = model.CustomerId,
                        ReceiptSn                = Sn,
                        PaidAmount               = model.PaidAmount,
                        AccountTransactionCharge = model.AccountTransactionCharge,
                        PaymentMethod            = model.PaymentMethod,
                        PaidDate              = DateTime.Now.BdTime().Date,
                        AccountId             = model.AccountId,
                        AccountCostPercentage = accountCostPercentage,

                        SellingPaymentList = new List <SellingPaymentList>
                        {
                            new SellingPaymentList
                            {
                                SellingId                = model.SellingId,
                                SellingPaidAmount        = model.PaidAmount,
                                AccountTransactionCharge = model.AccountTransactionCharge
                            }
                        }
                    };
                    await Context.SellingPayment.AddAsync(sellingPayment).ConfigureAwait(false);
                }

                selling.SellingDiscountAmount     = model.SellingDiscountAmount;
                selling.SellingPaidAmount        += model.PaidAmount;
                selling.AccountTransactionCharge += model.AccountTransactionCharge;
                selling.SellingAccountCost       += model.PaidAmount * accountCostPercentage / 100;
                selling.LastUpdateDate            = DateTime.Now.BdTime().Date;

                Context.Selling.Update(selling);

                //Account add balance
                if (model.PaidAmount > 0 && model.AccountId != null)
                {
                    db.Account.BalanceAdd(model.AccountId.Value, model.PaidAmount);
                }

                //Sales parson add balance
                if (model.PaidAmount > 0)
                {
                    db.Registrations.BalanceAdd(model.RegistrationId, model.PaidAmount);
                }

                await db.SaveChangesAsync().ConfigureAwait(false);

                db.Customers.UpdatePaidDue(model.CustomerId);



                response.IsSuccess = true;
                response.Message   = "Success";
                return(response);
            }
            catch (Exception e)
            {
                response.Message   = e.Message;
                response.IsSuccess = false;
                return(response);
            }
        }
Exemple #9
0
        public async Task <DbResponse <int> > DuePayMultipleAsync(SellingDuePayMultipleModel model, IUnitOfWork db)
        {
            var response = new DbResponse <int>();

            try
            {
                var sells = await Context.Selling.Where(s => model.Bills.Select(i => i.SellingId).Contains(s.SellingId)).ToListAsync().ConfigureAwait(false);

                //Calculate Each Bill Transaction Charge
                model.CalculateEachBillTransactionCharge();

                var accountCostPercentage = db.Account.GetCostPercentage(model.AccountId.GetValueOrDefault());

                foreach (var invoice in model.Bills)
                {
                    var sell = sells.FirstOrDefault(s => s.SellingId == invoice.SellingId);

                    var due = sell.SellingDueAmount;
                    if (invoice.SellingPaidAmount - invoice.AccountTransactionCharge > due)
                    {
                        response.IsSuccess = false;
                        response.Message   = $"{invoice.SellingPaidAmount} Paid amount is greater than due";
                        return(response);
                    }
                    sell.SellingPaidAmount        += invoice.SellingPaidAmount;
                    sell.AccountTransactionCharge += invoice.AccountTransactionCharge;
                    sell.SellingAccountCost       += model.PaidAmount * accountCostPercentage / 100;
                    sell.LastUpdateDate            = DateTime.Now.BdTime().Date;
                }

                var Sn = await db.SellingPayments.GetNewSnAsync().ConfigureAwait(false);

                var receipt = new SellingPayment
                {
                    RegistrationId           = model.RegistrationId,
                    CustomerId               = model.CustomerId,
                    ReceiptSn                = Sn,
                    PaidAmount               = model.PaidAmount,
                    AccountTransactionCharge = model.AccountTransactionCharge,
                    AccountId                = model.AccountId,
                    AccountCostPercentage    = accountCostPercentage,
                    PaidDate           = DateTime.Now.BdTime().Date,
                    SellingPaymentList = model.Bills.Select(i => new SellingPaymentList
                    {
                        SellingId                = i.SellingId,
                        SellingPaidAmount        = i.SellingPaidAmount,
                        AccountTransactionCharge = i.AccountTransactionCharge
                    }).ToList()
                };

                await Context.SellingPayment.AddAsync(receipt).ConfigureAwait(false);

                Context.Selling.UpdateRange(sells);

                //Account add balance
                if (model.PaidAmount > 0 && model.AccountId != null)
                {
                    db.Account.BalanceAdd(model.AccountId.Value, model.PaidAmount);
                }

                //Sales parson add balance
                if (model.PaidAmount > 0)
                {
                    db.Registrations.BalanceAdd(model.RegistrationId, model.PaidAmount);
                }

                await db.SaveChangesAsync().ConfigureAwait(false);

                db.Customers.UpdatePaidDue(model.CustomerId);


                response.IsSuccess = true;
                response.Message   = "Success";
                response.Data      = receipt.SellingPaymentId;
                return(response);
            }
            catch (Exception e)
            {
                response.Message   = e.Message;
                response.IsSuccess = false;
                return(response);
            }
        }
Exemple #10
0
        public async Task <DbResponse <int> > BillUpdated(SellingUpdatePostModel model, IUnitOfWork db)
        {
            var response = new DbResponse <int>();

            try
            {
                var stocks      = new List <ProductStock>();
                var productLogs = new List <ProductLogAddModel>();

                var accountCostPercentage = db.Account.GetCostPercentage(model.AccountId.GetValueOrDefault());
                if (model.AddedProductCodes != null)
                {
                    if (model.AddedProductCodes.Any())
                    {
                        var addedStocks = await db.ProductStocks.SellingStockFromCodesAsync(model.AddedProductCodes);

                        addedStocks = addedStocks.Select(s =>
                        {
                            s.IsSold = true;
                            return(s);
                        }).ToList();
                        stocks.AddRange(addedStocks);

                        var logs = addedStocks.Select(c => new ProductLogAddModel
                        {
                            SellingId                = model.SellingId,
                            ProductStockId           = c.ProductStockId,
                            ActivityByRegistrationId = model.UpdateRegistrationId,
                            Details   = $"Product Selling by bill changed",
                            LogStatus = ProductLogStatus.Sale
                        }).ToList();

                        productLogs.AddRange(logs);
                    }
                }

                var selling = Context.Selling.Include(s => s.SellingList).FirstOrDefault(s => s.SellingId == model.SellingId);
                if (selling == null)
                {
                    response.IsSuccess = false;
                    response.Message   = "Not found";
                    return(response);
                }

                var returnRecord = new SellingPaymentReturnRecordModel
                {
                    PrevReturnAmount    = selling.SellingReturnAmount,
                    CurrentReturnAmount = model.SellingReturnAmount,
                    AccountId           = model.AccountId,
                    SellingId           = selling.SellingId,
                    RegistrationId      = model.UpdateRegistrationId
                };



                selling.SellingTotalPrice         = model.SellingTotalPrice;
                selling.SellingDiscountAmount     = model.SellingDiscountAmount;
                selling.SellingReturnAmount       = model.SellingReturnAmount;
                selling.SellingPaidAmount        += model.PaidAmount;
                selling.AccountTransactionCharge += model.AccountTransactionCharge;
                selling.SellingAccountCost       += model.PaidAmount * accountCostPercentage / 100;
                selling.LastUpdateDate            = DateTime.Now.BdTime().Date;
                selling.ServiceCharge             = model.ServiceCharge;
                selling.ServiceCost = model.ServiceCost;
                selling.ServiceChargeDescription = model.ServiceChargeDescription;
                selling.PurchaseId             = model.PurchaseId;
                selling.PurchaseAdjustedAmount = model.PurchaseAdjustedAmount;
                selling.PurchaseDescription    = model.PurchaseDescription;

                if (model.PromisedPaymentDate != null)
                {
                    selling.PromisedPaymentDate = model.PromisedPaymentDate.Value.BdTime().Date;
                }

                var due = (selling.SellingTotalPrice + selling.SellingReturnAmount + selling.ServiceCharge + selling.AccountTransactionCharge) - (selling.SellingDiscountAmount + selling.SellingPaidAmount);
                if (due < 0)
                {
                    response.IsSuccess = false;
                    response.Message   = "Due cannot be less than zero";
                    return(response);
                }

                if (due > selling.SellingDueAmount && db.Customers.IsDueLimitCrossed(selling.CustomerId, due - selling.SellingDueAmount))
                {
                    response.Message   = "Customer Due limit crossed";
                    response.IsSuccess = false;
                    return(response);
                }

                if (model.Products != null)
                {
                    selling.SellingList = model.Products.Select(p => new SellingList
                    {
                        SellingListId = p.SellingListId,
                        SellingId     = model.SellingId,
                        ProductId     = p.ProductId,
                        SellingPrice  = p.SellingPrice,
                        PurchasePrice = p.RemainCodes.Length > 0 ? p.PurchasePrice : 0,
                        Description   = p.Description,
                        Warranty      = p.Warranty,
                        ProductStock  = stocks.Where(s => p.RemainCodes.Contains(s.ProductCode)).ToList()
                    }).ToList();

                    selling.BuyingTotalPrice = model.Products.Sum(p => p.PurchasePrice * p.RemainCodes.Length);
                }
                else
                {
                    selling.SellingList      = null;
                    selling.BuyingTotalPrice = 0;
                }



                if (model.RemovedProductCodes != null)
                {
                    if (model.RemovedProductCodes.Any())
                    {
                        var removedStocks =
                            await db.ProductStocks.SoldBillStockFromCodesAsync(model.SellingId, model.RemovedProductCodes);

                        removedStocks = removedStocks.Select(s =>
                        {
                            s.IsSold        = false;
                            s.SellingListId = null;
                            return(s);
                        }).ToList();

                        if (removedStocks.Any())
                        {
                            Context.ProductStock.UpdateRange(removedStocks);

                            var logs = removedStocks.Select(c => new ProductLogAddModel
                            {
                                SellingId                = model.SellingId,
                                ProductStockId           = c.ProductStockId,
                                ActivityByRegistrationId = model.UpdateRegistrationId,
                                Details   = $"Product return by bill changed",
                                LogStatus = ProductLogStatus.Return
                            }).ToList();

                            productLogs.AddRange(logs);
                        }
                    }
                }

                Context.Selling.Update(selling);

                if (model.PaidAmount > 0)
                {
                    var newSellingPaymentSn = await db.SellingPayments.GetNewSnAsync().ConfigureAwait(false);

                    var payment = new SellingPayment
                    {
                        RegistrationId           = model.UpdateRegistrationId,
                        CustomerId               = selling.CustomerId,
                        ReceiptSn                = newSellingPaymentSn,
                        PaidAmount               = model.PaidAmount,
                        AccountTransactionCharge = model.AccountTransactionCharge,
                        AccountId                = model.AccountId,
                        PaidDate = DateTime.Now.BdTime().Date,
                        AccountCostPercentage = accountCostPercentage,
                        SellingPaymentList    = new List <SellingPaymentList>
                        {
                            new SellingPaymentList
                            {
                                SellingPaidAmount        = model.PaidAmount,
                                AccountTransactionCharge = model.AccountTransactionCharge,
                                SellingId = model.SellingId
                            }
                        }
                    };

                    await Context.SellingPayment.AddAsync(payment);
                }

                //Account add balance
                if (model.PaidAmount > 0 && model.AccountId != null)
                {
                    db.Account.BalanceAdd(model.AccountId.Value, model.PaidAmount);
                }

                await Context.SaveChangesAsync();

                db.Customers.UpdatePaidDue(selling.CustomerId);
                //Product log
                db.ProductLog.AddList(productLogs);

                //Return amount account update
                db.Account.SellingReturnRecordAdd(returnRecord);
            }
            catch (Exception e)
            {
                response.IsSuccess = false;
                response.Message   = e.Message;
                return(response);
            }

            response.IsSuccess = true;
            response.Message   = "Success";
            response.Data      = model.SellingId;

            return(response);
        }
Exemple #11
0
        public async Task <DbResponse <int> > AddCustomAsync(SellingViewModel model, IUnitOfWork db)
        {
            var response = new DbResponse <int>();

            if (IsPurchaseIdExist(model.PurchaseId.GetValueOrDefault()))
            {
                response.Message   = "Purchase receipt already applied";
                response.IsSuccess = false;
                return(response);
            }

            var codes      = model.ProductList.SelectMany(p => p.ProductCodes).ToArray();
            var isStockOut = db.ProductStocks.IsStockOut(codes);

            if (isStockOut)
            {
                response.Message   = "Product Stock Out";
                response.IsSuccess = false;
                return(response);
            }

            var due = (model.SellingTotalPrice + model.ServiceCharge) - (model.SellingPaidAmount + model.SellingDiscountAmount + model.PurchaseAdjustedAmount);

            if (due > 0 && db.Customers.IsDueLimitCrossed(model.CustomerId, due))
            {
                response.Message   = "Customer Due limit crossed";
                response.IsSuccess = false;
                return(response);
            }

            var newSellingSn = await GetNewSnAsync().ConfigureAwait(false);

            var newSellingPaymentSn = await db.SellingPayments.GetNewSnAsync().ConfigureAwait(false);

            var sellingStock = await db.ProductStocks.SellingStockFromCodesAsync(codes);

            var accountCostPercentage = db.Account.GetCostPercentage(model.AccountId.GetValueOrDefault());
            var selling = new Selling
            {
                RegistrationId           = model.RegistrationId,
                CustomerId               = model.CustomerId,
                SellingSn                = newSellingSn,
                SellingTotalPrice        = model.SellingTotalPrice,
                SellingDiscountAmount    = model.SellingDiscountAmount,
                SellingPaidAmount        = model.SellingPaidAmount,
                AccountTransactionCharge = model.AccountTransactionCharge,
                SellingDate              = DateTime.Now.BdTime().Date,
                LastUpdateDate           = DateTime.Now.BdTime().Date,
                SellingList              = model.ProductList.Select(l => new SellingList
                {
                    ProductId     = l.ProductId,
                    SellingPrice  = l.SellingPrice,
                    PurchasePrice = l.PurchasePrice,
                    Description   = l.Description,
                    Warranty      = l.Warranty,
                    ProductStock  = sellingStock.Where(s => l.ProductCodes.Contains(s.ProductCode) && !s.IsSold).Select(s =>
                    {
                        s.IsSold = true;
                        return(s);
                    }).ToList()
                }).ToList(),
                SellingPaymentList = model.SellingPaidAmount > 0 ?
                                     new List <SellingPaymentList>
                {
                    new SellingPaymentList
                    {
                        SellingPaidAmount        = model.SellingPaidAmount,
                        AccountTransactionCharge = model.AccountTransactionCharge,
                        SellingPayment           = new SellingPayment
                        {
                            SellingPaymentId         = 0,
                            RegistrationId           = model.RegistrationId,
                            CustomerId               = model.CustomerId,
                            ReceiptSn                = newSellingPaymentSn,
                            PaidAmount               = model.SellingPaidAmount,
                            AccountTransactionCharge = model.AccountTransactionCharge,
                            PaymentMethod            = model.PaymentMethod,
                            PaidDate    = DateTime.Now.BdTime().Date,
                            AccountId   = model.AccountId,
                            AccountCost = accountCostPercentage
                        }
                    }
                } : null,
                BuyingTotalPrice    = model.ProductList.Sum(p => p.PurchasePrice * p.ProductCodes.Length),
                PromisedPaymentDate = model.PromisedPaymentDate,
                ExpenseTotal        = model.Expense,
                SellingExpense      = model.Expense > 0 ? new List <SellingExpense>
                {
                    new SellingExpense
                    {
                        Expense            = model.Expense,
                        ExpenseDescription = model.ExpenseDescription,
                        InsertDateUtc      = DateTime.Now.BdTime(),
                        AccountId          = model.AccountId
                    }
                } : null,
                ServiceCost              = model.ServiceCost,
                ServiceCharge            = model.ServiceCharge,
                ServiceChargeDescription = model.ServiceChargeDescription,
                SellingAccountCost       = model.SellingPaidAmount * accountCostPercentage / 100,
                PurchaseAdjustedAmount   = model.PurchaseAdjustedAmount,
                PurchaseDescription      = model.PurchaseDescription,
                PurchaseId = model.PurchaseId
            };


            await Context.Selling.AddAsync(selling).ConfigureAwait(false);

            try
            {
                //Account add balance
                if (model.SellingPaidAmount > 0 && model.AccountId != null)
                {
                    db.Account.BalanceAdd(model.AccountId.Value, model.SellingPaidAmount);
                }


                //Sales parson add balance
                if (model.SellingPaidAmount > 0)
                {
                    db.Registrations.BalanceAdd(model.RegistrationId, model.SellingPaidAmount);
                }

                await Context.SaveChangesAsync().ConfigureAwait(false);

                //Account Subtract balance for selling expense
                if (model.Expense > 0 && model.AccountId != null)
                {
                    db.Account.BalanceSubtract(model.AccountId.Value, model.Expense);
                }

                db.Customers.UpdatePaidDue(model.CustomerId);

                //Product Logs
                var logs = selling.SellingList.SelectMany(p => p.ProductStock.Select(c => new ProductLogAddModel
                {
                    SellingId                = selling.SellingId,
                    ProductStockId           = c.ProductStockId,
                    ActivityByRegistrationId = model.RegistrationId,
                    Details   = $"Product Selling at Receipt No: {selling.SellingSn}",
                    LogStatus = ProductLogStatus.Sale
                })).ToList();

                db.ProductLog.AddList(logs);

                response.IsSuccess = true;
                response.Message   = "Success";
                response.Data      = selling.SellingId;
            }
            catch (DbUpdateException e)
            {
                response.Message   = e.Message;
                response.IsSuccess = false;
            }

            return(response);
        }
        public async Task <DbResponse <int> > BillUpdated(PurchaseUpdatePostModel model, IUnitOfWork db, string userName)
        {
            var response = new DbResponse <int>();

            try
            {
                var purchase = Context.Purchase
                               .Include(s => s.PurchaseList)
                               .FirstOrDefault(s => s.PurchaseId == model.PurchaseId);

                if (purchase == null)
                {
                    response.IsSuccess = false;
                    response.Message   = "Not found";
                    return(response);
                }
                var registrationId = db.Registrations.GetRegID_ByUserName(userName);
                var returnRecord   = new PurchasePaymentReturnRecordModel
                {
                    PrevReturnAmount    = decimal.Round(purchase.PurchaseReturnAmount, 2),
                    CurrentReturnAmount = decimal.Round(model.PurchaseReturnAmount, 2),
                    AccountId           = model.AccountId,
                    PurchaseId          = purchase.PurchaseId,
                    RegistrationId      = registrationId
                };

                purchase.PurchaseTotalPrice     = decimal.Round(model.PurchaseTotalPrice, 2);
                purchase.PurchaseDiscountAmount = decimal.Round(model.PurchaseDiscountAmount, 2);
                purchase.PurchaseReturnAmount   = decimal.Round(model.PurchaseReturnAmount, 2);
                purchase.PurchasePaidAmount    += decimal.Round(model.PaidAmount, 2);


                var due = (purchase.PurchaseTotalPrice + purchase.PurchaseReturnAmount) - (purchase.PurchaseDiscountAmount + purchase.PurchasePaidAmount);
                if (due < 0)
                {
                    response.IsSuccess = false;
                    response.Message   = "Due cannot be less than zero";
                    return(response);
                }

                if (model.RemovedProductStockIds != null)
                {
                    if (model.RemovedProductStockIds.Any())
                    {
                        var removedStocks = Context.ProductStock
                                            .Include(s => s.ProductLog)
                                            .Include(s => s.Warranty)
                                            .Where(s => model.RemovedProductStockIds.Contains(s.ProductStockId)).ToList();

                        if (removedStocks.Any(s => s.IsSold))
                        {
                            response.IsSuccess = false;
                            response.Message   = "Sold product can not be return";
                            return(response);
                        }

                        if (removedStocks.Any())
                        {
                            Context.ProductStock.RemoveRange(removedStocks);
                        }
                    }
                }


                if (model.PurchaseList == null)
                {
                    purchase.PurchaseList = null;
                }

                Context.Purchase.Update(purchase);

                var existProduct = model.PurchaseList.Where(p => p.PurchaseListId != 0 && p.AddedProductCodes != null).ToList();


                foreach (var pItem in existProduct)
                {
                    var purchaseList = Context.PurchaseList.Find(pItem.PurchaseListId);

                    purchaseList.SellingPrice  = pItem.SellingPrice;
                    purchaseList.PurchasePrice = pItem.PurchasePrice;
                    purchaseList.Description   = pItem.Description;
                    purchaseList.Note          = pItem.Note;
                    purchaseList.Warranty      = pItem.Warranty;
                    purchaseList.ProductStock  = pItem.AddedProductCodes.Select(s => new ProductStock
                    {
                        ProductId   = pItem.ProductId,
                        ProductCode = s
                    }).ToList();

                    Context.PurchaseList.Update(purchaseList);
                }

                var newProduct = model.PurchaseList.Where(p => p.PurchaseListId == 0 && p.AddedProductCodes != null).ToList();

                var newPurchaseList = newProduct.Select(p => new PurchaseList
                {
                    PurchaseListId = p.PurchaseListId,
                    PurchaseId     = model.PurchaseId,
                    ProductId      = p.ProductId,
                    SellingPrice   = p.SellingPrice,
                    PurchasePrice  = p.PurchasePrice,
                    Description    = p.Description,
                    Note           = p.Note,
                    Warranty       = p.Warranty,
                    ProductStock   = p.AddedProductCodes.Select(s => new ProductStock
                    {
                        ProductId   = p.ProductId,
                        ProductCode = s
                    }).ToList()
                }).ToList();

                Context.PurchaseList.AddRange(newPurchaseList);



                if (model.PaidAmount > 0)
                {
                    var newSellingPaymentSn = await db.PurchasePayments.GetNewSnAsync().ConfigureAwait(false);

                    var payment = new PurchasePayment
                    {
                        RegistrationId      = registrationId,
                        VendorId            = purchase.VendorId,
                        ReceiptSn           = newSellingPaymentSn,
                        PaidAmount          = model.PaidAmount,
                        AccountId           = model.AccountId,
                        PaidDate            = DateTime.Now.BdTime().Date,
                        PurchasePaymentList = new List <PurchasePaymentList>
                        {
                            new PurchasePaymentList
                            {
                                PurchasePaidAmount = model.PaidAmount,
                                PurchaseId         = model.PurchaseId
                            }
                        }
                    };

                    await Context.PurchasePayment.AddAsync(payment);
                }

                //Account add balance
                if (model.PaidAmount > 0 && model.AccountId != null)
                {
                    db.Account.BalanceSubtract(model.AccountId.Value, model.PaidAmount);
                }


                await Context.SaveChangesAsync();

                db.Vendors.UpdatePaidDue(purchase.VendorId);

                //remove purchase list
                var removedPurchaseList = Context.PurchaseList.Where(l => !l.ProductStock.Any()).ToList();

                Context.RemoveRange(removedPurchaseList);
                await Context.SaveChangesAsync();

                //Product Logs
                var codes     = model.PurchaseList.SelectMany(l => l.AddedProductCodes).ToArray();
                var stockList = Context
                                .ProductStock
                                .Include(p => p.PurchaseList)
                                .Where(s => s.PurchaseList.PurchaseId == model.PurchaseId && codes.Contains(s.ProductCode))
                                .ToList();

                if (stockList.Any())
                {
                    var productLogs = stockList.Select(c => new ProductLogAddModel
                    {
                        PurchaseId               = model.PurchaseId,
                        ProductStockId           = c.ProductStockId,
                        ActivityByRegistrationId = registrationId,
                        Details   = $"Bill Updated: Product Buy at Receipt No: {purchase.PurchaseSn}",
                        LogStatus = ProductLogStatus.PurchaseUpdate
                    }).ToList();
                    //Product log
                    db.ProductLog.AddList(productLogs);
                }

                //Return amount account update
                db.Account.PurchaseReturnRecordAdd(returnRecord);
            }
            catch (Exception e)
            {
                response.IsSuccess = false;
                response.Message   = e.Message;
                return(response);
            }

            response.IsSuccess = true;
            response.Message   = "Success";
            response.Data      = model.PurchaseId;

            return(response);
        }
        public async Task <DbResponse <int> > AddCustomAsync(PurchaseViewModel model, IUnitOfWork db)
        {
            var response  = new DbResponse <int>();
            var newStocks = model.Products.SelectMany(p => p.ProductStocks.Select(s => s)).ToList();

            var duplicateStocks = await db.ProductStocks.IsExistListAsync(newStocks).ConfigureAwait(false);

            if (duplicateStocks.Any(s => !s.IsSold))
            {
                response.Message   = "Product code already exists";
                response.IsSuccess = false;
                return(response);
            }

            var newPurchaseSn = await GetNewSnAsync().ConfigureAwait(false);

            var newPurchasePaymentSn = await db.PurchasePayments.GetNewSnAsync().ConfigureAwait(false);

            var purchase = new Purchase
            {
                RegistrationId         = model.RegistrationId,
                VendorId               = model.VendorId,
                PurchaseSn             = newPurchaseSn,
                PurchaseTotalPrice     = model.PurchaseTotalPrice,
                PurchaseDiscountAmount = model.PurchaseDiscountAmount,
                PurchasePaidAmount     = model.PurchasePaidAmount,
                MemoNumber             = model.MemoNumber,
                PurchaseDate           = model.PurchaseDate.BdTime().Date,
                PurchaseList           = model.Products.Select(p => new PurchaseList
                {
                    ProductId     = p.ProductId,
                    Description   = p.Description,
                    Warranty      = p.Warranty,
                    Note          = p.Note,
                    PurchasePrice = p.PurchasePrice,
                    SellingPrice  = p.SellingPrice,
                    ProductStock  = p.ProductStocks.Select(s => new ProductStock
                    {
                        ProductId   = p.ProductId,
                        ProductCode = s.ProductCode
                    }).ToList()
                }).ToList(),
                PurchasePaymentList = model.PurchasePaidAmount > 0 ?
                                      new List <PurchasePaymentList>
                {
                    new PurchasePaymentList
                    {
                        PurchasePaidAmount = model.PurchasePaidAmount,
                        PurchasePayment    = new PurchasePayment
                        {
                            PurchasePaymentId = 0,
                            RegistrationId    = model.RegistrationId,
                            VendorId          = model.VendorId,
                            ReceiptSn         = newPurchasePaymentSn,
                            PaidAmount        = model.PurchasePaidAmount,
                            PaymentMethod     = model.PaymentMethod,
                            PaidDate          = model.PurchaseDate.BdTime().Date,
                            AccountId         = model.AccountId
                        }
                    }
                } : null
            };

            await Context.Purchase.AddAsync(purchase).ConfigureAwait(false);


            //Update Product Info
            foreach (var item in model.Products)
            {
                var product = await Context.Product.FindAsync(item.ProductId);

                product.ProductId    = item.ProductId;
                product.Description  = item.Description;
                product.Warranty     = item.Warranty;
                product.Note         = item.Note;
                product.SellingPrice = item.SellingPrice;
                Context.Product.Update(product);
            }


            try
            {
                //Account subtract balance
                if (model.PurchasePaidAmount > 0 && model.AccountId != null)
                {
                    db.Account.BalanceSubtract(model.AccountId.Value, model.PurchasePaidAmount);
                }

                await Context.SaveChangesAsync().ConfigureAwait(false);

                db.Vendors.UpdatePaidDue(model.VendorId);

                //Product Logs
                var logs = purchase.PurchaseList.SelectMany(p => p.ProductStock.Select(c => new ProductLogAddModel
                {
                    PurchaseId               = p.PurchaseId,
                    ProductStockId           = c.ProductStockId,
                    ActivityByRegistrationId = model.RegistrationId,
                    Details   = $"Product Buy at Receipt No: {purchase.PurchaseSn}",
                    LogStatus = ProductLogStatus.Buy
                })).ToList();

                db.ProductLog.AddList(logs);

                response.IsSuccess = true;
                response.Message   = "Success";
                response.Data      = purchase.PurchaseId;
            }
            catch (DbUpdateException e)
            {
                response.Message   = e.Message;
                response.IsSuccess = false;
            }

            return(response);
        }