components([ Forms\Components\Select::make('labor_id') ->label('Catalog manoperă') ->options(fn () => Labor::where('is_active', true) ->get() ->mapWithKeys(fn ($l) => [$l->id => "[{$l->category}] {$l->name_ro} ({$l->hours}h)"]) ->toArray()) ->searchable() ->live() ->afterStateUpdated(function ($state, Set $set) { if ($state && $labor = Labor::find($state)) { $set('name', $labor->name_ro); $set('hours', $labor->hours); $set('price_per_hour', $labor->hours > 0 ? round($labor->price / max((float) $labor->hours, 1), 2) : 0); } }) ->columnSpanFull(), Forms\Components\TextInput::make('name')->label('Nume')->required()->columnSpanFull(), Forms\Components\TextInput::make('hours')->label('Ore')->numeric()->default(1)->required(), Forms\Components\TextInput::make('price_per_hour')->label('Preț/h')->numeric()->required(), Forms\Components\Select::make('master_id') ->label('Maistru') ->options(fn () => User::pluck('name', 'id')) ->searchable(), Forms\Components\Select::make('status') ->options(WorkOrderWork::STATUSES) ->default('todo') ->required(), Forms\Components\Textarea::make('notes')->label('Notițe')->columnSpanFull()->rows(2), ]); } public function table(Table $table): Table { return $table ->recordTitleAttribute('name') ->columns([ Tables\Columns\TextColumn::make('name')->label('Manoperă')->wrap(), Tables\Columns\TextColumn::make('hours')->label('Ore')->numeric(decimalPlaces: 2)->alignRight(), Tables\Columns\TextColumn::make('price_per_hour')->label('Preț/h')->money('MDL')->alignRight(), Tables\Columns\TextColumn::make('total')->label('Total')->money('MDL')->alignRight(), Tables\Columns\TextColumn::make('master.name')->label('Maistru')->placeholder('—'), Tables\Columns\TextColumn::make('status') ->formatStateUsing(fn ($s) => WorkOrderWork::STATUSES[$s] ?? $s) ->badge() ->colors(['gray' => ['todo'], 'warning' => ['in_progress'], 'success' => ['done']]), ]) ->headerActions([ Actions\CreateAction::make() ->after(function (WorkOrderWork $record) { // Auto-add the labor's default parts to the parent WO. if (! $record->labor_id) return; $labor = Labor::with('laborParts.part')->find($record->labor_id); $wo = $record->workOrder; if (! $labor || ! $wo || $labor->laborParts->isEmpty()) return; $composer = app(\App\Services\ServiceComposer::class); foreach ($labor->laborParts as $lp) { if ($lp->part) { $composer->addPart($wo, $lp->part, (float) $lp->qty, $lp->unit); } } \Filament\Notifications\Notification::make() ->title('Piese implicite adăugate (' . $labor->laborParts->count() . ')') ->success()->send(); }), ]) ->actions([ Actions\EditAction::make(), Actions\DeleteAction::make(), ]); } }