feat(ops): pending widget + manual status change + bulk complete + fix changeStatus placement
This commit is contained in:
parent
09b511808d
commit
537d3c70a9
@ -140,6 +140,24 @@ class ShipmentChecklistResource extends Resource
|
|||||||
])
|
])
|
||||||
->bulkActions([
|
->bulkActions([
|
||||||
Tables\Actions\BulkActionGroup::make([
|
Tables\Actions\BulkActionGroup::make([
|
||||||
|
Tables\Actions\BulkAction::make('completeBulk')
|
||||||
|
->label('تکمیل گروهی')
|
||||||
|
->icon('heroicon-o-check-circle')
|
||||||
|
->color('success')
|
||||||
|
->requiresConfirmation()
|
||||||
|
->modalHeading('تکمیل آیتمهای انتخابشده')
|
||||||
|
->modalDescription('همهی آیتمهای انتخابشده بهعنوان تکمیلشده علامتگذاری میشوند.')
|
||||||
|
->action(function ($records) {
|
||||||
|
foreach ($records as $record) {
|
||||||
|
if (!$record->is_completed) {
|
||||||
|
$record->complete(auth()->id());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
\Filament\Notifications\Notification::make()
|
||||||
|
->title('آیتمهای انتخابشده تکمیل شدند')
|
||||||
|
->success()
|
||||||
|
->send();
|
||||||
|
}),
|
||||||
Tables\Actions\DeleteBulkAction::make()
|
Tables\Actions\DeleteBulkAction::make()
|
||||||
->visible(fn () => auth()->user()?->hasRole('super_admin')),
|
->visible(fn () => auth()->user()?->hasRole('super_admin')),
|
||||||
]),
|
]),
|
||||||
|
|||||||
@ -627,6 +627,41 @@ class ShipmentResource extends Resource
|
|||||||
->send();
|
->send();
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
Tables\Actions\Action::make('changeStatus')
|
||||||
|
->label('تغییر وضعیت')
|
||||||
|
->icon('heroicon-o-arrow-path')
|
||||||
|
->color('warning')
|
||||||
|
->visible(fn () => auth()->user()?->hasAnyRole(['super_admin', 'admin', 'staff']))
|
||||||
|
->form([
|
||||||
|
Forms\Components\Select::make('new_status')
|
||||||
|
->label('وضعیت جدید')
|
||||||
|
->options(collect(\App\Enums\ShipmentStatus::cases())->mapWithKeys(fn ($s) => [$s->value => $s->label()]))
|
||||||
|
->required(),
|
||||||
|
Forms\Components\Textarea::make('reason')
|
||||||
|
->label('دلیل/توضیح')
|
||||||
|
->rows(2),
|
||||||
|
])
|
||||||
|
->action(function ($record, array $data) {
|
||||||
|
$oldStatus = $record->status;
|
||||||
|
$newStatus = \App\Enums\ShipmentStatus::from($data['new_status']);
|
||||||
|
|
||||||
|
$record->update(['status' => $newStatus]);
|
||||||
|
|
||||||
|
\App\Models\ShipmentStatusHistory::create([
|
||||||
|
'shipment_id' => $record->id,
|
||||||
|
'from_status' => $oldStatus->value,
|
||||||
|
'to_status' => $newStatus->value,
|
||||||
|
'reason' => $data['reason'] ?? 'تغییر دستی توسط ' . auth()->user()->name,
|
||||||
|
'changed_by' => auth()->id(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
\Filament\Notifications\Notification::make()
|
||||||
|
->title('وضعیت سفارش تغییر کرد')
|
||||||
|
->body("از «{$oldStatus->label()}» به «{$newStatus->label()}»")
|
||||||
|
->success()
|
||||||
|
->send();
|
||||||
|
}),
|
||||||
])
|
])
|
||||||
->headerActions([
|
->headerActions([
|
||||||
Action::make('exportCsv')
|
Action::make('exportCsv')
|
||||||
@ -727,4 +762,15 @@ class ShipmentResource extends Resource
|
|||||||
'edit' => Pages\EditShipment::route('/{record}/edit'),
|
'edit' => Pages\EditShipment::route('/{record}/edit'),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function getNavigationBadge(): ?string
|
||||||
|
{
|
||||||
|
$count = static::getModel()::where('status', \App\Enums\ShipmentStatus::PendingApproval)->count();
|
||||||
|
return $count > 0 ? (string) $count : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getNavigationBadgeColor(): ?string
|
||||||
|
{
|
||||||
|
return 'warning';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
38
04_Laravel/app/Filament/Widgets/PendingOrdersWidget.php
Normal file
38
04_Laravel/app/Filament/Widgets/PendingOrdersWidget.php
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Widgets;
|
||||||
|
|
||||||
|
use App\Enums\ShipmentStatus;
|
||||||
|
use App\Models\Shipment;
|
||||||
|
use Filament\Widgets\StatsOverviewWidget as BaseWidget;
|
||||||
|
use Filament\Widgets\StatsOverviewWidget\Stat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ویجت سفارشهای در انتظار تأیید — مدیر را از سفارشهای جدید مطلع میکند.
|
||||||
|
*/
|
||||||
|
class PendingOrdersWidget extends BaseWidget
|
||||||
|
{
|
||||||
|
protected static ?int $sort = 3;
|
||||||
|
protected static bool $isLazy = false;
|
||||||
|
|
||||||
|
protected int | string | array $columnSpan = 'full';
|
||||||
|
|
||||||
|
protected function getStats(): array
|
||||||
|
{
|
||||||
|
$pendingCount = Shipment::where('status', ShipmentStatus::PendingApproval)->count();
|
||||||
|
$approvedUnpaidCount = Shipment::where('status', ShipmentStatus::Approved)->count();
|
||||||
|
|
||||||
|
return [
|
||||||
|
Stat::make('در انتظار تأیید', $pendingCount)
|
||||||
|
->description($pendingCount > 0 ? 'سفارش جدید منتظر بررسی' : 'سفارش جدیدی نیست')
|
||||||
|
->descriptionIcon('heroicon-m-clock')
|
||||||
|
->color($pendingCount > 0 ? 'warning' : 'gray')
|
||||||
|
->url($pendingCount > 0 ? '/panel/shipments' : null),
|
||||||
|
|
||||||
|
Stat::make('در انتظار پرداخت', $approvedUnpaidCount)
|
||||||
|
->description('سفارشهای تأییدشده — آماده پرداخت')
|
||||||
|
->descriptionIcon('heroicon-m-banknotes')
|
||||||
|
->color($approvedUnpaidCount > 0 ? 'info' : 'gray'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user