Developer forum

Forum » Development » Shipping/Delivery price modifier

Shipping/Delivery price modifier

Vilius Janulis
Reply
Hi,

I would need some help with Shipping/Delivery price modifier.
Basically what we need is to calculate differently and display delivery/shiping price in cart/order.

We tried using FeeProvider.cs, OrderTempalteExtender.cs, OrderLineTemplateExtender.cs, EcomCartLoadedObserver.cs and non of them fired any events.
How theoretically this should be done and what template should be used, to get / change depending on other product values /and print back the deliver price in the cart and order ?

Thank you. 

Replies

 
Nicolai Høeg Pedersen
Reply
A feeprovider does this...

Could you be a little more specific? Submit your code from your feeprovider?

Thanks!

 
Vilius Janulis
Reply
 Sorry for delay, but it seems that even your FeeProvider example does not work here.

 public override Dynamicweb.eCommerce.Prices.PriceRaw FindFee(Dynamicweb.eCommerce.Orders.Order Order)
        {
            Dynamicweb.eCommerce.Prices.PriceRaw ReturnFee = null;
            Order.AllowOverridePrices = true;
            
            ReturnFee = new Dynamicweb.eCommerce.Prices.PriceRaw(9.00, Dynamicweb.eCommerce.Common.Application.DefaultCurrency);

            return ReturnFee;
            throw new NotImplementedException();
        }

Code is completely from example in the FeeProvider code, just removed logic, and left hard coded value (9.00) but the delivery fee is still always 0 in frontend. Maybe some other example ? or suggestions with what could causes this?
 
Jeppe Eriksson Agger Dynamicweb Employee
Jeppe Eriksson Agger
Reply
Any specific reason you set AllowOverridePrices to true?

- Jeppe
 
Vilius Janulis
Reply
 No - sorry forgot to remove it with all my test and tries :) it does not work with it or without it :) Removed all other delivery price options from the solution so it wont be overriding.
 
Vilius Janulis
Reply
 Also tried to used debug methods like : 

Base.SetGs("/Globalsettings/Test/Test/Value2", "Test2");

Did nothing, it seems that this event or extender is not called at all.
 
Jeppe Eriksson Agger Dynamicweb Employee
Jeppe Eriksson Agger
Reply

Have you verified that your class has the correct public modifier?

public class myFeeProvider
and not just
class myFeeProvider

 
Vilius Janulis
Reply
 as in template :
 public class FeeProvider1 : FeeProvider
 
Vilius Janulis
Reply
 Any ideas ? :)
Is there other default template that can be used to get same results (task in first thread) ?

By the way version of DW is 8.
I have used the default templates that can be downloaded from developer site for visualstudio.
The solution is almost fully clean, and with more or less newest application version.
 
Imar Spaanjaars Dynamicweb Employee
Imar Spaanjaars
Reply
Hi Vilius,

Are you sure that the assembly with your FeeProvider ends up in the Bin folder of your web site? I just tried it myself and it works fine. Here's what i did:

1. Setup a new Custom Solution

2. Added a FeeProvider using the Dynamicweb 8 | eCommerce template.

3. Modified the code as follows:

using System;
using Dynamicweb.eCommerce.Common;
using Dynamicweb.eCommerce.Orders;
using Dynamicweb.eCommerce.Prices;

namespace CustomModulesDemo
{
  public class FeeProvider1 : FeeProvider
  {
    public override PriceRaw FindFee(Order Order)
    {
      return new PriceRaw(11.00, Application.DefaultCurrency);
    }
  }
}

4. Compiled the application

5. Went to the frontend and added something to the cart.

6. My cart summary immediately showed 11 as the delivery fee.

FYI: I was using the Bikez demo which is setup to show the fee in the Cart summary. Could it be that the value is there, but simply not displayed? Have you looked at the available tags using DwTemplateTags?

FYI2: I tested this on DW 8.0.1.2.

Cheers,

Imar
 
Vilius Janulis
Reply
Thanks for help :)

Actually everything did almost the same.
 
But just to be sure, tried your step-by-step suggestion, and it did not helped!
 
Version :
Dynamicweb.dll 8.0.1.3 
Standard cart template with standard options and etc.
 
Added copy of your code to my FeeProvider, added it to bin, added it to CustomModules folders (one at the time), excluded all custom modules. Compiled and did not worked.
 
Checked DwTempalteTags, there is not value of 11, and delivery/shiping fee is still 0.


Actually i have tried to add it in backend the shipping fee, and it still is 0 ... so that is maybe why the fee provider also does not work. Removed all discounts all other shipping, checked all products, all stock levels and everything else i could think of, even though i have inserted that one in backend it does not work. Checked dont have any module, provider or extender to change that to 0.



 
Any other suggestions ? :) Could there be something with solution ?

 
Imar Spaanjaars Dynamicweb Employee
Imar Spaanjaars
Reply

>> Any other suggestions ?

Not a lot.... ;-)

A few things I can think of:

1. Check the assembly in your Bin folder (e.g. /Bin for your web site) and look at the code with Reflector. Is your assembly there?

2. Check in the Management Center to see how the shipping provider is set up. Maybe you have "No fee for orders over" set to a low number? (Not sure how this affects things, and whether or not this should overrule a custom fee provider though).

I'll check with your version later today to see if the problem may be in that release.

Cheers.

Imar

 
Imar Spaanjaars Dynamicweb Employee
Imar Spaanjaars
Reply
Hmmmmm, I can see something weird's going on indeed. I repeated my steps by setting up a Bikez demo using 8.0.1.3. Ran the site, added something to my cart and saw my custom fee provider's value showed up just fine.

I then went into Management Center and deleted both existing fee providers. Went back to the frontend, and no longer saw the fee. Went back into Management Center and created a few new fee providers, but the value still doesn't show up in the frontend.

I then restored my Bikez demo database, went to the frontend, added something to my cart and voila: had the delivery fee added to the cart again.

Looks like a bug to me, and hopefully these steps are enough for someone from DW DK to reproduce and fix this.

Cheers,

Imar
 
Morten Snedker
Reply

 Copy that!

 

/Snedker

 
Vilius Janulis
Reply
 Thanks for help and confirmation :)

Have tried now to downgrade to 8.0.1.2. did not helped me, and since it will take some time and i even cant do that by myself (restore database), what should i do ? :)

Other possibilities to add this functionality ? Other eCom template maybe ? or something ? :)
Or is the restore of database and not touching the shipping option is the only way for now :) ?

 

Thank you all for help/

 
Imar Spaanjaars Dynamicweb Employee
Imar Spaanjaars
Reply
Hopefully Morten's "Copy that" means they are looking into it....

Imar

 
Vilius Janulis
Reply
Can anyone confirm that is being looking at ? :)
I just need to know should i wait for fix or best workaround or should i try to think of something else :)

Thank you.

 
Vladimir
Reply
Hi guys!
I had looked at this on some application version...

And I didn't able to repeat Imar's tests
 - in part of:
5. Went to the frontend and added something to the cart.
6. My cart summary immediately showed 11 as the delivery fee.

As I see in code, FeeProvider begin to work only if any shipping method is assigned for order.
But before shipping fee is calculated, there is a notification - "Notifications.eCommerce.Order.BeforeShippingFeeCalculation".
You can handle him and assign any shipping method you want if it not assigned yet
 -  I hope this will
acceptable solution...

Best regards,
Vladimir

 
Vilius Janulis
Reply
 Hey Vladimir,

really thank you for you help, will try with that "Notifications.eCommerce.Order.BeforeShippingFeeCalculation" since i am out of ideas now.
Can i ask you to share the simplest example with this notification ?
 
Vladimir
Reply
Hi Vilius!
ok, not problem:

    <Dynamicweb.Extensibility.Subscribe(Dynamicweb.Notifications.eCommerce.Order.BeforeShippingFeeCalculation)> _
    Public Class EcomOrderBeforeShippingFeeCalculationObserver1
        Inherits Dynamicweb.Extensibility.NotificationSubscriber

        Public Overrides Sub OnNotify(ByVal notification As String, ByVal args As Dynamicweb.Extensibility.NotificationArgs)
          Dim beforeShippingFeeCalculationArgs As Dynamicweb.Notifications.eCommerce.Order.BeforeShippingFeeCalculationArgs = TryCast(args, Dynamicweb.Notifications.eCommerce.Order.BeforeShippingFeeCalculationArgs)
          If beforeShippingFeeCalculationArgs IsNot Nothing Then
                If String.IsNullOrEmpty(beforeShippingFeeCalculationArgs.Order.ShippingMethodID) Then
                    beforeShippingFeeCalculationArgs.Order.ShippingMethodID = "SHIP1"
                End If
          End If
        End Sub

    End Class


 
Morten Snedker
Reply
 We are all eyes and looking into as never before! :-)

I'll get back with a response asap.

/Snedker
 
Bo Møller
Reply
Hi all, I'm one of Vilius' coworkers.
Morten Snedker asked me to add a further description of the problem, so here goes:

We select a delivery method in the EcomOrderBeforeShippingFeeCalculationObserver.
At the same time we set a FindFee in the FeeProvider.
This works perfect - the FIRST time.

If we change the FeeProvider after this, it will never work again.

 
Vladimir
Reply
Hello Bo,
sorry, I do not understand clearly that you have going on: (
what do you mean by change of FeeProvider?

can you explain a little more detail? screenshot / code of FeeProvider would be great :)

Best regards,
Vladimir

 
Jackie Nagel
Reply
 I'm yet another of Vilius' co-workers, who've taken over on this project. What we do is that we create the following EcomOrderBeforeShippingFeeCalculationObserver, to select a shipment method:

using Dynamicweb;
using Dynamicweb.eCommerce.Prices;
using Dynamicweb.eCommerce.Common;
using System.Xml;
using System.IO;

namespace CustomModules.CustomModules
{
    [Dynamicweb.Extensibility.Subscribe(Dynamicweb.Notifications.eCommerce.Order.BeforeShippingFeeCalculation)]
    public class EcomOrderBeforeShippingFeeCalculationObserver1 : Dynamicweb.Extensibility.NotificationSubscriber
    {
        public override void OnNotify(string notification, Dynamicweb.Extensibility.NotificationArgs args)
        {
            Dynamicweb.Notifications.eCommerce.Order.BeforeShippingFeeCalculationArgs beforeShippingFeeCalculationArgs = args as Dynamicweb.Notifications.eCommerce.Order.BeforeShippingFeeCalculationArgs;

            beforeShippingFeeCalculationArgs.Order.ShippingMethodID = "SHIP5";
            
        }
    }
}
We also have a FeeProvider running at the same time to modify the deliveryfee. This has to be changed from a webservice in the future, so this fee will be calculated uniquely for the order. What we do right now is:

using Dynamicweb.eCommerce.Orders;
using Dynamicweb.eCommerce.Prices;
using Dynamicweb.eCommerce.Common;

namespace CustomModules.CustomModules
{
    public class FeeProvider1 : FeeProvider
    {
        public override Dynamicweb.eCommerce.Prices.PriceRaw FindFee(Dynamicweb.eCommerce.Orders.Order Order)
        {
            return new PriceRaw(100.00, Application.DefaultCurrency);
        }
    }
}
This all works perfectly the first time we try it. If we modify the price in the FeeProvider, recompile and reupload, we'll still receive the price that was set in the old FeeProvider.

I'd happily submit if this is wrong method for solving our problem, but according to the FeeProvider specification, this should be the way to go.

Hope this helped, and I'd happily answer more if it should be to any help! :-)

//Jackie Nagel

 
Vladimir
Reply
Hi Jacki,
any oder can be in 2 states - when it calculated - before checkout process.
And when it completed - in that states different fees aren't changeable - and it's right.

As I understand, you try to change fee for completed order?
(Because of when you place a new dll in bin, application pool should been restarted - and not completed orders are disappeared)

Regards,
Vladimir

 
Jackie Nagel
Reply
 Hello! :-)

We're trying to calculate the shipping fee for the order before the cart is shown.

Are we doing something wrong by doing it the way we're trying to? If so then we'd very much appreciate a solution to our problem. As mentioned earlier, then the FeeProvider should be our desired choice for solving this problem, but are we wrong to think this?

We're not stating that it doesn't work - we're just wondering what to use to solve our problem! :-)
 
Vladimir
Reply
Hi Jackie
I think you're doing it right:)
Check only please - when you say that the price has remained old, did you checked the property Order.ShippingFee? And also, please ensure that the property Calculate == true

well, ... a naive question - is it possible to describe all the logic in a single fee provider, why you create a new?

Regards,
Vladimir


 
Jackie Nagel
Reply
 Hi again.

The FindFee method is NEVER invoked.Our problem is now down to setting the shippingfee on a specific order - we don't mind where it is set, if just we can set it somewhere. We've now also tried setting the shipping fee on a EcomCartBeforeRenderingNewStepObserver, but as on all other orders, the ShippingFee property is read only.

What it all comes down to now is - how would you set a shipping fee on a specific order?

 
Vladimir
Reply
Hi Jackie!
ShippingFee is really read only property, but it will recalculate when you read it(if Calculate == true).

Regards,
Vladimir
 
Jackie Nagel
Reply
Calculate is yet another read-only property, and it won't really calculate at any point of time we're navigating through the checkout process. Our solution has now come down to explicitly creating a new FeeProvider object and call the FindFee with the order as param at the correct point in time.

The only problem we're experiencing then is that we're having the well-known 'running twice bug', but alas, we just gotta live with that. Thanks for the guidance guys. :-)

public class EcomCartBeforeRenderingNewStepObserver1 : Dynamicweb.Extensibility.NotificationSubscriber
    {
        public override void OnNotify(string notification, Dynamicweb.Extensibility.NotificationArgs args)
        {
            Dynamicweb.Notifications.eCommerce.Cart.BeforeRenderingNewStepArgs beforeRenderingNewStepArgs = args as Dynamicweb.Notifications.eCommerce.Cart.BeforeRenderingNewStepArgs;

            if (beforeRenderingNewStepArgs.StepIndex == 2) {
                Order order = beforeRenderingNewStepArgs.Order;
                FeeProvider1 fee1 = new FeeProvider1();
                fee1.FindFee(order);
            }
        }
    }

 
Jeppe Eriksson Agger Dynamicweb Employee
Jeppe Eriksson Agger
Reply

You said that you were trying to get the FeeProvider invoked before the user enters the Cart, correct? Have you set the default methods in the Management Center -> eCommerce -> Advanced configuration -> Shopping Cart -> Default methods, Shipping? Setting this will cause the Cart to apply the shipping fee to the order as soon as it's created.

Not sure this will have any effect on you issue, but it might be worth a try.

- Jeppe

 
Jackie Nagel
Reply
 It was set as default, but unfortunately still didn't trigger the FindFee method.
 
Jackie Nagel
Reply
It seems like this project just does not want to end. 

The problem is now that we're setting the Shipping Fee correctly, and it is shown on one step in the cart, but the shipping fee doesn't show on the receipt or the orderconfirmation email.

Is this a matter of order.Save() is invoked at the wrong time or is there anything else that we're missing? :-)

Thanks alot for the help in advance - it would really be nice to find a solution in this matter! :-)
 
Vladimir
Reply
Hi Jackie!
Sorry, but to help you, I should know:
1) how you set Shipping Fee (seems to be not quite correctly...)?
2) what template do you use on precheckout step (step 2?)?
 
Jackie Nagel
Reply
 This is our classes that are used for changing the shipping fee:

EcomCartBeforeRenderNewStepObserver.cs:
using Dynamicweb;
using Dynamicweb.eCommerce.Orders;
using Dynamicweb.eCommerce.Prices;

namespace CustomModules.CustomModules
{
    [Dynamicweb.Extensibility.Subscribe(Dynamicweb.Notifications.eCommerce.Cart.BeforeRenderingNewStep)]
    public class EcomCartBeforeRenderingNewStepObserver1 : Dynamicweb.Extensibility.NotificationSubscriber
    {
        public override void OnNotify(string notification, Dynamicweb.Extensibility.NotificationArgs args)
        {
            Dynamicweb.Notifications.eCommerce.Cart.BeforeRenderingNewStepArgs beforeRenderingNewStepArgs = args as Dynamicweb.Notifications.eCommerce.Cart.BeforeRenderingNewStepArgs;

            if (beforeRenderingNewStepArgs.StepIndex == 2) {
                Order order = beforeRenderingNewStepArgs.Order;
                FeeProvider1 fee1 = new FeeProvider1();
                fee1.FindFee(order);
                order.Save();
            }
        }
    }
}
FeeProvider.cs:
using System;
using System.Data;
using Dynamicweb;
using Dynamicweb.Frontend;
using Dynamicweb.eCommerce;
using Dynamicweb.eCommerce.Orders;
using Dynamicweb.eCommerce.Products;
using Dynamicweb.eCommerce.Prices;
using Dynamicweb.eCommerce.International;
using System.IO;
using System.Xml;
using System.Net;
using System.Text;

namespace CustomModules.CustomModules
{
    public class FeeProvider1 : FeeProvider
    {
        public override Dynamicweb.eCommerce.Prices.PriceRaw FindFee(Dynamicweb.eCommerce.Orders.Order Order)
        {
            Order.ShippingMethodID = "SHIP5";

            //Prepare xml for webservice (taken out in this example since it has secret information)

            string outputxml = "xml_in=" + sw.ToString();

            System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
            Byte[] bytes = encoding.GetBytes(outputxml);

            WebRequest request = WebRequest.Create("http://iconnection.tnt.com:81/PriceGate.asp");
            ((HttpWebRequest)request).UserAgent = "PriceGate_socket/1.0";
            request.Method = "POST";
            request.ContentLength = bytes.Length;
            request.ContentType = "application/x-www-form-urlencoded";

            Stream dataStream = request.GetRequestStream();
            dataStream.Write(bytes, 0, bytes.Length);
            dataStream.Close();

            WebResponse response = request.GetResponse();

            //context.Response.Write(((HttpWebResponse)response).StatusDescription);
            Stream data = response.GetResponseStream();

            Encoding encode = System.Text.Encoding.GetEncoding("utf-8");

            // Pipe the stream to a higher level stream reader with the required encoding format. 
            StreamReader readStream = new StreamReader(data, encode);
            Char[] read = new Char[256];

            // Read 256 charcters at a time.    
            int count = readStream.Read(read, 0, 256);

            string responsexml = "";
            while (count > 0)
            {
                // Dump the 256 characters on a string and display the string onto the console.
                String str = new String(read, 0, count);
                responsexml += str;
                //context.Response.Write(str);
                count = readStream.Read(read, 0, 256);
            }

            // Release the resources of stream object.
            readStream.Close();
            response.Close();

            double returnPrice = 0.0;

            //Parsing the xml response to get the returnprice

            return new Dynamicweb.eCommerce.Prices.PriceRaw(returnPrice, Dynamicweb.eCommerce.Common.Application.DefaultCurrency);
        }
    }
}
Thats all - I've altered the  code since it has sensitive information - it's quite urgent so a quick solution to this would be awesome! :-)
 
Jeppe Eriksson Agger Dynamicweb Employee
Jeppe Eriksson Agger
Reply

Hi Jackie

I think I know what the problem is now. I see you're using BeforeRenderingNewStepArgs.StepIndex. There is a bug regarding this property where the step index is always 0. This has been fixed on 23 March 2012 and will be out with the next service release (8.0.2.0) which--hopefully--will be out on Monday (2 April 2012).

- Jeppe

 
Vladimir
Reply
Just a little optimization of EcomCartBeforeRenderNewStepObserver.cs:
using Dynamicweb;
using Dynamicweb.eCommerce.Orders;
using Dynamicweb.eCommerce.Prices;
 
namespace CustomModules.CustomModules
{
    [Dynamicweb.Extensibility.Subscribe(Dynamicweb.Notifications.eCommerce.Cart.BeforeRenderingNewStep)]
    public class EcomCartBeforeRenderingNewStepObserver1 : Dynamicweb.Extensibility.NotificationSubscriber
    {
        public override void OnNotify(string notification, Dynamicweb.Extensibility.NotificationArgs args)
        {
            Dynamicweb.Notifications.eCommerce.Cart.BeforeRenderingNewStepArgs beforeRenderingNewStepArgs = args as Dynamicweb.Notifications.eCommerce.Cart.BeforeRenderingNewStepArgs;
 
            if (beforeRenderingNewStepArgs.StepIndex == 2) {
                Order order = beforeRenderingNewStepArgs.Order;
                order.ShippingMethodID = "SHIP5";
                order.Save();
            }
        }
    }
}
and can you check that ShippingMethodID of completed orders is still "SHIP5"?
 
Jackie Nagel
Reply
 If I'm not explicitly calling the FeeProvider then it's never getting invoked - how would removing the line optimize the code then? :-)
 
Imar Spaanjaars Dynamicweb Employee
Imar Spaanjaars
Reply

I am following this thread with great interest. It seems that a lot of work is involved to have the FeeProvider being called. Isn't this simply a bug and should the FeeProvider be called anyway, regardless of setup in the backend or messy custom code?

Imar

 
Bo Møller
Reply
 Yes - I'm following this too.

It seems waaay to complitcated to call this FeeProvider. A fix could be really nice :-)
If someone could simply provide an example of a FeeProvider that acutally works (Please test your example a couple of times) - that would simply be great! :)
 
Jackie Nagel
Reply
 Hello again! :-)

I've changed it to Vladimir's code and my FeeProvider is actually being invoked now without me instantiating it first. I guess that has optimezed the code a bit.

The problem is still existent tho - on the receipt there's no shippingmethod selected at all - only on the given step. How should we save it so we're sure it saved correctly?

And yet again - thanks for all the support, we'd really love to close this case asap! :-)
 
Jackie Nagel
Reply
 and the StepIndex can't always be 0 if my method ShippingMethodID is being set on that exact step but not persisted.

Is it the default shipping that is taking effect?

We haven't experienced any problems with the StepIndex always being 0 because our webservice request is always invoked at the correct time? :-)
 
Vladimir
Reply
Jackie!! there was a question in my post:)) btw an additional: am I right that delivery payment is absent when you see the order details in admin interface?
 
Jackie Nagel
Reply
 Yes it is absent in the admin interface - and I've already answered your question. The ShippingMethodID is not set on further steps in the cart :-)
 
Vladimir
Reply
Hi Jackie,
I created some tests with such observer and such provider and had got same situation only when my Shipping (SHIP5) wasn't assigned with country of area. Hope this is only the reason of all fails...
Look at Country fees tab

Best regards,
Vladimir

 
Jackie Nagel
Reply
Thanks alot Vladimir (and others!) for helping us on this matter - it works like a charm now! :-)
 
Vladimir
Reply
:'-)
 
Jackie Nagel
Reply
 Just as we thought we were done yet another thing seems to have sprung out. After making these modifications to our order flow the solution is not sending any order confirmation emails out anymore. What can cause this from modifying the FeeProvider and the StepBeforeRenderObserver?

We've checked the email-settings accordingly to the documentation, but it still doesn't send any mails out :-(
 
Vladimir
Reply
Hi Jackie,
this is definitely not related with modifying of FeeProvider and the StepBeforeRenderObserver (in any case you can easy check this by removing them). I think the cause is that the IIS mail pickup service is down(check, is any emails are still sending?) or something with settings - if you provide me your solution url I can check settings...

Regards,
Vladimir

 
Jackie Nagel
Reply
 That would be amazing vladimir - it's running on the url below. We've been through partnersupport and were told that it could have something to do with out customcode, which I highly doubt. But thanks Vladimir! :-)
obel-p-group.dk
 
Vladimir
Reply
Hi Jackie!
I found a lot of log files with error messages: "Could not load type 'CheckoutDoneOrderIsCompleteArgs' from assembly 'Dynamicweb, Version=8.0.0.0, Culture=neutral, PublicKeyToken=null'.".  You can see them throught file manager in System/log/eCom/Cartv2/Errors folder. I'm not yet ready to say what is the reason of these errors - do you use somewhere in customcode EcomCartCheckoutDoneOrderIsCompleteObserver ? These cases occur because of mismatch of version number of Dll's references to other component. Make sure that from low level every thing is compiled and referenced to the other.

Regards,
Vladimir

 

You must be logged in to post in the forum