Hi.
I want to apply rounding to the prices so that they always round up when they are being shown in the productlist, but when added to the cart it should be the original price.
So say that i have a product that costs 45,25, it should be rounded up to 46 in the productlisting, but in the
I tried making a ProductListTemplateExtender, but it didnt seem to work at all, didnt get out any tags at all even though the code ran when i debugged.
Is this something that can be done through a templateextender or a NotificationSubscriber?
Thanks in advance
Best regards
Dan
Developer forum
E-mail notifications
Apply rounding to prices
Replies
Hi Dan,
Through template extender for product/productlist, you should be able to achieve rounded prices of displayed products.
Try posting your code..
/Snedker
Hi.
Thanks for your reply.
My code:
public class ProductListTemplateExtender1 : ProductListTemplateExtender
{
public override void ExtendTemplate(Dynamicweb.Rendering.Template template)
{
var col = new ProductCollection();
var product = new Product();
var priceObj = new Dynamicweb.eCommerce.Prices.Price();
foreach (var item in ProductList)
{
product = item;
var price = item.Price.Price;
var newPrice = Math.Ceiling(price);
priceObj.Amount = newPrice;
product.Prices.Add(priceObj);
product.Save();
}
}
}
Best regards
/Dan
Ive also tried creating a loop and set templatetags to see if i could loop out the prices, but for some reason the tags are not rendered.
Hi Dan,
Your attempt with changing the price on the product object is not going to work as the template extender is invoked after the product has been rendered into the template.
You have a few ways of doing this:
- Create a custom PriceProvider (http://developer.dynamicweb.com/documentation/for-developers/ecommerce/extensibility/providers/price-providers.aspx) and returning the correct price for the situation. Not recommended as you need to assume a lot of responsibility for prices in your own code instead of letting Dynamicweb handle it, and you need to handle both product list prices and cart prices.
- Create a BeforeRender notification subscriber (http://developer.dynamicweb-cms.com/api8/#Dynamicweb~Dynamicweb.Notifications.eCommerce+ProductList~BeforeRender.html) and loop the products updating the prices. Simplest solution as you can reuse the existing render functionality and tags. Also very focused solution, as this notification is only broadcast in the product list.
- Create your own set of template tags in a template extender as you've tried (http://developer.dynamicweb.com/documentation/for-developers/ecommerce/extensibility/template-extenders.aspx). Note that if you add your own loop, you need to commit the loop inside your code loop. See example below. This solution is the most atomic, as it does not require you to reuse any existing functionality or tags. Note: you need to link products and their prices yourself, probably using JS in the template, as the products are in one loop and the updated prices are in another.
Example:
var loop = Template.GetLoop("MyPriceLoop"); foreach (var p in ProductList) { // TODO: Manipulate price loop.CommitLoop(); }
You can choose any of the above solutions, or even just create a Razor template and modify the way the price is displayed there, eliminating the need for any custom code. I would recommend either the notification subscriber or the Razor template.
- Jeppe
Hi.
Thanks for your reply.
I think the NotificationSubscriber is what suits my solution the best.
Ive experimented with the "BeforeRender" and i still havent gotten it to work.
Could you provide some examplecode or tell me if im on the right track here?
My code below:
public override void OnNotify(string notification, Dynamicweb.Extensibility.NotificationArgs args)
{
Dynamicweb.Notifications.eCommerce.ProductList.BeforeRenderArgs beforeRenderArgs = args as Dynamicweb.Notifications.eCommerce.ProductList.BeforeRenderArgs;
Product product = new Product();
var priceObj = new Dynamicweb.eCommerce.Prices.Price();
foreach (var item in beforeRenderArgs.Products)
{
var price = item.Price.Price;
var newPrice = Math.Ceiling(price);
priceObj.Amount = newPrice;
item.Prices.Add(priceObj);
item.Save();
col.Add(item);
}
col.SaveAllProducts();
}
Best regards
Dan
You're on the right track. However, there are a few issues.
- A PriceInfo (Product.Price) object consists of multiple properties that constitute the price. These need to handled individually.
- Product.Prices is not related to this. Product.Prices are all the different prices (from the Price configuration on the product, i.e., Price Matrix).
- You do not want to save the product once you're done. These changes are not permanent, but live only in the confines of the product list.
Here is a sample that should help you progress.
using System; using Dynamicweb.eCommerce.Prices; using Dynamicweb.Extensibility; namespace PriceManipulator { [Subscribe(Dynamicweb.Notifications.eCommerce.ProductList.BeforeRender)] public class BeforeRenderObserver : NotificationSubscriber { public override void OnNotify(string notification, NotificationArgs args) { var a = args as Dynamicweb.Notifications.eCommerce.ProductList.BeforeRenderArgs; // Assuming 'a' is not null -- do a check /* * If the Product Catalog has Optimized Product Retrieval turned on * and products are not fetched using Index/Filters, * a.PageProducts and a.Products will contain the same products. */ // Iterating through a.PageProducts for backwards compatibility foreach (var p in a.PageProducts) { RoundPrice(p.Price); } } private static void RoundPrice(PriceInfo price) { // Assuming 'price' is not null -- do a check // Rounding PriceWithoutVAT price.PriceWithoutVAT = Math.Ceiling(price.PriceWithoutVAT); // Rounding PriceWithVAT price.PriceWithVAT = Math.Ceiling(price.PriceWithVAT); // Calculating new VAT price.VAT = price.PriceWithVAT - price.PriceWithoutVAT; } } }
You may want to change the way PriceWithVAT and PriceWithoutVAT are calculated, if they should not both merely be rounded.
- Jeppe
You must be logged in to post in the forum