From 9df91f4e4a44713cafd57f2301da79b7b02c3986 Mon Sep 17 00:00:00 2001 From: Constantin Graf Date: Tue, 3 Sep 2024 12:55:33 +0200 Subject: [PATCH] Fix billiable rate in updateMultiple time entries (ST-396) --- .../Api/V1/TimeEntryController.php | 2 + .../Endpoint/Api/V1/TimeEntryEndpointTest.php | 49 +++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/app/Http/Controllers/Api/V1/TimeEntryController.php b/app/Http/Controllers/Api/V1/TimeEntryController.php index 88711606..b30d5f94 100644 --- a/app/Http/Controllers/Api/V1/TimeEntryController.php +++ b/app/Http/Controllers/Api/V1/TimeEntryController.php @@ -299,6 +299,7 @@ class TimeEntryController extends Controller $error = new Collection(); foreach ($ids as $id) { + /** @var TimeEntry|null $timeEntry */ $timeEntry = $timeEntries->firstWhere('id', $id); if ($timeEntry === null) { // Note: ID wrong or time entry in different organization @@ -316,6 +317,7 @@ class TimeEntryController extends Controller if ($overwriteClient) { $timeEntry->client()->associate($client); } + $timeEntry->setComputedAttributeValue('billable_rate'); $timeEntry->save(); $success->push($id); } diff --git a/tests/Unit/Endpoint/Api/V1/TimeEntryEndpointTest.php b/tests/Unit/Endpoint/Api/V1/TimeEntryEndpointTest.php index ed502c6f..ec7d3883 100644 --- a/tests/Unit/Endpoint/Api/V1/TimeEntryEndpointTest.php +++ b/tests/Unit/Endpoint/Api/V1/TimeEntryEndpointTest.php @@ -1786,6 +1786,55 @@ class TimeEntryEndpointTest extends ApiEndpointTestAbstract ]); } + public function test_update_multiple_refreshes_billable_rate_on_updates_time_entries(): void + { + // Arrange + $data = $this->createUserWithPermission([ + 'time-entries:update:all', + ]); + + $oldProject = Project::factory()->forOrganization($data->organization)->billable()->create(); + $timeEntry1 = TimeEntry::factory()->forMember($data->member)->forProject($oldProject)->billable()->create(); + $timeEntry2 = TimeEntry::factory()->forMember($data->member)->forProject($oldProject)->notBillable()->create(); + $project = Project::factory()->billable()->forOrganization($data->organization)->create(); + Passport::actingAs($data->user); + + // Act + $response = $this->patchJson(route('api.v1.time-entries.update-multiple', [$data->organization->getKey()]), [ + 'ids' => [ + $timeEntry1->getKey(), + $timeEntry2->getKey(), + ], + 'changes' => [ + 'project_id' => $project->getKey(), + ], + ]); + + // Assert + $response->assertValid(); + $response->assertStatus(200); + $response->assertExactJson([ + 'success' => [ + $timeEntry1->getKey(), + $timeEntry2->getKey(), + ], + 'error' => [ + ], + ]); + $this->assertDatabaseHas(TimeEntry::class, [ + 'id' => $timeEntry1->getKey(), + 'project_id' => $project->getKey(), + 'billable' => true, + 'billable_rate' => $project->billable_rate, + ]); + $this->assertDatabaseHas(TimeEntry::class, [ + 'id' => $timeEntry2->getKey(), + 'project_id' => $project->getKey(), + 'billable' => false, + 'billable_rate' => null, + ]); + } + public function test_update_multiple_ignores_other_fields_in_changes(): void { // Arrange