Pre-fill batch origin rows from recipe spices automatically
Deploy / deploy (push) Successful in 14s

When creating a new batch, the Herkunft-Repeater is automatically populated
with one row per Rohstoff from the product's current recipe. The Rohstoff
field is shown as a read-only label (Hidden spice_id + Placeholder name)
so the user only fills in supplier, origin country, farmer and notes.

Changing the recipe field updates the origin rows accordingly.
On edit, existing origin data is preserved unchanged.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Malek TellissiandClaude Sonnet 4.6 committed 2026-09-12 18:54:00 +02:00
1 parent 6f78b22285
commit 62be3761a9
1 file changed
+63 -16
@@ -3,6 +3,8 @@
namespace App\Filament\User\Resources\ProductResource\RelationManagers; namespace App\Filament\User\Resources\ProductResource\RelationManagers;
use App\Models\ProductSize; use App\Models\ProductSize;
use App\Models\Recipe;
use App\Models\Spice;
use Filament\Forms; use Filament\Forms;
use Filament\Forms\Form; use Filament\Forms\Form;
use Filament\Forms\Get; use Filament\Forms\Get;
@@ -39,10 +41,31 @@ class BatchesRelationManager extends RelationManager
Forms\Components\Select::make('recipe_id') Forms\Components\Select::make('recipe_id')
->label('Rezeptur') ->label('Rezeptur')
->relationship('recipe', 'name') ->options(fn () => Recipe::where('product_id', $this->getOwnerRecord()->id)
->searchable() ->orderByDesc('version')
->preload() ->get()
->required(), ->mapWithKeys(fn ($r) => [$r->id => 'v' . $r->version . ' · ' . $r->created_at->format('d.m.Y')])
)
->default(fn () => $this->getOwnerRecord()->recipes_id)
->required()
->live()
->afterStateUpdated(function ($state, $set) {
if (! $state) {
$set('origins', []);
return;
}
$recipe = Recipe::with('spices')->find($state);
if (! $recipe) {
return;
}
$set('origins', $recipe->spices->map(fn ($s) => [
'spice_id' => $s->id,
'supplier_id' => null,
'origin_country' => null,
'farmer' => null,
'notes' => null,
])->toArray());
}),
Forms\Components\TextInput::make('units_produced') Forms\Components\TextInput::make('units_produced')
->label('Anzahl Einheiten') ->label('Anzahl Einheiten')
@@ -70,15 +93,36 @@ class BatchesRelationManager extends RelationManager
->label('Mindesthaltbarkeitsdatum'), ->label('Mindesthaltbarkeitsdatum'),
Forms\Components\Repeater::make('origins') Forms\Components\Repeater::make('origins')
->label('Herkunft der Gewürze') ->label('Herkunft der Rohstoffe')
->relationship() ->relationship()
->afterStateHydrated(function ($component, $record, $livewire) {
// Pre-fill from product's current recipe only when creating a new batch
if ($record?->id) {
return;
}
$recipeId = $livewire->getOwnerRecord()->recipes_id;
if (! $recipeId) {
return;
}
$recipe = Recipe::with('spices')->find($recipeId);
if (! $recipe) {
return;
}
$component->state($recipe->spices->map(fn ($s) => [
'spice_id' => $s->id,
'supplier_id' => null,
'origin_country' => null,
'farmer' => null,
'notes' => null,
])->toArray());
})
->schema([ ->schema([
Forms\Components\Select::make('spice_id') Forms\Components\Hidden::make('spice_id'),
->label('Gewürz') Forms\Components\Placeholder::make('spice_name')
->relationship('spice', 'name') ->label('Rohstoff')
->searchable() ->content(fn (Get $get): string =>
->preload() Spice::find($get('spice_id'))?->name ?? '—'
->required(), ),
Forms\Components\Select::make('supplier_id') Forms\Components\Select::make('supplier_id')
->label('Lieferant') ->label('Lieferant')
@@ -96,12 +140,12 @@ class BatchesRelationManager extends RelationManager
->maxLength(255), ->maxLength(255),
Forms\Components\Textarea::make('notes') Forms\Components\Textarea::make('notes')
->label('Infos zum Gewürz') ->label('Notizen')
->rows(2) ->rows(2)
->columnSpanFull(), ->columnSpanFull(),
]) ])
->columns(2) ->columns(2)
->addActionLabel('Gewürz hinzufügen') ->addActionLabel('Rohstoff hinzufügen')
->columnSpanFull(), ->columnSpanFull(),
]); ]);
} }
@@ -118,10 +162,13 @@ class BatchesRelationManager extends RelationManager
Tables\Columns\TextColumn::make('units_produced') Tables\Columns\TextColumn::make('units_produced')
->label('Einheiten') ->label('Einheiten')
->suffix(fn ($record) => $record->quantity_g ? ' (' . number_format($record->quantity_g, 0, ',', '.') . 'g)' : ''), ->suffix(fn ($record) => $record->quantity_g
? ' (' . number_format($record->quantity_g, 0, ',', '.') . 'g)'
: ''),
Tables\Columns\TextColumn::make('recipe.name') Tables\Columns\TextColumn::make('recipe.version')
->label('Rezeptur'), ->label('Rezeptur')
->formatStateUsing(fn ($state) => $state ? 'v' . $state : '—'),
Tables\Columns\TextColumn::make('produced_at') Tables\Columns\TextColumn::make('produced_at')
->label('Produktion') ->label('Produktion')