fix: central company view page 404 + broken stats query

The /admin/companies/{id} view page (ViewCompany extends Page) 404'd because
the {record} route param could arrive as a JSON-encoded model (Livewire typed-
property hydration), so findOrFail() received a non-id and threw
ModelNotFoundException. Added resolveRecordKey() to normalize scalar id / model
/ JSON-string down to the integer key.

Also fixed getStats() referencing non-existent parts columns `stock` /
`low_stock_threshold` (real columns are `qty` / `min_qty`), which would 500 the
page once mount resolved.

Added CentralCompanyViewTest as regression (asserts 200 + company name). Full
suite: 100 passed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-28 10:24:08 +00:00
parent d6a0bfb890
commit ac7d5b4733
2 changed files with 60 additions and 3 deletions
@@ -27,7 +27,27 @@ class ViewCompany extends Page
public function mount(int|string $record): void
{
$this->record = Company::with(['plan', 'subscriptions' => fn ($q) => $q->latest('period_end')->limit(10)])->findOrFail($record);
// The {record} route param may arrive as a scalar id, an Eloquent model,
// or (via Livewire's typed-property hydration) a JSON-encoded model.
// Normalize all of these down to the integer primary key.
$key = $this->resolveRecordKey($record);
$this->record = Company::with(['plan', 'subscriptions' => fn ($q) => $q->latest('period_end')->limit(10)])
->findOrFail($key);
}
private function resolveRecordKey(mixed $record): int|string
{
if ($record instanceof Company) {
return $record->getKey();
}
if (is_string($record) && str_starts_with(ltrim($record), '{')) {
$decoded = json_decode($record, true);
if (is_array($decoded) && isset($decoded['id'])) {
return $decoded['id'];
}
}
return $record;
}
public function getTitle(): string
@@ -50,8 +70,8 @@ class ViewCompany extends Page
'work_orders_open' => WorkOrder::whereNotIn('status', ['done', 'cancelled'])->count(),
'parts' => Part::count(),
'parts_low_stock' => Part::where('is_active', true)
->whereColumn('stock', '<=', 'low_stock_threshold')
->where('stock', '>', 0)
->whereColumn('qty', '<=', 'min_qty')
->where('qty', '>', 0)
->count(),
'revenue_this_month' => (float) Payment::whereYear('paid_at', date('Y'))
->whereMonth('paid_at', date('m'))->sum('amount'),