Restrict specialty modules to doctors assigned to that specialty.
Deploy Ladill Care / deploy (push) Successful in 1m10s
Deploy Ladill Care / deploy (push) Successful in 1m10s
Nav and pages require a linked practitioner desk in the module department; demo seeds specialty doctors and stops overwriting their assigned waiters. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -4,7 +4,9 @@ namespace App\Services\Care;
|
||||
|
||||
use App\Models\Branch;
|
||||
use App\Models\Department;
|
||||
use App\Models\Member;
|
||||
use App\Models\Organization;
|
||||
use App\Models\Practitioner;
|
||||
use App\Services\Queue\QueueClient;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
@@ -79,6 +81,86 @@ class SpecialtyModuleService
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enabled modules the member may open (role allowlist + doctor specialty assignment).
|
||||
*
|
||||
* @return list<array{key: string, definition: array<string, mixed>}>
|
||||
*/
|
||||
public function enabledModulesForMember(Organization $organization, ?Member $member): array
|
||||
{
|
||||
return array_values(array_filter(
|
||||
$this->enabledModules($organization),
|
||||
fn (array $item) => $this->memberCanAccess($organization, $member, $item['key']),
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the member may see/serve this specialty module.
|
||||
* Doctors must be linked to a practitioner desk in that specialty department.
|
||||
* Admins/receptionists keep org-wide visibility for operations.
|
||||
*/
|
||||
public function memberCanAccess(Organization $organization, ?Member $member, string $key): bool
|
||||
{
|
||||
if (! $this->isEnabled($organization, $key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$definition = $this->definition($key);
|
||||
if (! $definition) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$roles = $definition['roles'] ?? [];
|
||||
if (is_array($roles) && $roles !== [] && $member && ! in_array($member->role, $roles, true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($member && $member->role === 'doctor') {
|
||||
return $this->doctorAssignedToModule($organization, $member, $key);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function doctorAssignedToModule(Organization $organization, Member $member, string $key): bool
|
||||
{
|
||||
$definition = $this->definition($key);
|
||||
if (! $definition) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$departmentType = (string) ($definition['department_type'] ?? '');
|
||||
$provisionedIds = data_get(
|
||||
$organization->settings,
|
||||
"specialty_module_provisioning.{$key}.department_ids",
|
||||
[],
|
||||
);
|
||||
$provisionedIds = is_array($provisionedIds)
|
||||
? array_map('intval', $provisionedIds)
|
||||
: [];
|
||||
|
||||
$practitioners = Practitioner::owned((string) $organization->owner_ref)
|
||||
->where('organization_id', $organization->id)
|
||||
->where('is_active', true)
|
||||
->where(function ($query) use ($member) {
|
||||
$query->where('member_id', $member->id)
|
||||
->orWhere('user_ref', $member->user_ref);
|
||||
})
|
||||
->with('department')
|
||||
->get();
|
||||
|
||||
foreach ($practitioners as $practitioner) {
|
||||
if ($provisionedIds !== [] && in_array((int) $practitioner->department_id, $provisionedIds, true)) {
|
||||
return true;
|
||||
}
|
||||
if ($departmentType !== '' && $practitioner->department?->type === $departmentType) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function canManage(Organization $organization): bool
|
||||
{
|
||||
return $this->plans->hasFeature($organization, 'specialty_modules');
|
||||
|
||||
Reference in New Issue
Block a user