Show upgrade UI for assessment analytics instead of bare 403.
Deploy Ladill Care / deploy (push) Successful in 41s
Deploy Ladill Care / deploy (push) Successful in 41s
Non-Enterprise orgs hitting /reports/assessments get the in-app plans upsell; CSV export redirects to View plans with an upsell flash. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -11,12 +11,16 @@ trait RequiresPlanFeature
|
||||
{
|
||||
/**
|
||||
* For page views: return an upgrade screen when the org lacks the feature.
|
||||
*
|
||||
* @param 'pro'|'enterprise' $planHint Which tier to highlight in pricing copy
|
||||
*/
|
||||
protected function proFeatureUpgradeView(
|
||||
Request $request,
|
||||
string $feature,
|
||||
string $title,
|
||||
string $description,
|
||||
string $planHint = 'pro',
|
||||
?string $upgradeBody = null,
|
||||
): ?View {
|
||||
$organization = $this->organization($request);
|
||||
$plans = app(PlanService::class);
|
||||
@@ -25,11 +29,17 @@ trait RequiresPlanFeature
|
||||
return null;
|
||||
}
|
||||
|
||||
$isEnterprise = $planHint === 'enterprise';
|
||||
|
||||
return view('care.settings.pro-feature', [
|
||||
'organization' => $organization,
|
||||
'title' => $title,
|
||||
'description' => $description,
|
||||
'proPriceMinor' => $plans->proPricePerBranchMinor(),
|
||||
'planLabel' => $isEnterprise ? 'Enterprise' : 'Pro',
|
||||
'proPriceMinor' => $isEnterprise
|
||||
? $plans->enterprisePricePerBranchMinor()
|
||||
: $plans->proPricePerBranchMinor(),
|
||||
'upgradeBody' => $upgradeBody,
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App\Http\Controllers\Care;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Controllers\Care\Concerns\RequiresPlanFeature;
|
||||
use App\Http\Controllers\Care\Concerns\ScopesToAccount;
|
||||
use App\Models\Branch;
|
||||
use App\Services\Care\AdminOverviewService;
|
||||
@@ -10,6 +11,7 @@ use App\Services\Care\CareFeatures;
|
||||
use App\Services\Care\OrganizationResolver;
|
||||
use App\Services\Care\PlanService;
|
||||
use App\Services\Care\ReportService;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\View\View;
|
||||
@@ -17,8 +19,11 @@ use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
|
||||
class ReportController extends Controller
|
||||
{
|
||||
use RequiresPlanFeature;
|
||||
use ScopesToAccount;
|
||||
|
||||
private const ASSESSMENT_ANALYTICS_UPSELL = 'Assessment analytics are part of Care Enterprise. Upgrade to unlock multi-patient clinical form and outcome reports.';
|
||||
|
||||
public function __construct(
|
||||
protected ReportService $reports,
|
||||
protected AdminOverviewService $adminOverview,
|
||||
@@ -54,6 +59,21 @@ class ReportController extends Controller
|
||||
public function show(Request $request, string $type): View
|
||||
{
|
||||
$this->authorizeReport($request, $type);
|
||||
|
||||
if ($type === 'assessments') {
|
||||
if ($upgrade = $this->proFeatureUpgradeView(
|
||||
$request,
|
||||
'assessment_analytics',
|
||||
'Assessment analytics',
|
||||
'Org-level clinical form and outcome analytics across patients.',
|
||||
'enterprise',
|
||||
'GHS '.number_format(app(PlanService::class)->enterprisePricePerBranchMinor() / 100, 0)
|
||||
.' / branch / month for Enterprise — assessment analytics, priority support, and advanced workflows on top of Pro.',
|
||||
)) {
|
||||
return $upgrade;
|
||||
}
|
||||
}
|
||||
|
||||
$organization = $this->organization($request);
|
||||
$branchScope = app(OrganizationResolver::class)->branchScope($this->member($request));
|
||||
$branchId = $request->input('branch_id') ? (int) $request->input('branch_id') : $branchScope;
|
||||
@@ -80,9 +100,16 @@ class ReportController extends Controller
|
||||
]);
|
||||
}
|
||||
|
||||
public function export(Request $request, string $type): StreamedResponse
|
||||
public function export(Request $request, string $type): StreamedResponse|RedirectResponse
|
||||
{
|
||||
$this->authorizeReport($request, $type);
|
||||
|
||||
if ($type === 'assessments') {
|
||||
if ($deny = $this->denyWithoutFeature($request, 'assessment_analytics', self::ASSESSMENT_ANALYTICS_UPSELL)) {
|
||||
return $deny;
|
||||
}
|
||||
}
|
||||
|
||||
abort_unless(
|
||||
app(\App\Services\Care\CarePermissions::class)->can($this->member($request), 'reports.finance.export'),
|
||||
403,
|
||||
@@ -155,11 +182,7 @@ class ReportController extends Controller
|
||||
app(CareFeatures::class)->enabled($organization, CareFeatures::ASSESSMENTS_ENGINE),
|
||||
404,
|
||||
);
|
||||
abort_unless(
|
||||
app(PlanService::class)->hasFeature($organization, 'assessment_analytics'),
|
||||
403,
|
||||
'Assessment analytics require an Enterprise plan.',
|
||||
);
|
||||
// Plan gate: show() renders upgrade UI; export() redirects via denyWithoutFeature.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,8 +8,12 @@
|
||||
|
||||
<x-settings.card title="Upgrade your plan">
|
||||
<p class="text-sm text-slate-600">
|
||||
GHS {{ number_format($proPriceMinor / 100, 0) }} / branch / month for Pro —
|
||||
multi-branch locations, laboratory, pharmacy, encounter billing, and in-app service queues.
|
||||
@if (! empty($upgradeBody))
|
||||
{{ $upgradeBody }}
|
||||
@else
|
||||
GHS {{ number_format($proPriceMinor / 100, 0) }} / branch / month for {{ $planLabel ?? 'Pro' }} —
|
||||
multi-branch locations, laboratory, pharmacy, encounter billing, and in-app service queues.
|
||||
@endif
|
||||
</p>
|
||||
<div class="mt-4 flex flex-wrap items-center gap-3">
|
||||
<a href="{{ route('care.pro.index') }}" class="btn-primary">View plans</a>
|
||||
|
||||
@@ -111,7 +111,10 @@ class CareAssessmentExtrasTest extends TestCase
|
||||
|
||||
$this->actingAs($this->user)
|
||||
->get(route('care.reports.show', ['type' => 'assessments']))
|
||||
->assertForbidden();
|
||||
->assertOk()
|
||||
->assertSee('Upgrade your plan')
|
||||
->assertSee('View plans')
|
||||
->assertSee('Enterprise');
|
||||
}
|
||||
|
||||
public function test_fhir_export_web_and_api(): void
|
||||
|
||||
Reference in New Issue
Block a user