From 096fb6219fba6309fd67ddeab646be45b08e53d7 Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Thu, 14 Sep 2023 15:52:20 +0200 Subject: [PATCH] adapt User Entity to get/set MainScope and UserJob with Histories Collection --- src/Bundle/ChillMainBundle/Entity/User.php | 116 ++++++++++++++++++--- 1 file changed, 104 insertions(+), 12 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Entity/User.php b/src/Bundle/ChillMainBundle/Entity/User.php index 8cb45cd57..9656cb3e6 100644 --- a/src/Bundle/ChillMainBundle/Entity/User.php +++ b/src/Bundle/ChillMainBundle/Entity/User.php @@ -11,10 +11,14 @@ declare(strict_types=1); namespace Chill\MainBundle\Entity; +use Chill\MainBundle\Entity\User\UserJobHistory; +use Chill\MainBundle\Entity\User\UserScopeHistory; use DateTimeImmutable; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; +use Doctrine\Common\Collections\Criteria; use Doctrine\ORM\Mapping as ORM; +use Iterator; use RuntimeException; use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Serializer\Annotation as Serializer; @@ -113,9 +117,11 @@ class User implements UserInterface, \Stringable private ?Location $mainLocation = null; /** - * @ORM\ManyToOne(targetEntity=Scope::class) + * @var Collection + * @ORM\OneToMany(targetEntity=UserScopeHistory::class, + * mappedBy="user", cascade={"persist", "remove"}, orphanRemoval=true) */ - private ?Scope $mainScope = null; + private Collection $scopeHistories; /** * @ORM\Column(type="string", length=255) @@ -130,9 +136,11 @@ class User implements UserInterface, \Stringable private ?string $salt = null; /** - * @ORM\ManyToOne(targetEntity=UserJob::class) + * @var Collection + * @ORM\OneToMany(targetEntity=UserJobHistory::class, + * mappedBy="user", cascade={"persist", "remove"}, orphanRemoval=true) */ - private ?UserJob $userJob = null; + private Collection $jobHistories; /** * @ORM\Column(type="string", length=80) @@ -154,6 +162,8 @@ class User implements UserInterface, \Stringable public function __construct() { $this->groupCenters = new ArrayCollection(); + $this->scopeHistories = new ArrayCollection(); + $this->jobHistories = new ArrayCollection(); } /** @@ -252,9 +262,29 @@ class User implements UserInterface, \Stringable return $this->mainLocation; } - public function getMainScope(): ?Scope + public function getMainScope(?DateTimeImmutable $at = null): ?UserScopeHistory { - return $this->mainScope; + $at ??= new DateTimeImmutable('today'); + $criteria = new Criteria(); + $expr = Criteria::expr(); + + $criteria->where( + $expr->andX( + $expr->orX( + $expr->isNull('endDate'), + $expr->gt('endDate', $at) + ), + $expr->lte('startDate', $at) + ) + ); + + $scopes = $this->scopeHistories->matching($criteria); + + if ($scopes->count() > 0) { + return $scopes->first(); + } + + return null; } /** @@ -275,9 +305,28 @@ class User implements UserInterface, \Stringable return $this->salt; } - public function getUserJob(): ?UserJob + public function getUserJob(?DateTimeImmutable $at = null): ?UserJobHistory { - return $this->userJob; + $at ??= new DateTimeImmutable('today'); + $criteria = new Criteria(); + $expr = Criteria::expr(); + + $criteria->where( + $expr->andX( + $expr->orX( + $expr->isNull('endDate'), + $expr->gt('endDate', $at) + ), + $expr->lte('startDate') + ) + ); + + $jobs = $this->jobHistories->matching($criteria); + if ($jobs->count() > 0) { + return $jobs->first(); + } + + return null; } /** @@ -453,9 +502,31 @@ class User implements UserInterface, \Stringable return $this; } - public function setMainScope(?Scope $mainScope): User + public function setMainScope(UserScopeHistory $mainScope): User { - $this->mainScope = $mainScope; + if (!$this->scopeHistories->contains($mainScope)) { + $this->scopeHistories[] = $mainScope; + $mainScope->setUser($this); + } + + // ensure continuity of histories + $criteria = new Criteria(); + $criteria->orderBy(['startDate' => Criteria::ASC, 'id' => Criteria::ASC]); + + /** @var Iterator $scopes */ + $scopes = $this->getMainScope()->matching($criteria)->getIterator(); + $scopes->rewind(); + + do { + /** @var UserScopeHistory $current */ + $current = $scopes->current(); + $scopes->next(); + + if ($scopes->valid()) { + $next = $scopes->current(); + $current->setEndDate($next->getStartDate()); + } + } while ($scopes->valid()); return $this; } @@ -484,9 +555,30 @@ class User implements UserInterface, \Stringable return $this; } - public function setUserJob(?UserJob $userJob): User + public function setUserJob(UserJobHistory $userJob): User { - $this->userJob = $userJob; + if (!$this->jobHistories->contains($userJob)) { + $this->jobHistories[] = $userJob; + $userJob->setUser($this); + } + + $criteria = new Criteria(); + $criteria->orderBy(['startDate' => Criteria::ASC, 'id' => Criteria::ASC]); + + /** @var Iterator $jobs */ + $jobs = $this->getUserJob()->matching($criteria)->getIterator(); + $jobs->rewind(); + + do { + /** @var UserJobHistory $current */ + $current = $jobs->current(); + $jobs->next(); + + if ($jobs->valid()) { + $next = $jobs->current(); + $current->setEndDate($next->getStartDate()); + } + } while ($jobs->valid()); return $this; }