Developer forum

Forum » Development » Initiate new Cart/Order and full it products

Initiate new Cart/Order and full it products

Dmitrij Jazel
Reply
Hello DW guys,

I wanted to ask you if it is possible to make new Cart/Order in runtime?
Lets' say, you have an event, and you need it to make new order (you make cart and fill it with products), for specific user.

To avoid some problems with existing cart, I should check if the current cart of the current user contains any items, if it exists I should replace that cart with my custom filled cart.

To do this, I need to get to the current users shopping cart object.
Could anyone please help me here?

Thanks allot for the help in advance :-)

Dmitrij 

Replies

 
Jeppe Eriksson Agger Dynamicweb Employee
Jeppe Eriksson Agger
Reply
This post has been marked as an answer

Hi Dmitrij

The Dynamicweb.eCommerce.Common.Context.Cart will always contain the Cart--if one exists--for the current user whether he's logged in or not.

So what you could do is something like this:
 

var cart = Dynamicweb.eCommerce.Common.Context.Cart;

if (cart != null)
{
    var newCart = new Order();
    // TODO: Change Cart in what ever fashion you want.

    // Save and persist Cart
    Dynamicweb.eCommerce.Common.Context.SetCart(newCart);
}
Hope this helps :)

- Jeppe
Votes for this answer: 0
 
Dmitrij Jazel
Reply
Hej Jeppe,

Thanks again for the help :-)))
But lets's say if you want to add a product to it on thew fly.
For example, I make a cart object here, I need to fill it, I must get a product instance and add it to order.
Wounder if there is a method line stock.getProductByID(productID) or productNumber.
I could find some stuff here
Dynamicweb.eCommerce.Products.Product
But not sure how to get exact product if I know it's ID or Number.

When I add the product to the cart made on the fly ( as you described above), will the cart have a user assigned, is there a method to assign it?
Cause as I would expect, the cart would automatically apply discount if necessary for any product contained in the cart.

So that when I would make the cart for specific user, when that user views the cart would be great if he/she could see the cart filled accordingly :-)

Can we do something like this?
Kind regards,
Dmitrij
 
Jeppe Eriksson Agger Dynamicweb Employee
Jeppe Eriksson Agger
Reply
Which version of Dynamicweb are you using?
 
Dmitrij Jazel
Reply
It is Application 8.0.1.5 - I am coding against this one... so far so good...
Strangely enough it says "Application 8.0.1.3 - custom" at admin login page

So I guess I should say 8.0.1.5
 
Jeppe Eriksson Agger Dynamicweb Employee
Jeppe Eriksson Agger
Reply

Continuation of the previous code sample from the "TODO":
 

var newCart = new Order();

// Get product from database
var myProduct = Product.GetProductByID(prodID, variantID, languageID);

// Create new orderline based on the product. The orderline is automatically added to the Cart.
newCart.CreateOrderLine(myProduct);

// Save and persist Cart
Dynamicweb.eCommerce.Common.Context.SetCart(newCart);
 
Dmitrij Jazel
Reply
Hmm allright,
But please correct me if I am wrong here...

If I make a order in this way, I would need to assign a user to it eventually.
Than if I do assign a user to the order or order to a user - will discount be applied to the product, if the user group has a discount on this product?

Normally discount is added to the orderlines automatically if the user falls under conditions to get the discount.
But I am making order programatically, I add only product to the orderlines...

As I would imagine in this situation if I could present the user to the order ( or order to a user ) that this would add a discount due to the applicable user was assigned.

I hope you understand what I am trying to explain here. :-)

Cheers,
Dmitrij
 
Jeppe Eriksson Agger Dynamicweb Employee
Jeppe Eriksson Agger
Reply
I have just created a small test where a new Cart is created for the user when he or she logs in. I tested it locally and it works here. Note however that there currently is a bug with Order.CreateOrderLine on live versions of Dynamicweb 8 that will be fixed with the next release/hotfix. I will make a new post after this, showing how to create and add a new orderline to an order.

Anyways, here's the example:
using Dynamicweb.Extensibility;

namespace CartSwapTest
{
    [Subscribe(Dynamicweb.Notifications.Standard.User.OnExtranetLogin)]
    public class CartSwap : NotificationSubscriber
    {
        public override void OnNotify(string notification, NotificationArgs args)
        {
            // New cart
            var newCart = new Dynamicweb.eCommerce.Orders.Order();
            
            // Set Order object to have Cart state.
            newCart.IsCart = true;

            // Get the first product in the current language context - Just a product for test.
            var product = Dynamicweb.eCommerce.Products.Product.GetAllProducts()[0];

            // Add product to the new cart
            newCart.CreateOrderLine(product);

            // Save and persist Cart
            Dynamicweb.eCommerce.Common.Context.SetCart(newCart);
        }
    }
}

Like I said, it's working. The order is swapped, linked to the user, saved and discounts are calculated automatically.

Please be aware though, there's nothing preventing the user from manually emptying the cart :)
 
Jeppe Eriksson Agger Dynamicweb Employee
Jeppe Eriksson Agger
Reply

As promised in the above post, here's an example of how you could create a new OrderLine based on a Product and add it to an Order:
 

        private static void CreateOrderLine(Dynamicweb.eCommerce.Orders.Order order, Dynamicweb.eCommerce.Products.Product product, double quantity)
        {
            if (product == null)
                return;

            var ol = new Dynamicweb.eCommerce.Orders.OrderLine();
            ol.Product = product;
            ol.ProductID = product.ID;
            ol.ProductName = product.Name;
            ol.ProductNumber = product.Number;
            ol.ProductVariantID = string.IsNullOrEmpty(product.VariantID) ? product.VirtualVariantID : product.VariantID;
            ol.ProductVariantText = Dynamicweb.eCommerce.Variants.VariantNumber.VariantName(ol.ProductVariantID, product.LanguageID);
            ol.Quantity = quantity;
            if (product.DefaultUnit != null)
                ol.UnitID = product.DefaultUnit.UnitID;
            ol.SetUnitPrice(product.Price);
            ol.Type = ((int)Dynamicweb.eCommerce.Orders.OrderLine.OrderLineType.Product).ToString();
            ol.Modified = System.DateTime.Now;
            ol.Order = order;

            order.OrderLines.Add(ol);
            order.ClearCachedPrices();
        }

I will not go into too much detail with the different aspects of this, but--for the most part--it should apparent what's going on here. And it should help provide a base to start from :)
 
Dmitrij Jazel
Reply
Hej Jeppe :-)

I know I might drive you crazy by now, but I am VERY appreciated for you help...
But hope you can still help me here, since the issue must be addressed one way or another (you know how it is sometimes)
And thanks gain for on login example.

Only issue here is that the user is (received or accessed so to speak) through the event, that the user is calling when he/she log-ins.
As I actually have to do the same thing in plain method, not just in a new event.
Like when I am writing a custom module in getContent() method. When current user is actually viewing the page, I am getting the frontendUser, making order, adding products to the order, and than the user must make a orderSwap.

From the implementation you povided I have no questions what's so ever, all I need now is the assigning the order to the user not via an event because I cannot use this event. Something like this (this is just some mock code so you get the implementation of the getContent() method):
var user = user();
var order = order();
order(fillWithProducts);

// the part I need
user.swapOrder(order);
Hope that is possible to do :-) I must have this in that method if possible.

Kind regards,
Dmitrij

 
Jeppe Eriksson Agger Dynamicweb Employee
Jeppe Eriksson Agger
Reply

If you look carefully at my example, you'll see that I never get/call/use the current user. It's not needed. Assigning the order to the frontend user happens automatically when you call SetCart.

Have you tried implementing the code at all?

The only reason I used the OnExtranetLogin notification was because it was the one I picked from the bunch. It could just as easily have been a TemplateExtender or something else. The code is still the same.

 
Dmitrij Jazel
Reply
Nahh... ok that's how it is
I am in the process of using all this in different parts of the program. I could see this issue and wanted to address it in advance (this specific orderswap) was not clear to me first. But as you say now that it happens with SetCart call than it is allright!

I must truly thank you for this one, Just wanted to make sure I am with all the info here...

Thank ALOT :-)

Cheers,
Dmitrij
 
Dmitrij Jazel
Reply
Hello Jeppe,

I wanted to ask you for suggestions that you might have.
I am using your CreateOrderLine() method described above.
It does not throw any exceptions now, but when I am checking the cart again, it gives me exactly the same "view" overview of the cart - that is it shows that it was kind-of initiated, but not quite. 0 total price and empty product field. (See attachment)

Could you have any suggestions to help me out with this one?

All I do is simply add a list of products Product.GetProductByID("id here") to the list, and than add each of them into the order. with the method you just provided above.

Maybe there are other alternatives to this method?
Kind regards,
Dmitrij



emptyInitiatedCart.png
 
Jeppe Eriksson Agger Dynamicweb Employee
Jeppe Eriksson Agger
Reply

I have no way of knowing why you're seeing this behavior without looking at your code. My guess would be that you haven't set the newCart.IsCart property to true. This is important because if you don't, you don't get any of the built-in calculations done on your cart object.

 
Dmitrij Jazel
Reply
Hej Jeppe,
Well, that gave me an idea now, and I got interesting results.
I was using this method inside the call as in the method call, before for each.
But Now I tryed to use it outside, instead of Dynamicweb.eCommerce.Common.Context.SetCart(newCart);

And What it did actually that partially did the trick.
I can now add products to cart with my method. Wen I call this method, this method it adds products to ones already existing.
First I thought that it works, but than I could see that in order to add those products you must have atleast 1 product already in the cart.
In other words, you cannot add products to the cart unless unless it is not empty.
I tryed to use .SetCart(newCart) method in different places, but if I use it like after the cart.IsCart it comes back to old behavior...

As CreateOrderLine() method, I am using the implementation you provided above It is identical, and as I can see it does its part.

To this post I attached current implementation of the LoadCart method.
Would be really glad if you could take a look :-)

Kind regards,
Dmitrij

 
Jeppe Eriksson Agger Dynamicweb Employee
Jeppe Eriksson Agger
Reply
You uploaded your code as a .cs file. These files cannot be downloaded.
 
Dmitrij Jazel
Reply
Hej Jeppe,
Nah, sorry for that, here is the txt file...
 
Jeppe Eriksson Agger Dynamicweb Employee
Jeppe Eriksson Agger
Reply
The reason you don't get your cart filled if there is no cart first is because of the first check:

if (cart != null)
{
...

Remove this check and you should be able to create your cart.
 
Dmitrij Jazel
Reply
Allright, here it goes.
Here comes .txt file :-)

 

You must be logged in to post in the forum