add billable rate restriction for free organizations

This commit is contained in:
Gregor Vostrak
2026-10-13 14:59:12 +02:00
parent 9e6013eaf1
commit ba2b37f264
55 changed files with 1207 additions and 103 deletions

View File

@@ -119,7 +119,7 @@ class ClockifyTimeEntriesImporter extends DefaultImporter
$timeEntry->task_id = $taskId;
$timeEntry->project_id = $projectId;
$timeEntry->client_id = $clientId;
$timeEntry->organization_id = $this->organization->id;
$timeEntry->organization()->associate($this->organization);
if (strlen($record['Description']) > 5000) {
throw new ImportException('Time entry description is too long');
}

View File

@@ -126,6 +126,8 @@ abstract class DefaultImporter implements ImporterContract
if ($project->billable_rate === 0) {
$project->billable_rate = null;
}
// Note: Prevents a query per project for the billable rate restriction (see Project::booted)
$project->setRelation('organization', $this->organization);
});
$this->projectMemberImportHelper = new ImportDatabaseHelper(ProjectMember::class, ['project_id', 'member_id'], true, function (Builder $builder): Builder {
/** @var Builder<ProjectMember> $builder */
@@ -140,6 +142,11 @@ abstract class DefaultImporter implements ImporterContract
if ($projectMember->billable_rate === 0) {
$projectMember->billable_rate = null;
}
// Note: Prevents queries per project member for the billable rate restriction (see ProjectMember::booted)
$project = $this->projectImportHelper->getModelById($projectMember->project_id);
if ($project !== null) {
$projectMember->setRelation('project', $project->setRelation('organization', $this->organization));
}
});
$this->tagImportHelper = new ImportDatabaseHelper(Tag::class, ['name', 'organization_id'], true, function (Builder $builder): Builder {
/** @var Builder<Tag> $builder */

View File

@@ -129,7 +129,7 @@ class GenericTimeEntriesImporter extends DefaultImporter
$timeEntry->task_id = $taskId;
$timeEntry->project_id = $projectId;
$timeEntry->client_id = $clientId;
$timeEntry->organization_id = $this->organization->id;
$timeEntry->organization()->associate($this->organization);
$timeEntry->description = $record['description'];
if (! in_array($record['billable'], ['true', 'false'], true)) {
throw new ImportException('Invalid billable value');

View File

@@ -107,7 +107,7 @@ class HarvestTimeEntriesImporter extends DefaultImporter
$timeEntry->task_id = $taskId;
$timeEntry->project_id = $projectId;
$timeEntry->client_id = $clientId;
$timeEntry->organization_id = $this->organization->id;
$timeEntry->organization()->associate($this->organization);
if (strlen($record['Notes']) > 5000) {
throw new ImportException('Time entry note is too long');
}

View File

@@ -260,7 +260,7 @@ class SolidtimeImporter extends DefaultImporter
$timeEntry->task_id = $taskId;
$timeEntry->project_id = $projectId;
$timeEntry->client_id = $clientId;
$timeEntry->organization_id = $this->organization->id;
$timeEntry->organization()->associate($this->organization);
if (strlen($timeEntryRow['description']) > 5000) {
throw new ImportException('Time entry description is too long');
}

View File

@@ -113,7 +113,7 @@ class TogglTimeEntriesImporter extends DefaultImporter
$timeEntry->task_id = $taskId;
$timeEntry->project_id = $projectId;
$timeEntry->client_id = $clientId;
$timeEntry->organization_id = $this->organization->id;
$timeEntry->organization()->associate($this->organization);
$timeEntry->description = $record['Description'];
if (! in_array($record['Billable'], ['Yes', 'No'], true)) {
throw new ImportException('Invalid billable value');