Files
SpiceManagementSystem/app/Filament/User/Resources/BatchResource.php
T
Malek TellissiandClaude Sonnet 4.6 a34bb29620
Deploy / deploy (push) Successful in 14s
Auto-deduct spice inventory when batch is created/updated/deleted
- Add size_id, units_produced, quantity_g to batches table
- quantity_g auto-calculated from units × packing size on save
- Batch model deducts spice quantities on create, reverses on delete,
  recalculates on update when relevant fields change
- Batch form shows live total weight preview
- Chargen table shows units + grams produced

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-09-12 05:34:09 +02:00

176 lines
6.6 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace App\Filament\User\Resources;
use App\Filament\User\Resources\BatchResource\Pages;
use App\Models\Batch;
use App\Models\ProductSize;
use App\Models\Recipe;
use Filament\Forms;
use Filament\Forms\Form;
use Filament\Forms\Get;
use Filament\Resources\Resource;
use Illuminate\Support\HtmlString;
use Filament\Tables;
use Filament\Tables\Table;
class BatchResource extends Resource
{
protected static ?string $model = Batch::class;
protected static ?string $navigationIcon = 'heroicon-o-qr-code';
protected static ?string $navigationLabel = 'Chargen (LOT)';
protected static ?string $modelLabel = 'Charge';
protected static ?string $pluralModelLabel = 'Chargen';
protected static ?string $navigationGroup = 'Produkte';
protected static ?int $navigationSort = 3;
public static function form(Form $form): Form
{
return $form->schema([
Forms\Components\Section::make('Charge')->schema([
Forms\Components\TextInput::make('lot_number')
->label('LOT-Nummer')
->required()
->unique(ignoreRecord: true)
->maxLength(255),
Forms\Components\Select::make('product_id')
->label('Produkt')
->relationship('product', 'title')
->searchable()
->preload()
->required()
->live()
->afterStateUpdated(fn ($set) => $set('size_id', null)),
Forms\Components\Select::make('size_id')
->label('Variante (Verpackung)')
->options(fn (Get $get) => ProductSize::with('packing')
->where('product_id', $get('product_id'))
->get()
->mapWithKeys(fn ($s) => [$s->id => $s->packing->name . ' ' . $s->packing->size . 'g'])
)
->required()
->live(),
Forms\Components\Select::make('recipe_id')
->label('Rezeptur')
->relationship('recipe', 'name')
->searchable()
->preload()
->required()
->live(),
Forms\Components\TextInput::make('units_produced')
->label('Anzahl Einheiten')
->numeric()
->required()
->live(debounce: 400),
Forms\Components\Placeholder::make('quantity_g_preview')
->label('Gesamtgewicht (berechnet)')
->content(function (Get $get): HtmlString {
$units = (int) $get('units_produced');
$sizeId = $get('size_id');
if (! $units || ! $sizeId) {
return new HtmlString('<span class="text-gray-400">—</span>');
}
$size = ProductSize::with('packing')->find($sizeId);
$totalG = $units * ($size?->packing?->size ?? 0);
return new HtmlString("<strong>{$totalG} g</strong> ({$units} × {$size?->packing?->size}g)");
}),
Forms\Components\DatePicker::make('produced_at')
->label('Produktionsdatum'),
Forms\Components\DatePicker::make('expires_at')
->label('Mindesthaltbarkeitsdatum'),
])->columns(2),
Forms\Components\Section::make('Herkunft der Gewürze')->schema([
Forms\Components\Repeater::make('origins')
->label('')
->relationship()
->schema([
Forms\Components\Select::make('spice_id')
->label('Gewürz')
->relationship('spice', 'name')
->searchable()
->preload()
->required(),
Forms\Components\Select::make('supplier_id')
->label('Lieferant')
->relationship('supplier', 'name')
->searchable()
->preload()
->nullable(),
Forms\Components\TextInput::make('origin_country')
->label('Herkunftsland')
->maxLength(100),
Forms\Components\TextInput::make('farmer')
->label('Landwirt / Betrieb')
->maxLength(255),
Forms\Components\Textarea::make('notes')
->label('Infos zum Gewürz')
->rows(2)
->columnSpanFull(),
])
->columns(2)
->addActionLabel('Gewürz hinzufügen')
->reorderable(false),
]),
]);
}
public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('lot_number')
->label('LOT-Nummer')
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('product.title')
->label('Produkt')
->searchable(),
Tables\Columns\TextColumn::make('recipe.name')
->label('Rezeptur'),
Tables\Columns\TextColumn::make('produced_at')
->label('Produktion')
->date('d.m.Y')
->sortable(),
Tables\Columns\TextColumn::make('expires_at')
->label('MHD')
->date('d.m.Y')
->sortable(),
])
->defaultSort('produced_at', 'desc')
->filters([
Tables\Filters\SelectFilter::make('product')
->relationship('product', 'title')
->label('Produkt'),
])
->actions([
Tables\Actions\EditAction::make(),
Tables\Actions\DeleteAction::make(),
]);
}
public static function getPages(): array
{
return [
'index' => Pages\ListBatches::route('/'),
'create' => Pages\CreateBatch::route('/create'),
'edit' => Pages\EditBatch::route('/{record}/edit'),
];
}
}