Developer forum

Forum » Development » Implementing a custom PriceProvider using different units

Implementing a custom PriceProvider using different units

Martijn van Tongeren
Reply

I'm trying to implement a custom price provider that calculates the price according to a specified unit.

We have a custom table containing the information how to calculate from one unit to another:

ProductId FromUnit ToUnit Factor
1 piece m2 278
1 piece package 3000
... ... ... ...

As far as I can see, Dynamicweb doesn't support converting between units using a factor like above. So now I'm trying to solve this by implementing Dynamicweb.Ecommerce.Prices.PriceProvider.

I see the method FindPrice already receives a unitId parameter. So my first attempt was the following (simplified) implementation:

        public override PriceRaw FindPrice(Product product, double quantity, string variantId, Currency currency,
            string unitId, User user)
        {
            var defaultProvider = new DefaultPriceProvider();
            var price = defaultProvider.FindPrice(product, quantity, variantId, currency, unitId, user);

            if (string.IsNullOrEmpty(variantId)) return price;

            var defaultUnit = product.DefaultUnitId;
            var unitFactor = UnitService.Instance.GetUnitConversionFactor(int.Parse(product.Number), defaultUnit, unitId);
            price.Price *= unitFactor;

            return price;
        }

But thusfar I cannot find a way to call this method (from a template) using a specific unitId.
I tried:

        @foreach (var unit in GetLoop("Units")) {
            @unit.GetValue("Ecom:VariantOption.Price.Price")
        }

This does call FindPrice multiple times, but unitId is always empty.
Even if the above would call FindPrice with a unit, the loop only contains items based on the stock matrix if I'm not mistaken. And in our case we don't manage stock information in Dynamicweb, so I'd rather not have to populate these tables in order to get the price for a specific unit.


Replies

 
Nicolai Pedersen
Reply

Hi Martijn

Try calling PriceManager.FindPrice in side the loop instead of using a template tag: http://doc.dynamicweb-cms.com/api/html/e734936a-c807-a58c-9680-6d581ee4353a.htm

BR Nicolai

 
Nicolai Pedersen
Reply

Oh - that method returns an "object" that needs to be converted to either a PriceRaw or PriceInfo

 
Nicolai Pedersen
Reply

Something like this:


    PriceInfo priceInfo = null
    object price;
    if (price != null)
    {
        if ((price) is PriceInfo)
            priceInfo = (PriceInfo)price;
        else if ((price) is PriceRaw)
        {
            PriceRaw priceRaw = (PriceRaw)price;
            priceInfo = new PriceCalculated(Product, priceRaw);
        }
    }

 

 

 

 
Martijn van Tongeren
Reply

Thanks for your fast reply.

Your approach requires an instance of the Product.
Do I have access to this object inside a template? Or is it okay (performance-, and security-wise) to get this item using the products service inside a template?

 
Martijn van Tongeren
Reply
Original message by Nicolai Pedersen posted on 06/11/2018 14:23:28:

Something like this:


    PriceInfo priceInfo = null
    object price;
    if (price != null)
    {
        if ((price) is PriceInfo)
            priceInfo = (PriceInfo)price;
        else if ((price) is PriceRaw)
        {
            PriceRaw priceRaw = (PriceRaw)price;
            priceInfo = new PriceCalculated(Product, priceRaw);
        }
    }

 

 

 

The PriceCalculated constructor in your example is marked as deprecated.

 
Nicolai Pedersen
Reply

Hi Martijn

You have a productid and variant id and need to find the product in the product service. The only way I see. It should be relatively ok performance wise, but you have to look into it.

Use one of the other cunstructors instead.

BR Nicolai

 

You must be logged in to post in the forum