//
        // GET: /UpchargeSellPrice/Create
        public ActionResult Create()
        {
            ViewBag.UpchargeID = new SelectList(db.ProductUpcharges, "UpchargeID", "UpchargeName");

            // Generate Decoration method for member initialization
            UpchargeSellPrice upchargeSellPrice = new UpchargeSellPrice();
            upchargeSellPrice .OnCreate();

            return View(upchargeSellPrice);
        }
        public ActionResult Create(UpchargeSellPrice upchargesellprice)
        {
            if(ModelState.IsValid)
            {
                db.UpchargeSellPrices.Add(upchargesellprice);
                db.SaveChanges();
                return RedirectToAction("Index");
            }

            ViewBag.UpchargeID = new SelectList(db.ProductUpcharges.Where(p => p.UpchargeStatus != archived), "UpchargeID", "UpchargeName", upchargesellprice.UpchargeID);
            return View(upchargesellprice);
        }
        // UpchargeSellPrice
        public AuditTrail(DateTime dateTime, string userName, UpchargeSellPrice upchargeSellPrice, int id, string comment)
        {
            this.AuditTrailTimeStamp = dateTime;
            this.AuditTrailUserName = userName;
            this.AuditTrailComment = comment;

            if(id > 0)
            {
                this.UpchargeSellPriceID = id;
            }
            else
            {
                this.UpchargeSellPrice = upchargeSellPrice;
            }
        }
        public ActionResult SaveAndCalculateSellPriceToNearestFiveCents(Product product, HttpPostedFileBase ProductImage, HttpPostedFileBase DecorationImage, IEnumerable<HttpPostedFileBase> Documents, string returnUrl)
        {
            // Sets Viewbag data for dropdowns
            SetViewBagData(returnUrl, product);
            string preSaveStatus = db.Products.Where(p => p.ProductID == product.ProductID).Select(p => p.ProductStatus).FirstOrDefault();

            if (ModelState.IsValid)
            {
                int idIndex = -100;
                foreach (var fee in product.Fees)
                {
                    // IF it's a new fee
                    if (fee.FeeID <= 0)
                    {
                        fee.FeeID = idIndex;
                        idIndex++;
                    }
                }
                foreach (var upcharge in product.ProductUpcharges)
                {
                    if (upcharge.UpchargeID <= 0)
                    {
                        upcharge.UpchargeID = idIndex;
                        idIndex++;
                    }
                }

                foreach (var productDocument in product.ProductDocuments)
                {
                    // if it's a new document
                    if (productDocument.ID <= 0)
                    {
                        productDocument.ID = idIndex;
                        idIndex++;
                    }
                }

                db.Entry(product).State = EntityState.Modified;

                // Remove Fees
                var Fees = product.Fees.ToList();
                foreach (var fee in db.Fees.Where(p => p.ProductID == product.ProductID))
                {
                    if (!Fees.Contains(fee))
                    {
                        fee.FeeStatus = MyExtensions.GetEnumDescription(Status.Archived);
                        db.Entry(fee).State = EntityState.Modified; ;
                    }
                }

                // Remove Upcharges
                var Upcharges = product.ProductUpcharges.ToList();
                foreach (var upcharge in db.ProductUpcharges.Where(p => p.ProductID == product.ProductID))
                {
                    if (!Upcharges.Contains(upcharge))
                    {
                        upcharge.UpchargeStatus = MyExtensions.GetEnumDescription(Status.Archived);
                        db.Entry(upcharge).State = EntityState.Modified; ;
                    }
                }

                // Add/Update Fees
                foreach (var fee in product.Fees)
                {
                    // IF it's a new fee
                    if (fee.FeeID <= 0)
                    {
                        // Create a new Fee
                        db.Fees.Add(fee);
                    }
                    else
                    {
                        // Else update existing Fee
                        db.Entry(fee).State = EntityState.Modified;
                    }
                }

                // update  SellPriceFees
                foreach (var sellPrice in product.ProductSellPrices)
                {
                    // Update sellprice
                    db.Entry(sellPrice).State = EntityState.Modified;

                    //TODO: add/update/remove SellPriceFees
                    foreach (var fee in sellPrice.Fees)
                    {
                        if (fee.FeeID <= 0)
                        {
                            db.Fees.Add(fee);
                        }
                        else
                        {
                            db.Entry(fee).State = EntityState.Modified;
                        }
                    }
                }

                // Document
                // Remove
                var productDocuments = product.ProductDocuments.ToList();
                foreach (var productDocument in db.ProductDocuments.Where(p => p.ProductID == product.ProductID))
                {
                    if (!productDocuments.Contains(productDocument))
                    {
                        productDocument.Status = archived;
                        db.Entry(productDocument).State = EntityState.Modified;
                    }
                }
                //Files
                if (Documents != null)
                {
                    for (int index = 0; index < Documents.Count(); index++)
                    {
                        var productDocument = product.ProductDocuments.Where(p => p.Status != archived).ElementAt(product.ProductDocuments.Where(p => p.Status != archived).Count() - 1 - index);
                        var Document = Documents.ElementAt(index);
                        // file
                        if (Document != null && Document.ContentLength > 0)
                        {
                            byte[] documentBinaryData = new byte[Document.ContentLength];
                            int readresult = Document.InputStream.Read(documentBinaryData, 0, Document.ContentLength);
                            productDocument.Document = documentBinaryData;
                            productDocument.DocumentFileType = Document.ContentType;
                            productDocument.DocumentFileName = Document.FileName;
                        }
                    }
                }
                // Add/Update
                foreach (var productDocument in product.ProductDocuments)
                {
                    // IF it's a new productDocument
                    if (productDocument.ID <= 0)
                    {
                        // Create a new productDocument
                        db.ProductDocuments.Add(productDocument);
                    }
                    else
                    {
                        // Else update existing productDocument
                        db.Entry(productDocument).State = EntityState.Modified;
                    }
                }

                // update ProductAttachmentTypes
                foreach (var productAttachmentType in product.ProductUpcharges)
                {
                    db.Entry(productAttachmentType).State = EntityState.Modified;
                }

                // update Upcharges
                foreach (var upcharge in product.ProductUpcharges)
                {
                    // IF it's a new Upcharge
                    if (upcharge.UpchargeID <= 0)
                    {
                        // Create a new Upcharge
                        db.ProductUpcharges.Add(upcharge);
                        Product thisProduct = db.Products.Where(p => p.ProductID == product.ProductID).FirstOrDefault();
                        foreach (var sellPrice in thisProduct.ProductSellPrices)
                        {
                            UpchargeSellPrice newUpchargeSellPrice = new UpchargeSellPrice(upcharge, sellPrice.SellPriceName, sellPrice.SellPriceLevel);
                            db.UpchargeSellPrices.Add(newUpchargeSellPrice);
                        }
                    }
                    else
                    {
                        // Else update existing Fee
                        db.Entry(upcharge).State = EntityState.Modified;
                    }

                    //TODO: add/update/remove SellPriceFees
                    foreach (var upchargeSellPrice in upcharge.UpchargeSellPrices)
                    {
                        if (upchargeSellPrice.UpchargeSellPriceID <= 0)
                        {
                            db.UpchargeSellPrices.Add(upchargeSellPrice);
                        }
                        else
                        {
                            db.Entry(upchargeSellPrice).State = EntityState.Modified;
                        }
                    }
                }

                // Decorations
                // Remove
                var decorations = product.ProductDecorations.ToList();
                foreach (var decoration in db.ProductDecorations.Where(p => p.ProductID == product.ProductID))
                {
                    if (!decorations.Contains(decoration))
                    {
                        decoration.DecorationStatus = MyExtensions.GetEnumDescription(Status.Archived);
                        db.Entry(decoration).State = EntityState.Modified;
                    }
                }

                // Add/Update
                foreach (var decoration in product.ProductDecorations)
                {
                    if (DecorationImage != null && DecorationImage.ContentLength > 0)
                    {
                        byte[] imageBinaryData = new byte[DecorationImage.ContentLength];
                        int readresult = DecorationImage.InputStream.Read(imageBinaryData, 0, DecorationImage.ContentLength);
                        decoration.DecorationImage = imageBinaryData;
                        decoration.DecorationImageType = DecorationImage.ContentType;
                    }

                    // IF it's a new fee
                    if (decoration.DecorationID <= 0)
                    {
                        // Create a new Fee
                        db.ProductDecorations.Add(decoration);
                    }
                    else
                    {
                        // Else update existing Fee
                        db.Entry(decoration).State = EntityState.Modified;
                    }
                }

                if (ProductImage != null && ProductImage.ContentLength > 0)
                {
                    byte[] imageBinaryData = new byte[ProductImage.ContentLength];
                    int readresult = ProductImage.InputStream.Read(imageBinaryData, 0, ProductImage.ContentLength);
                    product.ProductImage = imageBinaryData;
                    product.ProductImageType = ProductImage.ContentType;
                }

                // Calculator
                Helpers.FeeCalculator newCalculator = new Helpers.FeeCalculator(product);
                try
                {
                    newCalculator.ComputeAllProductPrices(true);
                    newCalculator.ComputeMarginBasedOnSellprice();
                }
                catch (Exception ex)
                {
                    Console.Write("ProductController.cs SaveAndCalculateSellPriceToNearestFiveCents() ComputeAllProductPrices() failure. Exception: " + ex.ToString());
                }

                // Add Audit Entry
                AuditTrail audit = new AuditTrail(DateTime.Now, User.Identity.Name, product, product.ProductID, "Save and Calculate Prices");
                db.AuditTrails.Add(audit);

                // Send Emails
                #region SendEmails
                // Check previous status
                if (preSaveStatus != product.ProductStatus)
                {
                    List<EmailTo> sendEmailTos = MyExtensions.GetEmailTo(product.ProductStatus);
                    var urlBuilder = new System.UriBuilder(Request.Url.AbsoluteUri) { Path = Url.Action("Edit", "Product") + "/" + product.ProductID, Query = null, };
                    var campaign = db.Campaigns.Where(c => c.CampaignID == product.CampaignID).FirstOrDefault();
                    if (sendEmailTos != null && sendEmailTos.Count > 0)
                    {
                        UserMailer.SendStatusUpdate(sendEmailTos, "Product Updated by: " + MyExtensions.DisplayPrintFriendlyName(User.Identity.Name), urlBuilder.ToString(), db.Companies.Where(c => c.CompanyID == campaign.CompanyID).FirstOrDefault(), campaign, product).Send();
                    }
                }
                #endregion

                db.SaveChanges();

                return RedirectToAction("Edit", new { id = product.ProductID, ReturnUrl = returnUrl });
            }
            else
            {
                int count = 0;
                foreach (var modelStateVal in ModelState.Values)
                {
                    foreach (var error in modelStateVal.Errors)
                    {
                        var errorMessage = error.ErrorMessage;
                        var exception = error.Exception;
                        // You may log the errors if you want
                    }
                    count++;
                }
            }
            // Error
            product.Campaign = db.Campaigns.Where(c => c.CampaignID == product.CampaignID)
                                            .FirstOrDefault();
            return View("Edit", product);
        }
        public ActionResult Create(ProductUpcharge productUpcharge, string returnUrl)
        {
            if (ModelState.IsValid)
            {
                // Get productUpcharge's product and get sell prices
                Product thisProduct = db.Products.Where(p => p.ProductID == productUpcharge.ProductID).FirstOrDefault();
                foreach(var sellPrice in thisProduct.ProductSellPrices)
                {
                    UpchargeSellPrice newUpchargeSellPrice = new UpchargeSellPrice(productUpcharge, sellPrice.SellPriceName, sellPrice.SellPriceLevel);
                    db.UpchargeSellPrices.Add(newUpchargeSellPrice);
                }

                db.ProductUpcharges.Add(productUpcharge);
                db.SaveChanges();

                if(returnUrl == null)
                {
                    return RedirectToAction("Index");
                }
                return Redirect(returnUrl);
            }

            var list = db.Products.Where(p => p.ProductStatus != archived &&
                                                p.Campaign.CampaignStatus != archived &&
                                                p.Campaign.Company.CompanyStatus != archived);
            ViewBag.ProductID = new SelectList(list, "ProductID", "ProductName", productUpcharge.ProductID);
            return View(productUpcharge);
        }