📄 PrescriptionResource.php
📁 Path: /home/skhata/new.chandrapharma.com/app/Modules/Pharmacy/Filament/Resources/PrescriptionResource.php
📊 Size: 7.47 KB
🔒 Perm: 0600
📝 MIME: text/x-php
<?php
namespace App\Modules\Pharmacy\Filament\Resources;
use App\Modules\Pharmacy\Filament\Resources\PrescriptionResource\Pages;
use App\Modules\Pharmacy\Models\Prescription;
use Filament\Forms;
use Filament\Forms\Form;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Auth;
class PrescriptionResource extends Resource
{
protected static ?string $model = Prescription::class;
protected static ?string $navigationIcon = 'heroicon-o-document-check';
protected static ?string $navigationLabel = 'Prescriptions';
protected static ?string $navigationGroup = 'Pharmacy';
protected static ?int $navigationSort = 1;
protected static bool $shouldSkipAuthorization = true;
public static function canAccess(): bool
{
$user = auth()->user();
// Allow super_admin, admin, and pharmacist roles
return $user?->hasAnyRole(['super_admin', 'admin', 'pharmacist']);
}
public static function canCreate(): bool { return false; } // prescriptions come from frontend only
public static function canEdit($r): bool { return true; }
public static function canDelete($r): bool { return auth()->user()?->hasRole('admin'); }
public static function canView($r): bool { return true; }
// Explicit base query — prevents "::class on null" when Filament's
// lazy resource closure is resolved before the panel boots fully.
public static function getEloquentQuery(): Builder
{
return Prescription::query()->with(['customer', 'reviewer', 'orders']);
}
public static function getNavigationBadge(): ?string
{
$count = Prescription::pending()->count();
return $count > 0 ? (string) $count : null;
}
public static function getNavigationBadgeColor(): ?string
{
return 'danger';
}
public static function form(Form $form): Form
{
return $form->schema([
Forms\Components\Section::make('Prescription Details')->schema([
Forms\Components\TextInput::make('customer.name')
->label('Customer')
->disabled(),
Forms\Components\Select::make('status')
->options([
'pending' => 'Pending',
'approved' => 'Approved',
'rejected' => 'Rejected',
'expired' => 'Expired',
])
->required(),
Forms\Components\DatePicker::make('valid_until')
->label('Valid Until')
->nullable()
->helperText('Leave blank to auto-set 6 months from today on approval.'),
Forms\Components\Textarea::make('pharmacist_notes')
->label('Pharmacist Notes')
->rows(3)
->placeholder('Reason for rejection, or any notes for the customer...'),
])->columns(2),
]);
}
public static function table(Table $table): Table
{
return $table
// Clicking a row goes to the View page (no Edit page registered).
->recordUrl(fn (Prescription $record): string => static::getUrl('view', ['record' => $record]))
->columns([
Tables\Columns\TextColumn::make('id')
->label('Rx #')
->sortable(),
Tables\Columns\TextColumn::make('customer.name')
->label('Customer')
->searchable(),
Tables\Columns\TextColumn::make('customer.email')
->label('Email')
->searchable()
->toggleable(isToggledHiddenByDefault: true),
Tables\Columns\ImageColumn::make('file_url')
->label('Prescription')
->height(60)
->width(80),
Tables\Columns\TextColumn::make('file_type')
->label('Type')
->badge()
->color(fn (string $state) => $state === 'pdf' ? 'danger' : 'info'),
Tables\Columns\TextColumn::make('status')
->badge()
->color(fn (string $state) => match ($state) {
'approved' => 'success',
'rejected' => 'danger',
'expired' => 'gray',
default => 'warning',
}),
Tables\Columns\TextColumn::make('valid_until')
->label('Valid Until')
->date()
->placeholder('—')
->sortable(),
Tables\Columns\TextColumn::make('reviewer.name')
->label('Reviewed By')
->placeholder('—'),
Tables\Columns\TextColumn::make('created_at')
->label('Submitted')
->dateTime()
->sortable(),
])
->defaultSort('created_at', 'desc')
->filters([
Tables\Filters\SelectFilter::make('status')
->options([
'pending' => 'Pending',
'approved' => 'Approved',
'rejected' => 'Rejected',
'expired' => 'Expired',
]),
])
->actions([
// Quick approve action
Tables\Actions\Action::make('approve')
->label('Approve')
->icon('heroicon-o-check-circle')
->color('success')
->visible(fn (Prescription $record) => $record->status === 'pending')
->requiresConfirmation()
->form([
Forms\Components\Textarea::make('pharmacist_notes')
->label('Notes (optional)')
->rows(2),
])
->action(function (Prescription $record, array $data): void {
$record->approve(Auth::user(), $data['pharmacist_notes'] ?? null);
}),
// Quick reject action
Tables\Actions\Action::make('reject')
->label('Reject')
->icon('heroicon-o-x-circle')
->color('danger')
->visible(fn (Prescription $record) => $record->status === 'pending')
->requiresConfirmation()
->form([
Forms\Components\Textarea::make('pharmacist_notes')
->label('Reason for rejection')
->required()
->rows(2),
])
->action(function (Prescription $record, array $data): void {
$record->reject(Auth::user(), $data['pharmacist_notes']);
}),
Tables\Actions\ViewAction::make(),
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make(),
]),
]);
}
public static function getPages(): array
{
return [
'index' => Pages\ListPrescriptions::route('/'),
'view' => Pages\ViewPrescription::route('/{record}'),
];
}
}