From 3301a1e9b247093b488cf1823e05364e91232e07 Mon Sep 17 00:00:00 2001 From: Malek Tellissi Date: Sat, 12 Sep 2026 18:19:31 +0200 Subject: [PATCH] Fix 500 on recipe save and surface errors as notifications MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix root cause: recipes_spices.amount_in_percent was decimal(4,2) which overflows on 100% — widened to decimal(6,2) via migration - Wrap afterSave() in try-catch so DB/logic errors show as a persistent danger notification instead of a blank 500 page - Same for CreateProduct: errors show as notification; also reads recipe_spices from raw Livewire $this->data (not $data param which excludes dehydrated(false) fields) so recipes actually save on create Co-Authored-By: Claude Sonnet 4.6 --- .../ProductResource/Pages/CreateProduct.php | 73 +++++++++++-------- .../ProductResource/Pages/EditProduct.php | 13 +++- ...200000_fix_amount_in_percent_precision.php | 22 ++++++ 3 files changed, 77 insertions(+), 31 deletions(-) create mode 100644 database/migrations/2026_09_12_200000_fix_amount_in_percent_precision.php diff --git a/app/Filament/User/Resources/ProductResource/Pages/CreateProduct.php b/app/Filament/User/Resources/ProductResource/Pages/CreateProduct.php index c43f1dc..e4a40d5 100644 --- a/app/Filament/User/Resources/ProductResource/Pages/CreateProduct.php +++ b/app/Filament/User/Resources/ProductResource/Pages/CreateProduct.php @@ -5,6 +5,7 @@ namespace App\Filament\User\Resources\ProductResource\Pages; use App\Filament\User\Resources\ProductResource; use App\Models\ProductSize; use App\Models\Recipe; +use Filament\Notifications\Notification; use Filament\Resources\Pages\CreateRecord; use Illuminate\Database\Eloquent\Model; @@ -14,36 +15,50 @@ class CreateProduct extends CreateRecord protected function handleRecordCreation(array $data): Model { - $record = static::getModel()::create($data); + $sizes = $data['sizes'] ?? []; + $spices = $this->data['recipe_spices'] ?? []; + unset($data['sizes']); - foreach ($data['sizes'] ?? [] as $size) { - ProductSize::create([ - 'product_id' => $record->id, - 'packing_id' => $size['packing_id'], - 'description' => $size['description'] ?? null, - 'price' => $size['price'], - 'sku' => $size['sku'] ?? null, - 'gtin' => $size['gtin'] ?? null, - ]); + try { + $record = static::getModel()::create($data); + + foreach ($sizes as $size) { + if (empty($size['packing_id'])) { + continue; + } + $gtin = preg_replace('/\D/', '', (string) ($size['gtin'] ?? '')); + ProductSize::create([ + 'product_id' => $record->id, + 'packing_id' => (int) $size['packing_id'], + 'description' => $size['description'] ?? null, + 'price' => $size['price'], + 'sku' => $size['sku'] ?: null, + 'gtin' => $gtin !== '' ? $gtin : null, + ]); + } + + if (! empty($spices)) { + $recipe = Recipe::create([ + 'name' => $data['title'], + 'product_id' => $record->id, + 'version' => 1, + ]); + $pivotData = collect($spices)->mapWithKeys(fn ($s) => [ + (int) $s['spice_id'] => ['amount_in_percent' => (float) $s['amount_in_percent']], + ])->toArray(); + $recipe->spices()->sync($pivotData); + $record->update(['recipes_id' => $recipe->id]); + } + + return $record; + } catch (\Throwable $e) { + Notification::make() + ->title('Fehler beim Anlegen') + ->body($e->getMessage()) + ->danger() + ->persistent() + ->send(); + throw $e; } - - $spices = $data['recipe_spices'] ?? []; - - if (! empty($spices)) { - $recipe = Recipe::create([ - 'name' => $data['title'], - 'product_id' => $record->id, - 'version' => 1, - ]); - - $pivotData = collect($spices)->mapWithKeys(fn ($s) => [ - $s['spice_id'] => ['amount_in_percent' => $s['amount_in_percent']], - ])->toArray(); - - $recipe->spices()->sync($pivotData); - $record->update(['recipes_id' => $recipe->id]); - } - - return $record; } } diff --git a/app/Filament/User/Resources/ProductResource/Pages/EditProduct.php b/app/Filament/User/Resources/ProductResource/Pages/EditProduct.php index ffb3337..70e1b54 100644 --- a/app/Filament/User/Resources/ProductResource/Pages/EditProduct.php +++ b/app/Filament/User/Resources/ProductResource/Pages/EditProduct.php @@ -51,8 +51,17 @@ class EditProduct extends EditRecord protected function afterSave(): void { - $this->syncSizes(); - $this->syncRecipe(); + try { + $this->syncSizes(); + $this->syncRecipe(); + } catch (\Throwable $e) { + Notification::make() + ->title('Fehler beim Speichern') + ->body($e->getMessage()) + ->danger() + ->persistent() + ->send(); + } } protected function syncSizes(): void diff --git a/database/migrations/2026_09_12_200000_fix_amount_in_percent_precision.php b/database/migrations/2026_09_12_200000_fix_amount_in_percent_precision.php new file mode 100644 index 0000000..c60f39f --- /dev/null +++ b/database/migrations/2026_09_12_200000_fix_amount_in_percent_precision.php @@ -0,0 +1,22 @@ +decimal('amount_in_percent', 6, 2)->change(); + }); + } + + public function down(): void + { + Schema::table('recipes_spices', function (Blueprint $table) { + $table->decimal('amount_in_percent', 4, 2)->change(); + }); + } +};