Okay.
Our next task is to create the order itself.
And to help us with this, we'll create an create order DTO so that we can take the information we need
from the client.
And we'll create a new file in here.
And it's going to be a class and we'll call it Create Order DTO.
And what information do we need to get to be able to create an order.
And we effectively need to if we go and take a look at the order, what do we need to get from the browser
that we do not already have.
So we're going to have the buyer email.
The ID gets created for us, the shipping address, we don't know.
That's something we will need.
The order date we're initializing anyway.
The order items we get from the basket, the subtotal, delivery fee and discount we can work out for
ourselves the payment intent ID we can also get from the basket the order status we create, and the
payment summary is something else that we need to get from the client.
So the only things we need in our DTO is this payment summary and also the shipping address as well.
That's something that we cannot Not ascertain without getting that information from the browser.
So we'll have a couple of properties in here.
One will be for the shipping address.
And we'll get that from our order aggregates and we'll call it shipping address.
And we'll also have another property in here for the payment summary.
And we'll call it payment summary.
And we'll make both of these required.
Okay.
And then we can go back to our orders controller.
And we'll create the method to create a new order.
So this is going to be an HTTP post.
And we'll specify public async task.
That's an action result.
And we are going to return the order from this once it has been created.
And we'll call it create order.
And we'll pass up as its argument the Create Order DTO.
And we'll just call this order DTO.
So the first thing we'll do is we'll get hold of our basket, so we'll use our baskets.
Or in fact, we can just use the basket ID because we've got inside our extension methods we created
earlier basket extensions.
And we have inside here a get basket with items method that guarantees we get the baskets or throws
an exception if it cannot.
So we'll use this extension methods here.
So in our orders controller we'll use var basket equals and say await and context dot baskets.
And we'll use the get basket with items method.
And we need to pass in our basket ID which we can use the request dot cookies.
And in square brackets we can specify the basket ID.
So next we'll check to see if we have the basket.
So we'll check to see if the basket is equal to null.
Or.
We'll also make sure there's items in the basket as well.
And we'll make sure the basket dot items dot count is equal to zero.
And if that is the case, then we're going to return a bad request and say basket is empty or not found.
And below this we'll create a method to go and get our order items.
So I'll save our items equals create order items.
And we'll pass into this method the basket dot items.
And we'll put our cursor where the arrow is.
And we'll use the quick fix.
And we'll generate the method for creating the order items.
And we'll come back to that.
Following this we will work out our subtotal.
So the var subtotal equals items dot sum.
And we don't have access to the sum yet because we need to specify what we're returning from our create
order items method.
So let's swap object here for a list.
Of type order item.
And then we can work out our subtotal.
So this is going to be items dot.
Start some and we'll use x at the arrow and x dot price multiplied by x dot quantity.
And then we'll add the delivery fee.
So we'll say var delivery fee equals.
And we'll create a method for this as well.
So we'll use calculate delivery fee.
And we'll pass in the subtotal as its parameter.
And we'll put a cursor inside here.
And we'll generate this method as well.
And this is going to return a long.
And again we won't worry about populating the content of that method yet.
And below this we can create our new order.
So we'll say var order equals new order.
And we'll specify our order items is equal to the items the buyer email will set equal to the user dot.
Get username.
The shipping address we can get from our order DTO Auto shipping address.
The delivery fee will equal the delivery fee.
The subtotal will equal the subtotal.
The payment summary will get from our order DTO dot Payment Summary and the payment intent ID will get
from the basket dot Payment intent ID.
And then we can use our context dot orders dot add and pass in the order.
And at this point we can remove our baskets from the dot net side or our back end side of things.
So we'll use context dot baskets dot remove baskets.
And we'll also as a backup delete the cookie as well from here as well.
So we'll say response dot cookies dot delete and pass in the basket ID.
And then we can save our changes into the database.
So I'll say var results equals await context dot save changes async.
And we'll make sure that is greater than zero changes that have been saved into our database.
We'll check the results.
And if say if not results then we will return a bad request and say problem creating order.
And finally we can return the order.
And because we're creating something we're creating a resource in our database.
The correct response for this is a createdat action or created at root or a 201 created result is what
gets them back to the browser.
But we can use a method provided by dotnet called Createdat action.
And for the location header that gets returned, we just want to point to where the client can find
the recently created order.
So we'll use name of and we'll use get order details as this is the method, the endpoint that would
give us the specific order that's been created.
And the order details takes a parameter.
So we need to specify that inside here as the second argument.
And we'll say new in curly brackets we'll use ID equals.
And then we can use the order id as its parameter.
And finally we can return the order from this method.
And that will result in a 201 created being sent back to the browser.
So we've got a couple of methods that don't have any logic inside them.
And we'll call this a challenge.
So your challenge is to populate what we need inside here for both of these different methods.
And please give this a go.
And in the next lesson I'll cover what it is step by step.
What we need to do to get this functionality complete in this controller.