Controlling Popular Products

For general questions and discussions specific to the AbleCommerce GOLD ASP.Net shopping cart software.
Post Reply
Brewhaus
Vice Admiral (VADM)
Vice Admiral (VADM)
Posts: 878
Joined: Sat Jan 19, 2008 4:30 pm

Controlling Popular Products

Post by Brewhaus » Mon Sep 16, 2013 7:32 pm

In our AC7 installation we have the Popular Products set up to show 'x' number of items (we have it set to three) out of the top 20 items. I have tried to get the Gold version to do the same, but when we change

IList<Product> products = ProductDataSource.GetPopularProducts(this.MaxItems, prefferedCategoryId);

to the same as in our AC7 file (20, 7) we show the top 20 items from category 7. This seems to override

private int _MaxItems = 3;

How can we set the file up to show only three items, but pulled from the top 20 sellers?
Rick Morris
Brewhaus (America) Inc.
Hot Sauce Depot

jguengerich
Commodore (COMO)
Commodore (COMO)
Posts: 436
Joined: Tue May 07, 2013 1:59 pm

Re: Controlling Popular Products

Post by jguengerich » Tue Sep 17, 2013 12:19 pm

After you get the list of 20, you could use .Net's Radom class methods to get 3 (different) random numbers between 0 and 19. Then build a smaller list with the items in those 3 positions of the original list.
Jay

Brewhaus
Vice Admiral (VADM)
Vice Admiral (VADM)
Posts: 878
Joined: Sat Jan 19, 2008 4:30 pm

Re: Controlling Popular Products

Post by Brewhaus » Tue Sep 17, 2013 2:56 pm

It sounds like it is much more involved than the AC7 version. Is there that much of a change in the PopularProducts file?
Rick Morris
Brewhaus (America) Inc.
Hot Sauce Depot

jguengerich
Commodore (COMO)
Commodore (COMO)
Posts: 436
Joined: Tue May 07, 2013 1:59 pm

Re: Controlling Popular Products

Post by jguengerich » Tue Sep 17, 2013 2:57 pm

I don't know, I never had AC7. There might be a simpler way to accomplish what you want, my post was just the first thing I thought of.
Jay

Brewhaus
Vice Admiral (VADM)
Vice Admiral (VADM)
Posts: 878
Joined: Sat Jan 19, 2008 4:30 pm

Re: Controlling Popular Products

Post by Brewhaus » Tue Sep 17, 2013 6:30 pm

In AC7 we just change this

Code: Select all

        int prefferedCategoryId = PageHelper.GetCategoryId();
        List<Product> products = ProductDataSource.GetPopularProducts(this.MaxItems, prefferedCategoryId);
        if (products != null && products.Count > 0)
to

Code: Select all

        int prefferedCategoryId = PageHelper.GetCategoryId();
        //List<Product> products = ProductDataSource.GetPopularProducts(this.MaxItems, prefferedCategoryId);
        List<Product> products = ProductDataSource.GetPopularProducts(20, 7);
        List<Product> randomProducts = new List<Product>();
        Random random = new Random();
        int count = 0;
        if (products.Count > 0)
I tried this in Gold and got an error page. :-(
Rick Morris
Brewhaus (America) Inc.
Hot Sauce Depot

jguengerich
Commodore (COMO)
Commodore (COMO)
Posts: 436
Joined: Tue May 07, 2013 1:59 pm

Re: Controlling Popular Products

Post by jguengerich » Tue Sep 17, 2013 6:47 pm

I think if you look at your AC7 code and compare it to the AC Gold code more carefully, you'll find there are more lines you need to copy/change in AC Gold. What you show above is the start of what I suggested, but there has to be more code to finish the process.
Jay

Brewhaus
Vice Admiral (VADM)
Vice Admiral (VADM)
Posts: 878
Joined: Sat Jan 19, 2008 4:30 pm

Re: Controlling Popular Products

Post by Brewhaus » Tue Sep 17, 2013 7:10 pm

You are correct- I missed copying and pasting part of the code. It is below.

Code: Select all

        int prefferedCategoryId = PageHelper.GetCategoryId();
        //List<Product> products = ProductDataSource.GetPopularProducts(this.MaxItems, prefferedCategoryId);
        List<Product> products = ProductDataSource.GetPopularProducts(20, 7);
        List<Product> randomProducts = new List<Product>();
        Random random = new Random();
        int count = 0;
        if (products.Count > 0)
        {
            if (MaxItems > products.Count)
                MaxItems = products.Count;
            while (count < MaxItems)
            {
                int index = random.Next(0, products.Count);
                Product product = products[index];
                if (!randomProducts.Contains(product))
                {
                    randomProducts.Add(product);
                    count++;
                }
            }
        }
        products = randomProducts;
I have just not been able to figure out how to make this work with Gold. I keep coming up with errors. Am I overlooking something obvious?
Rick Morris
Brewhaus (America) Inc.
Hot Sauce Depot

jguengerich
Commodore (COMO)
Commodore (COMO)
Posts: 436
Joined: Tue May 07, 2013 1:59 pm

Re: Controlling Popular Products

Post by jguengerich » Wed Sep 18, 2013 6:42 am

What error(s) are you getting? Also, since it isn't very long, a copy of the entire .cs file would make it easier to spot a problem.
Jay

Brewhaus
Vice Admiral (VADM)
Vice Admiral (VADM)
Posts: 878
Joined: Sat Jan 19, 2008 4:30 pm

Re: Controlling Popular Products

Post by Brewhaus » Wed Sep 18, 2013 7:58 am

If I recall, the error that we get has something to do with the products.count reference. I had to change back to the original file in order to continue working on the site development.

Here is the AC7 file

Code: Select all

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Collections.Generic;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using CommerceBuilder.Common;
using CommerceBuilder.DigitalDelivery;
using CommerceBuilder.Products;
using CommerceBuilder.Orders;
using CommerceBuilder.Utility;

public partial class Webparts_PopularProductsDialog : System.Web.UI.UserControl
{
    private string _Caption = "Top Sellers";
    private int _MaxItems = 3;
    private string _Orientation = "HORIZONTAL";
    private int _Columns = 3;
    private string _ThumbnailPosition = "TOP"; // LEFT OR TOP

    /// <summary>
    /// Default is "TOP" , can be "TOP" or "LEFT"
    /// </summary>
    [Personalizable(), WebBrowsable()]
    public string ThumbnailPosition
    {
        get { return _ThumbnailPosition; }
        set { 
            _ThumbnailPosition = value;
            _ThumbnailPosition = value.ToUpperInvariant();
            if ((_ThumbnailPosition != "TOP") && (_ThumbnailPosition != "LEFT")) _ThumbnailPosition = "TOP";            

        }
    }

    /// <summary>
    /// Default is 3 columns, Only for HORIZONTAL Orientation
    /// </summary>
    [Personalizable(), WebBrowsable()]
    public int Columns
    {
        get { return _Columns; }
        set { 
            _Columns = value;
            if (Orientation == "HORIZONTAL") ProductList.RepeatColumns = Columns;
        }
    }
    

    [Personalizable(), WebBrowsable()]
    public string Orientation
    {
        get
        {
            return _Orientation;
        }
        set
        {
            _Orientation = value.ToUpperInvariant();
            if ((_Orientation != "HORIZONTAL") && (_Orientation != "VERTICAL")) _Orientation = "HORIZONTAL";
            if (_Orientation == "HORIZONTAL")
            {
                ProductList.RepeatColumns = Columns;
                ProductList.RepeatDirection = RepeatDirection.Horizontal;        
                ProductList.ItemStyle.CssClass = "rowSeparator";
                ProductList.AlternatingItemStyle.CssClass = "";
                
            }else{
                ProductList.RepeatColumns = 1;
                ProductList.RepeatDirection = RepeatDirection.Vertical;

                // THERE SHOULD BE DIFFERENT CSS STYLE FOR ALTERNATE ITEMS
                ProductList.ItemStyle.CssClass = "ProductItemView";
                ProductList.AlternatingItemStyle.CssClass = "ProductItemViewOdd";
            }
        }
    }

    [Personalizable(), WebBrowsable()]
    public string Caption
    {
        get { return _Caption; }
        set { _Caption = value; }
    }

    [Personalizable(), WebBrowsable()]
    public int MaxItems
    {
        get { return _MaxItems; }
        set { _MaxItems = value; }
    }

    protected void ProductList_ItemDataBound(object sender, DataListItemEventArgs e)
    {
        if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
        {
            Product product = (Product)e.Item.DataItem;
            Image thumbnail = PageHelper.RecursiveFindControl(e.Item, "Thumbnail") as Image;
            if (thumbnail != null)
            {
                if (!string.IsNullOrEmpty(product.ThumbnailUrl))
                {
                    thumbnail.ImageUrl = product.ThumbnailUrl;
                    thumbnail.Attributes.Add("hspace", "2");
                    thumbnail.Attributes.Add("vspace", "2");
                }
                else
                {
                    thumbnail.Visible = false;
                }
            }
            
            if (ThumbnailPosition == "LEFT")
            {
                Literal SingleRowLiteral = PageHelper.RecursiveFindControl(e.Item, "SingleRowLiteral") as Literal;
                Literal TwoRowsLiteral = PageHelper.RecursiveFindControl(e.Item, "TwoRowsLiteral") as Literal;

                if (SingleRowLiteral != null && TwoRowsLiteral != null)
                {
                    SingleRowLiteral.Visible = true;
                    TwoRowsLiteral.Visible = false;
                }                
            }
        }
    }

    protected void ProductList_ItemCommand(object source, DataListCommandEventArgs e)
    {
        if (e.CommandName == "AddToCart")
        {
            int productId = AlwaysConvert.ToInt(e.CommandArgument);
            BasketItem basketItem = BasketItemDataSource.CreateForProduct(productId, 1);
            if (basketItem != null)
            {
                // DETERMINE IF THE LICENSE AGREEMENT MUST BE REQUESTED
                BasketItemLicenseAgreementCollection basketItemLicenseAgreements = new BasketItemLicenseAgreementCollection(basketItem, LicenseAgreementMode.OnAddToBasket);
                if ((basketItemLicenseAgreements.Count > 0))
                {
                    // THESE AGREEMENTS MUST BE ACCEPTED TO ADD TO CART
                    List<BasketItem> basketItems = new List<BasketItem>();
                    basketItems.Add(basketItem);
                    string guidKey = Guid.NewGuid().ToString("N");
                    Cache.Add(guidKey, basketItems, null, System.Web.Caching.Cache.NoAbsoluteExpiration, new TimeSpan(0, 10, 0), System.Web.Caching.CacheItemPriority.NotRemovable, null);
                    string acceptUrl = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes("~/Basket.aspx"));
                    string declineUrl = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(Request.Url.ToString()));
                    Response.Redirect("~/BuyWithAgreement.aspx?Items=" + guidKey + "&AcceptUrl=" + acceptUrl + "&DeclineUrl=" + declineUrl);
                }
                Basket basket = Token.Instance.User.Basket;
                basket.Items.Add(basketItem);
                basket.Save();
                basket.Package();
                basket.Combine();
                Response.Redirect("~/Basket.aspx");
            }
        }
    }

    protected bool ShowAddToCart(object dataItem)
    {
        Product product = (Product)dataItem;
        return ((product.ProductOptions.Count == 0) && (product.KitStatus != KitStatus.Master));
    }

    protected void Page_PreRender(object sender, EventArgs e)
    {
        int prefferedCategoryId = PageHelper.GetCategoryId();
        //List<Product> products = ProductDataSource.GetPopularProducts(this.MaxItems, prefferedCategoryId);
        List<Product> products = ProductDataSource.GetPopularProducts(20, 7);
        List<Product> randomProducts = new List<Product>();
        Random random = new Random();
        int count = 0;
        if (products.Count > 0)
        {
            if (MaxItems > products.Count)
                MaxItems = products.Count;
            while (count < MaxItems)
            {
                int index = random.Next(0, products.Count);
                Product product = products[index];
                if (!randomProducts.Contains(product))
                {
                    randomProducts.Add(product);
                    count++;
                }
            }
        }
        products = randomProducts;


        if (products != null && products.Count > 0)
        {
            CaptionLabel.Text = this.Caption;
            ProductList.DataSource = products;
            ProductList.DataBind();
        }
        else
        {
            this.Visible = false;
        }
    }

    protected string GetThumbnailUrl(object thumbnailUrl)
    {
        if (!string.IsNullOrEmpty((string)thumbnailUrl)) return (string)thumbnailUrl;
        return "~/images/thumbs/ProductThumbnail.gif";
    }
}
and the Gold file

Code: Select all

namespace AbleCommerce.ConLib
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Web.UI.WebControls.WebParts;
    using CommerceBuilder.Products;
    using CommerceBuilder.UI;

    [Description("Display top seller products.")]    
    public partial class PopularProductsDialog : System.Web.UI.UserControl, ISidebarControl
    {
        private string _Caption = "Top Sellers";
        private int _MaxItems = 3;
        private int _Columns = -1;

        [Personalizable(), WebBrowsable()]
        [Browsable(true), DefaultValue(1)]
        [Description("The number of columns to display.")]
        public int Columns
        {
            get
            {
                if (_Columns < 0) return ProductList.RepeatColumns;
                return _Columns;
            }
            set
            {
                _Columns = value;
                ProductList.RepeatColumns = Columns;
            }
        }

        [Personalizable(), WebBrowsable()]
        [Browsable(true), DefaultValue("Top Sellers")]
        [Description("Caption / Title of the control")]
        public string Caption
        {
            get { return _Caption; }
            set { _Caption = value; }
        }

        [Personalizable(), WebBrowsable()]
        [Browsable(true), DefaultValue(3)]
        [Description("The maximum number of products that can be shown.")]
        public int MaxItems
        {
            get { return _MaxItems; }
            set { _MaxItems = value; }
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            int prefferedCategoryId = AbleCommerce.Code.PageHelper.GetCategoryId();
            IList<Product> products = ProductDataSource.GetPopularProducts(this.MaxItems, prefferedCategoryId);
            if (products != null && products.Count > 0)
            {

                ProductList.RepeatColumns = Columns;
                ProductList.DataSource = products;
                ProductList.DataBind();
            }
            else
            {
                this.Visible = false;
            }
        }
    }
}
Rick Morris
Brewhaus (America) Inc.
Hot Sauce Depot

jguengerich
Commodore (COMO)
Commodore (COMO)
Posts: 436
Joined: Tue May 07, 2013 1:59 pm

Re: Controlling Popular Products

Post by jguengerich » Wed Sep 18, 2013 8:16 am

I don't see any obvious problems in the code. If the customized code is copied from AC7's Page_Load method to Gold's Page_Load method, the file for Gold would look like this:

Code: Select all

    namespace AbleCommerce.ConLib
    {
        using System;
        using System.Collections;
        using System.Collections.Generic;
        using System.ComponentModel;
        using System.Web.UI.WebControls.WebParts;
        using CommerceBuilder.Products;
        using CommerceBuilder.UI;

        [Description("Display top seller products.")]   
        public partial class PopularProductsDialog : System.Web.UI.UserControl, ISidebarControl
        {
            private string _Caption = "Top Sellers";
            private int _MaxItems = 3;
            private int _Columns = -1;

            [Personalizable(), WebBrowsable()]
            [Browsable(true), DefaultValue(1)]
            [Description("The number of columns to display.")]
            public int Columns
            {
                get
                {
                    if (_Columns < 0) return ProductList.RepeatColumns;
                    return _Columns;
                }
                set
                {
                    _Columns = value;
                    ProductList.RepeatColumns = Columns;
                }
            }

            [Personalizable(), WebBrowsable()]
            [Browsable(true), DefaultValue("Top Sellers")]
            [Description("Caption / Title of the control")]
            public string Caption
            {
                get { return _Caption; }
                set { _Caption = value; }
            }

            [Personalizable(), WebBrowsable()]
            [Browsable(true), DefaultValue(3)]
            [Description("The maximum number of products that can be shown.")]
            public int MaxItems
            {
                get { return _MaxItems; }
                set { _MaxItems = value; }
            }

            protected void Page_Load(object sender, EventArgs e)
            {
                int prefferedCategoryId = AbleCommerce.Code.PageHelper.GetCategoryId();
                //List<Product> products = ProductDataSource.GetPopularProducts(this.MaxItems, prefferedCategoryId);
                List<Product> products = ProductDataSource.GetPopularProducts(20, 7);
                List<Product> randomProducts = new List<Product>();
                Random random = new Random();
                int count = 0;
                if (products.Count > 0)
                {
                    if (MaxItems > products.Count)
                        MaxItems = products.Count;
                    while (count < MaxItems)
                    {
                        int index = random.Next(0, products.Count);
                        Product product = products[index];
                        if (!randomProducts.Contains(product))
                        {
                            randomProducts.Add(product);
                            count++;
                        }
                    }
                }
                products = randomProducts;


                if (products != null && products.Count > 0)
                {

                    ProductList.RepeatColumns = Columns;
                    ProductList.DataSource = products;
                    ProductList.DataBind();
                }
                else
                {
                    this.Visible = false;
                }
            }
        }
    }
If you get an error using that code, post the error message here and maybe we can figure it out.
Jay

Brewhaus
Vice Admiral (VADM)
Vice Admiral (VADM)
Posts: 878
Joined: Sat Jan 19, 2008 4:30 pm

Re: Controlling Popular Products

Post by Brewhaus » Wed Sep 18, 2013 3:48 pm

Well, it is a step in the right direction. The page loads, but there is an error where the products are supposed to be displayed:

[[ConLib:Custom/PopularProductsDialog]] e:\Websites\ACGold Site\Hot Sauce Depot\ConLib\Custom\PopularProductsDialog.ascx.cs(57): error CS0266: Cannot implicitly convert type 'System.Collections.Generic.IList' to 'System.Collections.Generic.List'. An explicit conversion exists (are you missing a cast?)
Rick Morris
Brewhaus (America) Inc.
Hot Sauce Depot

jguengerich
Commodore (COMO)
Commodore (COMO)
Posts: 436
Joined: Tue May 07, 2013 1:59 pm

Re: Controlling Popular Products

Post by jguengerich » Mon Sep 23, 2013 2:28 pm

Sorry for the delayed response, I had to tweak a few iPad apps for iOS 7.

The line:

Code: Select all

List<Product> products = ProductDataSource.GetPopularProducts(20, 7);
should be

Code: Select all

IList<Product> products = ProductDataSource.GetPopularProducts(20, 7);
I didn't catch it because the original AbleCommerce line that you commented out:

Code: Select all

//List<Product> products = ProductDataSource.GetPopularProducts(this.MaxItems, prefferedCategoryId);
Should also start with "IList" instead of "List", but the "I" is missing in the first two messages you posted that have code in them.
You might want to put the "I" back in the commented line in case you ever want to switch back to original code.
Jay

Brewhaus
Vice Admiral (VADM)
Vice Admiral (VADM)
Posts: 878
Joined: Sat Jan 19, 2008 4:30 pm

Re: Controlling Popular Products

Post by Brewhaus » Mon Sep 23, 2013 2:59 pm

Thank you, Jay. That got it working. :-)
Rick Morris
Brewhaus (America) Inc.
Hot Sauce Depot

Post Reply