Deploy Ladill Care / deploy (push) Successful in 48s
Nurses keep Nursing Services for clinical work but can no longer browse or create structural units and departments. Co-authored-by: Cursor <cursoragent@cursor.com>
233 lines
8.7 KiB
PHP
233 lines
8.7 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Care;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Http\Controllers\Care\Concerns\ScopesToAccount;
|
|
use App\Models\CareUnit;
|
|
use App\Models\Department;
|
|
use App\Models\Visit;
|
|
use App\Services\Care\AuditLogger;
|
|
use App\Services\Care\CarePermissions;
|
|
use Illuminate\Http\RedirectResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Validation\Rule;
|
|
use Illuminate\View\View;
|
|
|
|
class CareUnitController extends Controller
|
|
{
|
|
use ScopesToAccount;
|
|
|
|
public function index(Request $request): View
|
|
{
|
|
$this->authorizeAbility($request, 'admin.departments.view');
|
|
$organization = $this->organization($request);
|
|
$owner = $this->ownerRef($request);
|
|
$member = $this->member($request);
|
|
$permissions = app(CarePermissions::class);
|
|
|
|
$units = CareUnit::owned($owner)
|
|
->where('organization_id', $organization->id)
|
|
->with(['department.branch'])
|
|
->orderBy('sort_order')
|
|
->orderBy('name')
|
|
->get();
|
|
|
|
$heroStats = [
|
|
'total' => $units->count(),
|
|
'inpatient' => $units->where('kind', 'inpatient')->count(),
|
|
'float' => $units->where('kind', 'float_pool')->count(),
|
|
'active' => $units->where('is_active', true)->count(),
|
|
];
|
|
|
|
return view('care.admin.care-units.index', [
|
|
'units' => $units,
|
|
'organization' => $organization,
|
|
'kinds' => config('care.care_unit_kinds'),
|
|
'heroStats' => $heroStats,
|
|
'canManage' => $permissions->can($member, 'admin.departments.manage'),
|
|
]);
|
|
}
|
|
|
|
public function create(Request $request): View
|
|
{
|
|
$this->authorizeAbility($request, 'admin.departments.manage');
|
|
$organization = $this->organization($request);
|
|
$owner = $this->ownerRef($request);
|
|
|
|
$departments = Department::owned($owner)
|
|
->whereHas('branch', fn ($q) => $q->where('organization_id', $organization->id))
|
|
->with('branch')
|
|
->where('is_active', true)
|
|
->orderBy('name')
|
|
->get();
|
|
|
|
return view('care.admin.care-units.create', [
|
|
'organization' => $organization,
|
|
'departments' => $departments,
|
|
'kinds' => config('care.care_unit_kinds'),
|
|
'selectedDepartmentId' => $request->integer('department_id') ?: null,
|
|
]);
|
|
}
|
|
|
|
public function store(Request $request): RedirectResponse
|
|
{
|
|
$this->authorizeAbility($request, 'admin.departments.manage');
|
|
$organization = $this->organization($request);
|
|
$owner = $this->ownerRef($request);
|
|
|
|
$validated = $request->validate([
|
|
'department_id' => ['required', 'integer', 'exists:care_departments,id'],
|
|
'name' => ['required', 'string', 'max:255'],
|
|
'code' => ['nullable', 'string', 'max:50'],
|
|
'kind' => ['required', 'string', Rule::in(array_keys(config('care.care_unit_kinds')))],
|
|
]);
|
|
|
|
$department = Department::owned($owner)->with('branch')->findOrFail($validated['department_id']);
|
|
abort_unless((int) $department->branch?->organization_id === (int) $organization->id, 404);
|
|
|
|
$unit = CareUnit::create([
|
|
'owner_ref' => $owner,
|
|
'organization_id' => $organization->id,
|
|
'department_id' => $department->id,
|
|
'name' => $validated['name'],
|
|
'code' => $validated['code'] ?? null,
|
|
'kind' => $validated['kind'],
|
|
'is_active' => true,
|
|
]);
|
|
|
|
AuditLogger::record($owner, 'care_unit.created', $organization->id, $owner, CareUnit::class, $unit->id);
|
|
|
|
return redirect()->route('care.care-units.show', $unit)->with('success', 'Care unit created.');
|
|
}
|
|
|
|
public function show(Request $request, CareUnit $careUnit): View
|
|
{
|
|
$this->authorizeCareUnitView($request);
|
|
$this->authorizeOwner($request, $careUnit);
|
|
$organization = $this->organization($request);
|
|
abort_unless((int) $careUnit->organization_id === (int) $organization->id, 404);
|
|
|
|
$careUnit->load(['department.branch', 'beds']);
|
|
|
|
$placedVisits = Visit::owned($this->ownerRef($request))
|
|
->where('organization_id', $organization->id)
|
|
->where('care_unit_id', $careUnit->id)
|
|
->whereIn('status', [Visit::STATUS_OPEN, Visit::STATUS_IN_PROGRESS])
|
|
->with(['patient', 'bed'])
|
|
->orderBy('placed_at')
|
|
->get();
|
|
|
|
$placeableVisits = Visit::owned($this->ownerRef($request))
|
|
->where('organization_id', $organization->id)
|
|
->where('branch_id', $careUnit->department?->branch_id)
|
|
->whereIn('status', [Visit::STATUS_OPEN, Visit::STATUS_IN_PROGRESS])
|
|
->where(function ($q) use ($careUnit) {
|
|
$q->whereNull('care_unit_id')
|
|
->orWhere('care_unit_id', '!=', $careUnit->id);
|
|
})
|
|
->with(['patient', 'careUnit'])
|
|
->orderByDesc('checked_in_at')
|
|
->limit(50)
|
|
->get();
|
|
|
|
$availableBeds = $careUnit->beds
|
|
->where('is_active', true)
|
|
->whereIn('status', ['available', 'reserved'])
|
|
->values();
|
|
|
|
$canPlace = app(CarePermissions::class)->can($this->member($request), 'inpatient.placement.manage');
|
|
|
|
return view('care.admin.care-units.show', [
|
|
'unit' => $careUnit,
|
|
'kinds' => config('care.care_unit_kinds'),
|
|
'bedStatuses' => config('care.bed_statuses'),
|
|
'placedVisits' => $placedVisits,
|
|
'placeableVisits' => $placeableVisits,
|
|
'availableBeds' => $availableBeds,
|
|
'canPlace' => $canPlace,
|
|
]);
|
|
}
|
|
|
|
protected function authorizeCareUnitView(Request $request): void
|
|
{
|
|
$permissions = app(CarePermissions::class);
|
|
$member = $this->member($request);
|
|
abort_unless(
|
|
$permissions->can($member, 'admin.departments.view')
|
|
|| $permissions->can($member, 'inpatient.placement.view'),
|
|
403,
|
|
);
|
|
}
|
|
|
|
public function edit(Request $request, CareUnit $careUnit): View
|
|
{
|
|
$this->authorizeAbility($request, 'admin.departments.manage');
|
|
$this->authorizeOwner($request, $careUnit);
|
|
$organization = $this->organization($request);
|
|
$owner = $this->ownerRef($request);
|
|
|
|
$departments = Department::owned($owner)
|
|
->whereHas('branch', fn ($q) => $q->where('organization_id', $organization->id))
|
|
->with('branch')
|
|
->orderBy('name')
|
|
->get();
|
|
|
|
return view('care.admin.care-units.edit', [
|
|
'unit' => $careUnit,
|
|
'departments' => $departments,
|
|
'kinds' => config('care.care_unit_kinds'),
|
|
]);
|
|
}
|
|
|
|
public function update(Request $request, CareUnit $careUnit): RedirectResponse
|
|
{
|
|
$this->authorizeAbility($request, 'admin.departments.manage');
|
|
$this->authorizeOwner($request, $careUnit);
|
|
$organization = $this->organization($request);
|
|
$owner = $this->ownerRef($request);
|
|
|
|
$validated = $request->validate([
|
|
'department_id' => ['required', 'integer', 'exists:care_departments,id'],
|
|
'name' => ['required', 'string', 'max:255'],
|
|
'code' => ['nullable', 'string', 'max:50'],
|
|
'kind' => ['required', 'string', Rule::in(array_keys(config('care.care_unit_kinds')))],
|
|
'is_active' => ['boolean'],
|
|
]);
|
|
|
|
$department = Department::owned($owner)->with('branch')->findOrFail($validated['department_id']);
|
|
abort_unless((int) $department->branch?->organization_id === (int) $organization->id, 404);
|
|
|
|
$careUnit->update([
|
|
'department_id' => $department->id,
|
|
'name' => $validated['name'],
|
|
'code' => $validated['code'] ?? null,
|
|
'kind' => $validated['kind'],
|
|
'is_active' => $request->boolean('is_active', true),
|
|
]);
|
|
|
|
AuditLogger::record($owner, 'care_unit.updated', $organization->id, $owner, CareUnit::class, $careUnit->id);
|
|
|
|
return redirect()->route('care.care-units.show', $careUnit)->with('success', 'Care unit updated.');
|
|
}
|
|
|
|
public function destroy(Request $request, CareUnit $careUnit): RedirectResponse
|
|
{
|
|
$this->authorizeAbility($request, 'admin.departments.manage');
|
|
$this->authorizeOwner($request, $careUnit);
|
|
|
|
$careUnit->delete();
|
|
|
|
AuditLogger::record(
|
|
$this->ownerRef($request),
|
|
'care_unit.deleted',
|
|
$careUnit->organization_id,
|
|
$this->ownerRef($request),
|
|
CareUnit::class,
|
|
$careUnit->id,
|
|
);
|
|
|
|
return redirect()->route('care.care-units.index')->with('success', 'Care unit removed.');
|
|
}
|
|
}
|