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.'); } }