Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


These support forums are now closed for new topics and comments.
Please head on over to http://eureka.ucommerce.net/ for support.

  • Bo Damgaard Mortensen 719 posts 1207 karma points
    May 07, 2012 @ 14:25
    Bo Damgaard Mortensen
    0

    Different prices for member/non-member orders

    Hi all,

    I'm currently building a webshop based on uCommerce where I need to be able to specify a different price than the normal price when a member is logged in.

    I have created the memberprice as a ShortText field on the productdefinitions and it's showing up like it should when I'm logged in as a member.

    Now, when I click the 'add to basket' button, I need to check if the member is logged in and if he/she is, the memberprice should be used instead of the original price.

    Is this possible at all? I've got a strange feeling that I have to rewrite the AddToBasket() method? ;-)

    Any help/hint is greatly appreciated!

    Thanks in advance,

    Bo

  • Søren Spelling Lund 1797 posts 2786 karma points
    May 07, 2012 @ 14:51
    Søren Spelling Lund
    0

    You can override the IPricingService to achieve just that. Simply inherit the PricingService class and register it in components.config in place of the existing one.

  • Bo Damgaard Mortensen 719 posts 1207 karma points
    May 07, 2012 @ 15:10
    Bo Damgaard Mortensen
    0

    Hi Søren,

    Thanks for the quick response, awesome! :)

    Being a novice when it comes to ucommerce, do you know if there's any code samples out there that overrides IPricingService?

    Thanks again.

    - Bo

  • Lasse Eskildsen 34 posts 57 karma points
    May 07, 2012 @ 20:41
    Lasse Eskildsen
    0

    Hi Bo,

    The methods you need to override in the PricingService are not virtual, so you need to do a bit of composition to make it work - something like this (sample code, but should compile, if you put your own code where the "..." 's are):

    using UCommerce.Catalog;
    using UCommerce.EntitiesV2;
    using umbraco.cms.businesslogic.member;
    namespace CustomPrices
    {
        public class CustomPricingService : IPricingService
        {
            private readonly IPricingService _base;
            public CustomPricingService()
            {
                _base = new PricingService();
            }

            public PriceGroupPrice GetProductPrice(Product product, ProductCatalog catalog)
            {
                if (!Member.IsLoggedOn())
                    return _base.GetProductPrice(product, catalog);
                return ...;
            }
            public PriceGroupPrice GetProductPrice(Product product, PriceGroup priceGroup)
            {
                if (!Member.IsLoggedOn())
                    return _base.GetProductPrice(product, priceGroup);
                return ...;
            }
        }
    }

    And in your components.config, change:

     

    <component id="PriceService"
    service="UCommerce.Catalog.IPricingService, UCommerce"
    type="UCommerce.Catalog.PricingService, UCommerce" lifestyle="Singleton"/>

    To:

     

    <component id="PriceService"
    service="UCommerce.Catalog.IPricingService, UCommerce"
    type="CustomPrices.CustomPricingService, CustomPrices" lifestyle="Singleton"/>

    - Lasse

  • Bo Damgaard Mortensen 719 posts 1207 karma points
    May 08, 2012 @ 11:22
    Bo Damgaard Mortensen
    0

    Hi Lasse,

    Thanks a lot for the example, greatly appreciated! :)

    I've been trying to get my head around it, but without a breakthrough. This is my test-code snippet:

    public UCommerce.EntitiesV2.PriceGroupPrice GetProductPrice(UCommerce.EntitiesV2.Product product, UCommerce.EntitiesV2.ProductCatalog catalog)
    {
        if (!Member.IsLoggedOn())
        {
             return _base.GetProductPrice(product, catalog);
        }
        else
        {
             var priceGroup = (from p in product.PriceGroupPrices
                               where p.PriceGroup.Name.Equals("MemberPrice")
                               select p).First();
             return _base.GetProductPrice(product, priceGroup.PriceGroup);                
        }
    }

    While it actually does return the pricegroup with the name of "MemberPrice" it seems to break all my XSLT files :/

    What exactly could I have done wrong here?

    Thanks again for your great support and help! :)

    All the best,

    Bo

  • Bo Damgaard Mortensen 719 posts 1207 karma points
    May 08, 2012 @ 11:56
    Bo Damgaard Mortensen
    0

    Alright, got it to display the correct pricegroup price with the following code:

    public UCommerce.EntitiesV2.PriceGroupPrice GetProductPrice(UCommerce.EntitiesV2.Product product, UCommerce.EntitiesV2.ProductCatalog catalog)
    {
         if (!Member.IsLoggedOn())
         {
             return _base.GetProductPrice(product, catalog);
         }
         else
         {
             PriceGroupPrice priceGroupPrice = null;
             foreach (var pg in product.PriceGroupPrices)
             {
                 if (pg.PriceGroup.Name.Equals("MemberPrice"))
                 {                        
                     priceGroupPrice = pg;
                 }                    
             }
    
             if (priceGroupPrice != null)
                 return priceGroupPrice;
             else
                 return _base.GetProductPrice(product, catalog);                              
             }
          }
    }

    However, when I add the product to the basket, the non-member price is displayed in the basket and in the checkout process :) 

    Back to investigating code ..

  • Søren Spelling Lund 1797 posts 2786 karma points
    May 08, 2012 @ 13:50
    Søren Spelling Lund
    0

    It might be that the order line was created using the old implementation. The unit price will not be changed for existing order lines when adding the same product multuple times.

    It might be worth getting rid of the existing basket and trying a clean one. Just reset your cookies and a new one will be assigned to you.

  • Bo Damgaard Mortensen 719 posts 1207 karma points
    May 08, 2012 @ 14:04
    Bo Damgaard Mortensen
    0

    Hi Søren,

    Thanks again for the quick answer :)

    I've tried nuking the cookie and created a new basket, but still it seem to grab the default/first (?) pricegroup price in the basket and on the checkout steps.

    The code I posted above is used in both of the PricingService methods. I've got a feeling that something is totally wrong, somewhere since it should just do all calculations with the given price that the PricingService returns, yes? :)

    Thanks again,

    Bo

  • Søren Spelling Lund 1797 posts 2786 karma points
    May 08, 2012 @ 14:05
    Søren Spelling Lund
    0

    OK.

    Try overriding both methods just to make sure. Just have one forward to the other.

     

  • Bo Damgaard Mortensen 719 posts 1207 karma points
    May 08, 2012 @ 14:07
    Bo Damgaard Mortensen
    0

    That's exactly what I did (I think :-P) the complete code of my serviceclass:

    private readonly IPricingService _base;
    
            public DerivedPricingService ()
            {
                _base = new PricingService();
            }
    
            public UCommerce.EntitiesV2.PriceGroupPrice GetProductPrice(UCommerce.EntitiesV2.Product product, UCommerce.EntitiesV2.PriceGroup priceGroup)
            {
                if (!Member.IsLoggedOn())
                {
                    return _base.GetProductPrice(product, priceGroup);
                }
                else
                {
                    PriceGroupPrice priceGroupPrice = null;
                    foreach (var pg in product.PriceGroupPrices)
                    {
                        if (pg.PriceGroup.Name.Equals("Forudbestillingspris"))
                        {
                            priceGroupPrice = pg;
                        }
    
                        if (priceGroupPrice == null && pg.PriceGroup.Name.Equals("Suppleringspris"))
                        {
                            priceGroupPrice = pg;
                        }
                    }
    
                    if (priceGroupPrice != null)
                        return priceGroupPrice;
                    else
                        return _base.GetProductPrice(product, priceGroup);
                }
            }
    
            public UCommerce.EntitiesV2.PriceGroupPrice GetProductPrice(UCommerce.EntitiesV2.Product product, UCommerce.EntitiesV2.ProductCatalog catalog)
            {
                if (!Member.IsLoggedOn())
                {
                    return _base.GetProductPrice(product, catalog);
                }
                else
                {
                    PriceGroupPrice priceGroupPrice = null;                
                    foreach (var pg in product.PriceGroupPrices)
                    {
                        if (pg.PriceGroup.Name.Equals("Forudbestillingspris"))
                        {                        
                            priceGroupPrice = pg;
                        }
    
                        if (priceGroupPrice == null && pg.PriceGroup.Name.Equals("Suppleringspris"))
                        {
                            priceGroupPrice = pg;
                        }
                    }
    
                    if (priceGroupPrice != null)
                        return priceGroupPrice;
                    else
                        return _base.GetProductPrice(product, catalog);                              
                }
            }
        }

    They basically do the exact same thing :) Although it seems like the first method is never really called (?)

  • Bo Damgaard Mortensen 719 posts 1207 karma points
    May 08, 2012 @ 14:12
    Bo Damgaard Mortensen
    0

    One thing I should say is that I'm rendering the basket/cart with XSLT by doing this:

    <xsl:variable name="orderTotal" select="$basket/purchaseOrder/@orderTotal" />

    But I take that's a not a big deal?

  • Bo Damgaard Mortensen 719 posts 1207 karma points
    May 08, 2012 @ 16:35
    Bo Damgaard Mortensen
    0

    Alright, so I think I have found where the "error" occurs :) Just haven't found a fix yet.

    It seems that the GetProductPrice gets called mutiple times when adding to the basket and the last time it gets called, the product.PriceGroupPrices is empty so by returning _base.GetProductPrice(product, catalog), I'm getting the standard/first price every time.

    Any1 know a way around this? :-)

    Thanks in advance.

    Bo

  • Søren Spelling Lund 1797 posts 2786 karma points
    May 09, 2012 @ 08:54
    Søren Spelling Lund
    0

    Sounds like it might be locating a variant without a price for you. Could you check what the values of SKU and VariantSKU of the product passed to you are?

    And also check if you have a row in uCommerce_Product with the same SKU and VariantSKU and whether it's got any prices assigned?

    By default uCommerce will use the price of the product family for variants if no price is given in the price group configured for the catalog. Is this the behavior you're seeing?

  • Bo Damgaard Mortensen 719 posts 1207 karma points
    May 09, 2012 @ 09:13
    Bo Damgaard Mortensen
    0

    Hi Søren, funny you mentioned it. The first thing I did today was to query the database directly with the products SKU and it returned two records, so you are certainly right: there was a variant with no prices on it - everything works as it should now.

    Thank you so much for your great support - that's just pure awesomeness! :)

  • Bo Damgaard Mortensen 719 posts 1207 karma points
    May 09, 2012 @ 09:20
    Bo Damgaard Mortensen
    0

    Funny thing though is that there actually are a pricegroup defined on the catalog :) It's just the dropdownlist that appears when clicking the product catalog, right?

  • Søren Spelling Lund 1797 posts 2786 karma points
    May 09, 2012 @ 10:03
    Søren Spelling Lund
    0

    You should be seeing the price from the product family in the configured price group. Can you confirm that that's the behavior you're seeing?

  • Bo Damgaard Mortensen 719 posts 1207 karma points
    May 09, 2012 @ 10:26
    Bo Damgaard Mortensen
    0

    Right now it is like this:

    When I'm not logged in it displays the standard pricegroup price called "DKK 25 pct" which works just fine.

    When I am logged in it displays the "Forhandlerpris" pricegroup price instead of the "DKK 25 pct" pricegroup price on the products. Even if the variants prices are not defined.

    Now, when the variants pricegroup prices are not set and I click "add to basket", the pricegroup price "DKK 25 pct" is added to the basket, when I'm logged in.

    When the variants of a product pricegroup prices are set and I click "add to basket" the correct pricegroup price ("Forhandlerpris") is added to the basket as it should.

    That's the scenario as it is at the moment ;-) 

  • Bo Damgaard Mortensen 719 posts 1207 karma points
    May 09, 2012 @ 10:27
    Bo Damgaard Mortensen
    0

    doublepost

  • Søren Spelling Lund 1797 posts 2786 karma points
    May 09, 2012 @ 10:39
    Søren Spelling Lund
    0

    And the price service is not called at all when the variants prices are not set?

  • Bo Damgaard Mortensen 719 posts 1207 karma points
    May 09, 2012 @ 10:42
    Bo Damgaard Mortensen
    0

    Yep, it's called for each variant and if the variants pricegroup prices are not defined it returns the default pricegroup defined on the catalog, if that makes sense? ;-)

  • Søren Spelling Lund 1797 posts 2786 karma points
    May 09, 2012 @ 10:59
    Søren Spelling Lund
    0

    That makes sense. That's the expected behavior.

    Internally the default pricing service uses the GetProductPrice(Product, PriceGroup) to do exactly what you describe.

  • Søren Spelling Lund 1797 posts 2786 karma points
    May 09, 2012 @ 11:00
    Søren Spelling Lund
    0

    For uCommerce 3 I'm considering removing of one the two methods to avoid confusing as to which one to override. One is really just there for convenience and it ends up not being that convenient after all :)

  • Bo Damgaard Mortensen 719 posts 1207 karma points
    May 09, 2012 @ 11:38
    Bo Damgaard Mortensen
    0

    Thanks Søren,

    I think removing the first method would make sense :-)

    So, the million dollar question would now be:

    Is it possible for each variant to just return the price specified under the "Price" tab on a product? Commerce-wise it wouldn't make much sense to "override" the variant prices, but this is a request by the client.

    My initial thought was to just query the database for every call to the PricingService and return the price based on the product SKU rather than the variantSku. Maybe? :-)

  • Bo Damgaard Mortensen 719 posts 1207 karma points
    May 09, 2012 @ 13:10
    Bo Damgaard Mortensen
    1

    Alright, I think I've solved it now :-)

    The complete code:

    public UCommerce.EntitiesV2.PriceGroupPrice GetProductPrice(UCommerce.EntitiesV2.Product product, UCommerce.EntitiesV2.ProductCatalog catalog)
            {
                if (!Member.IsLoggedOn())
                {
                    return _base.GetProductPrice(product, catalog);
                }
                else
                {
                    var p = Product.All().Where(x => x.Sku == product.Sku && x.ParentProductId == null).FirstOrDefault();                               
                    PriceGroupPrice priceGroupPrice = null;
                    if (p.PriceGroupPrices.Count > 0)
                    {
                        foreach (var pg in p.PriceGroupPrices)
                        {
                            if (pg.PriceGroup.Name.Equals("Forudbestillingspris"))
                            {
                                return pg;
                            }
    
                            if (priceGroupPrice == null && pg.PriceGroup.Name.Equals("Suppleringspris"))
                            {
                                return pg;
                            }
                        }
                    }
    
                    if (priceGroupPrice == null)
                        return _base.GetProductPrice(product, catalog);
                    else                
                        return _base.GetProductPrice(product, catalog);                
                }
            }

    So, basically I'm only interested in the main products pricegroup prices and not the variants, which is why I make a db call to get the product by it's SKU rather than the variantSku.

    Seems to work :-)

  • Esben Seindal 2 posts 22 karma points
    Jul 08, 2013 @ 13:21
    Esben Seindal
    0

    Hey Søren/Bo

    Is Ucommerce Enterprise Edition required to use this functionality?? 

Please Sign in or register to post replies

Write your reply to:

Draft