F
Filamentโ€ข3mo ago
toeknee

Relationship with a relationship after create?

I need to add some relationship data to a relationships relationship. For example: Order -> products -> customisations In a duplicate order function, We have the repeater loading which loads the products relationship, I want to then clone over the customisations relationship. We don't seem to be able to use mutateRelationshipDataBeforeCreating to assign the relationship values.. and theres no record at this state, it's almost like we need an afterCreate function on a repeater relationship?
14 Replies
Matthew
Matthewโ€ข3mo ago
Just use a custom handler ?
toeknee
toekneeOPโ€ข3mo ago
Not qutie that easy. we already. The only way I can see to do this, would be to run on the after method but in doing so it's awfully labersome.
Matthew
Matthewโ€ข3mo ago
I'm out then ๐Ÿ˜œ
toeknee
toekneeOPโ€ข3mo ago
I'll just use after, it's just woefully laboursome really to what i needed to be hehe That worked ok in the end ๐Ÿ™‚
pratik
pratikโ€ข3d ago
Hey @toeknee Exact same scenario, I need to do something after the repeater relationship has been created. How did you manage to do it ?
toeknee
toekneeOPโ€ข3d ago
I jsut used ->after() I think. What is your exact scenario?
pratik
pratikโ€ข3d ago
I am creating a new purchase, purchase has many payments that is being created with purchase using repeater. Then I need to access the total paid amount i.e sum of amount from multiple payments records and subtract it from total purchase amount to calculate due. My goal is to record this due amount in payments_due table. Using observer hasn't been much help as the payments is not created when purchase created event is fired.
toeknee
toekneeOPโ€ข3d ago
Observers are no good for this scenario.You want to use the after method
toeknee
toekneeOPโ€ข3d ago
GitHub
How to do action after create Filament Resource ยท filamentphp filam...
Package Form builder Package Version v3 How can we help you? i use filament resource for Product Resource , and i want to send newsletter or do anything after record , i see there's ->after ...
pratik
pratikโ€ข3d ago
I just got an idea while typing this, i can create a due hidden field, then I can use dehydrateStateusing and do my calculations there and customize the creation process to record the due. ? does this sound good ?
toeknee
toekneeOPโ€ข3d ago
you cna do that, but people can manipluate it lowering the due amount. Add the due amount to the record, and use ->after() to sum and save.
pratik
pratikโ€ข3d ago
Manipulating due amount is not a concern actually. It's an internal system.
toeknee
toekneeOPโ€ข3d ago
Then that would work ๐Ÿ™‚ I actuially do that now for internal payroll system ๐Ÿ™‚ On the repeater i do
->afterStateUpdated(function ($state, $set, $get) {
$set('total_pay', (string) self::calculateTotalAmount($get('total_earnings', 0), $state))
})
->afterStateUpdated(function ($state, $set, $get) {
$set('total_pay', (string) self::calculateTotalAmount($get('total_earnings', 0), $state))
})
pratik
pratikโ€ข2d ago
I managed to do it like this ๐Ÿ˜€
Hidden::make('due')
->dehydrateStateUsing(function ($get) {
$purchase_total = (float) $get('total_amount');

$discount_amount = (float) $get('discount_amount');

$tax_amount = (float) $get('tax_amount');

$total = $purchase_total - $discount_amount + $tax_amount;

$payments = $get('payments');

$total_paid = 0;

foreach ($payments as $payment) {
$total_paid = $total_paid + (float) $payment['amount'];
}

$due = round($total - $total_paid, 2);

return $due;
})
->default(0),
Hidden::make('due')
->dehydrateStateUsing(function ($get) {
$purchase_total = (float) $get('total_amount');

$discount_amount = (float) $get('discount_amount');

$tax_amount = (float) $get('tax_amount');

$total = $purchase_total - $discount_amount + $tax_amount;

$payments = $get('payments');

$total_paid = 0;

foreach ($payments as $payment) {
$total_paid = $total_paid + (float) $payment['amount'];
}

$due = round($total - $total_paid, 2);

return $due;
})
->default(0),
And then in createPurchase
protected function handleRecordCreation(array $data): Model
{
$model = static::getModel()::create(Arr::except($data, ['due']));

if ($data['due'] > 0) {
$model->due()
->create([
'amount' => $data['due'],
'status' => PaymentStatus::Due,
]);
}

return $model;
}
protected function handleRecordCreation(array $data): Model
{
$model = static::getModel()::create(Arr::except($data, ['due']));

if ($data['due'] > 0) {
$model->due()
->create([
'amount' => $data['due'],
'status' => PaymentStatus::Due,
]);
}

return $model;
}

Did you find this page helpful?