feat: add lab tests, patient file management, and prescription improvements
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
|
||||
namespace App\Filament\Resources;
|
||||
use App\Filament\Resources\PrescriptionResource\Pages;
|
||||
use App\Models\LabTest;
|
||||
use App\Models\Medication;
|
||||
use App\Models\Patient;
|
||||
use App\Models\Prescription;
|
||||
@@ -18,11 +19,14 @@
|
||||
use Filament\Actions\EditAction;
|
||||
use Filament\Forms\Components\CheckboxList;
|
||||
use Filament\Forms\Components\DatePicker;
|
||||
use Filament\Forms\Components\Hidden;
|
||||
use Filament\Forms\Components\RichEditor;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Schemas\Components\Grid;
|
||||
use Filament\Schemas\Components\Section;
|
||||
use Filament\Schemas\Components\Tabs;
|
||||
use Filament\Schemas\Components\Tabs\Tab;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Table;
|
||||
@@ -95,60 +99,131 @@ public static function form(Schema $schema): Schema
|
||||
->columns(2)
|
||||
->columnSpanFull(),
|
||||
|
||||
Section::make(__('prescriptions.sections.medications'))
|
||||
Section::make()
|
||||
->schema([
|
||||
CheckboxList::make('medication_ids')
|
||||
->label(__('prescriptions.fields.medication_ids'))
|
||||
->options(fn () => Medication::where('is_active', true)
|
||||
->orderBy('name')
|
||||
->get()
|
||||
->mapWithKeys(fn ($m) => [
|
||||
$m->id => implode(' ', array_filter([
|
||||
$m->dosage_form,
|
||||
$m->name,
|
||||
$m->strength,
|
||||
$m->quantity ? '#' . $m->quantity : null,
|
||||
$m->timing,
|
||||
])),
|
||||
])
|
||||
->toArray()
|
||||
)
|
||||
->columns(3)
|
||||
->live()
|
||||
->afterStateUpdated(function (array $state, callable $set) {
|
||||
if (empty($state)) {
|
||||
$set('content', null);
|
||||
return;
|
||||
}
|
||||
$medications = Medication::whereIn('id', $state)
|
||||
->orderBy('name')
|
||||
->get();
|
||||
$html = '<ul>' . $medications->map(fn ($m) =>
|
||||
'<li>' . implode(' ', array_filter([
|
||||
$m->dosage_form,
|
||||
$m->name,
|
||||
$m->strength,
|
||||
$m->quantity ? '#' . $m->quantity : null,
|
||||
$m->timing,
|
||||
])) . '</li>'
|
||||
)->implode('') . '</ul>';
|
||||
$set('content', $html);
|
||||
})
|
||||
->columnSpanFull(),
|
||||
])
|
||||
->columnSpanFull(),
|
||||
Tabs::make()
|
||||
->tabs([
|
||||
Tab::make(__('prescriptions.sections.medications'))
|
||||
->icon('heroicon-o-clipboard-document-list')
|
||||
->schema([
|
||||
Hidden::make('medication_order'),
|
||||
|
||||
Section::make(__('prescriptions.sections.content'))
|
||||
->schema([
|
||||
RichEditor::make('content')
|
||||
->label(__('prescriptions.fields.content'))
|
||||
CheckboxList::make('medication_ids')
|
||||
->label(__('prescriptions.fields.medication_ids'))
|
||||
->options(fn () => Medication::where('is_active', true)
|
||||
->orderBy('name')
|
||||
->get()
|
||||
->mapWithKeys(fn ($m) => [
|
||||
$m->id => implode(' ', array_filter([
|
||||
$m->dosage_form,
|
||||
$m->name,
|
||||
$m->strength,
|
||||
$m->quantity ? '#' . $m->quantity : null,
|
||||
$m->timing,
|
||||
])),
|
||||
])
|
||||
->toArray()
|
||||
)
|
||||
->columns(3)
|
||||
->live()
|
||||
->afterStateUpdated(function (array $state, callable $set, callable $get) {
|
||||
$currentOrder = array_map('intval', (array) ($get('medication_order') ?: []));
|
||||
$state = array_map('intval', $state);
|
||||
|
||||
$newOrder = array_values(
|
||||
array_filter($currentOrder, fn ($id) => in_array($id, $state))
|
||||
);
|
||||
foreach ($state as $id) {
|
||||
if (! in_array($id, $newOrder)) {
|
||||
$newOrder[] = $id;
|
||||
}
|
||||
}
|
||||
$set('medication_order', $newOrder);
|
||||
|
||||
if (empty($newOrder)) {
|
||||
$set('content', null);
|
||||
return;
|
||||
}
|
||||
$medications = Medication::whereIn('id', $newOrder)->get()->keyBy('id');
|
||||
$html = '<ul>' . collect($newOrder)
|
||||
->map(fn ($id) => isset($medications[$id])
|
||||
? '<li>' . implode(' ', array_filter([
|
||||
$medications[$id]->dosage_form,
|
||||
$medications[$id]->name,
|
||||
$medications[$id]->strength,
|
||||
$medications[$id]->quantity ? '#' . $medications[$id]->quantity : null,
|
||||
$medications[$id]->timing,
|
||||
])) . '</li>'
|
||||
: ''
|
||||
)
|
||||
->filter()
|
||||
->implode('') . '</ul>';
|
||||
$set('content', $html);
|
||||
})
|
||||
->columnSpanFull(),
|
||||
|
||||
RichEditor::make('content')
|
||||
->label(__('prescriptions.fields.content'))
|
||||
->columnSpanFull(),
|
||||
]),
|
||||
|
||||
Tab::make(__('prescriptions.sections.lab_tests'))
|
||||
->icon('heroicon-o-beaker')
|
||||
->schema([
|
||||
Hidden::make('lab_test_order'),
|
||||
|
||||
CheckboxList::make('lab_test_ids')
|
||||
->label(__('prescriptions.fields.lab_test_ids'))
|
||||
->options(fn () => LabTest::where('is_active', true)
|
||||
->orderBy('name')
|
||||
->get()
|
||||
->mapWithKeys(fn ($t) => [$t->id => $t->name])
|
||||
->toArray()
|
||||
)
|
||||
->columns(3)
|
||||
->live()
|
||||
->afterStateUpdated(function (array $state, callable $set, callable $get) {
|
||||
$currentOrder = array_map('intval', (array) ($get('lab_test_order') ?: []));
|
||||
$state = array_map('intval', $state);
|
||||
|
||||
$newOrder = array_values(
|
||||
array_filter($currentOrder, fn ($id) => in_array($id, $state))
|
||||
);
|
||||
foreach ($state as $id) {
|
||||
if (! in_array($id, $newOrder)) {
|
||||
$newOrder[] = $id;
|
||||
}
|
||||
}
|
||||
$set('lab_test_order', $newOrder);
|
||||
|
||||
if (empty($newOrder)) {
|
||||
$set('lab_content', null);
|
||||
return;
|
||||
}
|
||||
$tests = LabTest::whereIn('id', $newOrder)->get()->keyBy('id');
|
||||
$html = '<ul>' . collect($newOrder)
|
||||
->map(fn ($id) => isset($tests[$id])
|
||||
? '<li>' . $tests[$id]->name . '</li>'
|
||||
: ''
|
||||
)
|
||||
->filter()
|
||||
->implode('') . '</ul>';
|
||||
$set('lab_content', $html);
|
||||
})
|
||||
->columnSpanFull(),
|
||||
|
||||
RichEditor::make('lab_content')
|
||||
->label(__('prescriptions.fields.lab_content'))
|
||||
->columnSpanFull(),
|
||||
]),
|
||||
])
|
||||
->columnSpanFull(),
|
||||
])
|
||||
->columnSpanFull()
|
||||
->footerActions([
|
||||
fn (string $operation) => Action::make('createAndPrint')
|
||||
->label(__('prescriptions.actions.save_and_print'))
|
||||
->color('warning')
|
||||
->color('primary')
|
||||
->icon('heroicon-o-printer')
|
||||
->action(function ($livewire) {
|
||||
$livewire->printType = 'prescription';
|
||||
@@ -156,6 +231,26 @@ public static function form(Schema $schema): Schema
|
||||
})
|
||||
->visible($operation === 'create'),
|
||||
|
||||
fn (string $operation) => Action::make('createAndPrintLab')
|
||||
->label(__('prescriptions.actions.print_lab'))
|
||||
->color('gray')
|
||||
->icon('heroicon-o-beaker')
|
||||
->action(function ($livewire) {
|
||||
$livewire->printType = 'lab';
|
||||
$livewire->create();
|
||||
})
|
||||
->visible($operation === 'create'),
|
||||
|
||||
fn (string $operation) => Action::make('createAndPrintBoth')
|
||||
->label(__('prescriptions.actions.save_and_print_both'))
|
||||
->color('warning')
|
||||
->icon('heroicon-o-document-duplicate')
|
||||
->action(function ($livewire) {
|
||||
$livewire->printType = 'both';
|
||||
$livewire->create();
|
||||
})
|
||||
->visible($operation === 'create'),
|
||||
|
||||
fn (string $operation) => Action::make('cancelCreate')
|
||||
->label(__('filament-panels::resources/pages/create-record.form.actions.cancel.label'))
|
||||
->url(static::getUrl('index'))
|
||||
@@ -237,6 +332,18 @@ public static function table(Table $table): Table
|
||||
])
|
||||
->defaultSort('created_at', 'desc')
|
||||
->recordActions([
|
||||
Action::make('printBoth')
|
||||
->label(__('prescriptions.actions.print_both'))
|
||||
->icon('heroicon-o-document-duplicate')
|
||||
->color('purple')
|
||||
->modalContent(fn ($record) => view('filament.prescription-print-modal', [
|
||||
'url' => route('prescription.print', ['prescription' => $record, 'type' => 'both']),
|
||||
]))
|
||||
->modalHeading(fn ($record) => ($record->patientRecord?->full_name ?? '') . ' — نسخه و آزمایش')
|
||||
->modalWidth('7xl')
|
||||
->modalSubmitAction(false)
|
||||
->modalCancelActionLabel('بستن'),
|
||||
|
||||
Action::make('printPrescription')
|
||||
->label(__('prescriptions.actions.print_prescription'))
|
||||
->icon('heroicon-o-printer')
|
||||
|
||||
Reference in New Issue
Block a user