Align pending approval counts and PHP runtime requirement.

Scope dashboard pending counts to each approver's assigned projects, harden overtime validation against incomplete weekly arrays, remove legacy PD backfill labels, and declare the PHP 8.4 runtime required by the app.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Syazwan 2026-07-02 17:18:14 +08:00
parent 1833279731
commit ca4013d888
4 changed files with 28 additions and 12 deletions

View File

@ -75,9 +75,7 @@ class BackfillActivityLogFromApprovalLogs extends Command
'approved_pm' => 'Timesheet approved by PM',
'rejected_pm' => 'Timesheet rejected by PM',
'approved_program_manager' => 'Timesheet approved by Program Manager',
'approved_pd' => 'Timesheet approved by Program Manager',
'rejected_program_manager' => 'Timesheet rejected by Program Manager',
'rejected_pd' => 'Timesheet rejected by Program Manager',
'rejected' => 'Timesheet rejected',
'reverted' => 'Timesheet reverted to draft',
default => 'Timesheet workflow action: ' . str_replace('_', ' ', $action),

View File

@ -35,18 +35,34 @@ class WelcomeBanner extends Widget
public function getPendingCount(): int
{
$user = auth()->user();
$query = Timesheet::query()->whereIn('status', ['pending_pm', 'pending_program_manager']);
if ($user->isEmployee()) {
return $query->where('user_id', $user->id)->count();
if ($user->isAdmin()) {
return Timesheet::query()
->whereIn('status', ['pending_pm', 'pending_program_manager'])
->count();
}
if ($user->isEmployee()) {
return Timesheet::query()
->whereIn('status', ['pending_pm', 'pending_program_manager'])
->where('user_id', $user->id)
->count();
}
$query = Timesheet::query()->whereIn('status', ['pending_pm', 'pending_program_manager']);
if ($user->canApproveAsPm()) {
return (clone $query)->where('status', 'pending_pm')->count();
return (clone $query)
->where('status', 'pending_pm')
->whereHas('project', fn ($project) => $project->where('project_manager_id', $user->id))
->count();
}
if ($user->canApproveAsProgramManager()) {
return (clone $query)->where('status', 'pending_program_manager')->count();
return (clone $query)
->where('status', 'pending_program_manager')
->whereHas('project', fn ($project) => $project->where('program_manager_id', $user->id))
->count();
}
return $query->count();

View File

@ -17,11 +17,13 @@ class OvertimeValidator
$overtime = self::normalizeWeek($overtimeHours);
$dailyThreshold = Setting::overtimeDailyThreshold();
$weeklyThreshold = Setting::standardWeeklyHours();
$days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
$errors = [];
foreach ($regular as $index => $hours) {
$ot = $overtime[$index];
$day = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'][$index];
for ($index = 0; $index < 7; $index++) {
$hours = $regular[$index] ?? 0.0;
$ot = $overtime[$index] ?? 0.0;
$day = $days[$index];
if ($hours < 0 || $hours > 24 || $ot < 0 || $ot > 24) {
$errors["hours.{$index}"] = "{$day}: hours must be between 0 and 24.";
@ -53,7 +55,7 @@ class OvertimeValidator
{
return array_map(
fn (mixed $value): float => (float) (filled($value) ? $value : 0),
array_replace([0, 0, 0, 0, 0, 0, 0], array_values($hours)),
array_slice(array_replace([0, 0, 0, 0, 0, 0, 0], array_values($hours)), 0, 7),
);
}
}

View File

@ -6,7 +6,7 @@
"keywords": ["laravel", "framework"],
"license": "MIT",
"require": {
"php": "^8.3",
"php": "^8.4",
"barryvdh/laravel-dompdf": "^3.1",
"filament/filament": "^5.6",
"laravel/framework": "^13.8",