Lets say i have 2 table Movements and Stocks
Incomings
-----
id (Primary Key)
trx_number
trx_date
product_id (FK)
qty
Stocks
------
id (Primary Key)
product_id (FK)
begin_stock
in
out
end_stock
in and end_stock fields of Stocks table expcted to be updated Whenever incomings occured,
currenctly i use laravel Event and Listener to handle this, like so :
//Incoming Controller :
IlluminateSupportFacadesDB::transaction(function () use ($request) {
Incoming::create([
'trx-number' => 'TRX-001',
'trx-date' => '2023-07-31',
'product_id' => '1001',
'qty' => 10
]);
AppEventsIncomingOccured::dispatch($attr);
});
//IncomingOccured class will dispatched and will be listened by UpdateProductStock class :
AppEventsIncomingOccured::class => [
AppListenersUpdateProductStock::class
],
//Then inside UpdateProductStock class it will updating the model :
$stock = Stock::where('product_id', $item['product_id'])->first();
$stock = Stock::updateOrCreate(['product_id' => $item['product_id']]);
$stock->save();
$stock->increment('in', $requestedQty);
$stock->increment('end_stock', $requestedQty);
The goal was achieved, but i feel this is not the best way it is too complicated and event has nothing to do with this
What is a better way to do this ?
3
Answers
One clean way of checking for changes is using an observer (see here for the docs) for your model which can be created with:
Then, we can check when one of these models are created, and affect the stock quantities from there.
As a side note, generally a better approach for doing this would be to use a single source of truth and generate values based on aggregated data. This way, the logs of incomings and outcomings would be where the derived values come from, which would most likely be produced from an accessor that runs the queries.
You need to use Laravel’s best feature here.
That’s called an observer. When you change anything on any table, you will get an event for it, like create, update, or delete.
Also in this, you will track the old and new data in the update method for any specific field.
f you are listening for many events on a given model, you may use observers to group all of your listeners into a single class. Observer classes have method names which reflect the Eloquent events you wish to listen for. Each of these methods receives the affected model as their only argument. The make:observer Artisan command is the easiest way to create a new observer class:
This command will place the new observer in your app/Observers directory. If this directory does not exist, Artisan will create it for you. Your fresh observer will look like the following:
Register Observers class on provider.
app/Providers/EventServiceProvider.php
There are two ways to update this, first one generating observer class and handling events there.
Secondly, you can also catch an event in your model class like this.