Implement wildcard search on transmittal series, notes, and files to improve user experience when filtering records. Also extend search capabilities to client company and branch code fields for more comprehensive filtering.
233 lines
9.7 KiB
PHP
233 lines
9.7 KiB
PHP
<?php
|
|
|
|
namespace App\Filament\Resources;
|
|
|
|
use App\Commands\Transmittal\GenerateTransmittalSeries;
|
|
use App\Commands\Transmittal\StoreTransmittalCommand;
|
|
use App\Exports\TransmittalsExport;
|
|
use App\Filament\Resources\TransmittalResource\Pages;
|
|
use App\Jobs\ExportCompleteJob;
|
|
use App\Models\Branch;
|
|
use App\Models\Client;
|
|
use App\Models\Transmittal;
|
|
use App\Models\User;
|
|
use Filament\Forms;
|
|
use Filament\Forms\Components\DatePicker;
|
|
use Filament\Forms\Components\Repeater;
|
|
use Filament\Forms\Components\Select;
|
|
use Filament\Forms\Components\Textarea;
|
|
use Filament\Forms\Components\TextInput;
|
|
use Filament\Forms\Form;
|
|
use Filament\Notifications\Notification;
|
|
use Filament\Resources\Resource;
|
|
use Filament\Support\Enums\FontWeight;
|
|
use Filament\Tables;
|
|
use Filament\Tables\Filters\SelectFilter;
|
|
use Filament\Tables\Table;
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
use Illuminate\Support\Arr;
|
|
use Malzariey\FilamentDaterangepickerFilter\Filters\DateRangeFilter;
|
|
|
|
class TransmittalResource extends Resource
|
|
{
|
|
protected static ?string $model = Transmittal::class;
|
|
|
|
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
|
|
|
|
public static function getEloquentQuery(): Builder
|
|
{
|
|
return parent::getEloquentQuery()->orderBy('id', 'desc');
|
|
}
|
|
|
|
public static function table(Table $table): Table
|
|
{
|
|
return $table
|
|
->columns([
|
|
Tables\Columns\Layout\Split::make([
|
|
Tables\Columns\TextColumn::make('series')
|
|
->searchable(query: function (Builder $query, string $search): Builder {
|
|
$wildcardSearch = '%' . str_replace(' ', '%', $search) . '%';
|
|
|
|
return $query->where(function (Builder $query) use ($wildcardSearch) {
|
|
$query->where('series', 'like', $wildcardSearch)
|
|
->orWhereHas('notes', function (Builder $query) use ($wildcardSearch) {
|
|
$query->where('comment', 'like', $wildcardSearch);
|
|
})
|
|
->orWhereHas('files', function (Builder $query) use ($wildcardSearch) {
|
|
$query->where('description', 'like', $wildcardSearch);
|
|
});
|
|
});
|
|
})
|
|
->label('Series')
|
|
->weight(FontWeight::Bold)
|
|
->columnSpan(2),
|
|
Tables\Columns\Layout\Stack::make([
|
|
Tables\Columns\TextColumn::make('client.company')
|
|
->searchable(query: function (Builder $query, string $search): Builder {
|
|
return $query->whereHas('client', function (Builder $query) use ($search) {
|
|
$query->where('company', 'like', '%' . str_replace(' ', '%', $search) . '%');
|
|
});
|
|
})
|
|
->weight(FontWeight::SemiBold)->label('Client'),
|
|
Tables\Columns\TextColumn::make('branch.code')
|
|
->searchable(query: function (Builder $query, string $search): Builder {
|
|
return $query->whereHas('branch', function (Builder $query) use ($search) {
|
|
$query->where('code', 'like', '%' . str_replace(' ', '%', $search) . '%');
|
|
});
|
|
})
|
|
->label('Branch'),
|
|
]),
|
|
]),
|
|
Tables\Columns\Layout\View::make('transmittal.tables.collapsible-files-component')->collapsible(),
|
|
])
|
|
->filters([
|
|
SelectFilter::make('client_id')->label('Client filter')->options(function () {
|
|
return Client::query()->get()->pluck('company', 'id');
|
|
}),
|
|
SelectFilter::make('branch_id')->label('Branch Filter')->options(function () {
|
|
return Branch::query()->get()->pluck('code', 'id');
|
|
}),
|
|
SelectFilter::make('user_id')->label('Assigned To Filter')->options(function () {
|
|
return User::query()->get()->pluck('name', 'id');
|
|
}),
|
|
DateRangeFilter::make('date_created'),
|
|
DateRangeFilter::make('date_dispatch'),
|
|
DateRangeFilter::make('date_received'),
|
|
|
|
])
|
|
->heading('Transmittals')
|
|
->description('Click on toggle button at the end of table row to show additional details.')
|
|
->actions(static::getTableActions())
|
|
->bulkActions([
|
|
Tables\Actions\BulkActionGroup::make([
|
|
Tables\Actions\DeleteBulkAction::make(),
|
|
Tables\Actions\BulkAction::make('Bulk Export')->action(function ($records) {
|
|
|
|
static::exportTransmittal(Arr::flatten($records->pluck('id')));
|
|
}),
|
|
]),
|
|
]);
|
|
}
|
|
|
|
public static function getTableActions(): array
|
|
{
|
|
return [
|
|
Tables\Actions\Action::make('Export')->action(fn ($record) => static::exportTransmittal([$record->id])),
|
|
Tables\Actions\ViewAction::make(),
|
|
Tables\Actions\Action::make('Update Status')
|
|
->fillForm(function ($record) {
|
|
return [
|
|
'user_id' => $record->user_id,
|
|
'date_dispatch' => $record->date_dispatch,
|
|
'date_received' => $record->date_received,
|
|
'received_by' => $record->received_by,
|
|
];
|
|
})
|
|
->form([
|
|
Select::make('user_id')->label('Dispatch By')
|
|
->relationship('user', 'name')
|
|
->searchable()
|
|
->preload(),
|
|
Datepicker::make('date_dispatch')->label('Dispatch Date')
|
|
->native(false)->default(now()),
|
|
TextInput::make('received_by')->label('Received By'),
|
|
Datepicker::make('date_received')->label('Date Received')->native(false),
|
|
])
|
|
->action(function ($data, $record) {
|
|
$data['id'] = $record->id;
|
|
(new StoreTransmittalCommand)->execute($data);
|
|
})
|
|
->icon('heroicon-o-pencil-square')
|
|
->slideOver()
|
|
->hidden(! auth()->user()->can('update_transmittal')),
|
|
Tables\Actions\EditAction::make(),
|
|
Tables\Actions\DeleteAction::make(),
|
|
];
|
|
}
|
|
|
|
public static function exportTransmittal(array $id): void
|
|
{
|
|
$recipient = auth()->user();
|
|
|
|
static::generateExportNotification();
|
|
|
|
(new TransmittalsExport([$id]))->store('public/transmittal-export.xlsx')->chain([
|
|
app(ExportCompleteJob::class, ['user' => $recipient]),
|
|
]);
|
|
}
|
|
|
|
public static function generateExportNotification(): Notification
|
|
{
|
|
|
|
return Notification::make()
|
|
->title('Your export will be ready. check your notification for file download link.')
|
|
->success()
|
|
->send();
|
|
}
|
|
|
|
public static function form(Form $form): Form
|
|
{
|
|
return $form
|
|
->schema(static::getFormSchema());
|
|
}
|
|
|
|
public static function getFormSchema(): array
|
|
{
|
|
return [
|
|
Forms\Components\Select::make('client_id')
|
|
->options(function () {
|
|
return Client::query()->get()->pluck('company', 'id');
|
|
})
|
|
->label('Client')
|
|
->reactive()
|
|
->required()
|
|
->required()->columnSpan(3),
|
|
Forms\Components\Select::make('branch_id')->label('Branch')->relationship('branch')->options(function (callable $get) {
|
|
return Branch::query()->where('client_id', $get('client_id'))->get()->pluck('code', 'id');
|
|
})->required(),
|
|
Forms\Components\TextInput::make('series')->readOnly()->default((new GenerateTransmittalSeries)->execute([]))->unique('transmittals', ignoreRecord: true),
|
|
Forms\Components\DatePicker::make('date_created')
|
|
->native(false)
|
|
->required()->default(now()),
|
|
|
|
Repeater::make('files')
|
|
->relationship('files')
|
|
->label('Item')
|
|
->schema([
|
|
Textarea::make('description')->required(),
|
|
Repeater::make('comments')
|
|
->relationship('notes')
|
|
->label('Note')
|
|
->schema([
|
|
Forms\Components\TextInput::make('comment')->label('Note')->required(),
|
|
]),
|
|
Repeater::make('remarks')
|
|
->relationship('remarks')
|
|
->label('Remarks')
|
|
->schema([
|
|
Forms\Components\TextInput::make('remark')->label('Remark')->required(),
|
|
]),
|
|
])
|
|
->columns(3)
|
|
->columnSpan(3),
|
|
];
|
|
}
|
|
|
|
public static function getRelations(): array
|
|
{
|
|
return [
|
|
//
|
|
];
|
|
}
|
|
|
|
public static function getPages(): array
|
|
{
|
|
return [
|
|
'index' => Pages\ListTransmittals::route('/'),
|
|
'create' => Pages\CreateTransmittal::route('/create'),
|
|
'view' => Pages\ViewTransmittal::route('/{record}'),
|
|
'edit' => Pages\EditTransmittal::route('/{record}/edit'),
|
|
];
|
|
}
|
|
}
|