public ActionResult UpdateProduct(ProductModel update)
        {
            SIEBUEntities db = new SIEBUEntities();
            Product target_product = db.Products.FirstOrDefault(p => p.p_id == update.id);

            Product_History history = new Product_History();

            //if no product is found, create one
            bool add_new = false;
            if (target_product == null)
            {
                add_new = true;
                target_product = new Product();
                target_product.dateadded = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time"));
            }

            target_product.lastmodified = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time"));
            history.datemodified = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time"));
            bool change_made = false;
            if (target_product.name != update.name || target_product.sku != update.sku)
            {
                change_made = true;
                history.name = target_product.name;
                history.sku = target_product.sku;
                target_product.name = update.name;
                target_product.sku = update.sku;
            }

            if (!((target_product.cost + target_product.shipping_cost).Equals(update.cost + update.shipping_cost)))
            {
                change_made = true;
                history.cost = target_product.cost;
                history.shipping_cost = target_product.shipping_cost;
                target_product.cost = Convert.ToDecimal(update.cost, CultureInfo.GetCultureInfo("en"));
                target_product.shipping_cost = Convert.ToDecimal(update.shipping_cost, CultureInfo.GetCultureInfo("en"));
            }

            if (target_product.avail_inventory != update.avail_inventory)
            {
                change_made = true;
                history.avail_inventory = target_product.avail_inventory;
                target_product.avail_inventory = update.avail_inventory;
            }

            target_product.short_description = update.short_description;
            target_product.description = update.description;

            if (target_product.status != update.status)
            {
                change_made = true;
                history.status = target_product.status;
                target_product.status = update.status;
            }

            if (target_product.is_featured != update.is_featured)
            {
                change_made = true;
                history.is_featured = target_product.is_featured;
                target_product.is_featured = update.is_featured;
                if (update.is_featured)
                {
                    target_product.featured_since = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time"));
                }
                else
                {
                    target_product.featured_since = null;
                }
            }

            if (add_new)
            {
                target_product.store_id = update.store_id;
                db.Products.Add(target_product);
                db.SaveChanges(); //changes must be saved so that product_id exists for image/tag/history foreign key relationships
            }

            foreach (ProductImageModel pim in update.images)
            {
                Product_Image target_image = db.Product_Image.FirstOrDefault(p => p.pi_id == pim.id);

                //only save up to 8 images per product
                if (db.Product_Image.Count(p => p.product_id == target_product.p_id) <= 8)
                {

                    bool add_new_img = false;
                    if (target_image == null)
                    {
                        add_new_img = true;
                        target_image = new Product_Image();
                    }

                    target_image.product_id = target_product.p_id;
                    target_image.sort = pim.order;

                    //check to make sure update does not match existing content
                    if ((target_image.url == null || !(pim.url + "").Contains(target_image.url)) && pim.url != null)
                    {
                        //if different from original, determine whether value is blank (for purpose of removing images)
                        if (pim.url != null)
                            target_image.url = ImageController.UploadFile(pim.url, target_image.product_id + "" + target_image.pi_id + "" + target_product.lastmodified.Value.ToString("ffffff"));
                        else target_image.url = null;
                    }

                    if (add_new_img) db.Product_Image.Add(target_image);
                }

                if (pim.delete) db.Product_Image.Remove(target_image);
            }

            foreach (ProductTagModel ptm in update.tags)
            {
                //create tag if non-existent
                Tag ref_tag = db.Tags.FirstOrDefault(t => t.caption == ptm.caption.Trim().ToLower());
                if (ref_tag == null)
                {
                    ref_tag = new Tag();
                    ref_tag.caption = ptm.caption.Trim().ToLower();
                    db.Tags.Add(ref_tag);
                    db.SaveChanges();
                }

                //tolower to compare captions
                Product_Tag target_tag = db.Product_Tag.FirstOrDefault(t => t.product_id == update.id && t.Tag.t_id == ref_tag.t_id);
                bool add_new_tag = false;
                if (target_tag == null)
                {
                    add_new_tag = true;
                    target_tag = new Product_Tag();
                }

                target_tag.product_id = target_product.p_id;
                target_tag.tag_id = ref_tag.t_id;

                if (add_new_tag) db.Product_Tag.Add(target_tag);
                if (ptm.delete) db.Product_Tag.Remove(target_tag);
            }

            if (change_made) db.Product_History.Add(history);
            history.product_id = target_product.p_id;

            db.SaveChanges();
            return Json(target_product.p_id, JsonRequestBehavior.AllowGet);
        }
        public CatalogueModel(Product product, SIEBUEntities db = null)
        {
            if (db == null) db = new SIEBUEntities();

            id = product.store_id;
            status = (product.Store.status.HasValue ? product.Store.status.Value : -1);
            category = product.Store.category_id;
            name = product.Store.name;
            description = product.Store.description;
            logo = product.Store.logo;
            banner = product.Store.banner_img;
            background = product.Store.background_img;
            owner_name = product.Store.User.firstName + " " + product.Store.User.lastName;
            store_namespace = product.Store.name_space;
            email = (product.Store.Store_Contact.Count(c => c.Contact.caption == "Email Address") > 0 ? product.Store.Store_Contact.Where(c => c.Contact.caption == "Email Address").FirstOrDefault().value : "");
            website = (product.Store.Store_Contact.Count(c => c.Contact.caption == "Website") > 0 ? product.Store.Store_Contact.Where(c => c.Contact.caption == "Website").FirstOrDefault().value : "");
            social_media = SocialMediaModel.getSocialMedia(product.Store, db);

            if (product.Store.created_on.HasValue)
                created_date = product.Store.created_on.Value;

            if (product.is_deleted != true)
                catalogue = new List<ProductModel>() { new ProductModel(product, db: db) };
            else catalogue = new List<ProductModel>();
        }
        public ProductModel(Product p, Boolean expanded = true, SIEBUEntities db = null)
        {
            if (db == null) db = new SIEBUEntities();
            id = p.p_id;
            sku = (p.sku == null ? p.p_id.ToString() : p.sku);
            store_id = p.store_id;
            name = p.name;
            status = p.status;
            status_caption = p.Product_Status.caption;
            cost = Math.Round(p.cost.Value, 2);
            likes = db.Product_Like.Count(pl => pl.product_id == p.p_id);
            avail_inventory = p.avail_inventory.Value;
            short_description = getSummary(p);
            is_featured = (p.is_featured == true);

            if (p.dateadded.HasValue)
                dateadded = String.Format("{0:MMMM d, yyyy}", p.dateadded.Value);
            else dateadded = "N/A";

            if (p.lastmodified.HasValue)
                lastmodified = String.Format("{0:MMMM d, yyyy}", p.lastmodified.Value);
            else lastmodified = "N/A";

            if (expanded)
            {
                description = p.description;
                shipping_cost = Math.Round(p.shipping_cost.Value, 2);

                images = new List<ProductImageModel>();
                for (int i = 0; i < p.Product_Image.Count(); i++)
                {
                    Product_Image pimage = p.Product_Image.OrderBy(pi => pi.sort).Skip(i).Take(1).FirstOrDefault();
                    ProductImageModel pim = new ProductImageModel();
                    pim.id = pimage.pi_id;
                    pim.url = pimage.url;
                    pim.order = (pimage.sort.HasValue ? pimage.sort.Value : i);
                    images.Add(pim);
                }

                tags = new List<ProductTagModel>();
                foreach (Product_Tag tag in db.Product_Tag.Where(pt => pt.product_id == p.p_id))
                {
                    tags.Add(new ProductTagModel(tag.Tag.caption));
                }
            }
            else
            {
                images = new List<ProductImageModel>();
                Product_Image pimg = p.Product_Image.OrderBy(pi => pi.sort).FirstOrDefault();
                ProductImageModel pim = new ProductImageModel();

                if (pimg != null)
                {
                    pim.id = pimg.pi_id;
                    pim.url = pimg.url;
                    pim.order = (pimg.sort.HasValue ? pimg.sort.Value : 0);
                }
                else
                {
                    pim.id = 0;
                    pim.url = "/content/no-image";
                    pim.order = 0;
                }

                images.Add(pim);
            }
        }
        /// <summary>
        /// This function takes a news item, and checks whether or not a preexisting description exists. If no description is found,
        /// the body text of the blog is stripped of HTML tags, and reduced to the closest length that ends
        /// on one of multiple provided delimiters.
        /// </summary>
        /// <param name="p"></param>
        /// <param name="char_lim"></param>
        /// <returns></returns>
        public static string getSummary(Product p, int char_lim = 250)
        {
            if (p.short_description != null && p.short_description.Length > 0) return p.short_description;

            string output = p.description;

            output = Regex.Replace(output, @"<(.|\n)*?>", string.Empty);

            int length = output.Length;
            if (length > char_lim)
            {
                string[] delimiters = { ", ", ". ", "</p>" };
                foreach (string delim in delimiters)
                {
                    if (output.Contains(delim) && output.LastIndexOf(delim, char_lim) > 0)
                        length = (output.LastIndexOf(delim, char_lim)) + delim.Length;
                }
                output = output.Substring(0, length);
            };

            return output;
        }
 //create headline using product object
 public HeadlineModel(Product p)
 {
     title = p.name;
     image = p.Product_Image.Count == 0 ? null : p.Product_Image.OrderBy(pi => pi.sort).FirstOrDefault().url;
     body = ProductModel.getSummary(p, 500);
     url = String.Format("/{0}/products?id={1}", p.Store.name_space, p.p_id);
     if (p.featured_since.HasValue) date = p.featured_since.Value;
 }