fixing user specific rates in kimai v1 importer (#1521)

This commit is contained in:
Kevin Papst
2020-03-05 00:18:31 +01:00
committed by GitHub
parent b8273c4441
commit 25a74ffeee
2 changed files with 131 additions and 71 deletions

View File

@@ -21,5 +21,4 @@ parameters:
- '#Access to an undefined property Faker\\Generator::\$bs.#' - '#Access to an undefined property Faker\\Generator::\$bs.#'
- '#Method Symfony\\Contracts\\EventDispatcher\\EventDispatcherInterface::dispatch\(\) invoked with 2 parameters, 1 required.#' - '#Method Symfony\\Contracts\\EventDispatcher\\EventDispatcherInterface::dispatch\(\) invoked with 2 parameters, 1 required.#'
excludes_analyse: excludes_analyse:
- %rootDir%/../../../src/Command/KimaiImporterCommand.php
- %rootDir%/../../../src/Ldap/LdapDriver.php - %rootDir%/../../../src/Ldap/LdapDriver.php

View File

@@ -12,10 +12,12 @@ namespace App\Command;
use App\Doctrine\TimesheetSubscriber; use App\Doctrine\TimesheetSubscriber;
use App\Entity\Activity; use App\Entity\Activity;
use App\Entity\ActivityMeta; use App\Entity\ActivityMeta;
use App\Entity\ActivityRate;
use App\Entity\Customer; use App\Entity\Customer;
use App\Entity\CustomerMeta; use App\Entity\CustomerMeta;
use App\Entity\Project; use App\Entity\Project;
use App\Entity\ProjectMeta; use App\Entity\ProjectMeta;
use App\Entity\ProjectRate;
use App\Entity\Timesheet; use App\Entity\Timesheet;
use App\Entity\User; use App\Entity\User;
use App\Entity\UserPreference; use App\Entity\UserPreference;
@@ -58,52 +60,54 @@ final class KimaiImporterCommand extends Command
* Create the user default passwords * Create the user default passwords
* @var UserPasswordEncoderInterface * @var UserPasswordEncoderInterface
*/ */
protected $encoder; private $encoder;
/** /**
* Validates the entities before they will be created * Validates the entities before they will be created
* @var ValidatorInterface * @var ValidatorInterface
*/ */
protected $validator; private $validator;
/** /**
* Connection to the Kimai v2 database to write imported data to * Connection to the Kimai v2 database to write imported data to
* @var ManagerRegistry * @var ManagerRegistry
*/ */
protected $doctrine; private $doctrine;
/** /**
* Connection to the old database to import data from * Connection to the old database to import data from
* @var Connection * @var Connection
*/ */
protected $connection; private $connection;
/** /**
* Prefix for the v1 database tables. * Prefix for the v1 database tables.
* @var string * @var string
*/ */
protected $dbPrefix = ''; private $dbPrefix = '';
/** /**
* Old UserID => new User()
* @var User[] * @var User[]
*/ */
protected $users = []; private $users = [];
/** /**
* @var Customer[] * @var Customer[]
*/ */
protected $customers = []; private $customers = [];
/** /**
* Old Project ID => new Project()
* @var Project[] * @var Project[]
*/ */
protected $projects = []; private $projects = [];
/** /**
* id => [projectId => Activity] * id => [projectId => Activity]
* @var Activity[] * @var array<Activity[]>
*/ */
protected $activities = []; private $activities = [];
/** /**
* @var bool * @var bool
*/ */
protected $debug = false; private $debug = false;
/** /**
* @var array * @var array
*/ */
protected $oldActivities = []; private $oldActivities = [];
public function __construct(UserPasswordEncoderInterface $encoder, ManagerRegistry $registry, ValidatorInterface $validator) public function __construct(UserPasswordEncoderInterface $encoder, ManagerRegistry $registry, ValidatorInterface $validator)
{ {
@@ -710,31 +714,12 @@ final class KimaiImporterCommand extends Command
$project->setMetaField($metaField); $project->setMetaField($metaField);
foreach ($fixedRates as $fixedRow) {
if ($fixedRow['activityID'] !== null || $fixedRow['projectID'] === null) {
continue;
}
if ($fixedRow['projectID'] == $oldProject['projectID']) {
$project->setFixedRate($fixedRow['rate']);
}
}
foreach ($rates as $ratesRow) {
if ($ratesRow['userID'] !== null || $ratesRow['activityID'] !== null || $ratesRow['projectID'] === null) {
continue;
}
if ($ratesRow['projectID'] == $oldProject['projectID']) {
$project->setHourlyRate($ratesRow['rate']);
}
}
if (!$this->validateImport($io, $project)) { if (!$this->validateImport($io, $project)) {
throw new Exception('Failed to validate project: ' . $project->getName()); throw new Exception('Failed to validate project: ' . $project->getName());
} }
try { try {
$entityManager->persist($project); $entityManager->persist($project);
$entityManager->flush();
if ($this->debug) { if ($this->debug) {
$io->success('Created project: ' . $project->getName() . ' for customer: ' . $customer->getName()); $io->success('Created project: ' . $project->getName() . ' for customer: ' . $customer->getName());
} }
@@ -744,6 +729,54 @@ final class KimaiImporterCommand extends Command
$io->error('Reason: ' . $ex->getMessage()); $io->error('Reason: ' . $ex->getMessage());
} }
foreach ($fixedRates as $fixedRow) {
// activity rates a re assigned in createActivity()
if ($fixedRow['activityID'] !== null || $fixedRow['projectID'] === null) {
continue;
}
if ($fixedRow['projectID'] == $oldProject['projectID']) {
$projectRate = new ProjectRate();
$projectRate->setProject($project);
$projectRate->setRate($fixedRow['rate']);
$projectRate->setIsFixed(true);
try {
$entityManager->persist($projectRate);
if ($this->debug) {
$io->success('Created fixed project rate: ' . $project->getName() . ' for customer: ' . $customer->getName());
}
} catch (Exception $ex) {
$io->error(sprintf('Failed to create fixed project rate for %s: %s' . $project->getName(), $ex->getMessage()));
}
}
}
foreach ($rates as $ratesRow) {
if ($ratesRow['activityID'] !== null || $ratesRow['projectID'] === null) {
continue;
}
if ($ratesRow['projectID'] == $oldProject['projectID']) {
$projectRate = new ProjectRate();
$projectRate->setProject($project);
$projectRate->setRate($ratesRow['rate']);
if ($ratesRow['userID'] !== null) {
$projectRate->setUser($this->users[$ratesRow['userID']]);
}
try {
$entityManager->persist($projectRate);
if ($this->debug) {
$io->success('Created project rate: ' . $project->getName() . ' for customer: ' . $customer->getName());
}
} catch (Exception $ex) {
$io->error(sprintf('Failed to create project rate for %s: %s' . $project->getName(), $ex->getMessage()));
}
}
}
$entityManager->flush();
$this->projects[$oldProject['projectID']] = $project; $this->projects[$oldProject['projectID']] = $project;
} }
@@ -826,7 +859,7 @@ final class KimaiImporterCommand extends Command
* @param array $oldActivity * @param array $oldActivity
* @param array $fixedRates * @param array $fixedRates
* @param array $rates * @param array $rates
* @param int $projectId * @param int $oldProjectId
* @return Activity * @return Activity
* @throws Exception * @throws Exception
*/ */
@@ -836,12 +869,12 @@ final class KimaiImporterCommand extends Command
array $oldActivity, array $oldActivity,
array $fixedRates, array $fixedRates,
array $rates, array $rates,
$projectId $oldProjectId
) { ) {
$activityId = $oldActivity['activityID']; $oldActivityId = $oldActivity['activityID'];
if (isset($this->activities[$activityId][$projectId])) { if (isset($this->activities[$oldActivityId][$oldProjectId])) {
return $this->activities[$activityId][$projectId]; return $this->activities[$oldActivityId][$oldProjectId];
} }
$isActive = (bool) $oldActivity['visible'] && !(bool) $oldActivity['trash']; $isActive = (bool) $oldActivity['visible'] && !(bool) $oldActivity['trash'];
@@ -851,9 +884,9 @@ final class KimaiImporterCommand extends Command
$io->warning('Found empty activity name, setting it to: ' . $name); $io->warning('Found empty activity name, setting it to: ' . $name);
} }
if (null !== $projectId && !isset($this->projects[$projectId])) { if (null !== $oldProjectId && !isset($this->projects[$oldProjectId])) {
throw new Exception( throw new Exception(
sprintf('Did not find project [%s], skipping activity creation [%s] %s', $projectId, $activityId, $name) sprintf('Did not find project [%s], skipping activity creation [%s] %s', $oldProjectId, $oldActivityId, $name)
); );
} }
@@ -865,8 +898,8 @@ final class KimaiImporterCommand extends Command
->setBudget($oldActivity['budget'] ?? 0) ->setBudget($oldActivity['budget'] ?? 0)
; ;
if (null !== $projectId) { if (null !== $oldProjectId) {
$project = $this->projects[$projectId]; $project = $this->projects[$oldProjectId];
$activity->setProject($project); $activity->setProject($project);
} }
@@ -877,39 +910,12 @@ final class KimaiImporterCommand extends Command
$activity->setMetaField($metaField); $activity->setMetaField($metaField);
foreach ($fixedRates as $fixedRow) {
if ($fixedRow['activityID'] === null) {
continue;
}
if ($fixedRow['projectID'] !== null && $fixedRow['projectID'] !== $projectId) {
continue;
}
if ($fixedRow['activityID'] == $oldActivity['activityID']) {
$activity->setFixedRate($fixedRow['rate']);
}
}
foreach ($rates as $ratesRow) {
if ($ratesRow['userID'] !== null || $ratesRow['activityID'] === null) {
continue;
}
if ($ratesRow['projectID'] !== null && $ratesRow['projectID'] !== $projectId) {
continue;
}
if ($ratesRow['activityID'] == $oldActivity['activityID']) {
$activity->setHourlyRate($ratesRow['rate']);
}
}
if (!$this->validateImport($io, $activity)) { if (!$this->validateImport($io, $activity)) {
throw new Exception('Failed to validate activity: ' . $activity->getName()); throw new Exception('Failed to validate activity: ' . $activity->getName());
} }
try { try {
$entityManager->persist($activity); $entityManager->persist($activity);
$entityManager->flush();
if ($this->debug) { if ($this->debug) {
$io->success('Created activity: ' . $activity->getName()); $io->success('Created activity: ' . $activity->getName());
} }
@@ -918,10 +924,65 @@ final class KimaiImporterCommand extends Command
$io->error('Reason: ' . $ex->getMessage()); $io->error('Reason: ' . $ex->getMessage());
} }
if (!isset($this->activities[$activityId])) { if (!isset($this->activities[$oldActivityId])) {
$this->activities[$activityId] = []; $this->activities[$oldActivityId] = [];
} }
$this->activities[$activityId][$projectId] = $activity; $this->activities[$oldActivityId][$oldProjectId] = $activity;
foreach ($fixedRates as $fixedRow) {
if ($fixedRow['activityID'] === null) {
continue;
}
if ($fixedRow['projectID'] !== null && $fixedRow['projectID'] !== $oldProjectId) {
continue;
}
if ($fixedRow['activityID'] == $oldActivityId) {
$activityRate = new ActivityRate();
$activityRate->setActivity($activity);
$activityRate->setRate($fixedRow['rate']);
$activityRate->setIsFixed(true);
try {
$entityManager->persist($activityRate);
if ($this->debug) {
$io->success('Created fixed activity rate: ' . $activity->getName());
}
} catch (Exception $ex) {
$io->error(sprintf('Failed to create fixed activity rate for %s: %s' . $activity->getName(), $ex->getMessage()));
}
}
}
foreach ($rates as $ratesRow) {
if ($ratesRow['activityID'] === null) {
continue;
}
if ($ratesRow['projectID'] !== null && $ratesRow['projectID'] !== $oldProjectId) {
continue;
}
if ($ratesRow['activityID'] == $oldActivityId) {
$activityRate = new ActivityRate();
$activityRate->setActivity($activity);
$activityRate->setRate($ratesRow['rate']);
if ($ratesRow['userID'] !== null) {
$activityRate->setUser($this->users[$ratesRow['userID']]);
}
try {
$entityManager->persist($activityRate);
if ($this->debug) {
$io->success('Created activity rate: ' . $activity->getName());
}
} catch (Exception $ex) {
$io->error(sprintf('Failed to create activity rate for %s: %s' . $activity->getName(), $ex->getMessage()));
}
}
}
$entityManager->flush();
return $activity; return $activity;
} }