Integrate a complete workflow for commitment forms including secure template downloads, customer uploads via WordPress AJAX, and administrative verification with automated notifications. - Implement `downloadTemplate` and `downloadSigned` logic in `CommitmentFormController` to replace public symlinks with ownership-verified routes. - Add `CommitmentFormVerifiedNotification` and `CommitmentFormRejectedNotification` to alert customers of status changes. - Enhance WordPress bridge with AJAX-driven form listing, status badges, and upload capabilities. - Update Filament `CommitmentFormsRelationManager` to provide better visibility into form directions and descriptions while restricting status edits to specific actions. - Refactor Laravel 11 bootstrap configuration to handle guest redirection for API and web routes correctly. - Add administrative controllers for secure file access within the admin panel.
173 lines
8.3 KiB
PHP
173 lines
8.3 KiB
PHP
<?php
|
|
|
|
namespace App\Filament\Resources\ShipmentResource\RelationManagers;
|
|
|
|
use App\Models\ShipmentCommitmentForm;
|
|
use App\Notifications\CommitmentFormRejectedNotification;
|
|
use App\Notifications\CommitmentFormVerifiedNotification;
|
|
use Filament\Forms;
|
|
use Filament\Forms\Form;
|
|
use Filament\Resources\RelationManagers\RelationManager;
|
|
use Filament\Tables;
|
|
use Filament\Tables\Table;
|
|
|
|
class CommitmentFormsRelationManager extends RelationManager
|
|
{
|
|
protected static string $relationship = 'commitmentForms';
|
|
|
|
protected static ?string $title = 'تعهدنامهها';
|
|
|
|
protected static ?string $icon = 'heroicon-o-document-text';
|
|
|
|
public function form(Form $form): Form
|
|
{
|
|
// رکوردها فقط از آپلود مشتری یا مقداردهی خودکار ساخته میشوند؛
|
|
// از این فرم فقط یادداشت قابل ویرایش است (وضعیت با اکشنهای تأیید/رد تغییر میکند)
|
|
return $form->schema([
|
|
Forms\Components\Textarea::make('notes')
|
|
->rows(3)
|
|
->label('یادداشت')
|
|
->maxLength(1000),
|
|
]);
|
|
}
|
|
|
|
public function table(Table $table): Table
|
|
{
|
|
return $table
|
|
->columns([
|
|
Tables\Columns\TextColumn::make('form.title')
|
|
->label('فرم تعهدنامه')
|
|
->description(fn ($record) => $record->form?->description)
|
|
->limit(40),
|
|
Tables\Columns\TextColumn::make('form.direction')
|
|
->label('جهت')
|
|
->badge()
|
|
->color('gray')
|
|
->formatStateUsing(fn ($state): string => match ($state) {
|
|
'export' => 'صادرات',
|
|
'import' => 'واردات',
|
|
'both' => 'هردو',
|
|
default => (string) $state,
|
|
})
|
|
->toggleable(),
|
|
Tables\Columns\TextColumn::make('status')
|
|
->label('وضعیت')
|
|
->badge()
|
|
->color(fn (string $state): string => match ($state) {
|
|
'pending' => 'warning',
|
|
'uploaded' => 'info',
|
|
'verified' => 'success',
|
|
'rejected' => 'danger',
|
|
default => 'gray',
|
|
})
|
|
->formatStateUsing(fn (string $state): string => match ($state) {
|
|
'pending' => 'در انتظار آپلود',
|
|
'uploaded' => 'آپلود شده',
|
|
'verified' => 'تأیید شده',
|
|
'rejected' => 'رد شده',
|
|
default => $state,
|
|
}),
|
|
Tables\Columns\TextColumn::make('uploaded_file_type')
|
|
->label('فایل مشتری')
|
|
->formatStateUsing(function ($state, $record) {
|
|
if (!$state) return '—';
|
|
$size = $record->uploaded_file_size ? ' · ' . number_format($record->uploaded_file_size / 1024, 0) . ' KB' : '';
|
|
return strtoupper($state) . $size;
|
|
}),
|
|
Tables\Columns\TextColumn::make('created_at')
|
|
->label('تاریخ آپلود')
|
|
->dateTime('Y/m/d H:i')
|
|
->toggleable(),
|
|
Tables\Columns\TextColumn::make('uploader.name')
|
|
->label('بارگذاری توسط')
|
|
->toggleable(isToggledHiddenByDefault: true),
|
|
Tables\Columns\TextColumn::make('verifier.name')
|
|
->label('تأییدکننده')
|
|
->toggleable(),
|
|
Tables\Columns\TextColumn::make('verified_at')
|
|
->label('تاریخ تأیید')
|
|
->dateTime('Y/m/d H:i')
|
|
->toggleable(),
|
|
Tables\Columns\TextColumn::make('notes')
|
|
->label('یادداشت / دلیل')
|
|
->limit(40)
|
|
->toggleable(),
|
|
])
|
|
->defaultSort('created_at', 'desc')
|
|
// ساخت دستی مجاز نیست — این رکوردها از آپلود تعهدنامه توسط مشتری ایجاد میشوند
|
|
->headerActions([])
|
|
->actions([
|
|
Tables\Actions\Action::make('downloadTemplate')
|
|
->label('قالب')
|
|
->icon('heroicon-o-arrow-down-tray')
|
|
->color('gray')
|
|
->url(fn ($record) => $record->form?->file_path
|
|
? route('admin.commitment-forms.template', ['shipment' => $record->shipment_id, 'form' => $record->commitment_form_id])
|
|
: null)
|
|
->openUrlInNewTab()
|
|
->visible(fn ($record) => !empty($record->form?->file_path))
|
|
->tooltip('دانلود قالب خام تعهدنامه'),
|
|
Tables\Actions\Action::make('downloadSigned')
|
|
->label('فایل مشتری')
|
|
->icon('heroicon-o-document-arrow-down')
|
|
->color('info')
|
|
->url(fn ($record) => $record->uploaded_file_path
|
|
? route('admin.commitment-forms.signed', ['shipment' => $record->shipment_id, 'record' => $record->id])
|
|
: null)
|
|
->openUrlInNewTab()
|
|
->visible(fn ($record) => !empty($record->uploaded_file_path))
|
|
->tooltip('دانلود فایل امضاشدهٔ آپلودشده توسط مشتری'),
|
|
Tables\Actions\Action::make('verify')
|
|
->label('تأیید')
|
|
->icon('heroicon-o-check-circle')
|
|
->color('success')
|
|
->requiresConfirmation()
|
|
->modalDescription('با تأیید، به مشتری اعلان ارسال میشود.')
|
|
->form([
|
|
Forms\Components\Textarea::make('notes')
|
|
->label('یادداشت برای مشتری (اختیاری)')
|
|
->rows(2)
|
|
->maxLength(1000),
|
|
])
|
|
->action(function (ShipmentCommitmentForm $record, array $data): void {
|
|
$record->update([
|
|
'status' => 'verified',
|
|
'notes' => $data['notes'] ?: $record->notes,
|
|
'verified_by' => auth()->id(),
|
|
'verified_at' => now(),
|
|
]);
|
|
|
|
$record->shipment->user?->notify(new CommitmentFormVerifiedNotification($record));
|
|
})
|
|
->visible(fn ($record) => in_array($record->status, ['uploaded', 'rejected'])),
|
|
Tables\Actions\Action::make('reject')
|
|
->label('رد')
|
|
->icon('heroicon-o-x-circle')
|
|
->color('danger')
|
|
->form([
|
|
Forms\Components\Textarea::make('notes')
|
|
->label('دلیل رد (برای مشتری نمایش داده میشود)')
|
|
->rows(2)
|
|
->required()
|
|
->maxLength(1000),
|
|
])
|
|
->action(function (ShipmentCommitmentForm $record, array $data): void {
|
|
$record->update([
|
|
'status' => 'rejected',
|
|
'notes' => $data['notes'],
|
|
'verified_by' => auth()->id(),
|
|
'verified_at' => now(),
|
|
]);
|
|
|
|
$record->shipment->user?->notify(new CommitmentFormRejectedNotification($record));
|
|
})
|
|
->visible(fn ($record) => in_array($record->status, ['uploaded', 'verified'])),
|
|
Tables\Actions\EditAction::make()
|
|
->label('یادداشت')
|
|
->icon('heroicon-o-pencil-square')
|
|
->tooltip('ویرایش یادداشت'),
|
|
])
|
|
->bulkActions([]);
|
|
}
|
|
}
|