Files
ladill-care/app/Http/Controllers/Care/SettingsModulesController.php
T
isaaccladandCursor 56a663a777
Deploy Ladill Care / deploy (push) Successful in 26s
Replace Maternity with Women's Health (OB/GYN) and configurable service lines.
Keeps Fertility as a separate specialty, adds OB/GYN and fertility staff roles, and migrates live org settings from maternity → womens_health.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-20 09:48:19 +00:00

178 lines
6.8 KiB
PHP

<?php
namespace App\Http\Controllers\Care;
use App\Http\Controllers\Care\Concerns\ScopesToAccount;
use App\Http\Controllers\Controller;
use App\Services\Care\CarePermissions;
use App\Services\Care\CarePricingService;
use App\Services\Care\PlanService;
use App\Services\Care\SpecialtyModuleService;
use App\Services\Care\SpecialtyShellService;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;
class SettingsModulesController extends Controller
{
use ScopesToAccount;
public function edit(Request $request, SpecialtyModuleService $modules, PlanService $plans): View
{
$this->authorizeAbility($request, 'settings.view');
$organization = $this->organization($request);
$member = $this->member($request);
$canManage = app(CarePermissions::class)->can($member, 'settings.manage');
if ($modules->canManage($organization)) {
$modules->ensureDefaultModulesProvisioned($organization, $this->ownerRef($request));
$organization->refresh();
}
return view('care.settings.modules', [
'organization' => $organization,
'canManage' => $canManage,
'canUseSpecialtyModules' => $modules->canManage($organization),
'catalog' => $modules->catalog(),
'enabled' => collect($modules->enabledKeys($organization))->flip()->all(),
'planKey' => $plans->planKey($organization),
]);
}
public function show(
Request $request,
string $module,
SpecialtyModuleService $modules,
SpecialtyShellService $shell,
CarePricingService $pricing,
): View {
$this->authorizeAbility($request, 'settings.view');
$module = $modules->normalizeKey($module);
$definition = $modules->definition($module);
abort_unless($definition, 404);
$organization = $this->organization($request);
$member = $this->member($request);
$canManage = app(CarePermissions::class)->can($member, 'settings.manage');
$canUse = $modules->canManage($organization);
if ($canUse && $modules->isEnabled($organization, $module)) {
$shell->seedServices($organization, $module);
$organization->refresh();
}
$services = $canUse
? $shell->provisionedServices($organization, $module)
: $shell->catalogServices($module);
return view('care.settings.module-show', [
'organization' => $organization,
'moduleKey' => $module,
'definition' => $definition,
'services' => $services,
'serviceLines' => $modules->serviceLines($module),
'enabledServiceLines' => $modules->enabledServiceLines($organization, $module),
'enabled' => $modules->isEnabled($organization, $module),
'canManage' => $canManage && $canUse,
'canUseSpecialtyModules' => $canUse,
'canOpenWorkspace' => $modules->memberCanAccess($organization, $member, $module),
'currency' => strtoupper((string) config('care.billing.currency', 'GHS')),
]);
}
public function updateServiceLines(
Request $request,
string $module,
SpecialtyModuleService $modules,
): RedirectResponse {
$this->authorizeAbility($request, 'settings.manage');
$organization = $this->organization($request);
abort_unless($modules->definition($module), 404);
abort_unless($modules->canManage($organization), 403);
abort_unless($modules->serviceLines($module) !== [], 404);
$lines = $modules->serviceLines($module);
$rules = ['lines' => ['required', 'array']];
foreach (array_keys($lines) as $key) {
$rules["lines.{$key}"] = ['nullable', 'boolean'];
}
$validated = $request->validate($rules);
$desired = [];
foreach (array_keys($lines) as $key) {
$desired[$key] = (bool) ($validated['lines'][$key] ?? false);
}
$modules->syncServiceLines($organization, $module, $desired);
return redirect()
->route('care.settings.modules.show', $module)
->with('success', 'Service lines saved.');
}
public function updateServices(
Request $request,
string $module,
SpecialtyModuleService $modules,
SpecialtyShellService $shell,
CarePricingService $pricing,
): RedirectResponse {
$this->authorizeAbility($request, 'settings.manage');
$organization = $this->organization($request);
abort_unless($modules->definition($module), 404);
abort_unless($modules->canManage($organization), 403);
$validated = $request->validate([
'services' => ['required', 'array'],
'services.*.code' => ['required', 'string', 'max:64'],
'services.*.amount' => ['required', 'numeric', 'min:0', 'max:999999'],
'services.*.label' => ['nullable', 'string', 'max:255'],
]);
$shell->seedServices($organization, $module);
$pricing->updateSpecialtyServices($organization->fresh(), $module, $validated['services'], $shell);
return redirect()
->route('care.settings.modules.show', $module)
->with('success', 'Service prices saved.');
}
public function update(Request $request, SpecialtyModuleService $modules): RedirectResponse
{
$this->authorizeAbility($request, 'settings.manage');
$organization = $this->organization($request);
if (! $modules->canManage($organization)) {
return redirect()
->route('care.pro.index')
->with('upsell', 'Specialty modules are part of Care Pro. Upgrade to activate dentistry, eye care, and other specialty practice surfaces.');
}
$keys = array_keys($modules->catalog());
$desired = [];
foreach ($keys as $key) {
$desired[$key] = $request->boolean("modules.{$key}");
if ($modules->isDefaultOnPaidPlans($key)) {
$desired[$key] = true;
}
}
$modules->ensureDefaultModulesProvisioned($organization, $this->ownerRef($request));
$result = $modules->sync($organization->fresh(), $this->ownerRef($request), $desired);
if ($result['errors'] !== []) {
return back()->with('error', 'Some modules could not be updated: '.implode(' ', $result['errors']));
}
$parts = [];
if ($result['activated'] !== []) {
$parts[] = 'Activated '.count($result['activated']).' module(s)';
}
if ($result['deactivated'] !== []) {
$parts[] = 'Deactivated '.count($result['deactivated']).' module(s)';
}
return back()->with('success', $parts !== [] ? implode('. ', $parts).'.' : 'Modules saved.');
}
}