beforeSave whith relations

I have the following process in beforeSave() of EditSale.php, in which I restore the stock (quantities) of products, before the records are saved, as indicated by the "beforeSave" hook, but it turns out that when entering this hook the data of the relationship (SaleDetails) has already been saved.
protected function beforeSave(): void
{
//antes de guardar, DESHACEMOS EL STOCK
$originalDetails = $this->record->products->map(function($product) {
return [
'product_id' => $product->id,
'qty' => $product->getOriginal('qty'), // Obtener la cantidad original antes de la modificación
];
});
dd($originalDetails);
foreach ($originalDetails as $detail) {
$product = $detail->product;
Log::info('revert stock', ['product_id' => $product->id]);
Log::info('revert stock', ['cant anterior' => $detail->qty]);
Log::info('revert stock', ['stock anterior' => $product->stock_current]);
$product->stock_current += $detail->qty;
$product->save();
}

}
protected function beforeSave(): void
{
//antes de guardar, DESHACEMOS EL STOCK
$originalDetails = $this->record->products->map(function($product) {
return [
'product_id' => $product->id,
'qty' => $product->getOriginal('qty'), // Obtener la cantidad original antes de la modificación
];
});
dd($originalDetails);
foreach ($originalDetails as $detail) {
$product = $detail->product;
Log::info('revert stock', ['product_id' => $product->id]);
Log::info('revert stock', ['cant anterior' => $detail->qty]);
Log::info('revert stock', ['stock anterior' => $product->stock_current]);
$product->stock_current += $detail->qty;
$product->save();
}

}
i.e. where do i get the original detail before it is saved? is there a hook for this? for these cases beforesave does not work.
9 Replies
LeandroFerreira
LeandroFerreira3mo ago
relationships are saved automatically. If you want to access them in $data, add ->dehydrated() in the relationship components
Pedroesca
PedroescaOP3mo ago
Does it apply only to the repeater??? or to each component within it?
LeandroFerreira
LeandroFerreira3mo ago
if you add in the repeater, only the repeater
Pedroesca
PedroescaOP3mo ago
ok. i did that first, i try to get from beforeSave but it returns the data already modified.
Pedroesca
PedroescaOP3mo ago
I want to bring the original records from the database before they are updated (because they could remove some items) but everything is already returned modified
No description
LeandroFerreira
LeandroFerreira3mo ago
try $this->record->getOriginal()
Pedroesca
PedroescaOP3mo ago
It returns only the Sale model, but I need to retrieve the SaleDetail items, so I query the database for the original related records, assuming that beforeSave is executed BEFORE the data is saved, and dehydrated() did not work.
No description
Pedroesca
PedroescaOP3mo ago
La única forma que encontré para solucionar fue: 1. en afterFill (EditSale) protected function afterFill(): void { if ($this->record->draft == 1) { return; // Salir del método si la venta está en borrador } $this->originalDetails = $this->record->products->toArray(); session()->put('originalDetails', $this->record->products->toArray()); } 2. y en beforeSave recupero el registro original protected function beforeSave(): void { if ($this->record->draft === 1) { return; // Salir del método si la venta está en borrador } $this->originalDetails = session()->get('originalDetails', []); foreach ($this->originalDetails as $detail){ // Obtener el producto relacionado $product = Product::find($detail['product_id']); if ($product){ //REVERTIR STOCK $stockActual = $product->stock_current;
LeandroFerreira
LeandroFerreira3mo ago
maybe you can use mutateRelationshipDataBeforeSaveUsing in your Repeater
->mutateRelationshipDataBeforeSaveUsing(function (array $data, ?SaleDetail $record): array {

//$record: original model
//$data: repeater data

return $data;
})
->mutateRelationshipDataBeforeSaveUsing(function (array $data, ?SaleDetail $record): array {

//$record: original model
//$data: repeater data

return $data;
})
Want results from more Discord servers?
Add your server