From fccd57a3f3b5628074601b759c3adcf9e7604e01 Mon Sep 17 00:00:00 2001 From: Constantin Graf Date: Mon, 29 Apr 2024 17:21:57 +0200 Subject: [PATCH] Fixed timezone issue in timentry index endpoint --- .../Api/V1/TimeEntryController.php | 8 ++++--- .../Endpoint/Api/V1/TimeEntryEndpointTest.php | 22 ++++++++++++------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/app/Http/Controllers/Api/V1/TimeEntryController.php b/app/Http/Controllers/Api/V1/TimeEntryController.php index a8a7b526..8f2fbcec 100644 --- a/app/Http/Controllers/Api/V1/TimeEntryController.php +++ b/app/Http/Controllers/Api/V1/TimeEntryController.php @@ -17,6 +17,7 @@ use App\Service\TimezoneService; use Illuminate\Auth\Access\AuthorizationException; use Illuminate\Http\JsonResponse; use Illuminate\Http\Resources\Json\JsonResource; +use Illuminate\Support\Carbon; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Log; @@ -53,11 +54,11 @@ class TimeEntryController extends Controller ->orderBy('start', 'desc'); if ($request->has('before')) { - $timeEntriesQuery->whereDate('start', '<', $request->input('before')); + $timeEntriesQuery->where('start', '<', Carbon::createFromFormat('Y-m-d\TH:i:s\Z', $request->input('before'), 'UTC')); } if ($request->has('after')) { - $timeEntriesQuery->whereDate('start', '>', $request->input('after')); + $timeEntriesQuery->where('start', '>', Carbon::createFromFormat('Y-m-d\TH:i:s\Z', $request->input('after'), 'UTC')); } if ($request->has('active')) { @@ -105,7 +106,8 @@ class TimeEntryController extends Controller ]); $timeEntries = $timeEntriesQuery ->limit(5000) - ->whereDate('start', '=', $lastDate->toDateString()) + ->where('start', '>=', $lastDate->copy()->startOfDay()->utc()) + ->where('start', '<=', $lastDate->copy()->endOfDay()->utc()) ->get(); } } diff --git a/tests/Unit/Endpoint/Api/V1/TimeEntryEndpointTest.php b/tests/Unit/Endpoint/Api/V1/TimeEntryEndpointTest.php index 59717357..91b55b8a 100644 --- a/tests/Unit/Endpoint/Api/V1/TimeEntryEndpointTest.php +++ b/tests/Unit/Endpoint/Api/V1/TimeEntryEndpointTest.php @@ -311,21 +311,27 @@ class TimeEntryEndpointTest extends ApiEndpointTestAbstract 'time-entries:view:own', ]); $timeEntriesAfter = TimeEntry::factory()->forOrganization($data->organization)->forUser($data->user) - ->startBetween(Carbon::now()->subDay()->startOfDay(), Carbon::now()) + ->startBetween( + Carbon::now()->timezone($data->user->timezone)->subDay()->startOfDay()->utc(), + Carbon::now()->timezone($data->user->timezone)->utc() + ) ->createMany(3); $timeEntriesBefore = TimeEntry::factory()->forOrganization($data->organization)->forUser($data->user) - ->startBetween(Carbon::now()->subDays(2)->startOfDay(), Carbon::now()->subDays(2)->endOfDay()) + ->startBetween( + Carbon::now()->timezone($data->user->timezone)->subDays(2)->startOfDay()->utc(), + Carbon::now()->timezone($data->user->timezone)->subDays(2)->endOfDay()->utc() + ) ->createMany(3); $timeEntriesDirectlyBeforeLimit = TimeEntry::factory()->forOrganization($data->organization)->forUser($data->user) ->create([ - 'start' => Carbon::now()->subDays(2)->endOfDay(), + 'start' => Carbon::now()->timezone($data->user->timezone)->subDays(2)->endOfDay()->utc(), ]); Passport::actingAs($data->user); // Act $response = $this->getJson(route('api.v1.time-entries.index', [ $data->organization->getKey(), - 'before' => Carbon::now()->subDay()->startOfDay()->toIso8601ZuluString(), + 'before' => Carbon::now()->timezone($data->user->timezone)->subDay()->startOfDay()->toIso8601ZuluString(), 'user_id' => $data->user->getKey(), ])); @@ -348,21 +354,21 @@ class TimeEntryEndpointTest extends ApiEndpointTestAbstract 'time-entries:view:own', ]); $timeEntriesAfter = TimeEntry::factory()->forOrganization($data->organization)->forUser($data->user) - ->startBetween(Carbon::now()->startOfDay(), Carbon::now()) + ->startBetween(Carbon::now($data->user->timezone)->startOfDay()->utc(), Carbon::now($data->user->timezone)->utc()) ->createMany(3); $timeEntriesBefore = TimeEntry::factory()->forOrganization($data->organization)->forUser($data->user) - ->startBetween(Carbon::now()->subDay()->startOfDay(), Carbon::now()->subDay()->endOfDay()) + ->startBetween(Carbon::now($data->user->timezone)->subDay()->startOfDay()->utc(), Carbon::now($data->user->timezone)->subDay()->endOfDay()->utc()) ->createMany(3); $timeEntriesDirectlyAfterLimit = TimeEntry::factory()->forOrganization($data->organization)->forUser($data->user) ->create([ - 'start' => Carbon::now()->startOfDay(), + 'start' => Carbon::now($data->user->timezone)->startOfDay()->utc(), ]); Passport::actingAs($data->user); // Act $response = $this->getJson(route('api.v1.time-entries.index', [ $data->organization->getKey(), - 'after' => Carbon::now()->subDay()->endOfDay()->toIso8601ZuluString(), // yesterday + 'after' => Carbon::now($data->user->timezone)->subDay()->endOfDay()->toIso8601ZuluString(), // yesterday 'user_id' => $data->user->getKey(), ]));