update some queries in the interface to take into account history of user's scope and user's job

This commit is contained in:
2023-10-11 15:14:27 +02:00
parent 363785b779
commit 978db5a5c5
14 changed files with 210 additions and 57 deletions

View File

@@ -59,10 +59,10 @@ final readonly class UserExportController
'label',
'mainCenter_id' ,
'mainCenter_name',
'mainScope_id', ///
'mainScope_name', ///
'userJob_id', ///
'userJob_name', ///
'mainScope_id',
'mainScope_name',
'userJob_id',
'userJob_name',
'currentLocation_id',
'currentLocation_name',
'mainLocation_id',

View File

@@ -13,7 +13,8 @@ namespace Chill\MainBundle\Repository;
use Chill\MainBundle\Entity\GroupCenter;
use Chill\MainBundle\Entity\User;
use Doctrine\ORM\AbstractQuery;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Exception;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\NoResultException;
@@ -27,7 +28,11 @@ final readonly class UserRepository implements UserRepositoryInterface
{
private EntityRepository $repository;
public function __construct(private EntityManagerInterface $entityManager)
private const FIELDS = ['id', 'email', 'enabled', 'civility_id', 'civility_abbreviation', 'civility_name', 'label', 'mainCenter_id',
'mainCenter_name', 'mainScope_id', 'mainScope_name', 'userJob_id', 'userJob_name', 'currentLocation_id', 'currentLocation_name',
'mainLocation_id', 'mainLocation_name'];
public function __construct(private EntityManagerInterface $entityManager, private Connection $connection)
{
$this->repository = $entityManager->getRepository(User::class);
}
@@ -75,48 +80,58 @@ final readonly class UserRepository implements UserRepositoryInterface
}
/**
* @param string $lang
* @throws Exception
*/
public function findAllAsArray(string $lang): iterable
{
$dql = sprintf(<<<'DQL'
$sql = sprintf(<<<'SQL'
SELECT
u.id AS id,
u.id,
u.username AS username,
u.email,
u.email AS email,
u.enabled,
IDENTITY(u.civility) AS civility_id,
JSON_EXTRACT(civility.abbreviation, :lang) AS civility_abbreviation,
JSON_EXTRACT(civility.name, :lang) AS civility_name,
u.civility_id,
civility.abbreviation->>:lang AS civility_abbreviation,
civility.name->>:lang AS civility_name,
u.label,
mainCenter.id AS mainCenter_id,
mainCenter.name AS mainCenter_name,
IDENTITY(u.mainScope) AS mainScope_id,
JSON_EXTRACT(mainScope.name, :lang) AS mainScope_name,
IDENTITY(u.userJob) AS userJob_id,
JSON_EXTRACT(userJob.label, :lang) AS userJob_name,
mainScope.id AS mainScope_id,
mainScope.name->>:lang AS mainScope_name,
userJob.id AS userJob_id,
userJob.label->>:lang AS userJob_name,
currentLocation.id AS currentLocation_id,
currentLocation.name AS currentLocation_name,
mainLocation.id AS mainLocation_id,
mainLocation.name AS mainLocation_name,
u.absenceStart
FROM Chill\MainBundle\Entity\User u
LEFT JOIN u.civility civility
LEFT JOIN u.currentLocation currentLocation
LEFT JOIN u.mainLocation mainLocation
LEFT JOIN u.mainCenter mainCenter
LEFT JOIN u.mainScope mainScope
LEFT JOIN u.userJob userJob
ORDER BY u.label
DQL); /// mainScope userJob
FROM users u
LEFT JOIN chill_main_civility civility ON u.civility_id = civility.id
LEFT JOIN centers mainCenter ON u.maincenter_id = mainCenter.id
LEFT JOIN chill_main_user_job_history userJobHistory ON u.id = userJobHistory.user_id
LEFT JOIN chill_main_user_job userJob ON userJobHistory.job_id = userJob.id
LEFT JOIN chill_main_user_scope_history userScopeHistory ON u.id = userScopeHistory.user_id
LEFT JOIN scopes mainScope ON userScopeHistory.scope_id = mainScope.id
LEFT JOIN chill_main_location currentLocation ON u.currentlocation_id = currentLocation.id
LEFT JOIN chill_main_location mainLocation ON u.mainlocation_id = mainLocation.id
WHERE
tstzrange(userScopeHistory.startdate, userScopeHistory.enddate) @> NOW()
AND
tstzrange(userJobHistory.startdate, userJobHistory.enddate) @> NOW()
SQL);
$query = $this->entityManager->createQuery($dql)
->setHydrationMode(AbstractQuery::HYDRATE_ARRAY)
->setParameter('lang', $lang)
;
$query = $this->connection->prepare($sql);
foreach ($query->toIterable() as $u) {
yield $u;
foreach ($query->executeQuery(['lang' => $lang])->iterateAssociative() as $u) {
$converted = [];
foreach (self::FIELDS as $f) {
$converted[$f] = $u[strtolower($f)];
}
$converted['absenceStart'] = null !== $u['absencestart'] ? new \DateTimeImmutable($u['absencestart']) : null;
/** @phpstan-ignore-next-line phpstan does not take into account that all required keys will be present */
yield $converted;
}
}

View File

@@ -12,6 +12,7 @@ declare(strict_types=1);
namespace Chill\MainBundle\Service\EntityInfo;
use Doctrine\DBAL\Connection;
use Psr\Log\LoggerInterface;
class ViewEntityInfoManager
{
@@ -21,6 +22,7 @@ class ViewEntityInfoManager
*/
private readonly iterable $vienEntityInfoProviders,
private readonly Connection $connection,
private readonly LoggerInterface $logger,
) {}
public function synchronizeOnDB(): void
@@ -28,6 +30,8 @@ class ViewEntityInfoManager
$this->connection->transactional(function (Connection $conn): void {
foreach ($this->vienEntityInfoProviders as $viewProvider) {
foreach ($this->createOrReplaceViewSQL($viewProvider, $viewProvider->getViewName()) as $sql) {
$this->logger->debug("Will execute create view sql", ['sql' => $sql]);
$this->logger->debug($sql);
$conn->executeQuery($sql);
}
}
@@ -41,7 +45,7 @@ class ViewEntityInfoManager
{
return [
"DROP VIEW IF EXISTS {$viewName}",
sprintf("CREATE VIEW {$viewName} AS %s", $viewProvider->getViewQuery())
sprintf("CREATE OR REPLACE VIEW {$viewName} AS %s", $viewProvider->getViewQuery())
];
}
}