1
00:00:02,220 --> 00:00:06,120
So the next step is to make this orders page work.

2
00:00:06,120 --> 00:00:07,310
And actually for this,

3
00:00:07,310 --> 00:00:09,496
we'll have to repeat a bunch of logic,

4
00:00:09,496 --> 00:00:13,562
which be repeated over and over again in this section.

5
00:00:13,562 --> 00:00:17,287
We have to work on the HTML code in there,

6
00:00:17,287 --> 00:00:21,620
add some styling for the order items, and then write some

7
00:00:21,620 --> 00:00:23,960
code for fetching all the orders.

8
00:00:23,960 --> 00:00:27,370
That's not too fancy. And therefore, in order to

9
00:00:27,370 --> 00:00:28,571
not bore you,

10
00:00:28,571 --> 00:00:33,230
I finished this online shop since the only missing parts,

11
00:00:33,230 --> 00:00:37,610
really, were the orders-list and the administration of

12
00:00:37,610 --> 00:00:39,760
orders, which I'll show you in a second.

13
00:00:39,760 --> 00:00:44,220
And you'll find a bunch of files attached that contain the

14
00:00:44,220 --> 00:00:46,650
code that I did change.

15
00:00:46,650 --> 00:00:49,570
And of course I will walk through all those changes together

16
00:00:49,570 --> 00:00:50,403
with you,

17
00:00:50,403 --> 00:00:53,540
step-by-step, in great detail so that you fully understand

18
00:00:53,540 --> 00:00:56,536
what I changed and why I did it. Now for that,

19
00:00:56,536 --> 00:01:01,132
it probably makes sense to start in the order model. In

20
00:01:01,132 --> 00:01:05,503
there, I edit a couple of methods for finding orders:

21
00:01:05,503 --> 00:01:09,823
the FindAll and FindAllForUser methods.

22
00:01:10,690 --> 00:01:13,530
I also added a FindById method,

23
00:01:13,530 --> 00:01:16,700
which will become important for managing orders in the

24
00:01:16,700 --> 00:01:20,900
administration interface. But I'll come back to that. Now,

25
00:01:20,900 --> 00:01:24,538
FindAll and FindAllForUser, as you can see, are really

26
00:01:24,538 --> 00:01:27,623
not that special at all. In FindAll,

27
00:01:27,623 --> 00:01:30,214
I really just get all my orders.

28
00:01:30,214 --> 00:01:32,214
I, then, called transformOrderDocuments,

29
00:01:33,130 --> 00:01:35,460
which is just a helper method here,

30
00:01:35,460 --> 00:01:38,534
which maps all my order documents with help of

31
00:01:38,534 --> 00:01:40,550
transformOrderDocument,

32
00:01:40,550 --> 00:01:44,630
which is another helper method into order objects based on

33
00:01:44,630 --> 00:01:47,795
this blueprint. Nothing fancy there. In the end,

34
00:01:47,795 --> 00:01:52,240
I just instantiate a bunch of order objects and I transform

35
00:01:52,240 --> 00:01:55,550
all the order documents from the collection into such order

36
00:01:55,550 --> 00:01:57,330
objects in the end.

37
00:01:57,330 --> 00:02:00,960
That's what I do here and then FindAll for a user

38
00:02:00,960 --> 00:02:04,190
I do almost the same. But there, of course,

39
00:02:04,190 --> 00:02:09,060
I also have this little filter here where I dive into the

40
00:02:09,060 --> 00:02:12,145
user data field, which I have in my order documents,

41
00:02:12,145 --> 00:02:16,959
and then compare the ID of that user to the user ID,

42
00:02:16,959 --> 00:02:20,960
which I get here as a parameter value and which I then

43
00:02:20,960 --> 00:02:23,420
convert into a mongodb.ObjectID(object).

44
00:02:24,860 --> 00:02:25,980
That's all I do.

45
00:02:25,980 --> 00:02:28,936
So, I find the orders that belong to a given user

46
00:02:28,936 --> 00:02:30,803
by the user ID.

47
00:02:31,650 --> 00:02:35,200
I also have this extra sort method called here on this

48
00:02:35,200 --> 00:02:38,000
overall query, and that does what the name implies.

49
00:02:38,000 --> 00:02:42,860
It sorts the documents that are found and I'm sorting by ID

50
00:02:42,860 --> 00:02:45,210
in descending order.

51
00:02:45,210 --> 00:02:46,043
Thankfully,

52
00:02:46,043 --> 00:02:49,827
the ID's created by mongodb do contain a timestamp,

53
00:02:49,827 --> 00:02:52,230
implicitly, and therefore,

54
00:02:52,230 --> 00:02:56,209
we can use IDs to sort the orders such that the latest

55
00:02:56,209 --> 00:02:57,764
orders are on top.

56
00:02:57,764 --> 00:03:01,490
So, I write at the start of the list by simply

57
00:03:01,490 --> 00:03:03,320
sorting by the ID

58
00:03:03,320 --> 00:03:07,143
in descending order so that the latest ID's come first.

59
00:03:08,060 --> 00:03:11,330
We could also sort like this for finding all the orders,

60
00:03:11,330 --> 00:03:14,620
but I use FindAll in the administration interface and we

61
00:03:14,620 --> 00:03:16,790
can actually also sort like this

62
00:03:16,790 --> 00:03:20,670
when we find all orders. Here, we could also add this after

63
00:03:20,670 --> 00:03:22,380
Find before toArray,

64
00:03:22,380 --> 00:03:24,800
and then we would sort these orders as well.

65
00:03:24,800 --> 00:03:28,280
So actually that's another tiny change I'll make here.

66
00:03:28,280 --> 00:03:30,550
So in the attached order.model.js file,

67
00:03:30,550 --> 00:03:33,062
you will find all these changes and you can simply replace

68
00:03:33,062 --> 00:03:36,923
your order.model.js file with mine, of course.

69
00:03:38,040 --> 00:03:41,152
Now, besides that, I have the findById method,

70
00:03:41,152 --> 00:03:42,950
which does what the name implies.

71
00:03:42,950 --> 00:03:45,500
It finds an order by its ID.

72
00:03:45,500 --> 00:03:46,873
Nothing too fancy.

73
00:03:46,873 --> 00:03:49,768
And then I also transformed that foundOrder document into

74
00:03:49,768 --> 00:03:52,703
an instance of this order clause.

75
00:03:53,650 --> 00:03:54,750
And last but not least,

76
00:03:54,750 --> 00:03:58,530
I also added some logic to the save method so that we now

77
00:03:58,530 --> 00:04:00,563
cannot just create new orders,

78
00:04:00,563 --> 00:04:03,330
but that I also can update orders.

79
00:04:03,330 --> 00:04:06,940
If we already have an ID for this given order on which we're

80
00:04:06,940 --> 00:04:09,280
working, then I know that I want to update it.

81
00:04:09,280 --> 00:04:12,138
Then I convert the ID to a mongodb.ObjectID,

82
00:04:12,138 --> 00:04:17,137
and then with updateOne, finding the proper document by ID,

83
00:04:17,286 --> 00:04:19,800
I update that order.

84
00:04:19,800 --> 00:04:22,896
And updating simply means that I update the status because

85
00:04:22,896 --> 00:04:25,795
in this website, that's the only kind of update

86
00:04:25,795 --> 00:04:27,740
I want to allow to orders

87
00:04:27,740 --> 00:04:30,670
that the admin is able to change

88
00:04:30,670 --> 00:04:32,350
the order status.

89
00:04:32,350 --> 00:04:35,100
And I will show you the front end for this in a second.

90
00:04:36,180 --> 00:04:38,070
That's what I changed in the order model.

91
00:04:38,070 --> 00:04:39,480
I added the utility methods,

92
00:04:39,480 --> 00:04:42,625
and these find methods and the updating functionality.

93
00:04:42,625 --> 00:04:45,013
I did, of course, add these find methods

94
00:04:45,013 --> 00:04:46,690
so that we can get an

95
00:04:46,690 --> 00:04:48,260
output, the orders.

96
00:04:48,260 --> 00:04:50,338
I do that in the orders controller.

97
00:04:50,338 --> 00:04:54,499
Here in orders.controller, I added this getOrders function,

98
00:04:54,499 --> 00:04:58,340
or I populated it with more life to be precise.

99
00:04:58,340 --> 00:05:02,184
And I try finding all the orders for a given user because

100
00:05:02,184 --> 00:05:07,080
this function will be executed for regular users who should

101
00:05:07,080 --> 00:05:09,390
only be able to see their own orders,

102
00:05:09,390 --> 00:05:11,678
not orders of other users.

103
00:05:11,678 --> 00:05:15,700
And, for finding the orders for a given user,

104
00:05:15,700 --> 00:05:17,570
I use a res.locals.uid,

105
00:05:17,570 --> 00:05:20,050
which I get from my session in the end with help of the

106
00:05:20,050 --> 00:05:22,180
check-off middleware there,

107
00:05:22,180 --> 00:05:25,160
I get the user ID from the session and store data in

108
00:05:25,160 --> 00:05:27,172
res.locals.uid thereafter.

109
00:05:27,172 --> 00:05:30,490
And I use that in the orders.controller to, then,

110
00:05:30,490 --> 00:05:33,317
find all the orders for that user by that ID.

111
00:05:33,317 --> 00:05:37,760
Then, I rendered this all-orders template as we did before.

112
00:05:37,760 --> 00:05:41,520
And to that template, I passed the orders I found.

113
00:05:41,520 --> 00:05:43,453
I also added error handling.

114
00:05:44,920 --> 00:05:48,120
And that's all I added in here in the orders.controller.

115
00:05:48,120 --> 00:05:50,020
Other than that, nothing changed here.

116
00:05:51,430 --> 00:05:54,000
In the all-orders.ejs file,

117
00:05:54,000 --> 00:05:56,130
I added more code.

118
00:05:56,130 --> 00:05:59,050
To be precise, I included this code snippet

119
00:05:59,050 --> 00:06:01,293
here, where I output an order-list.

120
00:06:01,293 --> 00:06:05,600
And this code snippet is stored in the shared folder and

121
00:06:05,600 --> 00:06:09,250
there in the includes folder because I also will use it in

122
00:06:09,250 --> 00:06:11,140
the administration area later.

123
00:06:11,140 --> 00:06:12,563
We'll see that in a second.

124
00:06:13,404 --> 00:06:15,738
Now in this order-list.ejs file-

125
00:06:15,738 --> 00:06:16,660
And again,

126
00:06:16,660 --> 00:06:20,020
you find all these new and updated files attached-

127
00:06:20,020 --> 00:06:21,940
In this order-list.ejs file,

128
00:06:21,940 --> 00:06:24,491
I have a simple loop as we added multiple times.

129
00:06:24,491 --> 00:06:28,087
I use an order-list because I do sort to the orders.

130
00:06:28,087 --> 00:06:30,440
So using an order-list makes sense,

131
00:06:30,440 --> 00:06:33,160
because you order clearly matters to me.

132
00:06:33,160 --> 00:06:36,610
And then I loop through all the orders that I got and then I

133
00:06:36,610 --> 00:06:39,048
include another snippet for every order-item.

134
00:06:39,048 --> 00:06:41,454
And that is the order-items snippet here,

135
00:06:41,454 --> 00:06:43,399
where I have an article.

136
00:06:43,399 --> 00:06:45,280
And in that article,

137
00:06:45,280 --> 00:06:48,100
I will have a bunch of markup outputting,

138
00:06:48,100 --> 00:06:51,930
basically some information about the total price of that

139
00:06:51,930 --> 00:06:55,450
order by using the totalPrice right from inside the order

140
00:06:55,450 --> 00:06:59,050
for the product data that's stored in the order.

141
00:06:59,050 --> 00:07:02,180
And keep in mind, the product data that's stored

142
00:07:02,180 --> 00:07:03,477
in the order is in the end,

143
00:07:03,477 --> 00:07:06,623
the cart for which the order was placed.

144
00:07:07,770 --> 00:07:09,202
I also called toFixed(2)

145
00:07:09,202 --> 00:07:12,793
to make sure we always display two decimal places.

146
00:07:13,658 --> 00:07:17,259
Then I have a regular dash output as plain text here.

147
00:07:17,259 --> 00:07:20,600
And then after that, this formatedDate,

148
00:07:20,600 --> 00:07:23,653
which you saw in the order clause constructor function,

149
00:07:24,830 --> 00:07:27,760
and then after this title I have this batch,

150
00:07:27,760 --> 00:07:31,200
which displays the current order status in all upper case

151
00:07:32,272 --> 00:07:34,240
characters, thanks to this transformation function here,

152
00:07:34,240 --> 00:07:35,073
which I call.

153
00:07:36,340 --> 00:07:38,297
Here, I also reuse this batch clause,

154
00:07:38,297 --> 00:07:42,520
which we defined before for this batch here in our

155
00:07:42,520 --> 00:07:45,676
navigation for this cart button here.

156
00:07:45,676 --> 00:07:49,760
Then, I output some order details and here I also have some

157
00:07:49,760 --> 00:07:51,883
special output for administrators.

158
00:07:52,730 --> 00:07:54,100
For administrators,

159
00:07:54,100 --> 00:07:56,910
I also show an address element here,

160
00:07:56,910 --> 00:08:01,350
or I output an address element with more information about

161
00:08:01,350 --> 00:08:03,860
the user who placed the order,

162
00:08:03,860 --> 00:08:05,430
because I think that makes sense.

163
00:08:05,430 --> 00:08:08,623
If you view all the orders from all the users in the

164
00:08:08,623 --> 00:08:10,849
administration panel,

165
00:08:10,849 --> 00:08:15,220
you need all these user details to then ship the order to

166
00:08:15,220 --> 00:08:19,030
your users, if this would be a real online shop.

167
00:08:19,030 --> 00:08:21,410
Therefore, here I output the username.

168
00:08:21,410 --> 00:08:25,120
I ensure that the user can be contacted by using user email

169
00:08:25,120 --> 00:08:27,530
address here for this link.

170
00:08:27,530 --> 00:08:29,550
And I then output the street address,

171
00:08:29,550 --> 00:08:31,933
the postal code, and the city of the user.

172
00:08:33,154 --> 00:08:34,530
And all that data

173
00:08:34,530 --> 00:08:36,770
is coming from the order that we created

174
00:08:36,770 --> 00:08:38,673
and that's stored in the database.

175
00:08:39,558 --> 00:08:43,960
Now, this is only shown on the administration panel.

176
00:08:43,960 --> 00:08:48,060
If you are viewing your orders as a regular user, you, of

177
00:08:48,060 --> 00:08:50,240
course, don't need that extra data.

178
00:08:50,240 --> 00:08:52,390
You know who you are and therefore, then,

179
00:08:52,390 --> 00:08:56,010
I just show details about the order to be precise about the

180
00:08:56,010 --> 00:08:57,933
items that were ordered.

181
00:08:58,780 --> 00:08:59,613
For that,

182
00:08:59,613 --> 00:09:02,560
I accessed the items in that cart, which is in the end,

183
00:09:02,560 --> 00:09:05,111
which is part of that order and output the title of the

184
00:09:05,111 --> 00:09:09,475
product, the total price fixed to two decimal places,

185
00:09:09,475 --> 00:09:14,113
and then also the details on how that total price was

186
00:09:14,113 --> 00:09:18,410
calculated by using the individual product price.

187
00:09:18,410 --> 00:09:21,640
So, really looking into an individual product

188
00:09:21,640 --> 00:09:23,532
and seeing what the price of that would have been

189
00:09:23,532 --> 00:09:25,497
and showing you also the quantity,

190
00:09:25,497 --> 00:09:28,536
so the number of these products you had in your cart,

191
00:09:28,536 --> 00:09:31,870
which then leads to this total price in the end.

192
00:09:31,870 --> 00:09:34,100
Now, if you are an administrator,

193
00:09:34,100 --> 00:09:37,070
I then also show you more options

194
00:09:37,070 --> 00:09:38,300
because then you should be

195
00:09:38,300 --> 00:09:40,980
able to update this order status.

196
00:09:40,980 --> 00:09:45,190
You should not be able to update it as a regular user.

197
00:09:45,190 --> 00:09:47,550
So as an administrator, you get this extra form,

198
00:09:47,550 --> 00:09:50,289
which shows a select drop-down in the end,

199
00:09:50,289 --> 00:09:53,490
where you can switch between these statuses.

200
00:09:53,490 --> 00:09:56,293
You can switch between pending, fulfilled and canceled and

201
00:09:56,293 --> 00:09:59,300
you can then click the update button to, in the end,

202
00:09:59,300 --> 00:10:00,850
submit this form.

203
00:10:00,850 --> 00:10:04,660
And I always include the CSRF token and a hidden input field

204
00:10:04,660 --> 00:10:06,870
that contains the ID of that order,

205
00:10:06,870 --> 00:10:10,186
which should be updated so that this is then also a part of

206
00:10:10,186 --> 00:10:12,630
the form submission.

207
00:10:12,630 --> 00:10:15,330
Though the form here actually

208
00:10:15,330 --> 00:10:17,916
won't be submitted automatically by the browser--

209
00:10:17,916 --> 00:10:20,428
Instead, I wrote a Java script file,

210
00:10:20,428 --> 00:10:23,438
a browser side Java script file,

211
00:10:23,438 --> 00:10:25,480
the order management file here,

212
00:10:25,480 --> 00:10:28,880
where I actually stop that form submission with

213
00:10:28,880 --> 00:10:33,100
preventDefault and then send an Ajax request manually to the

214
00:10:33,100 --> 00:10:36,340
backend so that I can send a patch request.

215
00:10:36,340 --> 00:10:40,100
And so that we again have another example for Ajax requests,

216
00:10:40,100 --> 00:10:42,423
but I'll come back to this script in a second.

217
00:10:43,300 --> 00:10:45,620
For the moment, that's it's for the order item

218
00:10:45,620 --> 00:10:47,330
and with all of that,

219
00:10:47,330 --> 00:10:48,941
with all these capabilities,

220
00:10:48,941 --> 00:10:53,750
you can now visit the orders page as a regular user and view

221
00:10:53,750 --> 00:10:55,140
your orders here.

222
00:10:55,140 --> 00:10:56,990
That's what you see here.

223
00:10:56,990 --> 00:10:57,823
And here,

224
00:10:57,823 --> 00:11:00,100
you see all the details I showed you in code a couple of

225
00:11:00,100 --> 00:11:01,003
seconds ago.

