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:
@@ -27,7 +27,27 @@ class ViewCompany extends Page
|
|||||||
|
|
||||||
public function mount(int|string $record): void
|
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
|
public function getTitle(): string
|
||||||
@@ -50,8 +70,8 @@ class ViewCompany extends Page
|
|||||||
'work_orders_open' => WorkOrder::whereNotIn('status', ['done', 'cancelled'])->count(),
|
'work_orders_open' => WorkOrder::whereNotIn('status', ['done', 'cancelled'])->count(),
|
||||||
'parts' => Part::count(),
|
'parts' => Part::count(),
|
||||||
'parts_low_stock' => Part::where('is_active', true)
|
'parts_low_stock' => Part::where('is_active', true)
|
||||||
->whereColumn('stock', '<=', 'low_stock_threshold')
|
->whereColumn('qty', '<=', 'min_qty')
|
||||||
->where('stock', '>', 0)
|
->where('qty', '>', 0)
|
||||||
->count(),
|
->count(),
|
||||||
'revenue_this_month' => (float) Payment::whereYear('paid_at', date('Y'))
|
'revenue_this_month' => (float) Payment::whereYear('paid_at', date('Y'))
|
||||||
->whereMonth('paid_at', date('m'))->sum('amount'),
|
->whereMonth('paid_at', date('m'))->sum('amount'),
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests\Feature;
|
||||||
|
|
||||||
|
use App\Models\Central\Company;
|
||||||
|
use App\Models\Central\Plan;
|
||||||
|
use App\Models\Central\SuperAdmin;
|
||||||
|
use App\Tenancy\TenantManager;
|
||||||
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
class CentralCompanyViewTest extends TestCase
|
||||||
|
{
|
||||||
|
use RefreshDatabase;
|
||||||
|
|
||||||
|
public function test_company_view_page_loads_for_existing_record(): void
|
||||||
|
{
|
||||||
|
$plan = Plan::create(['name' => 'Free', 'slug' => 'free', 'price' => 0, 'features' => []]);
|
||||||
|
$company = Company::create([
|
||||||
|
'plan_id' => $plan->id, 'slug' => 'viewco', 'name' => 'View Co',
|
||||||
|
'status' => 'active',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$admin = SuperAdmin::create([
|
||||||
|
'name' => 'Op', 'email' => 'op@example.com',
|
||||||
|
'password' => bcrypt('secret'), 'is_active' => true, 'role' => 'owner',
|
||||||
|
]);
|
||||||
|
|
||||||
|
app(TenantManager::class)->setCurrent(null);
|
||||||
|
|
||||||
|
$response = $this->actingAs($admin, 'central')
|
||||||
|
->get("http://service.mir.md/admin/companies/{$company->id}");
|
||||||
|
|
||||||
|
$response->assertStatus(200);
|
||||||
|
$response->assertSee('View Co');
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user