where('status', 'new')->count(); return $new > 0 ? (string) $new : null; } public static function getNavigationBadgeColor(): ?string { return 'warning'; } public static function form(Schema $schema): Schema { return $schema->components([ Schemas\Components\Section::make('Comandă') ->columns(3) ->schema([ Forms\Components\TextInput::make('number')->label('Nr.')->disabled()->dehydrated(false), Forms\Components\Select::make('status')->options(OnlineOrder::STATUSES)->required(), Forms\Components\Select::make('delivery_method')->label('Livrare')->options(OnlineOrder::DELIVERY)->required(), Forms\Components\TextInput::make('customer_name')->label('Client')->required(), Forms\Components\TextInput::make('customer_phone')->label('Telefon')->required(), Forms\Components\TextInput::make('customer_email')->label('Email'), Forms\Components\TextInput::make('address')->label('Adresă')->columnSpan(2), Forms\Components\TextInput::make('delivery_fee')->label('Taxă livrare')->numeric(), Forms\Components\Textarea::make('notes')->label('Observații')->columnSpanFull()->rows(2), ]), ]); } public static function table(Table $table): Table { return $table ->columns([ Tables\Columns\TextColumn::make('number')->label('Nr.')->searchable()->sortable(), Tables\Columns\TextColumn::make('created_at')->label('Data')->dateTime('d.m.Y H:i')->sortable(), Tables\Columns\TextColumn::make('customer_name')->label('Client')->searchable(), Tables\Columns\TextColumn::make('customer_phone')->label('Telefon')->copyable(), Tables\Columns\TextColumn::make('delivery_method') ->label('Livrare') ->formatStateUsing(fn ($s) => OnlineOrder::DELIVERY[$s] ?? $s), Tables\Columns\TextColumn::make('status') ->formatStateUsing(fn ($s) => OnlineOrder::STATUSES[$s] ?? $s) ->badge() ->colors([ 'warning' => ['new'], 'info' => ['confirmed', 'packed'], 'primary' => ['shipped'], 'success' => ['delivered'], 'danger' => ['cancelled'], ]), Tables\Columns\TextColumn::make('total')->money('MDL')->alignRight()->sortable(), ]) ->filters([ Tables\Filters\SelectFilter::make('status')->options(OnlineOrder::STATUSES), ]) ->actions([ Actions\Action::make('fulfill') ->label('Onorează (scade stoc)') ->icon('heroicon-m-check-badge') ->color('success') ->visible(fn (OnlineOrder $r) => ! in_array($r->status, ['delivered', 'cancelled'], true)) ->requiresConfirmation() ->modalDescription('Scade din stoc piesele legate de catalog (FIFO) și marchează comanda confirmată.') ->action(function (OnlineOrder $r) { $svc = app(\App\Services\Warehouse\WarehouseService::class); $issued = 0; $skipped = 0; foreach ($r->items as $item) { if ($item->fulfilled) continue; if (! $item->part_id) { $skipped++; continue; } $part = \App\Models\Tenant\Part::find($item->part_id); if (! $part) { $skipped++; continue; } try { $svc->issue($part, (float) $item->qty, null, $r, "Comandă online #{$r->number}"); $item->fulfilled = true; $item->save(); $issued++; } catch (\App\Services\Warehouse\InsufficientStockException $e) { $skipped++; } } if ($r->status === 'new') { $r->status = 'confirmed'; $r->save(); } Notification::make() ->title("Onorat: {$issued} linii scăzute" . ($skipped ? ", {$skipped} sărite (stoc/lipsă link)" : '')) ->{$skipped ? 'warning' : 'success'}() ->send(); }), Actions\EditAction::make(), ]) ->defaultSort('created_at', 'desc'); } public static function getRelations(): array { return [ RelationManagers\ItemsRelationManager::class, ]; } public static function getPages(): array { return [ 'index' => Pages\ListOnlineOrders::route('/'), 'edit' => Pages\EditOnlineOrder::route('/{record}/edit'), ]; } }