Removed option to update billable rate without updating time entries

This commit is contained in:
Constantin Graf
2024-07-15 14:01:33 +02:00
committed by Constantin Graf
parent be50397775
commit 1dc35f1f55
14 changed files with 22 additions and 58 deletions

View File

@@ -71,8 +71,10 @@ class MemberController extends Controller
{
$this->checkPermission($organization, 'members:update', $member);
if ($request->has('billable_rate')) {
if ($request->has('billable_rate') && $member->billable_rate !== $request->getBillableRate()) {
$member->billable_rate = $request->getBillableRate();
$billableRateService->updateTimeEntriesBillableRateForMember($member);
}
if ($request->has('role') && $member->role !== $request->getRole()->value) {
$newRole = $request->getRole();
@@ -95,10 +97,6 @@ class MemberController extends Controller
}
$member->save();
if ($request->getBillableRateUpdateTimeEntries()) {
$billableRateService->updateTimeEntriesBillableRateForMember($member);
}
return new MemberResource($member);
}

View File

@@ -38,10 +38,11 @@ class OrganizationController extends Controller
$this->checkPermission($organization, 'organizations:update');
$organization->name = $request->input('name');
$oldBillableRate = $organization->billable_rate;
$organization->billable_rate = $request->getBillableRate();
$organization->save();
if ($request->getBillableRateUpdateTimeEntries()) {
if ($oldBillableRate !== $request->getBillableRate()) {
$billableRateService->updateTimeEntriesBillableRateForOrganization($organization);
}

View File

@@ -117,11 +117,12 @@ class ProjectController extends Controller
if ($request->has('is_archived')) {
$project->archived_at = $request->getIsArchived() ? Carbon::now() : null;
}
$oldBillableRate = $project->billable_rate;
$project->billable_rate = $request->getBillableRate();
$project->client_id = $request->input('client_id');
$project->save();
if ($request->getBillableRateUpdateTimeEntries()) {
if ($oldBillableRate !== $request->getBillableRate()) {
$billableRateService->updateTimeEntriesBillableRateForProject($project);
}

View File

@@ -91,10 +91,11 @@ class ProjectMemberController extends Controller
public function update(Organization $organization, ProjectMember $projectMember, ProjectMemberUpdateRequest $request, BillableRateService $billableRateService): JsonResource
{
$this->checkPermission($organization, 'project-members:update', projectMember: $projectMember);
$oldBillableRate = $projectMember->billable_rate;
$projectMember->billable_rate = $request->getBillableRate();
$projectMember->save();
if ($request->getBillableRateUpdateTimeEntries()) {
if ($oldBillableRate !== $request->getBillableRate()) {
$billableRateService->updateTimeEntriesBillableRateForProjectMember($projectMember);
}

View File

@@ -257,6 +257,7 @@ class TimeEntryController extends Controller
$timeEntry->fill($request->validated());
$timeEntry->description = $request->input('description', $timeEntry->description) ?? '';
$timeEntry->setComputedAttributeValue('billable_rate');
$timeEntry->save();
return new TimeEntryResource($timeEntry);

View File

@@ -32,9 +32,6 @@ class MemberUpdateRequest extends FormRequest
'integer',
'min:0',
],
'billable_rate_update_time_entries' => [
'boolean',
],
];
}
@@ -45,12 +42,6 @@ class MemberUpdateRequest extends FormRequest
return $input !== null && $input !== 0 ? (int) $this->input('billable_rate') : null;
}
public function getBillableRateUpdateTimeEntries(): bool
{
return $this->has('billable_rate_update_time_entries') &&
$this->boolean('billable_rate_update_time_entries');
}
public function getRole(): Role
{
return Role::from($this->input('role'));

View File

@@ -31,9 +31,6 @@ class OrganizationUpdateRequest extends FormRequest
'integer',
'min:0',
],
'billable_rate_update_time_entries' => [
'boolean',
],
];
}
@@ -43,10 +40,4 @@ class OrganizationUpdateRequest extends FormRequest
return $input !== null && $input !== 0 ? (int) $this->input('billable_rate') : null;
}
public function getBillableRateUpdateTimeEntries(): bool
{
return $this->has('billable_rate_update_time_entries') &&
$this->boolean('billable_rate_update_time_entries');
}
}

View File

@@ -62,9 +62,6 @@ class ProjectUpdateRequest extends FormRequest
'integer',
'min:0',
],
'billable_rate_update_time_entries' => [
'boolean',
],
];
}
@@ -81,10 +78,4 @@ class ProjectUpdateRequest extends FormRequest
return $input !== null && $input !== 0 ? (int) $this->input('billable_rate') : null;
}
public function getBillableRateUpdateTimeEntries(): bool
{
return $this->has('billable_rate_update_time_entries') &&
$this->boolean('billable_rate_update_time_entries');
}
}

View File

@@ -26,9 +26,6 @@ class ProjectMemberUpdateRequest extends FormRequest
'integer',
'min:0',
],
'billable_rate_update_time_entries' => [
'boolean',
],
];
}
@@ -38,10 +35,4 @@ class ProjectMemberUpdateRequest extends FormRequest
return $input !== null && $input !== 0 ? (int) $this->input('billable_rate') : null;
}
public function getBillableRateUpdateTimeEntries(): bool
{
return $this->has('billable_rate_update_time_entries') &&
$this->boolean('billable_rate_update_time_entries');
}
}

View File

@@ -23,6 +23,7 @@ class TestJob implements ShouldQueue
private User $user;
private string $message;
private bool $fail;
/**
@@ -37,6 +38,7 @@ class TestJob implements ShouldQueue
/**
* Execute the job.
*
* @throws Exception
*/
public function handle(): void

View File

@@ -91,20 +91,21 @@ class MemberEndpointTest extends ApiEndpointTestAbstract
$data = $this->createUserWithPermission([
'members:update',
]);
$member = Member::factory()->forOrganization($data->organization)->role(Role::Admin)->create();
$member = Member::factory()->forOrganization($data->organization)->withBillableRate()->role(Role::Admin)->create();
$this->assertBillableRateServiceIsUnused();
Passport::actingAs($data->user);
// Act
$response = $this->putJson(route('api.v1.members.update', [$data->organization->id, $member]), [
'billable_rate' => 10001,
'billable_rate' => $member->billable_rate,
'role' => Role::Employee->value,
]);
// Assert
$response->assertStatus(200);
$oldBillableRate = $member->billable_rate;
$member->refresh();
$this->assertSame(10001, $member->billable_rate);
$this->assertSame($oldBillableRate, $member->billable_rate);
$this->assertSame(Role::Employee->value, $member->role);
}
@@ -124,7 +125,6 @@ class MemberEndpointTest extends ApiEndpointTestAbstract
// Act
$response = $this->putJson(route('api.v1.members.update', [$data->organization->getKey(), $data->member]), [
'billable_rate' => 10001,
'billable_rate_update_time_entries' => true,
]);
// Assert

View File

@@ -142,7 +142,6 @@ class OrganizationEndpointTest extends ApiEndpointTestAbstract
$response = $this->withoutExceptionHandling()->putJson(route('api.v1.organizations.update', [$data->organization->getKey()]), [
'name' => $organizationFake->name,
'billable_rate' => $organizationFake->billable_rate,
'billable_rate_update_time_entries' => true,
]);
// Assert

View File

@@ -507,7 +507,7 @@ class ProjectEndpointTest extends ApiEndpointTestAbstract
$this->assertFalse($project->is_archived);
}
public function test_update_endpoint_can_update_projects_billable_rate(): void
public function test_update_endpoint_does_not_update_billable_rates_of_time_entries_if_billable_rate_is_unchanged(): void
{
// Arrange
$data = $this->createUserWithPermission([
@@ -523,7 +523,7 @@ class ProjectEndpointTest extends ApiEndpointTestAbstract
'name' => $projectFake->name,
'color' => $projectFake->color,
'is_billable' => $projectFake->is_billable,
'billable_rate' => 10002,
'billable_rate' => $project->billable_rate,
]);
// Assert
@@ -531,7 +531,7 @@ class ProjectEndpointTest extends ApiEndpointTestAbstract
$this->assertDatabaseHas(Project::class, [
'name' => $projectFake->name,
'color' => $projectFake->color,
'billable_rate' => 10002,
'billable_rate' => $project->billable_rate,
]);
}
@@ -556,7 +556,6 @@ class ProjectEndpointTest extends ApiEndpointTestAbstract
'color' => $projectFake->color,
'is_billable' => $projectFake->is_billable,
'billable_rate' => 10003,
'billable_rate_update_time_entries' => true,
]);
// Assert

View File

@@ -281,28 +281,27 @@ class ProjectMemberEndpointTest extends ApiEndpointTestAbstract
$response->assertForbidden();
}
public function test_update_endpoint_updates_project_member(): void
public function test_update_endpoint_updates_project_member_with_unchanged_billable_rate(): void
{
// Arrange
$data = $this->createUserWithPermission([
'project-members:update',
]);
$project = Project::factory()->forOrganization($data->organization)->create();
$billableRate = 1001;
$projectMember = ProjectMember::factory()->forProject($project)->create();
$this->assertBillableRateServiceIsUnused();
Passport::actingAs($data->user);
// Act
$response = $this->putJson(route('api.v1.project-members.update', [$data->organization->getKey(), $projectMember->getKey()]), [
'billable_rate' => $billableRate,
'billable_rate' => $projectMember->billable_rate,
]);
// Assert
$response->assertStatus(200);
$this->assertDatabaseHas(ProjectMember::class, [
'id' => $projectMember->getKey(),
'billable_rate' => $billableRate,
'billable_rate' => $projectMember->billable_rate,
'member_id' => $projectMember->member_id,
]);
}
@@ -326,7 +325,6 @@ class ProjectMemberEndpointTest extends ApiEndpointTestAbstract
// Act
$response = $this->putJson(route('api.v1.project-members.update', [$data->organization->getKey(), $projectMember->getKey()]), [
'billable_rate' => $billableRate,
'billable_rate_update_time_entries' => true,
]);
// Assert