public ActionResult ArchiveConfirmed(int id)
        {
            Company company = db.Companies.Find(id);
            company.CompanyStatus = MyExtensions.GetEnumDescription(Status.Archived);

            // Add Audit Entry
            AuditTrail audit = new AuditTrail(DateTime.Now, User.Identity.Name, company, company.CompanyID, "Archive");
            db.AuditTrails.Add(audit);

            db.Entry(company).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        public ActionResult ArchiveConfirmed(int id)
        {
            PackagingType packagingtype = db.PackagingTypes.Find(id);

            // Add Audit Entry
            AuditTrail audit = new AuditTrail(DateTime.Now, User.Identity.Name, packagingtype, packagingtype.PackagingTypeID, "Archive");
            db.AuditTrails.Add(audit);

            // Archive
            packagingtype.PackagingTypeStatus = MyExtensions.GetEnumDescription(Status.Archived);
            db.Entry(packagingtype).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        public ActionResult ArchiveConfirmed(int id)
        {
            MajorCategoryOrdering majorcategoryordering = db.MajorCategoryOrderings.Find(id);

            // Add Audit Entry
            AuditTrail audit = new AuditTrail(DateTime.Now, User.Identity.Name, majorcategoryordering, majorcategoryordering.ID, "Archive");
            db.AuditTrails.Add(audit);

            // Archive
            majorcategoryordering.Status = MyExtensions.GetEnumDescription(Status.Archived);
            db.Entry(majorcategoryordering).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        public ActionResult ArchiveConfirmed(int id)
        {
            VendorType vendortype = db.VendorTypes.Find(id);

            // Add Audit Entry
            AuditTrail audit = new AuditTrail(DateTime.Now, User.Identity.Name, vendortype, id, "Archive");
            db.AuditTrails.Add(audit);

            // Archive
            vendortype.VendorTypeStatus = archived;
            db.Entry(vendortype).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        public ActionResult ArchiveConfirmed(int id)
        {
            DecorationMethod decorationmethod = db.DecorationMethods.Find(id);

            // Add Audit Entry
            AuditTrail audit = new AuditTrail(DateTime.Now, User.Identity.Name, decorationmethod, id, "Archive");
            db.AuditTrails.Add(audit);

            // Archive
            decorationmethod.DecorationMethodStatus = MyExtensions.GetEnumDescription(Status.Archived);
            db.Entry(decorationmethod).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        public ActionResult ArchiveConfirmed(int id)
        {
            ProductDecoration productdecoration = db.ProductDecorations.Find(id);

            // Add Audit Entry
            AuditTrail audit = new AuditTrail(DateTime.Now, User.Identity.Name, productdecoration, id, "Archive");
            db.AuditTrails.Add(audit);

            // Archive
            productdecoration.DecorationStatus = MyExtensions.GetEnumDescription(Status.Archived);
            db.Entry(productdecoration).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        public ActionResult ArchiveConfirm(int id)
        {
            ProductDocument productDocument = db.ProductDocuments.Find(id);

            // Add Audit Entry
            AuditTrail audit = new AuditTrail(DateTime.Now, User.Identity.Name, productDocument, id, "Archive");
            db.AuditTrails.Add(audit);

            // Archive
            productDocument.Status = archived;
            db.Entry(productDocument).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        public ActionResult Create(Category category)
        {
            if (ModelState.IsValid)
            {
                // Add Audit Entry
                AuditTrail audit = new AuditTrail(DateTime.Now, User.Identity.Name, category, category.CategoryID, "Create");
                db.AuditTrails.Add(audit);

                db.Categories.Add(category);
                db.SaveChanges();
                return RedirectToAction("Index");
            }

            return View(category);
        }
        public ActionResult Create(PackagingType packagingtype)
        {
            if(ModelState.IsValid)
            {
                // Add Audit Entry
                AuditTrail audit = new AuditTrail(DateTime.Now, User.Identity.Name, packagingtype, packagingtype.PackagingTypeID, "Create");
                db.AuditTrails.Add(audit);

                db.PackagingTypes.Add(packagingtype);
                db.SaveChanges();
                return RedirectToAction("Index");
            }

            return View(packagingtype);
        }
        public ActionResult ArchiveConfirmed(int id, string returnUrl)
        {
            PricingTier pricingtier = db.PricingTiers.Find(id);

            // Add Audit Entry
            AuditTrail audit = new AuditTrail(DateTime.Now, User.Identity.Name, pricingtier, pricingtier.PricingTierID, "Archive");
            db.AuditTrails.Add(audit);

            //Archive
            pricingtier.PricingTierStatus = MyExtensions.GetEnumDescription(Status.Archived);
            db.Entry(pricingtier).State = EntityState.Modified;
            db.SaveChanges();

            if(returnUrl == null)
            {
                return RedirectToAction("Index");
            }
            return Redirect(returnUrl);
        }
        public ActionResult ArchiveConfirmed(int id, string returnUrl)
        {
            Campaign campaign = db.Campaigns.Find(id);

            // TODO: Set status to disabled/hidden and no longer show
            campaign.CampaignStatus = MyExtensions.GetEnumDescription(Status.Archived);

            // Add Audit Entry
            AuditTrail audit = new AuditTrail(DateTime.Now, User.Identity.Name, campaign, campaign.CampaignID, "Archive");
            db.AuditTrails.Add(audit);

            db.Entry(campaign).State = EntityState.Modified;
            db.SaveChanges();

            if (returnUrl == null)
            {
                return RedirectToAction("Index");
            }
            return Redirect(returnUrl);
        }
        public ActionResult Create(ProductDecoration productdecoration)
        {
            if(ModelState.IsValid)
            {
                // Add Audit Entry
                AuditTrail audit = new AuditTrail(DateTime.Now, User.Identity.Name, productdecoration, productdecoration.DecorationID, "Create");
                db.AuditTrails.Add(audit);

                db.ProductDecorations.Add(productdecoration);
                db.SaveChanges();
                return RedirectToAction("Index");
            }

            var productList = db.Products.Where(p => p.ProductStatus != archived &&
                                                p.Campaign.CampaignStatus != archived &&
                                                p.Campaign.Company.CompanyStatus != archived);

            var decorationMethodList = db.DecorationMethods.Where(d => d.DecorationMethodStatus != archived)
                                                            .OrderBy(d => d.DecorationMethodName);

            ViewBag.ProductID = new SelectList(productList, "ProductID", "ProductName", productdecoration.ProductID);
            ViewBag.DecorationMethodID = new SelectList(decorationMethodList, "DecorationMethodID", "DecorationMethodName", productdecoration.DecorationMethodID);
            return View(productdecoration);
        }
        public ActionResult Create(Campaign campaign, string returnUrl)
        {
            if (ModelState.IsValid)
            {
                // Add Audit Entry
                AuditTrail audit = new AuditTrail(DateTime.Now, User.Identity.Name, campaign, campaign.CampaignID, "Create");
                db.AuditTrails.Add(audit);

                db.Campaigns.Add(campaign);
                db.SaveChanges();

                return RedirectToAction("Edit", new { id = campaign.CampaignID, ReturnUrl = returnUrl });
            }

            ViewBag.CompanyID = new SelectList(db.Companies.Where(c => c.CompanyStatus != archived), "CompanyID", "CompanyName", campaign.CompanyID);
            return View(campaign);
        }
        public ActionResult Create([Bind(Exclude = "CompanyImage")]Company company, HttpPostedFileBase CompanyImage, string returnUrl)
        {
            if (ModelState.IsValid)
            {
                if (CompanyImage != null && CompanyImage.ContentLength > 0)
                {
                    byte[] imageBinaryData = new byte[CompanyImage.ContentLength];
                    int readresult = CompanyImage.InputStream.Read(imageBinaryData, 0, CompanyImage.ContentLength);
                    company.CompanyImage = imageBinaryData;
                    company.CompanyImageType = CompanyImage.ContentType;
                }

                // Add Audit Entry
                AuditTrail audit = new AuditTrail(DateTime.Now, User.Identity.Name, company, company.CompanyID, "Create");
                db.AuditTrails.Add(audit);

                db.Companies.Add(company);
                db.SaveChanges();

                return RedirectToAction("Edit", new { id = company.CompanyID, ReturnUrl = returnUrl });
            }

            return View(company);
        }
        public ActionResult Create(DecorationMethod decorationmethod)
        {
            if(ModelState.IsValid)
            {
                // Add Audit Entry
                AuditTrail audit = new AuditTrail(DateTime.Now, User.Identity.Name, decorationmethod, decorationmethod.DecorationMethodID, "Create");
                db.AuditTrails.Add(audit);

                db.DecorationMethods.Add(decorationmethod);
                db.SaveChanges();
                return RedirectToAction("Index");
            }

            return View(decorationmethod);
        }
        public ActionResult SaveAndUpdateMargins(Company company, HttpPostedFileBase CompanyImage)
        {
            string preSaveStatus = db.Companies.Where(c => c.CompanyID == company.CompanyID).Select(c => c.CompanyStatus).FirstOrDefault();

            if (ModelState.IsValid)
            {
                if (CompanyImage != null && CompanyImage.ContentLength > 0)
                {
                    byte[] imageBinaryData = new byte[CompanyImage.ContentLength];
                    int readresult = CompanyImage.InputStream.Read(imageBinaryData, 0, CompanyImage.ContentLength);
                    company.CompanyImage = imageBinaryData;
                    company.CompanyImageType = CompanyImage.ContentType;
                }

                // Add Audit Entry
                AuditTrail audit = new AuditTrail(DateTime.Now, User.Identity.Name, company, company.CompanyID, "Edit");
                db.AuditTrails.Add(audit);

                //Update Margins
                MyExtensions.UpdateActiveMarginsBasedOnCompany(db.Companies.Where(c => c.CompanyID == company.CompanyID).FirstOrDefault(), company.CompanyDefaultMargin, ref db);

                // Send Emails
                #region SendEmails
                // Check previous status
                if (preSaveStatus != company.CompanyStatus)
                {
                    List<EmailTo> sendEmailTos = MyExtensions.GetEmailTo(company.CompanyStatus);
                    var urlBuilder = Request.Url.AbsoluteUri;
                    if (sendEmailTos != null && sendEmailTos.Count > 0)
                    {
                        UserMailer.SendStatusUpdate(sendEmailTos, "Company Updated by: " + MyExtensions.DisplayPrintFriendlyName(User.Identity.Name), urlBuilder.ToString(), company, null, null).Send();
                    }
                }
                #endregion

                var current = db.Companies.Find(company.CompanyID);
                db.Entry(current).CurrentValues.SetValues(company);
                db.SaveChanges();
                return RedirectToAction("Edit", new { id = company.CompanyID });
            }
            return View(company);
        }
        public ActionResult Edit(FeeName feename)
        {
            if (ModelState.IsValid)
            {
                // Add Audit Entry
                AuditTrail audit = new AuditTrail(DateTime.Now, User.Identity.Name, feename, feename.FeeNameID, "Edit");
                db.AuditTrails.Add(audit);

                var current = db.FeeNames.Find(feename.FeeNameID);
                db.Entry(current).CurrentValues.SetValues(feename);
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            return View(feename);
        }
        public ActionResult Create([Bind(Exclude = "ProductImage")]Product product, HttpPostedFileBase ProductImage, string returnUrl)
        {
            if (product.ProductInitialOrderQuantity == null)
            {
                product.ProductInitialOrderQuantity = (decimal?)0;
            }
            if (product.ProductGatewayCDIMinumumOrder == null)
            {
                product.ProductGatewayCDIMinumumOrder = (decimal?)0;
            }
            if (ModelState.IsValid)
            {
                // Get product's campaign and loop though that campaigns, companies price tiers
                Campaign thisCampaign = db.Campaigns.Where(c => c.CampaignID == product.CampaignID).FirstOrDefault();
                foreach (var tier in thisCampaign.Company.PricingTiers.Where(p => p.PricingTierStatus != MyExtensions.GetEnumDescription(Status.Archived)))
                {
                    // Create a new sell price for each price tier and add to DB
                    ProductSellPrice newSellPrice = new ProductSellPrice(product, tier.PricingTierName, tier.PricingTierLevel, (decimal)thisCampaign.Company.CompanyDefaultMargin);
                    db.ProductSellPrices.Add(newSellPrice);

                    // Attach fees
                    foreach (var fee in tier.Fees.Where(f => f.FeeStatus != MyExtensions.GetEnumDescription(Status.Archived)))
                    {
                        Fee newFee = new Fee(fee.FeeNameID, newSellPrice, fee.FeeType, fee.FeeCalculation, fee.FeeDollarAmount, fee.FeeAmortizedCharge, fee.FeeAmortizedType, fee.FeePercent, fee.FeePercentType, fee.FeeID);
                        db.Fees.Add(newFee);
                    }
                }

                // Loop though Attachment Types and add a ProductAttachmentType for each Attachment Type
                foreach (var attachmentType in db.AttachmentTypes.Where(a => a.Status != archived).OrderBy(a => a.TypeName))
                {
                    // Create a Product Attament type
                    ProductAttachmentType newProductAttachmentType = new ProductAttachmentType(product.ProductID, attachmentType.ID);
                    db.ProductAttachmentTypes.Add(newProductAttachmentType);
                }

                // Product Image
                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;
                }

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

                db.Products.Add(product);
                db.SaveChanges();

                if (returnUrl == null)
                {
                    return RedirectToAction("Index");
                }
                return RedirectToAction("Edit", new { id = product.ProductID, ReturnUrl = returnUrl });
            }

            // Sets Viewbag data for dropdowns
            SetViewBagData(returnUrl, product);

            return View(product);
        }
        public ActionResult Edit(AttachmentType AttachmentType)
        {
            if (ModelState.IsValid)
            {
                // Add Audit Entry
                AuditTrail audit = new AuditTrail(DateTime.Now, User.Identity.Name, AttachmentType, AttachmentType.ID, "Edit");
                db.AuditTrails.Add(audit);

                db.Entry(AttachmentType).State = EntityState.Modified;
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            return View(AttachmentType);
        }
        public ActionResult Create(FeeName feename, string returnUrl)
        {
            if (ModelState.IsValid)
            {
                // Add Audit Entry
                AuditTrail audit = new AuditTrail(DateTime.Now, User.Identity.Name, feename, feename.FeeNameID, "Create");
                db.AuditTrails.Add(audit);

                db.FeeNames.Add(feename);
                db.SaveChanges();

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

            return View(feename);
        }
        public ActionResult UnArchiveConfirmed(int id, string returnUrl)
        {
            Product product = db.Products.Find(id);

            // Archive Product
            product.ProductStatus = MyExtensions.GetEnumDescription(Status.Active);
            db.Entry(product).State = EntityState.Modified;

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

            db.SaveChanges();

            if (returnUrl == null)
            {
                return RedirectToAction("Index");
            }
            return Redirect(returnUrl);
        }
        public ActionResult Create([Bind(Exclude = "Document")]ProductDocument productDocument, HttpPostedFileBase Document)
        {
            if (ModelState.IsValid)
            {
                // Add Audit Entry
                AuditTrail audit = new AuditTrail(DateTime.Now, User.Identity.Name, productDocument, productDocument.ID, "Create");
                db.AuditTrails.Add(audit);

                // Document
                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;
                }

                db.ProductDocuments.Add(productDocument);
                db.SaveChanges();
                return RedirectToAction("Index");
            }

            SetViewBagData(productDocument);
            return View(productDocument);
        }
        public ActionResult Create(ProductAttachmentType productAttachmentType)
        {
            if (ModelState.IsValid)
            {
                // Add Audit Entry
                AuditTrail audit = new AuditTrail(DateTime.Now, User.Identity.Name, productAttachmentType, productAttachmentType.ID, "Create");
                db.AuditTrails.Add(audit);

                db.ProductAttachmentTypes.Add(productAttachmentType);
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            SetViewBagData(productAttachmentType);
            return View(productAttachmentType);
        }
        public ActionResult Create(PricingTier pricingtier, string returnUrl)
        {
            if (ModelState.IsValid)
            {
                // Add Audit Entry
                AuditTrail audit = new AuditTrail(DateTime.Now, User.Identity.Name, pricingtier, pricingtier.PricingTierID, "Create");
                db.AuditTrails.Add(audit);

                db.PricingTiers.Add(pricingtier);
                db.SaveChanges();

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

            ViewBag.CompanyID = new SelectList(db.Companies.Where(c => c.CompanyStatus != archived), "CompanyID", "CompanyName", pricingtier.CompanyID);
            return View(pricingtier);
        }
        public ActionResult Edit(Campaign campaign, string returnUrl)
        {
            string preSaveStatus = db.Campaigns.Where(c => c.CampaignID == campaign.CampaignID).Select(c => c.CampaignStatus).FirstOrDefault();

            if (ModelState.IsValid)
            {
                // Add Audit Entry
                AuditTrail audit = new AuditTrail(DateTime.Now, User.Identity.Name, campaign, campaign.CampaignID, "Edit");
                db.AuditTrails.Add(audit);

                // Send Emails
                #region SendEmails
                // Check if the status is changed
                if (preSaveStatus != campaign.CampaignStatus)
                {
                    List<EmailTo> sendEmailTos = MyExtensions.GetEmailTo(campaign.CampaignStatus);
                    var urlBuilder = Request.Url.AbsoluteUri;

                    if (sendEmailTos != null && sendEmailTos.Count > 0)
                    {
                        UserMailer.SendStatusUpdate(sendEmailTos, "Company Updated by: " + MyExtensions.DisplayPrintFriendlyName(User.Identity.Name), urlBuilder.ToString(), db.Companies.Where(c => c.CompanyID == campaign.CompanyID).FirstOrDefault(), campaign, null).Send();
                    }
                }
                #endregion

                // Save entry into DB
                var current = db.Campaigns.Find(campaign.CampaignID);
                db.Entry(current).CurrentValues.SetValues(campaign);
                db.SaveChanges();

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

                return Redirect(returnUrl);
            }

            ViewBag.CompanyID = new SelectList(db.Companies.Where(c => c.CompanyStatus != archived), "CompanyID", "CompanyName", campaign.CompanyID);
            return View(campaign);
        }
        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 Edit(DecorationMethod decorationmethod)
        {
            if(ModelState.IsValid)
            {
                // Add Audit Entry
                AuditTrail audit = new AuditTrail(DateTime.Now, User.Identity.Name, decorationmethod, decorationmethod.DecorationMethodID, "Edit");
                db.AuditTrails.Add(audit);

                var current = db.DecorationMethods.Find(decorationmethod.DecorationMethodID);
                db.Entry(current).CurrentValues.SetValues(decorationmethod);
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            return View(decorationmethod);
        }
        public ActionResult Edit(PackagingType packagingtype)
        {
            if(ModelState.IsValid)
            {
                // Add Audit Entry
                AuditTrail audit = new AuditTrail(DateTime.Now, User.Identity.Name, packagingtype, packagingtype.PackagingTypeID, "Edit");
                db.AuditTrails.Add(audit);

                var current = db.PackagingTypes.Find(packagingtype.PackagingTypeID);
                db.Entry(current).CurrentValues.SetValues(packagingtype);
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            return View(packagingtype);
        }