public ActivityHistoryViewModel(Store s, SIEBUEntities db = null)
        {
            if (db == null) db = new SIEBUEntities();

            foreach (Transaction_Subtransaction sub in db.Transaction_Subtransaction.Where(st => st.store_id == s.s_id && st.Transaction.is_processed == true).OrderByDescending(st => st.Transaction.dateprocessed))
                history.Add(new ActivityHistoryModel(sub, db));

            type = salesActivity;
        }
        public DashboardModel(Store s, SIEBUEntities db = null)
        {
            if (db == null) db = new SIEBUEntities();

            id = s.s_id;
            name = s.name;
            description = s.description;
            logo = s.logo;
            banner = s.banner_img;
            background = s.background_img;
            owner_name = s.User.firstName + " " + s.User.lastName;
            store_namespace = s.name_space;
            social_media = SocialMediaModel.getSocialMedia(s, db);
            credit = Math.Round(s.credit.Value, 2);

            if (s.created_on.HasValue)
                created_date = s.created_on.Value;

            status_caption = s.Store_Status.caption;
            category_caption = s.Store_Category.text;

            catalogue = getCatalogue(s, count: 6, active: true, db: db);
            recent_blogs = StoreBlogModel.getEntries(s.s_id, count: 4, db: db);
        }
        public ActionResult UpdateStore(StoreModel update)
        {
            //StoreModel update = JsonConvert.DeserializeObject<StoreModel>(obj);
            SIEBUEntities db = new SIEBUEntities();
            Store target_store = db.Stores.FirstOrDefault(s => s.s_id == update.id);

            //if no store is found, create one
            bool add_new = false;
            if (target_store == null)
            {
                add_new = true;
                target_store = new Store();
                target_store.creator_id = WebSecurity.CurrentUserId;
                target_store.created_on = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time"));
                target_store.credit = 0;
            }

            //check for conflicting namespace
            if (ValidationController.checkNamespaceAvailability(update.store_namespace) != true)
                return Json(new { error = "The namespace is unavailable for use." }, JsonRequestBehavior.AllowGet);

            target_store.name = update.name;
            target_store.name_space = update.store_namespace;
            target_store.description = update.description;

            target_store.category_id = update.category;
            target_store.status = update.status;

            //create store before connections required
            if (add_new)
            {
                db.Stores.Add(target_store);
                db.SaveChanges();
            }

            if (target_store.logo == null || !(update.logo + "").Contains(target_store.logo)) //(!(target_store.logo == update.logo || update.logo.Contains(target_store.logo)))
                target_store.logo = update.logo != null ? ImageController.UploadFile(update.logo, "logo" + target_store.s_id) : null;

            if (target_store.banner_img == null || !(update.banner + "").Contains(target_store.banner_img))
                target_store.banner_img = update.banner != null ? ImageController.UploadFile(update.banner, "banner" + target_store.s_id) : null;

            if (target_store.background_img == null || !(update.background + "").Contains(target_store.background_img)) //) CHANGED FOR PARTIAL URLS
                target_store.background_img = update.background != null ? ImageController.UploadFile(update.background, "background" + target_store.s_id) : null;

            //update social media
            foreach (SocialMediaModel sm in update.social_media)
            {
                Store_Contact ssm = db.Store_Contact.FirstOrDefault(q => q.store == update.id && q.Contact.caption == sm.type);

                bool add_new_sm = false;
                if (ssm == null)
                {
                    add_new = true;
                    ssm = new Store_Contact();
                }
                ssm.value = sm.url;

                if (add_new_sm) db.Store_Contact.Add(ssm);
            }

            db.SaveChanges();

            return Json(target_store.name_space, JsonRequestBehavior.AllowGet);
        }
        public StoreCustomizationModel(Store s, SIEBUEntities db = null)
        {
            if (db == null) db = new SIEBUEntities();

            id = s.s_id;
            status = (s.status.HasValue ? s.status.Value : -1);
            category = s.category_id;
            name = s.name;
            description = s.description;
            logo = s.logo;
            banner = s.banner_img;
            background = s.background_img;
            owner_name = s.User.firstName + " " + s.User.lastName;
            store_namespace = s.name_space;
            social_media = SocialMediaModel.getSocialMedia(s, db);

            if (s.created_on.HasValue)
                created_date = s.created_on.Value;

            category_list = new Dictionary<int, string>();
            foreach (Store_Category cat in db.Store_Category)
                category_list.Add(cat.c_id, cat.text);
            status_list = new Dictionary<int, string>();
            foreach (Store_Status stat in db.Store_Status)
                status_list.Add(stat.status_id, stat.caption);
        }
        public StoreTransactionsModel(Store s, SIEBUEntities db = null)
        {
            if (db == null) db = new SIEBUEntities();

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

            if (s.created_on.HasValue)
                created_date = s.created_on.Value;

            history = new List<ActivityHistoryModel>();
            foreach (Transaction_Subtransaction sub in db.Transaction_Subtransaction.Where(st => st.store_id == s.s_id && st.Transaction.is_processed == true).OrderByDescending(st => st.Transaction.dateprocessed))
                history.Add(new ActivityHistoryModel(sub, db));
        }
        public StoreInformationModel(Store s, Boolean min = false, SIEBUEntities db = null)
        {
            if (db == null) db = new SIEBUEntities();

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

            if (s.created_on.HasValue)
                created_date = s.created_on.Value;

            UserModel owner = new UserModel(s.User, db);
            owners = new List<UserModel>();
            owners.Add(owner);
        }
        /// <summary>
        /// getHeadlines - using a given store, get the 5 most recent featured items and 5 most recent featured news posts.
        /// with the remaining set of 10, organize again by date and grab the 5 most recent among them.
        /// The output should be the 5 most recent featured items overall.
        /// </summary>
        /// <param name="s">store object</param>
        /// <param name="count"># of headlines req'd</param>
        /// <param name="db">entity framework instance</param>
        /// <returns></returns>
        /// 
        public List<HeadlineModel> getHeadlines(Store s, int count, SIEBUEntities db = null)
        {
            List<HeadlineModel> output = new List<HeadlineModel>();

            //collect 5 product headlines
            foreach (Product product in db.Products.Where(p => p.store_id == s.s_id && p.is_featured == true && (!p.is_deleted.HasValue || p.is_deleted != true)).OrderByDescending(p => p.featured_since).Take(count))
                output.Add(new HeadlineModel(product));

            //collect 5 blogpost headlines
            foreach (Store_NewsItem newsitem in db.Store_NewsItem.Where(ni => ni.store_id == s.s_id && ni.is_featured == true && ((!ni.is_deleted.HasValue || ni.is_deleted.Value != true) && (!ni.is_draft.HasValue || ni.is_draft.Value != true))).OrderByDescending(ni => ni.featured_since).Take(count))
                output.Add(new HeadlineModel(newsitem));

            //List<HeadlineModel> headlines = (db.Products.Select(p => new HeadlineModel(p.name, p.Product_Image.Count == 0 ? "/content/no-image" : p.Product_Image.FirstOrDefault().url, p.description, "/" + p.Store.name_space + "/products?id=" + p.p_id, p.featured_since)))
            //    .Concat(db.Store_NewsItem.Select(ni => new HeadlineModel(ni.title, ni.img == null ? "/content/no-image" : ni.img, ni.description, "/" + ni.Store.name_space + "/blog?id=" + ni, ni.featured_since)))
            //    .ToList();

            return output.OrderByDescending(q => q.date).Take(count).ToList();
        }
        public StoreFrontModel(Store s, int display, int index, Boolean active, SIEBUEntities db = null)
        {
            if (db == null) db = new SIEBUEntities();

            id = s.s_id;
            status = (s.status.HasValue ? s.status.Value : -1);
            category = s.category_id;
            name = s.name;
            description = s.description;
            logo = s.logo;
            banner = s.banner_img;
            background = s.background_img;
            owner_name = s.User.firstName + " " + s.User.lastName;
            store_namespace = s.name_space;
            social_media = SocialMediaModel.getSocialMedia(s, db);

            if (s.created_on.HasValue)
                created_date = s.created_on.Value;

            if (display > 0)
                catalogue = getCatalogue(s, count: display, index: index, active: active, db: db);

            headlines = getHeadlines(s, 5, db);
        }
        public StoreBlogModel(Store s, int display = 8, int index = 0, bool include_draft = false, SIEBUEntities db = null)
        {
            if (db == null) db = new SIEBUEntities();

            id = s.s_id;
            status = (s.status.HasValue ? s.status.Value : -1);
            category = s.category_id;
            name = s.name;
            description = s.description;
            logo = s.logo;
            banner = s.banner_img;
            background = s.background_img;
            owner_name = s.User.firstName + " " + s.User.lastName;
            store_namespace = s.name_space;
            email = (s.Store_Contact.Count(c => c.Contact.caption == "Email Address") > 0 ? s.Store_Contact.Where(c => c.Contact.caption == "Email Address").FirstOrDefault().value : "");
            website = (s.Store_Contact.Count(c => c.Contact.caption == "Website") > 0 ? s.Store_Contact.Where(c => c.Contact.caption == "Website").FirstOrDefault().value : "");
            entries = getEntries(s.s_id, count: display, index: index, include_draft: include_draft, db: db);
            social_media = SocialMediaModel.getSocialMedia(s, db);
        }
        /// <summary>
        /// Update the recent stores viewed in the cookie and add in the database
        /// </summary>
        /// <param name="userId">user's id</param>
        /// <param name="store">store viewed</param>
        /// <param name="max">max items in a cookie</param>
        /// <returns></returns>
        public static HttpCookie updateStoreViewHistory(int userId, HttpCookie cookie, Store store, int max = 10)
        {
            HttpCookie returnCookie = new HttpCookie(cookie.Name);
            returnCookie.Value = "";
            //add the new store in the database
            SIEBUEntities db = new SIEBUEntities();
            User_SearchHistory record = db.User_SearchHistory.FirstOrDefault(search => search.store_id == store.s_id &&
                search.product_id == null);
            if (record != null)  //modify existing record in the database or add it
            {
                record.dateaccessed = DateTime.Now;
            }
            else //add new record in the database
            {
                record = new User_SearchHistory();
                record.store_id = store.s_id;
                record.user_id = userId;
                record.dateaccessed = DateTime.Now;
                db.User_SearchHistory.Add(record);
            }
            db.SaveChanges();

            String storeHist = "";
            HttpCookie storeCookie = null;
            if (cookie == null) //cookie doesn't exist
            {
                storeCookie = recentStoreViewedCookie(userId);
                storeHist = storeCookie.Value;
            }
            else //get the value
            {
                storeHist = cookie.Value;
            }

            if (storeHist != "")
            {
                String[] cookieRecords = storeHist.Split('|');
                Boolean contains = false;
                int index = -1;
                try
                {
                    for (int i = 0; i < cookieRecords.Length; i++) // Check and find the index of the item if it is in the cookie
                    {
                        String[] cookieRecord = cookieRecords[i].Split('&');
                        int storeId = int.Parse(cookieRecord[0].ToString());

                        if (storeId == store.s_id)
                        {
                            contains = true;
                            index = i;
                            break;
                        }
                    }
                    String cookieValue = "";

                    if (!contains) //new record
                    {
                        if (cookieRecords.Length >= max)
                        {
                            for (int i = 0; i < cookieRecords.Length - 1; i++) //Take the first items in the record minus the last element
                            {
                                cookieValue = cookieValue + "|" + cookieRecords[i];
                            }
                            //add element 0 before cookieValue;
                            returnCookie.Value = getStoreCookieValue(store.s_id, store.name,
                                store.name_space, (store.logo != null) ? store.logo : "/content/no-image") + cookieValue;
                        }
                        else
                        {
                            returnCookie.Value = getStoreCookieValue(store.s_id, store.name,
                            store.name_space, (store.logo != null) ? store.logo : "/content/no-image") + "|" + storeHist;
                        }
                    }
                    else //modify existing cookie
                    {
                        if (index != 0) // if index == 0 then it's just the first element and we don't need to do anything
                        {
                            if (index == cookieRecords.Length - 1) //the record is the last element in the cookie.
                            {
                                cookieValue = cookieRecords[cookieRecords.Length - 1];
                                for (int i = 0; i != cookieRecords.Length - 1; i++)
                                {
                                    cookieValue = cookieValue + "|" + cookieRecords[i];
                                }
                                returnCookie.Value = cookieValue;
                            }
                            else //record is in the middle of the cookie
                            {
                                String before = cookieRecords[0];

                                for (int i = 1; i < index; i++)
                                {
                                    before = before + "|" + cookieRecords[i];
                                }

                                String after = cookieRecords[index + 1];
                                for (int i = index + 2; i < cookieRecords.Length; i++)
                                {
                                    after = after + "|" + cookieRecords[i];
                                }
                                returnCookie.Value = cookieRecords[index] + "|" + before + "|" + after;
                            }
                        }
                        else
                        {
                            returnCookie.Value = storeHist; //just return the same cookie.
                        }
                    }
                }
                catch (Exception e)
                {
                    //Debug.WriteLine("Exception has occured with modifying the recently viewed store cookie: " + e.ToString());
                    returnCookie.Value = storeHist;
                    //Response.Cookies.Add(recentStoreViewedCookie(WebSecurity.CurrentUserId));
                }

            }
            else //first shop viewed.
            {
                returnCookie.Value = getStoreCookieValue(store.s_id, store.name,
                        store.name_space, store.logo);
            }
            return returnCookie;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="store"></param>
        /// <param name="sort">0: newest, 1: alphabetical, 2: cost ascending, 3: cost descending, 4: by transaction item count</param>
        /// <param name="count">number of products to collect...</param>
        /// <param name="index">starting from index</param>
        /// <param name="search">search value</param>
        /// <param name="active">from active items only</param>
        /// <param name="db"></param>
        /// <returns></returns>
        public static List<ProductModel> getCatalogue(Store store, int sort = 0, int count = 8, int index = 0, string search = null, Boolean active = false, SIEBUEntities db = null)
        {
            if (db == null) db = new SIEBUEntities();
            List<ProductModel> output = new List<ProductModel>();
            IEnumerable<Product> products = store.Products.Where(p => !p.is_deleted.HasValue || p.is_deleted != true);

            if (active) products = products.Where(pr => pr.status == 1);

            //search and sort
            if (search != null) products = products.Where(p => (p.sku + p.name + p.short_description + p.description).ToLower().Contains(search.ToLower()) || p.Product_Tag.Count(t => t.Tag.caption.ToLower().Contains(search.ToLower())) > 0);
            switch (sort)
            {
                case 0: products = products.OrderByDescending(p => p.dateadded);
                    break;
                case 1: products = products.OrderByDescending(p => p.name);
                    break;
                case 2: products = products.OrderBy(p => p.cost);
                    break;
                case 3: products = products.OrderByDescending(p => p.cost);
                    break;
                case 4: products = products.OrderByDescending(p => p.Transaction_Item.Count());
                    break;
            }

            products = products.Skip(index).Take(count);
            foreach (Product p in products)
                output.Add(new ProductModel(p, false, db));

            return output;
        }
        public CatalogueModel(Store s, int display, int index, Boolean active, SIEBUEntities db = null)
        {
            if (db == null) db = new SIEBUEntities();

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

            if (s.created_on.HasValue)
                created_date = s.created_on.Value;

            if (display > 0)
                catalogue = getCatalogue(s, count: display, index: index, active: active, db: db);
        }
        public static List<SubscriberModel> getSubscribers(Store subscription)
        {
            List<SubscriberModel> subscribers = new List<SubscriberModel>();

            foreach (User_StoreSubscription sub in subscription.User_StoreSubscription)
                subscribers.Add(new SubscriberModel(sub));

            return subscribers;
        }
        public StoreModel(Store s, Boolean min = false)
        {
            id = s.s_id;
            name = s.name;
            store_namespace = s.name_space;
            logo = s.logo;

            if (!min)
            {
                category = s.category_id;
                status = (s.status.HasValue ? s.status.Value : -1);
                description = s.description;
                banner = s.banner_img;
                background = s.background_img;
                owner_name = s.User.firstName + " " + s.User.lastName;
                email = (s.Store_Contact.Count(c => c.Contact.caption == "Email Address") > 0 ? s.Store_Contact.Where(c => c.Contact.caption == "Email Address").FirstOrDefault().value : "");
                website = (s.Store_Contact.Count(c => c.Contact.caption == "Website") > 0 ? s.Store_Contact.Where(c => c.Contact.caption == "Website").FirstOrDefault().value : "");
                social_media = SocialMediaModel.getSocialMedia(s);

                if (s.created_on.HasValue)
                    created_date = s.created_on.Value;
            }
        }
        public static List<SocialMediaModel> getSocialMedia(Store s, SIEBUEntities db = null)
        {
            if (db == null) db = new SIEBUEntities();

            List<SocialMediaModel> output = new List<SocialMediaModel>();
            foreach (Contact sm_type in db.Contacts.Where(c => c.is_socialmedia == true))
            {
                SocialMediaModel smodel = new SocialMediaModel(sm_type);
                smodel.url = (s.Store_Contact.Any(m => m.social_media == sm_type.sm_id) ? s.Store_Contact.FirstOrDefault(m => m.social_media == sm_type.sm_id).value : null);
                output.Add(smodel);
            }

            return output;
        }