private async void Save()
        {
            try
            {
                var purchaseProduct = new PurchaseProductModel();
                purchaseProduct.PurchaseProductID = _purchaseProductID;
                purchaseProduct.ProductID         = _productID;
                purchaseProduct.Quantity          = txtQuantity.Text.ToInt();
                //purchaseProduct.IsQuantityUploaded = chkUploadQuantity.Checked;
                purchaseProduct.UnitCost = txtPrice.Text.ToDecimal();
                if (_purchaseProductID > 0)
                {
                    // edit
                    await _purchaseService.EditPurchaseProduct(purchaseProduct);
                }
                else
                {
                    // add
                    await _purchaseService.AddPurchaseProductAsync(_purchaseID, purchaseProduct);
                }
                this.Close();
            }
            catch (CustomBaseException ex)
            {
                MetroMessageBox.Show(this, ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            catch (Exception ex)
            {
                MetroMessageBox.Show(this, ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        public JsonResult AddWithProduct(PurchaseProductModel purchaseModel)
        {
            using (var transaction = _mahadevHwContext.Database.BeginTransaction())
            {
                try
                {
                    purchaseModel.Purchase.Date = DateTime.ParseExact(purchaseModel.Purchase.TempDate, "dd-MM-yyyy",
                                                                      CultureInfo.InvariantCulture);
                    _mahadevHwContext.Purchase.Add(purchaseModel.Purchase);
                    _mahadevHwContext.SaveChanges();

                    foreach (var item in purchaseModel.PurchaseItems)
                    {
                        item.PurchaseId = purchaseModel.Purchase.Id;

                        if (item.IsExistingProduct)
                        {
                            var existingItem = _mahadevHwContext.Items.Where(e => e.Id == item.ItemId).FirstOrDefault();
                            existingItem.Quantity += item.Quantity;
                        }
                        else
                        {
                            var newItem = new Item()
                            {
                                Category      = item.Category,
                                Name          = item.Name,
                                HSN           = item.HSN,
                                SellPrice     = item.SellPrice,
                                CGST          = item.CGST,
                                SGST          = item.SGST,
                                Price         = item.Price,
                                Discount      = item.Discount,
                                DiscountPrice = item.DiscountPrice,
                                MeasuringUnit = item.MeasuringUnit,
                                Quantity      = item.Quantity,
                                SoldQuantity  = item.SoldQuantity
                            };
                            _mahadevHwContext.Items.Add(newItem);
                            _mahadevHwContext.SaveChanges();
                            item.ItemId = newItem.Id;
                        }
                        _mahadevHwContext.PurchaseItems.Add(item);
                    }
                    _mahadevHwContext.SaveChanges();
                    transaction.Commit();
                    return(Json(new { Message = "Save successfull" }));
                }
                catch (Exception ex)
                {
                    transaction.Rollback();
                    Response.StatusCode = (int)HttpStatusCode.InternalServerError;
                    return(Json(new { Message = "Internal Server error" }));
                }
            }
        }
        public async Task EditPurchaseProduct(PurchaseProductModel model)
        {
            using (var db = new DataContext())
            {
                ValidatePurchaseProduct(model.ProductID, model.Quantity);

                var purchaseProduct = db.PurchaseProducts.Find(model.PurchaseProductID);
                if (purchaseProduct.IsQuantityUploaded)
                {
                    //purchases where uploaded quantity is true must not available for edit
                    throw new EditNotPermittedException();
                }
                var newPurchaseProduct = Mapping.Mapper.Map(model, purchaseProduct);
                db.Entry(newPurchaseProduct).State = EntityState.Modified;
                await db.SaveChangesAsync();
            }
        }
        public async Task AddPurchaseProductAsync(int purchaseID, PurchaseProductModel model)
        {
            using (var db = new DataContext())
            {
                ValidatePurchaseProduct(model.ProductID, model.Quantity);
                var existProductOnPurchase = db.PurchaseProducts.FirstOrDefault(x => x.ProductID == model.ProductID && x.PurchaseID == purchaseID);
                if (existProductOnPurchase != null)
                {
                    //no duplicate products for every purchases
                    throw new RecordAlreadyExistsException(string.Format("Product {0}", existProductOnPurchase.Product.Name));
                }
                var product = db.Products.Find(model.ProductID);
                if (model.IsQuantityUploaded)
                {
                    // add the quantity to current product quantity if isquantityuploaded is true

                    product.Quantity       += model.Quantity;
                    db.Entry(product).State = EntityState.Modified;
                }

                if (model.UnitCost >= product.Price)
                {
                    throw new InvalidFieldException2(string.Format("Purchase Unit Price {1} must be less than product price {0}.",
                                                                   product.Price.ToCurrencyFormat(), model.UnitCost.ToString()));
                }
                var purchaseProduct = Mapping.Mapper.Map <PurchaseProduct>(model);

                purchaseProduct.PurchaseID = purchaseID;
                db.PurchaseProducts.Add(purchaseProduct);

                // set is fully paid to false when adding new purchase product
                var purchase = db.Purchases.Find(purchaseID);
                purchase.IsFullyPaid     = false;
                db.Entry(purchase).State = EntityState.Modified;

                await db.SaveChangesAsync();
            }
        }