This episode is for members only

Sign up to access "Build an E-Commerce Platform" right now.

Get started
Already a member? Sign in to continue
Playing
65. Detecting order status changes

Episodes

0%
Your progress
  • Total: 8h 42m
  • Played: 0m
  • Remaining: 8h 42m
Join or sign in to track your progress
01. Introduction and demo
9m 42s
0%
02. Installing Laravel, Breeze and Livewire
4m 47s
0%
03. Creating categories
9m 4s
0%
04. Recursively displaying categories
8m 21s
0%
05. Product model and migration
2m 50s
0%
06. Showing a product
7m 50s
0%
07. Product variation setup
10m 26s
0%
08. Creating the product selector
10m 34s
0%
09. Loading child variation dropdowns
4m 28s
0%
10. Faking adding the final variation
9m 33s
0%
11. Setting up product stock
4m 34s
0%
12. Calculating variation stock levels
9m 1s
0%
13. Adding product images with MediaLibrary
8m 50s
0%
14. Creating the product gallery
7m 28s
0%
15. Providing a fallback image
2m 56s
0%
16. Adding media to product variations
3m 37s
0%
17. Creating the cart model
3m 37s
0%
18. Registering the cart service
6m 34s
0%
19. Creating a cart session
11m 4s
0%
20. Showing the cart in the navigation
9m 19s
0%
21. Caching the cart instance
3m 2s
0%
22. Adding items to the cart
14m 1s
0%
23. Creating the notification component
8m 5s
0%
24. Showing the user's cart
6m 50s
0%
25. Outputting cart items
4m 50s
0%
26. Showing variation specifics
8m 8s
0%
27. Updating item quantity
8m 2s
0%
28. Removing an item from the cart
6m 1s
0%
29. Calculating the cart summary
8m 7s
0%
30. Showing the category products page
5m 1s
0%
31. Indexing products in Meilisearch
8m 32s
0%
32. Hooking up products to categories
4m 15s
0%
33. Building the product browser
13m 32s
0%
34. Showing child categories
1m 51s
0%
35. Indexing product variations for filtering
8m
0%
36. Outputting variations for filtering
12m 52s
0%
37. Hooking up product filters with Livewire
7m 48s
0%
38. Filtering products
12m 24s
0%
39. Filtering by price
9m 50s
0%
40. Adding global navigation search
7m 50s
0%
41. Handling products that are not live
3m 22s
0%
42. Price range category fix
1m 18s
0%
43. Scaffolding the checkout page
8m 6s
0%
44. Listing shipping options
9m 3s
0%
45. Calculating the cart totals
2m 52s
0%
46. Validating the account form
9m 10s
0%
47. Validating the shipping form
5m 47s
0%
48. Saving the shipping address
8m 4s
0%
49. Selecting a saved shipping address
6m 39s
0%
50. Fix shipping address error for non authenticated users
1m 7s
0%
51. Redirecting if the cart is empty
2m 42s
0%
52. Checking for quantity changes
7m 11s
0%
53. Syncing if quantities have changed
11m 59s
0%
54. Flashing a message when quantities have changed
5m 48s
0%
55. Setting up for orders
5m 17s
0%
56. Creating an order
13m 24s
0%
57. Attaching variations to order
6m 13s
0%
58. Reducing stock after ordering
2m 56s
0%
59. Meilisearch filter query fix
1m 33s
0%
60. Showing the order confirmation page
7m 39s
0%
61. Attaching orders for registering guest users
5m 17s
0%
62. Scaffolding the orders page
5m 30s
0%
63. Filling in order variation details
5m 24s
0%
64. Returning the order status
4m 39s
0%
65. Detecting order status changes
10m 49s
0%
66. Sending the order status change email
5m 12s
0%
67. Sending an order confirmation email
2m 47s
0%
68. Handling deleted cart records
4m 44s
0%
69. Transferring the guest cart
2m 44s
0%
70. Creating a presenter for the order status
4m 31s
0%
71. Setting up Stripe
3m 43s
0%
72. Creating and updating a PaymentIntent
16m 21s
0%
73. The Stripe card form
3m 35s
0%
74. Validating before payment
5m 34s
0%
75. Submitting a payment
6m 40s
0%
76. Checking for a successful payment
5m 47s
0%
77. Handling Stripe client errors
3m 11s
0%
78. Entangling Stripe customer data
2m 18s
0%

Transcript

00:00
When an order status changes, you're probably going to want to notify your customers by email. That's exactly what we're going to be looking at over the next couple of parts. In this episode, we're going to focus on detecting when the order status changes. That's a little bit more complicated than it sounds.
00:16
And in the next episode, we'll look at sending the email. Now, we're going to be triggering this when this is updated via Eloquent, not when it's just manually updated in the database. So if you eventually get to the point where you add an admin panel to this
00:29
and you physically change the order status and save it back to the database via Eloquent, that is when this is going to trigger. So to test this, what we're going to be doing is running phpartisan tinker to go ahead and grab out that particular order, update the status, and then see this trigger.
00:47
Now, the first thing that we want to do is attach an observer to our orders so we can detect when something changes. So to do this, we're going to go ahead and run phpartisan, make observer, and we're going to call this order observer.
01:02
And just before we dive into that, let's go ahead and register this. So we can do this over in our event service provider. If we come down to boot, let's go ahead and grab the model that we want to observe and just use the observe method here.
01:15
And then we just pass the observer in, which is our order observer that we just created. Great. Let's pull the model in for order. And we're done. Now, over in our order observer, we can basically pick up on
01:29
any of the eloquent events that we get. In our case, it's when the order is updated. So let's go ahead and just go and create our updated method. When that is updated, we'll get an order in.
01:42
So the order that is being updated. And then we can just do something in here. For now, let's just die dump on the order. And let's test this over in tinker just to see this work.
01:54
So let's pick one from the day space that we're going to be testing. Let's get rid of the packaged at date on this order. And let's go ahead and grab the ID of this, which happens to just be one. So we're going to go ahead and within tinker, say order find and one.
02:10
And then we're going to go ahead and say order update. And let's update one of these. So packaged at. So let's say packaged at.
02:21
And we'll set that to the current date and time. And there we go. That's died and dumped. So that is coming from here.
02:27
So we know that this is triggering properly. And now we need to do a few things. Now what we could do in here is say something like the following. I'll just roughly mock this out.
02:38
We could say order and get original, for example. Or we could even grab the dirty records from this, which are the ones that are being updated. And we could check what is being filled somehow. So we could say, well, is packaged at being filled?
02:53
Well, if it is, or changed rather, not necessarily filled. If it is, then we'll go ahead and send the email with a packaged at status. The only problem with this is if, for example, we had both of these filled and the status gets rolled back, this is being updated and set back to null.
03:14
So we would not want to trigger an email when shipped at is being set back to null, for example. So what we want to do is detect that something is being properly filled in the right order and not being set back to null. Now we'll go a kind of longer way around doing this like we have been for most things.
03:33
And then we can come back and refactor this a little bit later. So the first thing that we're going to do is create our filled statuses array, which is going to filter out anything that has been filled and that haven't been set back to null. So what we're going to do is collect up the order, and we're going to use getDirty here,
03:55
which is going to go ahead and grab the things that have been changed. Then we're going to go ahead and only pluck out the order statuses. So remember, we have this statuses property that we created earlier, which is a custom property on here.
04:12
We could actually set that to public, or you could create a getter for that. And then we want to go ahead and filter this. And we saw this earlier from the status where we actually used last later. But in this case, we're still using that filled helper method,
04:28
and we're filtering out everything that has been filled. So let's just die dump on these filled statuses and just see what we get. Let's call that statuses. Actually, that makes a little bit more sense.
04:40
OK, so we're going to come over to Tinker again. Let's just quit out of this and go back in. And let's again find that order. And we will update that order like we did before.
04:53
Let's find out where we did that. We don't have that in history, so let's just do this manually. So let's say package that. And we will set that to now.
05:04
Now let's just make sure that that's empty before we update it. And there we go. So that has now been filled. So we know which one is being filled.
05:15
If we do the same thing here and just grab that command again and do this in here with the shipped out, let's see what we get. And there we go, shipped out. So this is always going to give us back what we're updating
05:32
that is currently being filled with the things that are being updated. So as an example, and the reason that this is so important, what we could be doing is updating two things. So of course, we might think, well, we're just going to notify
05:47
based on the thing that is being updated. But if both of these are being updated at the same time, for example, if packaged out and shipped out are being updated, so let's just go ahead and add this in.
06:01
Packaged at now and shipped at now. We get both of these back because both of these are being filled out of what we've done. Now, that isn't terribly useful in our example, because what might also happen is, let's just discard that.
06:17
These might already be available. And then we might be filling, say, packaged at and getting rid of shipped at. So let's just pull back the command here. I don't know why that's not in history, but let's just copy and paste this back into here.
06:31
And let's go ahead and set packaged at to now and shipped out to null. Perhaps we're reverting this status back. Packaged at is in there. Even though we are updating null, we're filtering that out.
06:45
Hopefully that makes sense. These are just the filled statuses that we can use to compare. So what we want to do down here is basically check if the original order, so we'll grab that out in just a second,
06:57
status doesn't equal the current order status, e.g. using that status method that we implemented earlier over on our model, then we want to send the email. Now, the original order needs to kind of be mocked,
07:15
because the order that we've got here will have already had that status update, because when we get this through, this order represents what has been saved. So we're going to go ahead and say original order. And we're just going to create our new order model.
07:31
Bear with me. And into here, we're going to pass in the original properties of that order. And we're only going to fill that with the order statuses that we have and just cast that to an array.
07:47
So effectively, what we're doing is we're building up something that looks like the following. Packaged at etc. But we're just grabbing the originals in there and just creating
07:59
a kind of fake original order. So let's just go ahead and dump that out. Let's go back to here. And again, just grab this, paste this in.
08:08
And that's going to give us the original details back. So if we were to change this over and update just shipped out, for example, to now, that looks like it might have already been updated. So let's go and change that back to null.
08:29
We end up with a empty collection here. Let's just quit out of this, actually, and pull it back up. Because I have a feeling that that is not up to date. So let's go ahead and find order one again.
08:38
And let's go and just update this something different. So shipped out is null. So when we do update shipped out to now, that original order should contain shipped out as null.
08:53
So we're basically getting back the original order before the state has been changed. So now, after all that, we can go ahead and very quickly check the order status. So if the original order status doesn't equal the current order status, and really importantly, with the filled statuses,
09:15
we actually have something in there that has changed, then we can go and send the email. So hopefully that makes sense. If it doesn't, might need another rewatch.
09:26
So let's go over and just try this out. So I'm going to go ahead and just quit out of Tinker. Pull this back in. And let's go to our database.
09:34
Get rid of these two. And let's try this out. Let's just do a couple of example scenarios. OK, so let's go and find that order first.
09:45
Great. And we'll go ahead and say order update packaged at. And we'll set that to now. That should send an email.
09:58
If we go and, again, I don't know why the history is not here. Set the shipped at date to now. We send an email. However, if I get rid of the shipped at date.
10:11
So let's set that to null. That shouldn't trigger an email. And it doesn't. We just get true back because that's been completed.
10:22
Now, the reason that that happened is within our original order, the status doesn't match because it's been reverted back to packaged at. But we have no filled statuses, which we looked at earlier. So there wouldn't have been anything in there because we set this back to null.
10:37
And we're filtering that out. Hopefully that makes sense. That's as best I can explain it. But now this should trigger properly when an order status actually changes.
78 episodes8 hrs 42 mins

Overview

Build a robust e-commerce platform with a Laravel and Livewire. Features products with unlimited and flexible variations, a product browser with filters and price range slider, global product search, guest checkout, shipping and payment implementation, order status tracking and more.

Alex Garrett-Smith
Alex Garrett-Smith
Hey, I'm the founder of Codecourse!

Episode discussion

No comments, yet. Be the first!