Example #1
0
        static public bool?IsBasketValidated(TempWeekBasket tempBasket, ApplicationDbContext context)
        {
            ValidatedWeekBasket validatedBasket = context.ValidatedWeekBaskets
                                                  .Include(x => x.AdherentStolon)
                                                  .Include(x => x.BillEntries)
                                                  .AsNoTracking()
                                                  .FirstOrDefault(x => x.AdherentStolon.AdherentId == tempBasket.AdherentStolon.AdherentId);

            if (validatedBasket == null)
            {
                return(false);
            }
            if (validatedBasket.BillEntries.Count != tempBasket.BillEntries.Count)
            {
                return(false);
            }
            foreach (BillEntry billEntry in tempBasket.BillEntries.ToList())
            {
                BillEntry validatedEntry = validatedBasket.BillEntries.FirstOrDefault(x => x.ProductStockId == billEntry.ProductStockId);

                if (validatedEntry == null)
                {
                    return(false);
                }
                if (billEntry.Quantity != validatedEntry.Quantity)
                {
                    return(false);
                }
            }
            return(true);
        }
Example #2
0
        public void SaveEntryToDataBase()
        {
            double amount = 0;

            mainDBHelper.InitializeNewBillEntry("Suresh", true);
            mainDBHelper.UpdateCustomerName("Ram");
            mainDBHelper.UpdatePhoneNumber("9447586655");
            mainDBHelper.AddProduct("Selfie", out amount);
            mainDBHelper.UpdateBillType(2);
            mainDBHelper.UpdateDeliverStatus(true);
            int beforeCount = dbHelper.GetBillEntryCount();

            mainDBHelper.SaveEntryToDatabase();
            int afterCount = dbHelper.GetBillEntryCount();

            Assert.AreEqual(beforeCount + 1, afterCount, "Bill Entry not saved to the database");
            mainDBHelper.UpdateBillType(1);
            mainDBHelper.SaveEntryToDatabase();
            int currentCount = dbHelper.GetBillEntryCount();

            Assert.AreEqual(afterCount, currentCount, "Updating the entry should not add a record to the database.");
            BillEntry latestEntry = dbHelper.GetCustomer("Ram", "9447586655");

            Assert.IsNotNull(latestEntry, "Bill Entry should not be null");
            Assert.AreEqual(2, (int)latestEntry.BillType, "Updated value didn't get saved after save.");
        }
            public void FillModel(ref BillEntry objBillEntry)
            {
                objBillEntry.ProductName = this.ProductName;
                objBillEntry.Price       = this.Price;
                objBillEntry.Quantity    = this.Quantity;

                ProductCategory objProductCategory = new ProductCategory();

                this.Category.FillModel(ref objProductCategory);
                objBillEntry.Category = objProductCategory;
            }
Example #4
0
        public IActionResult RemoveBillEntry(string weekBasketId, string productStockId)
        {
            TempWeekBasket tempWeekBasket = _context.TempsWeekBaskets.Include(x => x.AdherentStolon).ThenInclude(x => x.Adherent).Include(x => x.BillEntries).ThenInclude(x => x.ProductStock).ThenInclude(x => x.Product).First(x => x.Id.ToString() == weekBasketId);

            tempWeekBasket.RetrieveProducts(_context);
            BillEntry billEntry = tempWeekBasket.BillEntries.First(x => x.ProductId.ToString() == productStockId);

            tempWeekBasket.BillEntries.Remove(billEntry);
            _context.Remove(billEntry);
            _context.SaveChanges();
            return(JsonTmpWeekBasket());
        }
 public BillEntryApiWrapper(BillEntry objBillEntry)
 {
     this.LastModifiedDate = objBillEntry.LastModifiedDate;
     this.ExternalSystemID = objBillEntry.ExternalSystemID;
     this.BillEntryID      = objBillEntry.BillEntryID;
     this.ProductName      = objBillEntry.ProductName;
     this.Price            = objBillEntry.Price;
     this.Quantity         = objBillEntry.Quantity;
     if (objBillEntry.Category != null)
     {
         this.Category = new ProductCategoryController.ProductCategoryApiWrapper(objBillEntry.Category);
     }
 }
Example #6
0
        private TempWeekBasket AddProductQuantity(string weekBasketId, string productStockId, int quantity)
        {
            TempWeekBasket tempWeekBasket = _context.TempsWeekBaskets.Include(x => x.AdherentStolon).Include(x => x.AdherentStolon.Adherent).Include(x => x.BillEntries).First(x => x.Id.ToString() == weekBasketId);
            //tempWeekBasket.RetrieveProducts(_context);
            ValidatedWeekBasket validatedWeekBasket = _context.ValidatedWeekBaskets.Include(x => x.AdherentStolon).Include(x => x.BillEntries).AsNoTracking().FirstOrDefault(x => x.AdherentStolon.AdherentId == tempWeekBasket.AdherentStolon.AdherentId);

            int validatedQuantity = 0;

            if (validatedWeekBasket != null)
            {
                BillEntry validatedEntry = validatedWeekBasket.BillEntries.FirstOrDefault(x => x.ProductStockId.ToString() == productStockId);

                if (validatedEntry != null)
                {
                    validatedQuantity = validatedEntry.Quantity;
                }
            }
            BillEntry          billEntry    = tempWeekBasket.BillEntries.FirstOrDefault(x => x.ProductStockId.ToString() == productStockId);
            ProductStockStolon productStock = _context.ProductsStocks.Include(x => x.Product).FirstOrDefault(x => x.Id.ToString() == productStockId);

            decimal stepStock = productStock.RemainingStock;

            if (productStock.Product.Type != Product.SellType.Piece)
            {
                stepStock = (productStock.RemainingStock * 1000.0M) / productStock.Product.QuantityStep;
            }
            bool proceed = false;

            if (productStock.Product.StockManagement == Product.StockType.Unlimited)
            {
                proceed = true;
            }
            if (!(quantity > 0 && stepStock < (billEntry.Quantity - validatedQuantity) + quantity))
            {
                proceed = true;
            }
            if (proceed == true)
            {
                billEntry.Quantity = billEntry.Quantity + quantity;

                if (billEntry.Quantity <= 0)
                {
                    //La quantite est 0 on supprime le produit
                    tempWeekBasket.BillEntries.Remove(billEntry);
                    _context.Remove(billEntry);
                }
                _context.SaveChanges();
            }
            return(tempWeekBasket);
        }
Example #7
0
            public void FillModel(ref Bill objBill, bool bFillForUpdate)
            {
                objBill.PurchaseDate = this.PurchaseDate;

                if (!bFillForUpdate)
                {
                    objBill.Entries = new List <BillEntry>();
                    foreach (BillEntryController.BillEntryApiWrapper objBillEntryApiWrapper in this.Entries)
                    {
                        BillEntry objBillEntry = new BillEntry();
                        objBillEntryApiWrapper.FillModel(ref objBillEntry);
                        objBill.Entries.Add(objBillEntry);
                    }
                }
            }
Example #8
0
        public bool InitializeNewBillEntry(string BilledBy, bool forceCreate)
        {
            if (forceCreate || !saveNeeded)
            {
                currentBillEntry = new BillEntry();
                currentBillEntry.CustomerName = "";
                currentBillEntry.PhoneNumber  = "";
                currentBillEntry.BillID       = File.ReadAllText("MRStudio\\count.txt").Replace("\r\n", "");
                currentBillEntry.BilledByUser = BilledBy;
                saveNeeded    = false;
                firsttimesave = true;
                return(true);
            }

            return(false);
        }
Example #9
0
        public IActionResult AddToBasket(string weekBasketId, string productStockId)
        {
            TempWeekBasket tempWeekBasket = _context.TempsWeekBaskets.Include(x => x.AdherentStolon).Include(x => x.AdherentStolon.Adherent).Include(x => x.BillEntries).AsNoTracking().First(x => x.Id.ToString() == weekBasketId);

            if (tempWeekBasket.BillEntries.Any(x => x.ProductStockId.ToString() == productStockId))
            {
                return(JsonTmpWeekBasket());//On a déjà le produit
            }
            ProductStockStolon ProductStock = _context.ProductsStocks.Include(x => x.Product).ThenInclude(x => x.Producer).Single(x => x.Id.ToString() == productStockId);
            BillEntry          billEntry    = BillEntry.CloneFromProduct(ProductStock);

            billEntry.ProductStockId   = ProductStock.Id;
            billEntry.Quantity         = 1;
            billEntry.TempWeekBasketId = tempWeekBasket.Id;
            _context.Add(billEntry);
            _context.SaveChanges();
            return(JsonTmpWeekBasket());
        }
Example #10
0
        private static void TriggerDeliveryAndStockUpdateMode(Stolon stolon, ApplicationDbContext dbContext)
        {
            //Consumer (create bills)
            List <ValidatedWeekBasket> consumerWeekBaskets = dbContext.ValidatedWeekBaskets
                                                             .Include(x => x.BillEntries)
                                                             .Include(x => x.AdherentStolon)
                                                             .Include(x => x.AdherentStolon.Stolon)
                                                             .Include(x => x.AdherentStolon.Adherent)
                                                             .Where(x => x.AdherentStolon.StolonId == stolon.Id)
                                                             .ToList();

            foreach (var weekBasket in consumerWeekBaskets)
            {
                //Remove TempWeekBasket and linked billEntry
                var tempWeekBasketToRemove = dbContext.TempsWeekBaskets.FirstOrDefault(x => x.AdherentStolonId == weekBasket.AdherentStolon.Id);
                if (tempWeekBasketToRemove == null)
                {
                    continue;
                }
                var linkedBillEntriesToRemove = dbContext.BillEntrys.Where(x => x.TempWeekBasketId == tempWeekBasketToRemove.Id).ToList();
                dbContext.RemoveRange(linkedBillEntriesToRemove);
                dbContext.SaveChanges();
                dbContext.Remove(tempWeekBasketToRemove);
                dbContext.SaveChanges();
                //Creates new bill entryes
                List <BillEntry> billEntries = new List <BillEntry>();
                foreach (var oldBillEntry in weekBasket.BillEntries.ToList())
                {
                    BillEntry newBillEntry = oldBillEntry.Clone();
                    billEntries.Add(newBillEntry);
                    dbContext.Remove(oldBillEntry);
                    dbContext.Add(newBillEntry);
                    dbContext.SaveChanges();
                }
                dbContext.Remove(weekBasket);
                dbContext.SaveChanges();

                //Generate bill for consumer
                ConsumerBill consumerBill = CreateBill <ConsumerBill>(weekBasket.AdherentStolon, billEntries);
                consumerBill.HtmlBillContent = GenerateHtmlBillContent(consumerBill, dbContext);
                dbContext.Add(consumerBill);
                dbContext.SaveChanges();
            }

            List <ProducerBill> producerBills = new List <ProducerBill>();
            List <ConsumerBill> consumerBills = dbContext.ConsumerBills
                                                .Include(x => x.BillEntries)
                                                .ThenInclude(x => x.ProductStock)
                                                .ThenInclude(x => x.Product)
                                                .Include(x => x.AdherentStolon)
                                                .Include(x => x.AdherentStolon.Adherent)
                                                .Include(x => x.AdherentStolon.Stolon)
                                                .Where(x => x.AdherentStolon.Stolon.Id == stolon.Id && x.EditionDate.GetIso8601WeekOfYear() == DateTime.Now.GetIso8601WeekOfYear() && x.EditionDate.Year == DateTime.Now.Year)
                                                .ToList();

            //Producer (creates bills)
            foreach (var producer in dbContext.AdherentStolons.Include(x => x.Adherent).Include(x => x.Stolon).Where(x => x.StolonId == stolon.Id && x.IsProducer).ToList())
            {
                List <BillEntry> billEntries = new List <BillEntry>();
                foreach (var consumerBill in consumerBills)
                {
                    foreach (var billEntry in consumerBill.BillEntries.Where(billEntry => billEntry.ProductStock.Product.ProducerId == producer.AdherentId))
                    {
                        billEntries.Add(billEntry);
                    }
                }
                //Generate bill for producer
                ProducerBill bill = CreateBill <ProducerBill>(producer, billEntries);
                bill.HtmlBillContent  = GenerateHtmlBillContent(bill, dbContext);
                bill.HtmlOrderContent = GenerateHtmlOrderContent(bill, dbContext);
                producerBills.Add(bill);
                if (billEntries.Any())
                {
                    dbContext.Add(bill);
                    dbContext.SaveChanges();
                }
            }

            //Stolons
            StolonsBill stolonsBill = GenerateBill(stolon, consumerBills, dbContext);

            stolonsBill.Producers = producerBills.Count;
            if (dbContext.StolonsBills.Any(x => x.BillNumber == stolonsBill.BillNumber))
            {
                StolonsBill tempBill = dbContext.StolonsBills.FirstOrDefault(x => x.BillNumber == stolonsBill.BillNumber);
                tempBill.Amount          = stolonsBill.Amount;
                tempBill.EditionDate     = stolonsBill.EditionDate;
                tempBill.HtmlBillContent = stolonsBill.HtmlBillContent;
                tempBill.ProducersFee    = stolonsBill.ProducersFee;
            }
            else
            {
                dbContext.Add(stolonsBill);
            }

            dbContext.SaveChanges();
            //Move stolon's products to stock
            foreach (ProductStockStolon productStock in dbContext.ProductsStocks.Include(x => x.AdherentStolon).Include(x => x.Product).Where(x => x.AdherentStolon.StolonId == stolon.Id).ToList())
            {
                if (productStock.State == ProductState.Enabled && productStock.Product.StockManagement == StockType.Week)
                {
                    productStock.State          = ProductState.Stock;
                    productStock.RemainingStock = productStock.WeekStock;
                }
            }
            //

            dbContext.SaveChanges();
            //For stolons
            try
            {
                GeneratePDF(stolonsBill.HtmlBillContent, stolonsBill.GetStolonBillFilePath());
            }
            catch (Exception exept)
            {
                AuthMessageSender.SendEmail(stolon.Label,
                                            Configurations.Application.ContactMailAddress,
                                            "Stolons",
                                            "Erreur lors de la génération de la facture Stolons",
                                            "Message d'erreur : " + exept.Message);
            }

            // => Producer, send mails
            foreach (var bill in producerBills)
            {
                Task.Factory.StartNew(() => { GenerateOrderPdfAndSendEmail(bill); });
            }

            //Bills (save bills and send mails to user)
            foreach (var bill in consumerBills)
            {
                Task.Factory.StartNew(() => { GenerateOrderPdfAndSendEmail(bill); });
            }
        }
Example #11
0
        public IActionResult ValidateBasket(string basketId)
        {
            var    adherentStolon = GetActiveAdherentStolon();
            Stolon stolon         = GetCurrentStolon();

            if (stolon.GetMode() == Stolon.Modes.DeliveryAndStockUpdate)
            {
                return(Redirect("Index"));
            }
            //TempWeekBasket tempWeekBasket = _context.TempsWeekBaskets.Include(x => x.BillEntries).Include(x => x.AdherentStolon).AsNoTracking().FirstOrDefault(x => x.Id.ToString() == basketId);
            //tempWeekBasket.RetrieveProducts(_context);
            ValidatedWeekBasket validatedWeekBasket = _context.ValidatedWeekBaskets.Include(x => x.AdherentStolon).ThenInclude(x => x.Adherent).Include(x => x.BillEntries).FirstOrDefault(x => x.AdherentStolonId == adherentStolon.Id);

            if (validatedWeekBasket == null)
            {
                //First validation of the week
                validatedWeekBasket = new ValidatedWeekBasket
                {
                    BillEntries    = new List <BillEntry>(),
                    AdherentStolon = adherentStolon
                };
                _context.Add(validatedWeekBasket);
                _context.SaveChanges();
            }
            else
            {
                validatedWeekBasket.RetrieveProducts(_context);
            }
            TempWeekBasket tempWeekBasket = _context.TempsWeekBaskets.Include(x => x.BillEntries).Include(x => x.AdherentStolon).FirstOrDefault(x => x.Id.ToString() == basketId);

            tempWeekBasket.RetrieveProducts(_context);
            //TODO LOCK to prevent multi insert at this moment ?
            if (tempWeekBasket.BillEntries.Any())
            {
                List <BillEntry> rejectedEntries = new List <BillEntry>();
                //Sauvegarde des produits déja validés
                List <BillEntry> previousBillEntries = validatedWeekBasket.BillEntries;
                //On met le panier validé dans le même état que le temporaire
                validatedWeekBasket.BillEntries = new List <BillEntry>();
                foreach (BillEntry billEntry in tempWeekBasket.BillEntries.ToList())
                {
                    validatedWeekBasket.BillEntries.Add(billEntry.Clone());
                }

                //Gestion de la suppression et du changement de quantité sur des billEntry existantes
                foreach (BillEntry prevEntry in previousBillEntries)
                {
                    BillEntry          newEntry     = validatedWeekBasket.BillEntries.FirstOrDefault(x => x.ProductStockId == prevEntry.ProductStockId);
                    ProductStockStolon productStock = _context.ProductsStocks.Include(x => x.Product).Include(x => x.AdherentStolon).Single(x => x.Id == prevEntry.ProductStockId);

                    if (newEntry == null)
                    {
                        //produit supprimé du panier
                        UpdateProductStock(productStock, prevEntry.Quantity);
                    }
                    else
                    {
                        int     qtyDiff   = newEntry.Quantity - prevEntry.Quantity;
                        decimal stepStock = productStock.RemainingStock;
                        if (productStock.Product.Type != Product.SellType.Piece)
                        {
                            //Actual remaining stock in terms of quantity step Kg/L for weight type products
                            stepStock = (productStock.RemainingStock / productStock.Product.QuantityStep) * 1000.0M;
                        }
                        if (stepStock < qtyDiff && productStock.Product.StockManagement != Product.StockType.Unlimited)
                        {
                            //Stock insuffisant, on supprime la nouvelle ligne et on garde l'ancienne
                            validatedWeekBasket.BillEntries.Remove(newEntry);
                            validatedWeekBasket.BillEntries.Add(prevEntry);
                            rejectedEntries.Add(newEntry);
                        }
                        else
                        {
                            UpdateProductStock(productStock, -qtyDiff);
                            //On supprime la bill entry précédente ( ancienne bill entry)
                            _context.BillEntrys.Remove(prevEntry);
                        }
                    }
                }

                //Gestion de l'ajout de produits
                foreach (BillEntry newEntry in validatedWeekBasket.BillEntries.ToList())
                {
                    BillEntry prevEntry = previousBillEntries.FirstOrDefault(x => x.ProductStockId == newEntry.ProductStockId);

                    if (prevEntry == null)
                    {
                        //Nouveau produit
                        ProductStockStolon productStock = _context.ProductsStocks.Include(x => x.Product).Include(x => x.AdherentStolon).Single(x => x.Id == newEntry.ProductStockId);

                        decimal stepStock = productStock.RemainingStock;
                        if (productStock.Product.Type != Product.SellType.Piece)
                        {
                            stepStock = (productStock.RemainingStock / productStock.Product.QuantityStep) * 1000.0M;
                        }
                        if (newEntry.Quantity <= stepStock || productStock.Product.StockManagement == Product.StockType.Unlimited)
                        {
                            //product.RemainingStock -= newEntry.Quantity;
                            UpdateProductStock(productStock, -newEntry.Quantity);
                        }
                        else
                        {
                            validatedWeekBasket.BillEntries.Remove(newEntry);
                            rejectedEntries.Add(newEntry);
                        }
                    }
                }

                _context.SaveChanges();
                //On supprime toute les BillEntry du tempWeekBasket
                _context.BillEntrys.RemoveRange(_context.BillEntrys.Where(x => x.TempWeekBasketId == tempWeekBasket.Id).ToList());
                _context.SaveChanges();
                //On met le panier temporaire dans le même état que le validé
                foreach (BillEntry entry in validatedWeekBasket.BillEntries)
                {
                    tempWeekBasket.BillEntries.Add(entry.Clone());
                }
                tempWeekBasket.Validated = true;

                _context.SaveChanges();
                //END LOCK TODO

                //Recuperation du detail produit pour utilisation dans la Vue
                validatedWeekBasket.RetrieveProducts(_context);

                //Send email to user
                string subject;
                if (rejectedEntries.Count == 0)
                {
                    subject = "Validation de votre panier de la semaine";
                }
                else
                {
                    subject = "Validation partielle de votre panier de la semaine";
                }
                ValidationSummaryViewModel validationSummaryViewModel = new ValidationSummaryViewModel(adherentStolon, validatedWeekBasket, rejectedEntries)
                {
                    Total = GetBasketPrice(validatedWeekBasket)
                };
                Services.AuthMessageSender.SendEmail(adherentStolon.Stolon.Label, validatedWeekBasket.AdherentStolon.Adherent.Email, validatedWeekBasket.AdherentStolon.Adherent.Name, subject, base.RenderPartialViewToString("Templates/ValidatedBasketTemplate", validationSummaryViewModel));
                //Return view
                return(View("ValidatedBasket", validationSummaryViewModel));
            }
            else
            {
                //On annule tout le contenu du panier
                foreach (BillEntry entry in validatedWeekBasket.BillEntries)
                {
                    ProductStockStolon productStock = _context.ProductsStocks.Include(x => x.Product).Include(x => x.AdherentStolon).Single(x => x.Id == entry.ProductStockId);
                    UpdateProductStock(productStock, entry.Quantity);
                    //entry.Product.RemainingStock += entry.Quantity;
                }
                _context.Remove(tempWeekBasket);
                _context.Remove(validatedWeekBasket);
                _context.SaveChanges();

                //Il ne commande rien du tout
                //On lui signale
                Services.AuthMessageSender.SendEmail(stolon.Label, validatedWeekBasket.AdherentStolon.Adherent.Email, validatedWeekBasket.AdherentStolon.Adherent.Name, "Panier de la semaine annulé", base.RenderPartialViewToString("Templates/ValidatedBasketTemplate", null));
            }
            return(View("ValidatedBasket"));
        }
Example #12
0
 public BillEntryViewModel(BillEntry objBillEntry)
 {
     this.ProductName = objBillEntry.ProductName;
     this.Quantity    = objBillEntry.Quantity;
     this.Price       = objBillEntry.Price;
 }
Example #13
0
        public void ProcessRequest(HttpContext objHttpContext)
        {
            string strJSON   = new StreamReader(objHttpContext.Request.InputStream).ReadToEnd();
            string strAction = objHttpContext.Request.QueryString["Action"];

            if (strAction.Equals("Create"))
            {
                try
                {
                    ViewBill objViewBill = JsonConvert.DeserializeObject <ViewBill>(strJSON);

                    ApplicationDBContext objApplicationDBContext = new ApplicationDBContext();

                    int nCurrentUserID = SessionManager.GetCurrentUser().UserID;

                    Models.User objUser = objApplicationDBContext
                                          .Users
                                          .Include("Bills")
                                          .Where(x => x.UserID == nCurrentUserID).FirstOrDefault();

                    List <ProductCategory> listProductCategory = objApplicationDBContext
                                                                 .ProductCategories
                                                                 .Where(x => x.UserOwnerId == nCurrentUserID)
                                                                 .ToList();

                    List <BillEntry> listBillEntry = new List <BillEntry>();

                    foreach (ViewProduct objViewProduct in objViewBill.Products)
                    {
                        listBillEntry.Add(new BillEntry()
                        {
                            Category         = listProductCategory.Find(x => x.ProductCategoryID == objViewProduct.ProductCategoryID),
                            Price            = objViewProduct.Price,
                            ProductName      = objViewProduct.ProductName,
                            Quantity         = objViewProduct.Quantity,
                            LastModifiedDate = DateTime.Now
                        });
                    }

                    Bill objBill = new Bill()
                    {
                        PurchaseDate     = objViewBill.PurchaseDate,
                        Entries          = listBillEntry,
                        LastModifiedDate = DateTime.Now
                    };

                    AssignShopToBill(objApplicationDBContext, ref objBill, objViewBill, nCurrentUserID);

                    objUser.Bills.Add(objBill);
                    objApplicationDBContext.SaveChanges();

                    // update cache
                    User objUserSession = SessionManager.GetCurrentUser();
                    objUserSession.Bills.Add(objBill);
                    SessionManager.SetCurrentUser(objUserSession);

                    // nulls to avoid json recursion exception
                    // this data will be not used anyway
                    objBill.Shop.UserOwner = null;
                    for (int i = 0; i < objBill.Entries.Count; i++)
                    {
                        if (objBill.Entries[i].Category != null)
                        {
                            objBill.Entries[i].Category.UserOwner = null;
                        }
                    }

                    objHttpContext.Response.ContentType = "application/json";
                    objHttpContext.Response.Write(JsonConvert.SerializeObject(
                                                      new Response()
                    {
                        Success           = true,
                        Message           = "OK",
                        Bill              = objBill,
                        NewPriceFormatted = objBill.Entries.Sum(x => x.Price).ToString("C", new System.Globalization.CultureInfo("pl-PL")),
                        NewProductsCount  = objBill.Entries.Count,
                        NewShopName       = objBill.Shop.ShopName
                    }));
                }
                catch (Exception ex)
                {
                    objHttpContext.Response.ContentType = "application/json";
                    objHttpContext.Response.Write(JsonConvert.SerializeObject(new Response()
                    {
                        Success = false, Message = ex.ToString()
                    }));
                }
            }
            else if (strAction.Equals("Edit"))
            {
                try
                {
                    ViewBill objViewBill = JsonConvert.DeserializeObject <ViewBill>(strJSON);

                    ApplicationDBContext objApplicationDBContext = new ApplicationDBContext();

                    Bill objBill = objApplicationDBContext
                                   .Bills
                                   .Include("Entries")
                                   .Include("Shop")
                                   .Include("Entries.Category")
                                   .Where(x => x.BillID == objViewBill.BillID)
                                   .FirstOrDefault();

                    if (objBill != null)
                    {
                        int nCurrentUserID = SessionManager.GetCurrentUser().UserID;

                        List <ProductCategory> listProductCategory = objApplicationDBContext
                                                                     .ProductCategories
                                                                     .Where(x => x.UserOwnerId == nCurrentUserID)
                                                                     .ToList();

                        objBill.PurchaseDate     = objViewBill.PurchaseDate;
                        objBill.LastModifiedDate = DateTime.Now;
                        AssignShopToBill(objApplicationDBContext, ref objBill, objViewBill, nCurrentUserID);

                        // remove deleted entries
                        objBill.Entries.RemoveAll(x => !objViewBill.Products.Select(y => y.ProductID).Contains(x.BillEntryID));

                        for (int i = 0; i < objViewBill.Products.Count; i++)
                        {
                            BillEntry objBillEntryToUpdate = objBill.Entries.Find(x => x.BillEntryID == objViewBill.Products[i].ProductID);

                            if (objBillEntryToUpdate == null)
                            {
                                objBill.Entries.Add(new BillEntry()
                                {
                                    Category         = listProductCategory.Find(x => x.ProductCategoryID == objViewBill.Products[i].ProductCategoryID),
                                    ProductName      = objViewBill.Products[i].ProductName,
                                    Quantity         = objViewBill.Products[i].Quantity,
                                    Price            = objViewBill.Products[i].Price,
                                    LastModifiedDate = DateTime.Now
                                });
                            }
                            else
                            {
                                objBillEntryToUpdate.Category         = listProductCategory.Find(x => x.ProductCategoryID == objViewBill.Products[i].ProductCategoryID);
                                objBillEntryToUpdate.ProductName      = objViewBill.Products[i].ProductName;
                                objBillEntryToUpdate.Quantity         = objViewBill.Products[i].Quantity;
                                objBillEntryToUpdate.Price            = objViewBill.Products[i].Price;
                                objBillEntryToUpdate.LastModifiedDate = DateTime.Now;
                            }
                        }

                        objApplicationDBContext.SaveChanges();

                        // update cache
                        User objUser = SessionManager.GetCurrentUser();
                        int  nIndex  = objUser.Bills.FindIndex(x => x.BillID == objBill.BillID);
                        objUser.Bills[nIndex] = objBill;
                        SessionManager.SetCurrentUser(objUser);
                    }

                    // nulls to avoid json recursion exception
                    // this data will be not used anyway
                    objBill.Shop.UserOwner = null;
                    for (int i = 0; i < objBill.Entries.Count; i++)
                    {
                        if (objBill.Entries[i].Category != null)
                        {
                            objBill.Entries[i].Category.UserOwner = null;
                        }
                    }

                    objHttpContext.Response.ContentType = "application/json";
                    objHttpContext.Response.Write(JsonConvert.SerializeObject(new Response()
                    {
                        Success           = true,
                        Message           = "OK",
                        Bill              = objBill,
                        NewPriceFormatted = objBill.Entries.Sum(x => x.Price).ToString("C", new System.Globalization.CultureInfo("pl-PL")),
                        NewProductsCount  = objBill.Entries.Count,
                        NewShopName       = objBill.Shop.ShopName
                    }));
                }
                catch (Exception ex)
                {
                    objHttpContext.Response.ContentType = "application/json";
                    objHttpContext.Response.Write(JsonConvert.SerializeObject(new Response()
                    {
                        Success = false, Message = ex.ToString()
                    }));
                }
            }
            else if (strAction.Equals("Delete"))
            {
                ViewBill objViewBill = JsonConvert.DeserializeObject <ViewBill>(strJSON);

                User objUser = SessionManager.GetCurrentUser();
                int  nIndex  = objUser.Bills.FindIndex(x => x.BillID == objViewBill.BillID);

                objHttpContext.Response.ContentType = "application/json";

                if (nIndex != -1)
                {
                    ApplicationDBContext objApplicationDBContext = new ApplicationDBContext();

                    Bill objBillToDelete = objApplicationDBContext
                                           .Bills
                                           .Include("Entries")
                                           .Where(x => x.BillID == objViewBill.BillID)
                                           .FirstOrDefault();

                    if (objBillToDelete != null)
                    {
                        objApplicationDBContext.BillEntries.RemoveRange(objBillToDelete.Entries);
                        objApplicationDBContext.Bills.Remove(objBillToDelete);
                        objApplicationDBContext.SaveChanges();
                    }

                    objUser.Bills.RemoveAt(nIndex);
                    SessionManager.SetCurrentUser(objUser);

                    objHttpContext.Response.Write(JsonConvert.SerializeObject(new Response()
                    {
                        Success = true
                    }));
                }
                else
                {
                    objHttpContext.Response.Write(JsonConvert.SerializeObject(new Response()
                    {
                        Success = false
                    }));
                }
            }
            else if (strAction.Equals("Get"))
            {
                User objUser = SessionManager.GetCurrentUser();
                int  nBillID = Convert.ToInt32(objHttpContext.Request.QueryString["BillID"]);
                Bill objBill = objUser.Bills.Where(x => x.BillID == nBillID).FirstOrDefault();
                objHttpContext.Response.ContentType = "application/json";

                // nulls to avoid json recursion exception
                // this data will be not used anyway
                objBill.Shop.UserOwner = null;
                for (int i = 0; i < objBill.Entries.Count; i++)
                {
                    if (objBill.Entries[i].Category != null)
                    {
                        objBill.Entries[i].Category.UserOwner = null;
                    }
                }

                objHttpContext.Response.Write(JsonConvert.SerializeObject(new Response()
                {
                    Success = objBill != null,
                    Bill    = objBill
                }
                                                                          ));
            }
        }