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? ;-)
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.
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 ...; } } }
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.
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? :)
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.
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?
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! :)
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?
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.
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? ;-)
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 :)
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? :-)
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.
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
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.
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
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):
And in your components.config, change:
To:
- Lasse
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:
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
Alright, got it to display the correct pricegroup price with the following code:
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 ..
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.
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
OK.
Try overriding both methods just to make sure. Just have one forward to the other.
That's exactly what I did (I think :-P) the complete code of my serviceclass:
They basically do the exact same thing :) Although it seems like the first method is never really called (?)
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?
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
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?
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! :)
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?
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?
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 ;-)
doublepost
And the price service is not called at all when the variants prices are not set?
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? ;-)
That makes sense. That's the expected behavior.
Internally the default pricing service uses the GetProductPrice(Product, PriceGroup) to do exactly what you describe.
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 :)
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? :-)
Alright, I think I've solved it now :-)
The complete code:
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 :-)
Hey Søren/Bo
Is Ucommerce Enterprise Edition required to use this functionality??
is working on a reply...