Compare commits

..

1 Commits

Author SHA1 Message Date
dependabot[bot]
6f1c58e216 Bump the minor-updates group across 1 directory with 7 updates
Bumps the minor-updates group with 7 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [brick/money](https://github.com/brick/money) | `0.15.1` | `0.15.2` |
| [dedoc/scramble](https://github.com/dedoc/scramble) | `0.13.45` | `0.13.47` |
| [filament/filament](https://github.com/filamentphp/panels) | `5.8.4` | `5.9.0` |
| [inertiajs/inertia-laravel](https://github.com/inertiajs/inertia-laravel) | `3.3.4` | `3.5.1` |
| [laravel/framework](https://github.com/laravel/framework) | `13.33.0` | `13.34.0` |
| [stechstudio/filament-impersonate](https://github.com/stechstudio/filament-impersonate) | `5.6.0` | `5.6.1` |
| [fumeapp/modeltyper](https://github.com/fumeapp/modeltyper) | `3.13.0` | `3.14.0` |



Updates `brick/money` from 0.15.1 to 0.15.2
- [Release notes](https://github.com/brick/money/releases)
- [Changelog](https://github.com/brick/money/blob/main/CHANGELOG.md)
- [Commits](https://github.com/brick/money/compare/0.15.1...0.15.2)

Updates `dedoc/scramble` from 0.13.45 to 0.13.47
- [Release notes](https://github.com/dedoc/scramble/releases)
- [Commits](https://github.com/dedoc/scramble/compare/v0.13.45...v0.13.47)

Updates `filament/filament` from 5.8.4 to 5.9.0
- [Commits](https://github.com/filamentphp/panels/compare/v5.8.4...v5.9.0)

Updates `inertiajs/inertia-laravel` from 3.3.4 to 3.5.1
- [Release notes](https://github.com/inertiajs/inertia-laravel/releases)
- [Changelog](https://github.com/inertiajs/inertia-laravel/blob/3.x/CHANGELOG.md)
- [Commits](https://github.com/inertiajs/inertia-laravel/compare/v3.3.4...v3.5.1)

Updates `laravel/framework` from 13.33.0 to 13.34.0
- [Release notes](https://github.com/laravel/framework/releases)
- [Changelog](https://github.com/laravel/framework/blob/13.x/CHANGELOG.md)
- [Commits](https://github.com/laravel/framework/compare/v13.33.0...v13.34.0)

Updates `stechstudio/filament-impersonate` from 5.6.0 to 5.6.1
- [Release notes](https://github.com/stechstudio/filament-impersonate/releases)
- [Commits](https://github.com/stechstudio/filament-impersonate/compare/v5.6.0...v5.6.1)

Updates `fumeapp/modeltyper` from 3.13.0 to 3.14.0
- [Release notes](https://github.com/fumeapp/modeltyper/releases)
- [Commits](https://github.com/fumeapp/modeltyper/compare/v3.13.0...v3.14.0)

---
updated-dependencies:
- dependency-name: brick/money
  dependency-version: 0.15.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: minor-updates
- dependency-name: dedoc/scramble
  dependency-version: 0.13.47
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: minor-updates
- dependency-name: filament/filament
  dependency-version: 5.9.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: minor-updates
- dependency-name: inertiajs/inertia-laravel
  dependency-version: 3.5.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: minor-updates
- dependency-name: laravel/framework
  dependency-version: 13.34.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: minor-updates
- dependency-name: stechstudio/filament-impersonate
  dependency-version: 5.6.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: minor-updates
- dependency-name: fumeapp/modeltyper
  dependency-version: 3.14.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: minor-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-10-05 08:04:56 +00:00
5 changed files with 240 additions and 382 deletions

View File

@@ -39,7 +39,7 @@ class SelfHostDatabaseConsistency extends Command
$problems = DB::table('time_entries')
->select(['time_entries.id as id'])
->join('tasks', 'time_entries.task_id', '=', 'tasks.id')
->whereRaw('tasks.project_id is distinct from time_entries.project_id')
->where('tasks.project_id', '!=', DB::raw('time_entries.project_id'))
->get();
$this->logProblems($problems, 'Time entries have a task that does not belong to the project of the time entry', $hadAProblem);

View File

@@ -679,10 +679,6 @@ class TimeEntryController extends Controller
$timeEntry->member()->associate($newMember);
$timeEntry->user()->associate($newMember->user);
}
// If project is changed, but task is not, we remove the old task from the time entry
if ($request->has('project_id') && ! $request->has('task_id') && $oldTask !== null && $oldTask->project_id !== $project?->getKey()) {
$timeEntry->task()->disassociate();
}
$timeEntry->description = $request->input('description', $timeEntry->description) ?? '';
$timeEntry->setComputedAttributeValue('billable_rate');
$timeEntry->save();
@@ -794,7 +790,7 @@ class TimeEntryController extends Controller
$timeEntry->user_id = $newMember->user_id;
}
// If project is changed, but task is not, we remove the old task from the time entry
if ($request->has('changes.project_id') && ! $request->has('changes.task_id') && $oldTask !== null && $oldTask->project_id !== $project?->getKey()) {
if ($oldProject !== null && $project !== null && $oldProject->isNot($project) && $task === null) {
$timeEntry->task()->disassociate();
}
if ($overwriteClient) {

472
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -38,26 +38,6 @@ class SelfHostDatabaseConsistencyCommandTest extends TestCaseWithDatabase
$this->assertSame("Consistency problem: Time entries have a task that does not belong to the project of the time entry\n - ".$timeEntry->getKey()."\n", $output);
}
public function test_checks_that_task_need_to_be_part_of_project_in_time_entries_with_no_project_in_time_entry(): void
{
// Arrange
$user = $this->createUserWithRole(Role::Owner);
$project = Project::factory()->forOrganization($user->organization)->create();
$task = Task::factory()->forOrganization($user->organization)->forProject($project)->create();
$timeEntry = TimeEntry::factory()->forMember($user->member)->forTask($task)->create([
'project_id' => null,
'client_id' => null,
]);
// Act
$exitCode = $this->withoutMockingConsoleOutput()->artisan('self-host:database-consistency');
// Assert
$this->assertSame(Command::FAILURE, $exitCode);
$output = Artisan::output();
$this->assertSame("Consistency problem: Time entries have a task that does not belong to the project of the time entry\n - ".$timeEntry->getKey()."\n", $output);
}
public function test_checks_that_client_id_is_the_client_id_of_the_project(): void
{
// Arrange

View File

@@ -2780,90 +2780,6 @@ class TimeEntryEndpointTest extends ApiEndpointTestAbstract
});
}
public function test_update_endpoint_removes_task_if_project_is_changed_without_setting_a_new_task(): void
{
// Arrange
$data = $this->createUserWithPermission([
'time-entries:update:own',
'projects:view:all',
]);
$project1 = Project::factory()->forOrganization($data->organization)->create();
$project2 = Project::factory()->forOrganization($data->organization)->create();
$task1 = Task::factory()->forProject($project1)->forOrganization($data->organization)->create();
$timeEntry = TimeEntry::factory()->forOrganization($data->organization)->forProject($project1)->forTask($task1)->forMember($data->member)->create();
Passport::actingAs($data->user);
// Act
$response = $this->putJson(route('api.v1.time-entries.update', [$data->organization->getKey(), $timeEntry->getKey()]), [
'project_id' => $project2->getKey(),
]);
// Assert
$response->assertValid();
$this->assertResponseCode($response, 200);
$response->assertJsonPath('data.project_id', $project2->getKey());
$response->assertJsonPath('data.task_id', null);
$this->assertDatabaseHas(TimeEntry::class, [
'id' => $timeEntry->getKey(),
'project_id' => $project2->getKey(),
'task_id' => null,
]);
}
public function test_update_endpoint_removes_task_if_project_is_removed_without_removing_the_task(): void
{
// Arrange
$data = $this->createUserWithPermission([
'time-entries:update:own',
'projects:view:all',
]);
$project = Project::factory()->forOrganization($data->organization)->create();
$task = Task::factory()->forProject($project)->forOrganization($data->organization)->create();
$timeEntry = TimeEntry::factory()->forOrganization($data->organization)->forProject($project)->forTask($task)->forMember($data->member)->create();
Passport::actingAs($data->user);
// Act
$response = $this->putJson(route('api.v1.time-entries.update', [$data->organization->getKey(), $timeEntry->getKey()]), [
'project_id' => null,
]);
// Assert
$response->assertValid();
$this->assertResponseCode($response, 200);
$this->assertDatabaseHas(TimeEntry::class, [
'id' => $timeEntry->getKey(),
'project_id' => null,
'task_id' => null,
]);
}
public function test_update_endpoint_keeps_task_if_project_is_set_to_the_project_of_the_task(): void
{
// Arrange
$data = $this->createUserWithPermission([
'time-entries:update:own',
'projects:view:all',
]);
$project = Project::factory()->forOrganization($data->organization)->create();
$task = Task::factory()->forProject($project)->forOrganization($data->organization)->create();
$timeEntry = TimeEntry::factory()->forOrganization($data->organization)->forProject($project)->forTask($task)->forMember($data->member)->create();
Passport::actingAs($data->user);
// Act
$response = $this->putJson(route('api.v1.time-entries.update', [$data->organization->getKey(), $timeEntry->getKey()]), [
'project_id' => $project->getKey(),
]);
// Assert
$response->assertValid();
$this->assertResponseCode($response, 200);
$this->assertDatabaseHas(TimeEntry::class, [
'id' => $timeEntry->getKey(),
'project_id' => $project->getKey(),
'task_id' => $task->getKey(),
]);
}
public function test_update_endpoint_fails_if_employee_tries_to_update_time_entry_to_private_project_without_access(): void
{
// Arrange
@@ -3891,44 +3807,6 @@ class TimeEntryEndpointTest extends ApiEndpointTestAbstract
]);
}
public function test_update_multiple_removes_task_from_time_entries_if_project_is_removed_without_removing_the_task(): void
{
// Arrange
$data = $this->createUserWithPermission([
'time-entries:update:own',
'projects:view:all',
]);
$project = Project::factory()->forOrganization($data->organization)->create();
$task = Task::factory()->forProject($project)->forOrganization($data->organization)->create();
$timeEntry = TimeEntry::factory()->forOrganization($data->organization)->forProject($project)->forTask($task)->forMember($data->member)->create();
Passport::actingAs($data->user);
// Act
$response = $this->patchJson(route('api.v1.time-entries.update-multiple', [$data->organization->getKey()]), [
'ids' => [
$timeEntry->getKey(),
],
'changes' => [
'project_id' => null,
],
]);
// Assert
$response->assertValid();
$this->assertResponseCode($response, 200);
$response->assertExactJson([
'success' => [
$timeEntry->getKey(),
],
'error' => [],
]);
$this->assertDatabaseHas(TimeEntry::class, [
'id' => $timeEntry->getKey(),
'project_id' => null,
'task_id' => null,
]);
}
public function test_update_multiple_updates_own_time_entries_and_fails_for_time_entries_of_other_users_and_and_other_organizations_with_own_time_entries_permission(): void
{
// Arrange