fix(work-order-dashboard): rename route param to {wo} to bypass model binding

Root cause of the "Fișa #0" bug: the page had
    public ?WorkOrder \$record = null;
and the route slug was work-orders/{record}/dashboard. Livewire/Laravel
saw the {record} param and the typed \$record property with the same
name and attempted route model binding via BelongsToTenant scope. When
that resolution didn't return a Model instance in a Livewire hydration
context, mount() ended up being called with 0, so the button worked
but the destination page redirected saying "Fișa #0".

Fix: rename the route parameter to {wo} so it no longer collides with
the property name, receive it as int|string in mount(), and do the
find() ourselves. The property stays as \$record for the Blade view
but is now always populated by our own code.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-05 20:27:38 +00:00
parent bd8e42d3d1
commit f82a3ebc57
2 changed files with 20 additions and 11 deletions
@@ -18,28 +18,37 @@ class WorkOrderDashboard extends Page
protected string $view = 'filament.tenant.pages.work-order-dashboard';
/**
* Livewire persists this across hydration. We use a plain int (NOT
* a typed Model) to avoid triggering route model binding earlier
* `public ?WorkOrder $record` made Livewire attempt to bind the
* {wo} route param to a WorkOrder, and when that resolution failed
* mount() ended up receiving 0.
*/
public ?int $recordId = null;
public ?WorkOrder $record = null;
public string $activeTab = 'works';
public static function getSlug(?\Filament\Panel $panel = null): string
{
return 'work-orders/{record}/dashboard';
return 'work-orders/{wo}/dashboard';
}
public static function getRoutePath(?\Filament\Panel $panel = null): string
{
return 'work-orders/{record}/dashboard';
return 'work-orders/{wo}/dashboard';
}
public function mount(int|string $record): void
public function mount(int|string $wo): void
{
$id = (int) $record;
$id = (int) $wo;
$this->recordId = $id;
// Log every single mount attempt so we can diagnose the exact request
\Log::warning('WorkOrderDashboard.mount', [
'record_raw' => $record,
'record_int' => $id,
'wo_raw' => $wo,
'wo_int' => $id,
'url' => request()->fullUrl(),
'referer' => request()->headers->get('referer'),
'method' => request()->method(),
@@ -47,7 +56,7 @@ class WorkOrderDashboard extends Page
'tenant' => app(\App\Tenancy\TenantManager::class)->current()?->slug,
]);
$wo = WorkOrder::with([
$found = WorkOrder::with([
'client', 'vehicle', 'master',
'works.labor', 'works.master',
'parts.part',
@@ -55,7 +64,7 @@ class WorkOrderDashboard extends Page
'subcontractJobs.subcontractor',
])->find($id);
if (! $wo) {
if (! $found) {
$existsGlobally = WorkOrder::withoutGlobalScopes()
->where('id', $id)->exists();
$tenant = app(\App\Tenancy\TenantManager::class)->current();
@@ -72,7 +81,7 @@ class WorkOrderDashboard extends Page
$this->redirect('/app/work-orders');
return;
}
$this->record = $wo;
$this->record = $found;
}
public function setTab(string $tab): void
@@ -37,7 +37,7 @@ class EditWorkOrder extends EditRecord
->icon('heroicon-m-squares-2x2')
->color('info')
->url(fn () => \App\Filament\Tenant\Pages\WorkOrderDashboard::getUrl(
parameters: ['record' => $this->record->id],
parameters: ['wo' => $this->record->id],
panel: 'tenant',
)),
Actions\Action::make('apply_template')