From ae4992b81aaa3bf225ee4b86e6ed5505673b0053 Mon Sep 17 00:00:00 2001 From: PuvaanRaaj Date: Sat, 1 Aug 2026 14:08:47 +0800 Subject: [PATCH] fix(widgets): order recent records by id Use the primary key for timestamp-less dashboard models and cover descending record order across the affected widgets. Fixes #694 --- .../Company/Widgets/RecentExpensesWidget.php | 2 +- .../Feature/RecentExpensesWidgetTest.php | 22 +++++++++++ .../Company/Widgets/RecentPaymentsWidget.php | 2 +- .../Feature/RecentPaymentsWidgetTest.php | 37 +++++++++++++++++++ .../Company/Widgets/RecentProjectsWidget.php | 2 +- .../Company/Widgets/RecentTasksWidget.php | 2 +- .../Feature/RecentProjectsWidgetTest.php | 29 +++++++++++++++ .../Tests/Feature/RecentTasksWidgetTest.php | 22 +++++++++++ 8 files changed, 114 insertions(+), 4 deletions(-) diff --git a/Modules/Expenses/Filament/Company/Widgets/RecentExpensesWidget.php b/Modules/Expenses/Filament/Company/Widgets/RecentExpensesWidget.php index 6157587bc..d779e5cc3 100644 --- a/Modules/Expenses/Filament/Company/Widgets/RecentExpensesWidget.php +++ b/Modules/Expenses/Filament/Company/Widgets/RecentExpensesWidget.php @@ -30,7 +30,7 @@ public function table(Table $table): Table protected function getTableQuery(): Builder|Relation|null { /** @var Builder $query */ - $query = Expense::query()->latest()->limit(10); + $query = Expense::query()->latest('id')->limit(10); return $query; } diff --git a/Modules/Expenses/Tests/Feature/RecentExpensesWidgetTest.php b/Modules/Expenses/Tests/Feature/RecentExpensesWidgetTest.php index 6f3237e14..845662adf 100644 --- a/Modules/Expenses/Tests/Feature/RecentExpensesWidgetTest.php +++ b/Modules/Expenses/Tests/Feature/RecentExpensesWidgetTest.php @@ -31,4 +31,26 @@ public function it_links_each_row_to_the_expenses_index_page(): void $component->assertSuccessful(); $component->assertSee(ExpenseResource::getUrl('index'), false); } + + #[Test] + #[Group('smoke')] + public function it_lists_newer_expenses_before_older_expenses(): void + { + /* Arrange */ + $olderExpense = Expense::factory() + ->for($this->company) + ->create(['expense_number' => 'EXP-OLDER']); + $newerExpense = Expense::factory() + ->for($this->company) + ->create(['expense_number' => 'EXP-NEWER']); + + /* Act */ + $component = Livewire::actingAs($this->user) + ->test(RecentExpensesWidget::class); + + /* Assert */ + $component + ->assertSuccessful() + ->assertCanSeeTableRecords([$newerExpense, $olderExpense], inOrder: true); + } } diff --git a/Modules/Payments/Filament/Company/Widgets/RecentPaymentsWidget.php b/Modules/Payments/Filament/Company/Widgets/RecentPaymentsWidget.php index b8b81a67b..b45185e3c 100644 --- a/Modules/Payments/Filament/Company/Widgets/RecentPaymentsWidget.php +++ b/Modules/Payments/Filament/Company/Widgets/RecentPaymentsWidget.php @@ -28,7 +28,7 @@ public function table(Table $table): Table protected function getTableQuery(): Builder|Relation|null { /** @var Builder $query */ - $query = Payment::query()->latest()->limit(10); + $query = Payment::query()->latest('id')->limit(10); return $query; } diff --git a/Modules/Payments/Tests/Feature/RecentPaymentsWidgetTest.php b/Modules/Payments/Tests/Feature/RecentPaymentsWidgetTest.php index e41a15796..e6422301e 100644 --- a/Modules/Payments/Tests/Feature/RecentPaymentsWidgetTest.php +++ b/Modules/Payments/Tests/Feature/RecentPaymentsWidgetTest.php @@ -45,4 +45,41 @@ public function it_links_each_row_to_the_payments_index_page(): void $component->assertSuccessful(); $component->assertSee(PaymentResource::getUrl('index'), false); } + + #[Test] + #[Group('smoke')] + public function it_lists_newer_payments_before_older_payments(): void + { + /* Arrange */ + $customer = Relation::factory()->for($this->company)->customer()->create(); + $invoice = Invoice::factory() + ->for($this->company) + ->create([ + 'customer_id' => $customer->id, + 'user_id' => $this->user->id, + ]); + $olderPayment = Payment::factory() + ->for($this->company) + ->create([ + 'payment_number' => 'PAY-OLDER', + 'customer_id' => $customer->id, + 'invoice_id' => $invoice->id, + ]); + $newerPayment = Payment::factory() + ->for($this->company) + ->create([ + 'payment_number' => 'PAY-NEWER', + 'customer_id' => $customer->id, + 'invoice_id' => $invoice->id, + ]); + + /* Act */ + $component = Livewire::actingAs($this->user) + ->test(RecentPaymentsWidget::class); + + /* Assert */ + $component + ->assertSuccessful() + ->assertCanSeeTableRecords([$newerPayment, $olderPayment], inOrder: true); + } } diff --git a/Modules/Projects/Filament/Company/Widgets/RecentProjectsWidget.php b/Modules/Projects/Filament/Company/Widgets/RecentProjectsWidget.php index 5a3b21519..48d501310 100644 --- a/Modules/Projects/Filament/Company/Widgets/RecentProjectsWidget.php +++ b/Modules/Projects/Filament/Company/Widgets/RecentProjectsWidget.php @@ -30,7 +30,7 @@ public function table(Table $table): Table protected function getTableQuery(): Builder|Relation|null { /** @var Builder $query */ - $query = Project::query()->latest()->limit(10); + $query = Project::query()->latest('id')->limit(10); return $query; } diff --git a/Modules/Projects/Filament/Company/Widgets/RecentTasksWidget.php b/Modules/Projects/Filament/Company/Widgets/RecentTasksWidget.php index d98a00deb..7dc6cdfcb 100644 --- a/Modules/Projects/Filament/Company/Widgets/RecentTasksWidget.php +++ b/Modules/Projects/Filament/Company/Widgets/RecentTasksWidget.php @@ -30,7 +30,7 @@ public function table(Table $table): Table protected function getTableQuery(): Builder|Relation|null { /** @var Builder $query */ - $query = Task::query()->latest()->limit(10); + $query = Task::query()->latest('id')->limit(10); return $query; } diff --git a/Modules/Projects/Tests/Feature/RecentProjectsWidgetTest.php b/Modules/Projects/Tests/Feature/RecentProjectsWidgetTest.php index df31addc5..172989f41 100644 --- a/Modules/Projects/Tests/Feature/RecentProjectsWidgetTest.php +++ b/Modules/Projects/Tests/Feature/RecentProjectsWidgetTest.php @@ -37,4 +37,33 @@ public function it_links_each_row_to_the_projects_index_page(): void $component->assertSuccessful(); $component->assertSee(ProjectResource::getUrl('index'), false); } + + #[Test] + #[Group('smoke')] + public function it_lists_newer_projects_before_older_projects(): void + { + /* Arrange */ + $customer = Relation::factory()->for($this->company)->customer()->create(); + $olderProject = Project::factory() + ->for($this->company) + ->create([ + 'project_number' => 'PRJ-OLDER', + 'customer_id' => $customer->id, + ]); + $newerProject = Project::factory() + ->for($this->company) + ->create([ + 'project_number' => 'PRJ-NEWER', + 'customer_id' => $customer->id, + ]); + + /* Act */ + $component = Livewire::actingAs($this->user) + ->test(RecentProjectsWidget::class); + + /* Assert */ + $component + ->assertSuccessful() + ->assertCanSeeTableRecords([$newerProject, $olderProject], inOrder: true); + } } diff --git a/Modules/Projects/Tests/Feature/RecentTasksWidgetTest.php b/Modules/Projects/Tests/Feature/RecentTasksWidgetTest.php index 84b310581..65c61ffdb 100644 --- a/Modules/Projects/Tests/Feature/RecentTasksWidgetTest.php +++ b/Modules/Projects/Tests/Feature/RecentTasksWidgetTest.php @@ -31,4 +31,26 @@ public function it_links_each_row_to_the_tasks_index_page(): void $component->assertSuccessful(); $component->assertSee(TaskResource::getUrl('index'), false); } + + #[Test] + #[Group('smoke')] + public function it_lists_newer_tasks_before_older_tasks(): void + { + /* Arrange */ + $olderTask = Task::factory() + ->for($this->company) + ->create(['task_number' => 'TSK-OLDER']); + $newerTask = Task::factory() + ->for($this->company) + ->create(['task_number' => 'TSK-NEWER']); + + /* Act */ + $component = Livewire::actingAs($this->user) + ->test(RecentTasksWidget::class); + + /* Assert */ + $component + ->assertSuccessful() + ->assertCanSeeTableRecords([$newerTask, $olderTask], inOrder: true); + } }