mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
1511 lines
41 KiB
PHP
1511 lines
41 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
/*
|
|
* Chill is a software for social workers
|
|
*
|
|
* For the full copyright and license information, please view
|
|
* the LICENSE file that was distributed with this source code.
|
|
*/
|
|
|
|
namespace Chill\PersonBundle\Entity;
|
|
|
|
use Chill\MainBundle\Doctrine\Model\TrackCreationInterface;
|
|
use Chill\MainBundle\Doctrine\Model\TrackUpdateInterface;
|
|
use Chill\MainBundle\Entity\Address;
|
|
use Chill\MainBundle\Entity\Center;
|
|
use Chill\MainBundle\Entity\HasCentersInterface;
|
|
use Chill\MainBundle\Entity\HasScopesInterface;
|
|
use Chill\MainBundle\Entity\Location;
|
|
use Chill\MainBundle\Entity\Scope;
|
|
use Chill\MainBundle\Entity\User;
|
|
use Chill\MainBundle\Entity\UserJob;
|
|
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodLocationHistory;
|
|
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodStepHistory;
|
|
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork;
|
|
use Chill\PersonBundle\Entity\AccompanyingPeriod\ClosingMotive;
|
|
use Chill\PersonBundle\Entity\AccompanyingPeriod\Comment;
|
|
use Chill\PersonBundle\Entity\AccompanyingPeriod\Origin;
|
|
use Chill\PersonBundle\Entity\AccompanyingPeriod\Resource;
|
|
use Chill\PersonBundle\Entity\AccompanyingPeriod\UserHistory;
|
|
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
|
|
use Chill\PersonBundle\Validator\Constraints\AccompanyingPeriod\AccompanyingPeriodValidity;
|
|
use Chill\PersonBundle\Validator\Constraints\AccompanyingPeriod\ConfidentialCourseMustHaveReferrer;
|
|
use Chill\PersonBundle\Validator\Constraints\AccompanyingPeriod\LocationValidity;
|
|
use Chill\PersonBundle\Validator\Constraints\AccompanyingPeriod\ParticipationOverlap;
|
|
use Chill\PersonBundle\Validator\Constraints\AccompanyingPeriod\ResourceDuplicateCheck;
|
|
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
|
use DateTime;
|
|
use DateTimeImmutable;
|
|
use DateTimeInterface;
|
|
use Doctrine\Common\Collections\ArrayCollection;
|
|
use Doctrine\Common\Collections\Collection;
|
|
use Doctrine\Common\Collections\Criteria;
|
|
use Doctrine\Common\Collections\ReadableCollection;
|
|
use Doctrine\ORM\Mapping as ORM;
|
|
use Iterator;
|
|
use LogicException;
|
|
use Symfony\Component\Serializer\Annotation\DiscriminatorMap;
|
|
use Symfony\Component\Serializer\Annotation\Groups;
|
|
use Symfony\Component\Validator\Constraints as Assert;
|
|
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
|
use Symfony\Component\Validator\GroupSequenceProviderInterface;
|
|
|
|
use UnexpectedValueException;
|
|
|
|
use function array_key_exists;
|
|
use const SORT_REGULAR;
|
|
|
|
/**
|
|
* AccompanyingPeriod Class.
|
|
*
|
|
* @ORM\Entity
|
|
* @ORM\Table(name="chill_person_accompanying_period")
|
|
* @DiscriminatorMap(typeProperty="type", mapping={
|
|
* "accompanying_period": AccompanyingPeriod::class
|
|
* })
|
|
* @Assert\GroupSequenceProvider
|
|
* @AccompanyingPeriodValidity(groups={AccompanyingPeriod::STEP_DRAFT, AccompanyingPeriod::STEP_CONFIRMED})
|
|
* @LocationValidity(groups={AccompanyingPeriod::STEP_DRAFT, AccompanyingPeriod::STEP_CONFIRMED})
|
|
* @ConfidentialCourseMustHaveReferrer(groups={AccompanyingPeriod::STEP_DRAFT, AccompanyingPeriod::STEP_CONFIRMED})
|
|
*/
|
|
class AccompanyingPeriod implements
|
|
GroupSequenceProviderInterface,
|
|
HasCentersInterface,
|
|
HasScopesInterface,
|
|
TrackCreationInterface,
|
|
TrackUpdateInterface
|
|
{
|
|
public const INTENSITIES = [self::INTENSITY_OCCASIONAL, self::INTENSITY_REGULAR];
|
|
|
|
/**
|
|
* Mark an accompanying period as "occasional".
|
|
*
|
|
* used in INTENSITY
|
|
*/
|
|
public const INTENSITY_OCCASIONAL = 'occasional';
|
|
|
|
/**
|
|
* Mark an accompanying period as "regular".
|
|
*
|
|
* used in INTENSITY
|
|
*/
|
|
public const INTENSITY_REGULAR = 'regular';
|
|
|
|
/**
|
|
* Mark an accompanying period as "closed".
|
|
*
|
|
* This means that the accompanying period **is**
|
|
* closed by the creator
|
|
*/
|
|
public const STEP_CLOSED = 'CLOSED';
|
|
|
|
/**
|
|
* Mark an accompanying period as "confirmed".
|
|
*
|
|
* This means that the accompanying period **is**
|
|
* confirmed by the creator
|
|
*/
|
|
public const STEP_CONFIRMED = 'CONFIRMED';
|
|
|
|
/**
|
|
* Mark an accompanying period as "draft".
|
|
*
|
|
* This means that the accompanying period is not yet
|
|
* confirmed by the creator
|
|
*/
|
|
public const STEP_DRAFT = 'DRAFT';
|
|
|
|
/**
|
|
* @ORM\ManyToOne(
|
|
* targetEntity=Address::class
|
|
* )
|
|
*/
|
|
private ?Address $addressLocation = null;
|
|
|
|
/**
|
|
* @ORM\ManyToOne(targetEntity="Chill\MainBundle\Entity\Location")
|
|
* @Groups({"read", "write"})
|
|
* @Assert\NotBlank(groups={AccompanyingPeriod::STEP_CONFIRMED})
|
|
*/
|
|
private ?Location $administrativeLocation = null;
|
|
|
|
/**
|
|
* @ORM\OneToMany(targetEntity="Chill\CalendarBundle\Entity\Calendar", mappedBy="accompanyingPeriod")
|
|
*/
|
|
private Collection $calendars;
|
|
|
|
/**
|
|
* @var DateTime
|
|
*
|
|
* @ORM\Column(type="date", nullable=true)
|
|
* @Groups({"read", "write", "docgen:read"})
|
|
* @Assert\NotBlank(groups={AccompanyingPeriod::STEP_CLOSED})
|
|
* @Assert\GreaterThanOrEqual(
|
|
* propertyPath="openingDate",
|
|
* groups={AccompanyingPeriod::STEP_CLOSED},
|
|
* message="The closing date must be later than the date of creation"
|
|
* )
|
|
*/
|
|
private ?DateTime $closingDate = null;
|
|
|
|
/**
|
|
* @var AccompanyingPeriod\ClosingMotive
|
|
*
|
|
* @ORM\ManyToOne(
|
|
* targetEntity="Chill\PersonBundle\Entity\AccompanyingPeriod\ClosingMotive")
|
|
* @ORM\JoinColumn(nullable=true)
|
|
* @Groups({"read", "write"})
|
|
* @Assert\NotBlank(groups={AccompanyingPeriod::STEP_CLOSED})
|
|
*/
|
|
private ?ClosingMotive $closingMotive = null;
|
|
|
|
/**
|
|
* @ORM\OneToMany(targetEntity="Chill\PersonBundle\Entity\AccompanyingPeriod\Comment",
|
|
* mappedBy="accompanyingPeriod",
|
|
* cascade={"persist", "remove"},
|
|
* orphanRemoval=true
|
|
* )
|
|
* @Assert\NotBlank(groups={AccompanyingPeriod::STEP_DRAFT})
|
|
*/
|
|
private Collection $comments;
|
|
|
|
/**
|
|
* @ORM\Column(type="boolean", options={"default": false})
|
|
* @Groups({"read", "write", "docgen:read"})
|
|
*/
|
|
private bool $confidential = false;
|
|
|
|
/**
|
|
* @ORM\Column(type="datetime", nullable=true, options={"default": NULL})
|
|
* @Groups({"docgen:read"})
|
|
*/
|
|
private ?DateTimeInterface $createdAt = null;
|
|
|
|
/**
|
|
* @ORM\ManyToOne(targetEntity=User::class)
|
|
* @ORM\JoinColumn(nullable=true)
|
|
* @Groups({"read", "docgen:read"})
|
|
*/
|
|
private ?User $createdBy = null;
|
|
|
|
/**
|
|
* @ORM\Column(type="boolean", options={"default": false})
|
|
* @Groups({"read", "write", "docgen:read"})
|
|
*/
|
|
private bool $emergency = false;
|
|
|
|
/**
|
|
* @ORM\Id
|
|
* @ORM\Column(name="id", type="integer")
|
|
* @ORM\GeneratedValue(strategy="AUTO")
|
|
* @Groups({"read", "docgen:read"})
|
|
*/
|
|
private ?int $id = null;
|
|
|
|
/**
|
|
* @var string
|
|
* @ORM\Column(type="string", nullable=true)
|
|
* @Groups({"read"})
|
|
* @Assert\NotBlank(groups={AccompanyingPeriod::STEP_CONFIRMED})
|
|
*/
|
|
private $intensity = self::INTENSITY_OCCASIONAL;
|
|
|
|
/**
|
|
* @ORM\ManyToOne(
|
|
* targetEntity=UserJob::class
|
|
* )
|
|
* @Groups({"read", "write"})
|
|
* @Assert\NotBlank(groups={AccompanyingPeriod::STEP_CONFIRMED})
|
|
*/
|
|
private ?UserJob $job = null;
|
|
|
|
/**
|
|
* @ORM\OneToMany(targetEntity=AccompanyingPeriodLocationHistory::class,
|
|
* mappedBy="period", cascade={"persist", "remove"}, orphanRemoval=true)
|
|
*/
|
|
private Collection $locationHistories;
|
|
|
|
/**
|
|
* @var DateTime
|
|
*
|
|
* @ORM\Column(type="date")
|
|
* @Groups({"read", "write", "docgen:read"})
|
|
* @Assert\LessThan(value="tomorrow", groups={AccompanyingPeriod::STEP_CONFIRMED})
|
|
* @Assert\LessThanOrEqual(propertyPath="closingDate", groups={AccompanyingPeriod::STEP_CONFIRMED})
|
|
*/
|
|
private ?DateTime $openingDate = null;
|
|
|
|
/**
|
|
* @ORM\ManyToOne(targetEntity=Origin::class)
|
|
* @ORM\JoinColumn(nullable=true)
|
|
* @Groups({"read", "write"})
|
|
* @Assert\NotBlank(groups={AccompanyingPeriod::STEP_CONFIRMED})
|
|
*/
|
|
private ?Origin $origin = null;
|
|
|
|
/**
|
|
* @ORM\OneToMany(targetEntity=AccompanyingPeriodParticipation::class,
|
|
* mappedBy="accompanyingPeriod", orphanRemoval=true,
|
|
* cascade={"persist", "refresh", "remove", "merge", "detach"})
|
|
* @Groups({"read", "docgen:read"})
|
|
* @ParticipationOverlap(groups={AccompanyingPeriod::STEP_DRAFT, AccompanyingPeriod::STEP_CONFIRMED})
|
|
*/
|
|
private Collection $participations;
|
|
|
|
/**
|
|
* @ORM\ManyToOne(
|
|
* targetEntity=Person::class,
|
|
* inversedBy="periodLocatedOn"
|
|
* )
|
|
*/
|
|
private ?Person $personLocation = null;
|
|
|
|
/**
|
|
* @ORM\ManyToOne(
|
|
* targetEntity=Comment::class,
|
|
* cascade={"persist"},
|
|
* )
|
|
* @Groups({"read"})
|
|
* @ORM\JoinColumn(onDelete="SET NULL")
|
|
*/
|
|
private ?Comment $pinnedComment = null;
|
|
|
|
private bool $preventUserIsChangedNotification = false;
|
|
|
|
/**
|
|
* @ORM\Column(type="text")
|
|
* @Groups({"read", "write"})
|
|
*/
|
|
private string $remark = '';
|
|
|
|
/**
|
|
* @ORM\Column(type="boolean", options={"default": false})
|
|
* @Groups({"read", "write", "docgen:read"})
|
|
*/
|
|
private bool $requestorAnonymous = false;
|
|
|
|
/**
|
|
* @ORM\ManyToOne(targetEntity=Person::class, inversedBy="accompanyingPeriodRequested")
|
|
* @ORM\JoinColumn(nullable=true)
|
|
*/
|
|
private ?Person $requestorPerson = null;
|
|
|
|
/**
|
|
* @ORM\ManyToOne(targetEntity=ThirdParty::class)
|
|
* @ORM\JoinColumn(nullable=true)
|
|
*/
|
|
private ?ThirdParty $requestorThirdParty = null;
|
|
|
|
/**
|
|
* @ORM\OneToMany(
|
|
* targetEntity="Chill\PersonBundle\Entity\AccompanyingPeriod\Resource",
|
|
* mappedBy="accompanyingPeriod",
|
|
* cascade={"persist", "remove"},
|
|
* orphanRemoval=true
|
|
* )
|
|
* @Groups({"read", "docgen:read"})
|
|
* @ResourceDuplicateCheck(groups={AccompanyingPeriod::STEP_DRAFT, AccompanyingPeriod::STEP_CONFIRMED, "Default", "default"})
|
|
*/
|
|
private Collection $resources;
|
|
|
|
/**
|
|
* @ORM\ManyToMany(
|
|
* targetEntity=Scope::class,
|
|
* cascade={}
|
|
* )
|
|
* @ORM\JoinTable(
|
|
* name="accompanying_periods_scopes",
|
|
* joinColumns={@ORM\JoinColumn(name="accompanying_period_id", referencedColumnName="id")},
|
|
* inverseJoinColumns={@ORM\JoinColumn(name="scope_id", referencedColumnName="id")}
|
|
* )
|
|
* @Groups({"read", "docgen:read"})
|
|
* @Assert\Count(min=1, groups={AccompanyingPeriod::STEP_CONFIRMED}, minMessage="A course must be associated to at least one scope")
|
|
*/
|
|
private Collection $scopes;
|
|
|
|
/**
|
|
* @ORM\ManyToMany(
|
|
* targetEntity=SocialIssue::class
|
|
* )
|
|
* @ORM\JoinTable(
|
|
* name="chill_person_accompanying_period_social_issues"
|
|
* )
|
|
* @Groups({"read", "docgen:read"})
|
|
* @Assert\Count(min=1, groups={AccompanyingPeriod::STEP_CONFIRMED}, minMessage="A course must contains at least one social issue")
|
|
*/
|
|
private Collection $socialIssues;
|
|
|
|
/**
|
|
* @ORM\Column(type="string", length=32, nullable=true)
|
|
* @Groups({"read"})
|
|
*/
|
|
private string $step = self::STEP_DRAFT;
|
|
|
|
/**
|
|
* @ORM\OneToMany(targetEntity=AccompanyingPeriodStepHistory::class,
|
|
* mappedBy="period", cascade={"persist", "remove"}, orphanRemoval=true)
|
|
*/
|
|
private Collection $stepHistories;
|
|
|
|
/**
|
|
* @ORM\Column(type="datetime", nullable=true, options={"default": NULL})
|
|
*/
|
|
private ?DateTimeInterface $updatedAt = null;
|
|
|
|
/**
|
|
* @ORM\ManyToOne(
|
|
* targetEntity=User::class
|
|
* )
|
|
*/
|
|
private ?User $updatedBy = null;
|
|
|
|
/**
|
|
* @ORM\ManyToOne(targetEntity=User::class)
|
|
* @ORM\JoinColumn(nullable=true)
|
|
* @Groups({"read", "write", "docgen:read"})
|
|
*/
|
|
private ?User $user = null;
|
|
|
|
/**
|
|
* @ORM\OneToMany(targetEntity=UserHistory::class, mappedBy="accompanyingPeriod", orphanRemoval=true,
|
|
* cascade={"persist", "remove"})
|
|
*
|
|
* @var Collection|UserHistory[]
|
|
*/
|
|
private Collection $userHistories;
|
|
|
|
private bool $userIsChanged = false;
|
|
|
|
/**
|
|
* Temporary field, which is filled when the user is changed.
|
|
*
|
|
* Used internally for listener when user change
|
|
*/
|
|
private ?User $userPrevious = null;
|
|
|
|
/**
|
|
* @ORM\OneToMany(
|
|
* targetEntity=AccompanyingPeriodWork::class,
|
|
* mappedBy="accompanyingPeriod"
|
|
* )
|
|
* @Assert\Valid(traverse=true)
|
|
*/
|
|
private Collection $works;
|
|
|
|
/**
|
|
* AccompanyingPeriod constructor.
|
|
*
|
|
* @param DateTime $dateOpening
|
|
*
|
|
* @uses AccompanyingPeriod::setClosingDate()
|
|
*/
|
|
public function __construct(?DateTime $dateOpening = null)
|
|
{
|
|
$this->calendars = new ArrayCollection(); // TODO we cannot add a dependency between AccompanyingPeriod and calendars
|
|
$this->participations = new ArrayCollection();
|
|
$this->scopes = new ArrayCollection();
|
|
$this->socialIssues = new ArrayCollection();
|
|
$this->comments = new ArrayCollection();
|
|
$this->works = new ArrayCollection();
|
|
$this->resources = new ArrayCollection();
|
|
$this->userHistories = new ArrayCollection();
|
|
$this->locationHistories = new ArrayCollection();
|
|
$this->stepHistories = new ArrayCollection();
|
|
$this->setOpeningDate($dateOpening ?? new DateTime('now'));
|
|
}
|
|
|
|
/**
|
|
* Return an array with open participations sorted by household
|
|
* [
|
|
* [
|
|
* "household" => Household x,
|
|
* "members" => [
|
|
* Participation y , Participation z, ...
|
|
* ]
|
|
* ],
|
|
* ].
|
|
*/
|
|
public function actualParticipationsByHousehold(): array
|
|
{
|
|
$participations = $this->getOpenParticipations()->toArray();
|
|
|
|
$households = [];
|
|
|
|
foreach ($participations as $p) {
|
|
$households[] = $p->getPerson()->getCurrentHousehold();
|
|
}
|
|
$households = array_unique($households, SORT_REGULAR);
|
|
|
|
$array = [];
|
|
|
|
foreach ($households as $household) {
|
|
$members = [];
|
|
|
|
foreach ($participations as $p) {
|
|
if ($p->getPerson()->getCurrentHousehold() === $household) {
|
|
$members[] = array_shift($participations);
|
|
} else {
|
|
$participations[] = array_shift($participations);
|
|
}
|
|
}
|
|
$array[] = ['household' => $household, 'members' => $members];
|
|
}
|
|
|
|
return $array;
|
|
}
|
|
|
|
public function addComment(Comment $comment): self
|
|
{
|
|
$this->comments[] = $comment;
|
|
$comment->setAccompanyingPeriod($this);
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function addLocationHistory(AccompanyingPeriodLocationHistory $history): self
|
|
{
|
|
if ($this->getStep() === self::STEP_DRAFT) {
|
|
return $this;
|
|
}
|
|
|
|
if (!$this->locationHistories->contains($history)) {
|
|
$this->locationHistories[] = $history;
|
|
$history->setPeriod($this);
|
|
}
|
|
|
|
// ensure continuity of histories
|
|
$criteria = new Criteria();
|
|
$criteria->orderBy(['startDate' => Criteria::ASC, 'id' => Criteria::ASC]);
|
|
|
|
/** @var Iterator $locations */
|
|
$locations = $this->getLocationHistories()->matching($criteria)->getIterator();
|
|
$locations->rewind();
|
|
|
|
do {
|
|
/** @var AccompanyingPeriodLocationHistory $current */
|
|
$current = $locations->current();
|
|
$locations->next();
|
|
|
|
if ($locations->valid()) {
|
|
$next = $locations->current();
|
|
$current->setEndDate($next->getStartDate());
|
|
}
|
|
} while ($locations->valid());
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function addPerson(?Person $person = null): self
|
|
{
|
|
if (null !== $person) {
|
|
$this->createParticipationFor($person);
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function addResource(Resource $resource): self
|
|
{
|
|
$resource->setAccompanyingPeriod($this);
|
|
$this->resources[] = $resource;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function addScope(Scope $scope): self
|
|
{
|
|
if (!$this->scopes->contains($scope)) {
|
|
$this->scopes[] = $scope;
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function addSocialIssue(SocialIssue $socialIssue): self
|
|
{
|
|
if (!$this->socialIssues->contains($socialIssue)) {
|
|
$this->socialIssues[] = $socialIssue;
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function addWork(AccompanyingPeriodWork $work): self
|
|
{
|
|
$this->works[] = $work;
|
|
$work->setAccompanyingPeriod($this);
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* If the period can be reopened.
|
|
*
|
|
* This function test if the period is closed and if the period is the last
|
|
* for the given person
|
|
*/
|
|
public function canBeReOpened(Person $person): bool
|
|
{
|
|
if ($this->isOpen() === true) {
|
|
return false;
|
|
}
|
|
|
|
$participation = $this->getOpenParticipationContainsPerson($person);
|
|
|
|
if (null === $participation) {
|
|
return false;
|
|
}
|
|
|
|
$periods = $participation->getPerson()->getAccompanyingPeriodsOrdered();
|
|
|
|
return end($periods) === $this;
|
|
}
|
|
|
|
/**
|
|
* Close a participation for a person.
|
|
*
|
|
* Search for the person's participation and set the end date at
|
|
* 'now'.
|
|
*
|
|
* @param mixed $person
|
|
*/
|
|
public function closeParticipationFor($person): ?AccompanyingPeriodParticipation
|
|
{
|
|
$participation = $this->getOpenParticipationContainsPerson($person);
|
|
|
|
if ($participation instanceof AccompanyingPeriodParticipation) {
|
|
$participation->setEndDate(new DateTime('now'));
|
|
}
|
|
|
|
return $participation;
|
|
}
|
|
|
|
/**
|
|
* Return true if the accompanying period contains a person.
|
|
*
|
|
* **Note**: this participation can be opened or not.
|
|
*/
|
|
public function containsPerson(Person $person): bool
|
|
{
|
|
return $this->getParticipationsContainsPerson($person)->count() > 0;
|
|
}
|
|
|
|
/**
|
|
* Open a new participation for a person.
|
|
*/
|
|
public function createParticipationFor(Person $person): AccompanyingPeriodParticipation
|
|
{
|
|
$participation = new AccompanyingPeriodParticipation($this, $person);
|
|
$this->participations[] = $participation;
|
|
|
|
return $participation;
|
|
}
|
|
|
|
public function getAddressLocation(): ?Address
|
|
{
|
|
return $this->addressLocation;
|
|
}
|
|
|
|
public function getAdministrativeLocation(): ?Location
|
|
{
|
|
return $this->administrativeLocation;
|
|
}
|
|
|
|
/**
|
|
* Get a list of person which have an adresse available for a valid location.
|
|
*
|
|
* @return ReadableCollection<(int|string), Person>
|
|
*/
|
|
public function getAvailablePersonLocation(): ReadableCollection
|
|
{
|
|
return $this->getOpenParticipations()
|
|
->filter(
|
|
static fn (AccompanyingPeriodParticipation $p): bool => $p->getPerson()->hasCurrentHouseholdAddress()
|
|
)
|
|
->map(
|
|
static fn (AccompanyingPeriodParticipation $p): ?Person => $p->getPerson()
|
|
);
|
|
}
|
|
|
|
public function getCalendars(): Collection
|
|
{
|
|
return $this->calendars;
|
|
}
|
|
|
|
public function getCenter(): ?Center
|
|
{
|
|
if ($this->getPersons()->count() === 0) {
|
|
return null;
|
|
}
|
|
|
|
return $this->getPersons()->first()->getCenter();
|
|
}
|
|
|
|
public function getCenters(): ?iterable
|
|
{
|
|
$centers = [];
|
|
|
|
foreach ($this->getPersons() as $person) {
|
|
if (
|
|
null !== $person->getCenter()
|
|
&& !array_key_exists(spl_object_hash($person->getCenter()), $centers)
|
|
) {
|
|
$centers[spl_object_hash($person->getCenter())] = $person->getCenter();
|
|
}
|
|
}
|
|
|
|
return array_values($centers);
|
|
}
|
|
|
|
/**
|
|
* Get closingDate.
|
|
*
|
|
* @return DateTime
|
|
*/
|
|
public function getClosingDate(): ?DateTime
|
|
{
|
|
return $this->closingDate;
|
|
}
|
|
|
|
public function getClosingMotive(): ?ClosingMotive
|
|
{
|
|
return $this->closingMotive;
|
|
}
|
|
|
|
/**
|
|
* @Groups({"read"})
|
|
* @return ReadableCollection<(int|string), Comment>
|
|
*/
|
|
public function getComments(): ReadableCollection
|
|
{
|
|
$pinnedComment = $this->pinnedComment;
|
|
|
|
return $this
|
|
->comments
|
|
->filter(
|
|
static fn (Comment $c): bool => $c !== $pinnedComment
|
|
);
|
|
}
|
|
|
|
public function getCreatedAt(): ?DateTime
|
|
{
|
|
return $this->createdAt;
|
|
}
|
|
|
|
public function getCreatedBy(): ?User
|
|
{
|
|
return $this->createdBy;
|
|
}
|
|
|
|
/**
|
|
* @Groups({"docgen:read"})
|
|
*/
|
|
public function getCurrentParticipations(): ReadableCollection
|
|
{
|
|
return $this->getOpenParticipations();
|
|
}
|
|
|
|
public function getGroupSequence()
|
|
{
|
|
if ($this->getStep() === self::STEP_DRAFT) {
|
|
return [[self::STEP_DRAFT]];
|
|
}
|
|
|
|
if ($this->getStep() === self::STEP_CONFIRMED) {
|
|
return [[self::STEP_DRAFT, self::STEP_CONFIRMED]];
|
|
}
|
|
|
|
if ($this->getStep() === self::STEP_CLOSED) {
|
|
return [[self::STEP_DRAFT, self::STEP_CONFIRMED, self::STEP_CLOSED]];
|
|
}
|
|
|
|
throw new LogicException('no validation group permitted with this step: ' . $this->getStep());
|
|
}
|
|
|
|
public function getId(): ?int
|
|
{
|
|
return $this->id;
|
|
}
|
|
|
|
public function getIntensity(): ?string
|
|
{
|
|
return $this->intensity;
|
|
}
|
|
|
|
public function getJob(): ?UserJob
|
|
{
|
|
return $this->job;
|
|
}
|
|
|
|
public function getLastLocationHistory(): ?AccompanyingPeriodLocationHistory
|
|
{
|
|
foreach ($this->getLocationHistories() as $locationHistory) {
|
|
if (null === $locationHistory->getEndDate()) {
|
|
return $locationHistory;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Get the location, taking precedence into account.
|
|
*
|
|
* @Groups({"read"})
|
|
*/
|
|
public function getLocation(?DateTimeImmutable $at = null): ?Address
|
|
{
|
|
if ($this->getPersonLocation() instanceof Person) {
|
|
return $this->getPersonLocation()->getCurrentPersonAddress();
|
|
}
|
|
|
|
return $this->getAddressLocation();
|
|
}
|
|
|
|
/**
|
|
* @return Collection|AccompanyingPeriodLocationHistory[]
|
|
*/
|
|
public function getLocationHistories(): Collection
|
|
{
|
|
return $this->locationHistories;
|
|
}
|
|
|
|
/**
|
|
* Get where the location is.
|
|
*
|
|
* @Groups({"read"})
|
|
*/
|
|
public function getLocationStatus(): string
|
|
{
|
|
if ($this->getPersonLocation() instanceof Person) {
|
|
return 'person';
|
|
}
|
|
|
|
if ($this->getAddressLocation() instanceof Address) {
|
|
return 'address';
|
|
}
|
|
|
|
return 'none';
|
|
}
|
|
|
|
public function getNextCalendarsForPerson(Person $person, $limit = 5): Collection
|
|
{
|
|
$today = new DateTimeImmutable('today');
|
|
$criteria = Criteria::create()
|
|
->where(Criteria::expr()->gte('startDate', $today))
|
|
//->andWhere(Criteria::expr()->memberOf('persons', $person))
|
|
->orderBy(['startDate' => 'DESC'])
|
|
->setMaxResults($limit * 2);
|
|
|
|
return $this->calendars->matching($criteria)
|
|
->matching(
|
|
// due to a bug, filter two times
|
|
Criteria::create()
|
|
->where(Criteria::expr()->memberOf('persons', $person))
|
|
->setMaxResults($limit)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Get openingDate.
|
|
*
|
|
* @return DateTime
|
|
*/
|
|
public function getOpeningDate(): ?DateTime
|
|
{
|
|
return $this->openingDate;
|
|
}
|
|
|
|
/**
|
|
* Get the opened participation containing a person.
|
|
*
|
|
* "Open" means that the closed date is NULL
|
|
*/
|
|
public function getOpenParticipationContainsPerson(Person $person): ?AccompanyingPeriodParticipation
|
|
{
|
|
$collection = $this
|
|
->getParticipationsContainsPerson($person)
|
|
->filter(
|
|
static function (AccompanyingPeriodParticipation $participation): bool {
|
|
return null === $participation->getEndDate();
|
|
}
|
|
);
|
|
|
|
return $collection->count() > 0 ? $collection->first() : null;
|
|
}
|
|
|
|
/**
|
|
* @return ReadableCollection<(int|string), AccompanyingPeriodParticipation>
|
|
*/
|
|
public function getOpenParticipations(): ReadableCollection
|
|
{
|
|
return $this
|
|
->getParticipations()
|
|
->filter(
|
|
static function (AccompanyingPeriodParticipation $participation): bool {
|
|
return null === $participation->getEndDate();
|
|
}
|
|
);
|
|
}
|
|
|
|
public function getOrigin(): ?Origin
|
|
{
|
|
return $this->origin;
|
|
}
|
|
|
|
/**
|
|
* Get Participations Collection.
|
|
*/
|
|
public function getParticipations(): Collection
|
|
{
|
|
return $this->participations;
|
|
}
|
|
|
|
/**
|
|
* Get the participation containing a person.
|
|
* @return ReadableCollection<(int|string), AccompanyingPeriodParticipation>
|
|
*/
|
|
public function getParticipationsContainsPerson(Person $person): ReadableCollection
|
|
{
|
|
return $this
|
|
->getParticipations()
|
|
->filter(
|
|
static fn (AccompanyingPeriodParticipation $participation): bool => $participation->getPerson() === $person
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @Groups({"read"})
|
|
*/
|
|
public function getPersonLocation(): ?Person
|
|
{
|
|
return $this->personLocation;
|
|
}
|
|
|
|
/**
|
|
* Get a list of all persons which are participating to this course.
|
|
*
|
|
* @psalm-return Collection<(int|string), Person|null>
|
|
*/
|
|
public function getPersons(): Collection
|
|
{
|
|
return $this
|
|
->participations
|
|
->map(
|
|
static fn (AccompanyingPeriodParticipation $participation): ?Person => $participation->getPerson()
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @Groups({"read"})
|
|
*/
|
|
public function getPinnedComment(): ?Comment
|
|
{
|
|
return $this->pinnedComment;
|
|
}
|
|
|
|
public function getPreviousUser(): ?User
|
|
{
|
|
return $this->userPrevious;
|
|
}
|
|
|
|
/**
|
|
* @return Collection|SocialAction[] All the descendant social actions of all
|
|
* the descendants of the entity
|
|
*/
|
|
public function getRecursiveSocialActions(): Collection
|
|
{
|
|
$recursiveSocialActions = new ArrayCollection();
|
|
|
|
foreach ($this->socialIssues as $socialIssue) {
|
|
foreach ($socialIssue->getRecursiveSocialActions() as $descendant) {
|
|
if (!$recursiveSocialActions->contains($descendant)) {
|
|
$recursiveSocialActions->add($descendant);
|
|
}
|
|
}
|
|
}
|
|
|
|
return $recursiveSocialActions;
|
|
}
|
|
|
|
/**
|
|
* @return Collection|SocialIssues[] All social issues and their descendants
|
|
*/
|
|
public function getRecursiveSocialIssues(): Collection
|
|
{
|
|
$recursiveSocialIssues = new ArrayCollection();
|
|
|
|
foreach ($this->socialIssues as $socialIssue) {
|
|
foreach ($socialIssue->getDescendantsWithThis() as $descendant) {
|
|
if (!$recursiveSocialIssues->contains($descendant)) {
|
|
$recursiveSocialIssues->add($descendant);
|
|
}
|
|
}
|
|
}
|
|
|
|
return $recursiveSocialIssues;
|
|
}
|
|
|
|
public function getRemark(): string
|
|
{
|
|
return $this->remark;
|
|
}
|
|
|
|
/**
|
|
* @return Person|ThirdParty
|
|
* @Groups({"read"})
|
|
*/
|
|
public function getRequestor()
|
|
{
|
|
return $this->requestorPerson ?? $this->requestorThirdParty;
|
|
}
|
|
|
|
/**
|
|
* @return string 'person' if requestor is an instanceof @see{Person::class}, 'thirdparty' if this is an instanceof @see{ThirdParty::class}, or 'none'
|
|
*/
|
|
public function getRequestorKind(): string
|
|
{
|
|
if ($this->getRequestor() instanceof ThirdParty) {
|
|
return 'thirdparty';
|
|
}
|
|
|
|
if ($this->getRequestor() instanceof Person) {
|
|
return 'person';
|
|
}
|
|
|
|
return 'none';
|
|
}
|
|
|
|
public function getRequestorPerson(): ?Person
|
|
{
|
|
return $this->requestorPerson;
|
|
}
|
|
|
|
public function getRequestorThirdParty(): ?ThirdParty
|
|
{
|
|
return $this->requestorThirdParty;
|
|
}
|
|
|
|
public function getResources(): Collection
|
|
{
|
|
return $this->resources;
|
|
}
|
|
|
|
/**
|
|
* @return Collection|iterable
|
|
*/
|
|
public function getScopes(): Collection
|
|
{
|
|
return $this->scopes;
|
|
}
|
|
|
|
public function getSocialIssues(): Collection
|
|
{
|
|
return $this->socialIssues;
|
|
}
|
|
|
|
public function getStep(): ?string
|
|
{
|
|
return $this->step;
|
|
}
|
|
|
|
public function getStepHistories(): Collection
|
|
{
|
|
return $this->stepHistories;
|
|
}
|
|
|
|
public function getUser(): ?User
|
|
{
|
|
return $this->user;
|
|
}
|
|
|
|
/**
|
|
* @return AccompanyingPeriodWork[]
|
|
*/
|
|
public function getWorks(): Collection
|
|
{
|
|
return $this->works;
|
|
}
|
|
|
|
public function hasPreviousUser(): bool
|
|
{
|
|
return null !== $this->userPrevious;
|
|
}
|
|
|
|
public function hasUser(): bool
|
|
{
|
|
return null !== $this->user;
|
|
}
|
|
|
|
public function isChangedUser(): bool
|
|
{
|
|
return $this->userIsChanged && $this->user !== $this->userPrevious;
|
|
}
|
|
|
|
/**
|
|
* Returns true if the closing date is after the opening date.
|
|
*/
|
|
public function isClosingAfterOpening(): bool
|
|
{
|
|
if (null === $this->getClosingDate()) {
|
|
return false;
|
|
}
|
|
$diff = $this->getOpeningDate()->diff($this->getClosingDate());
|
|
|
|
if (0 === $diff->invert) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public function isConfidential(): bool
|
|
{
|
|
return $this->confidential;
|
|
}
|
|
|
|
/**
|
|
* Validation functions.
|
|
*/
|
|
public function isDateConsistent(ExecutionContextInterface $context)
|
|
{
|
|
if ($this->isOpen()) {
|
|
return;
|
|
}
|
|
|
|
if (!$this->isClosingAfterOpening()) {
|
|
$context->buildViolation('The date of closing is before the date of opening')
|
|
->atPath('dateClosing')
|
|
->addViolation();
|
|
}
|
|
}
|
|
|
|
public function isEmergency(): bool
|
|
{
|
|
return $this->emergency;
|
|
}
|
|
|
|
public function isOpen(): bool
|
|
{
|
|
if ($this->getOpeningDate() > new DateTimeImmutable('now')) {
|
|
return false;
|
|
}
|
|
|
|
if ($this->getClosingDate() === null) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public function isPreventUserIsChangedNotification(): bool
|
|
{
|
|
return $this->preventUserIsChangedNotification;
|
|
}
|
|
|
|
public function isRequestorAnonymous(): bool
|
|
{
|
|
return $this->requestorAnonymous;
|
|
}
|
|
|
|
public function removeComment(Comment $comment): void
|
|
{
|
|
$comment->setAccompanyingPeriod(null);
|
|
$this->comments->removeElement($comment);
|
|
}
|
|
|
|
public function removeLocationHistory(AccompanyingPeriodLocationHistory $history): self
|
|
{
|
|
if ($this->locationHistories->removeElement($history)) {
|
|
$history->setPeriod(null);
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Remove Participation.
|
|
*/
|
|
public function removeParticipation(AccompanyingPeriodParticipation $participation)
|
|
{
|
|
$participation->setAccompanyingPeriod(null);
|
|
}
|
|
|
|
/**
|
|
* Remove Person.
|
|
*/
|
|
public function removePerson(Person $person): self
|
|
{
|
|
$this->closeParticipationFor($person);
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function removeResource(Resource $resource): void
|
|
{
|
|
$resource->setAccompanyingPeriod(null);
|
|
$this->resources->removeElement($resource);
|
|
}
|
|
|
|
public function removeScope(Scope $scope): void
|
|
{
|
|
$this->scopes->removeElement($scope);
|
|
}
|
|
|
|
public function removeSocialIssue(SocialIssue $socialIssue): void
|
|
{
|
|
$this->socialIssues->removeElement($socialIssue);
|
|
}
|
|
|
|
public function removeWork(AccompanyingPeriodWork $work): self
|
|
{
|
|
$this->works->removeElement($work);
|
|
$work->setAccompanyingPeriod(null);
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function reOpen(): void
|
|
{
|
|
$this->setClosingDate(null);
|
|
$this->setClosingMotive(null);
|
|
$this->setStep(AccompanyingPeriod::STEP_CONFIRMED);
|
|
}
|
|
|
|
public function resetPreviousUser(): self
|
|
{
|
|
$this->userPrevious = null;
|
|
$this->userIsChanged = false;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @Groups({"write"})
|
|
*/
|
|
public function setAddressLocation(?Address $addressLocation = null): self
|
|
{
|
|
if ($this->addressLocation !== $addressLocation) {
|
|
$this->addressLocation = $addressLocation;
|
|
|
|
if (null !== $addressLocation) {
|
|
$locationHistory = new AccompanyingPeriodLocationHistory();
|
|
$locationHistory
|
|
->setStartDate(new DateTimeImmutable('now'))
|
|
->setAddressLocation($addressLocation);
|
|
|
|
$this->addLocationHistory($locationHistory);
|
|
}
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function setAdministrativeLocation(?Location $administrativeLocation): AccompanyingPeriod
|
|
{
|
|
$this->administrativeLocation = $administrativeLocation;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Set closingDate.
|
|
*
|
|
* For closing a Person file, you should use Person::setClosed instead.
|
|
*
|
|
* @param mixed $closingDate
|
|
*
|
|
* @return AccompanyingPeriod
|
|
*/
|
|
public function setClosingDate($closingDate)
|
|
{
|
|
$this->closingDate = $closingDate;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function setClosingMotive(?ClosingMotive $closingMotive = null): self
|
|
{
|
|
$this->closingMotive = $closingMotive;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function setConfidential(bool $confidential): self
|
|
{
|
|
$this->confidential = $confidential;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function setCreatedAt(DateTimeInterface $datetime): self
|
|
{
|
|
$this->createdAt = $datetime;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function setCreatedBy(User $createdBy): self
|
|
{
|
|
$this->createdBy = $createdBy;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function setEmergency(bool $emergency): self
|
|
{
|
|
$this->emergency = $emergency;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function setIntensity(string $intensity): self
|
|
{
|
|
$this->intensity = $intensity;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function setJob(?UserJob $job): self
|
|
{
|
|
$this->job = $job;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Set openingDate.
|
|
*
|
|
* @param mixed $openingDate
|
|
*
|
|
* @return AccompanyingPeriod
|
|
*/
|
|
public function setOpeningDate($openingDate)
|
|
{
|
|
if ($this->openingDate !== $openingDate) {
|
|
$this->openingDate = $openingDate;
|
|
|
|
$this->ensureStepContinuity();
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function setOrigin(Origin $origin): self
|
|
{
|
|
$this->origin = $origin;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @Groups({"write"})
|
|
*/
|
|
public function setPersonLocation(?Person $person = null): self
|
|
{
|
|
if ($this->personLocation !== $person) {
|
|
$this->personLocation = $person;
|
|
|
|
if (null !== $person) {
|
|
$locationHistory = new AccompanyingPeriodLocationHistory();
|
|
$locationHistory
|
|
->setStartDate(new DateTimeImmutable('now'))
|
|
->setPersonLocation($person);
|
|
|
|
$this->addLocationHistory($locationHistory);
|
|
}
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @Groups({"write"})
|
|
*/
|
|
public function setPinnedComment(?Comment $comment = null): self
|
|
{
|
|
if (null !== $this->pinnedComment) {
|
|
$this->addComment($this->pinnedComment);
|
|
}
|
|
|
|
$this->pinnedComment = $comment;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function setRemark(?string $remark = null): self
|
|
{
|
|
$this->remark = (string) $remark;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Set a requestor.
|
|
*
|
|
* The requestor is either an instance of ThirdParty, or an
|
|
* instance of Person
|
|
*
|
|
* @param $requestor Person|ThirdParty
|
|
* @throw UnexpectedValueException if the requestor is not a Person or ThirdParty
|
|
* @Groups({"write"})
|
|
*/
|
|
public function setRequestor($requestor): self
|
|
{
|
|
if ($requestor instanceof Person) {
|
|
$this->setRequestorThirdParty(null);
|
|
$this->setRequestorPerson($requestor);
|
|
} elseif ($requestor instanceof ThirdParty) {
|
|
$this->setRequestorThirdParty($requestor);
|
|
$this->setRequestorPerson(null);
|
|
} elseif (null === $requestor) {
|
|
$this->setRequestorPerson(null);
|
|
$this->setRequestorThirdParty(null);
|
|
} else {
|
|
throw new UnexpectedValueException('requestor is not an instance of Person or ThirdParty');
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function setRequestorAnonymous(bool $requestorAnonymous): self
|
|
{
|
|
$this->requestorAnonymous = $requestorAnonymous;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function setStep(string $step): self
|
|
{
|
|
$previous = $this->step;
|
|
|
|
$this->step = $step;
|
|
|
|
if (self::STEP_DRAFT === $previous && self::STEP_DRAFT !== $step) {
|
|
$this->bootPeriod();
|
|
}
|
|
|
|
if (self::STEP_DRAFT !== $this->step && $previous !== $step) {
|
|
// we create a new history
|
|
$history = new AccompanyingPeriodStepHistory();
|
|
$history->setStep($this->step)->setStartDate(new DateTimeImmutable('now'));
|
|
|
|
$this->addStepHistory($history);
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function setUpdatedAt(DateTimeInterface $datetime): self
|
|
{
|
|
$this->updatedAt = $datetime;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function setUpdatedBy(User $user): self
|
|
{
|
|
$this->updatedBy = $user;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function setUser(?User $user, bool $preventNotification = false): self
|
|
{
|
|
if ($this->user !== $user) {
|
|
$this->userPrevious = $this->user;
|
|
$this->userIsChanged = true;
|
|
$this->preventUserIsChangedNotification = $preventNotification;
|
|
|
|
foreach ($this->userHistories as $history) {
|
|
if (null === $history->getEndDate()) {
|
|
$history->setEndDate(new DateTimeImmutable('now'));
|
|
}
|
|
}
|
|
|
|
if (null !== $user) {
|
|
$this->userHistories->add(new UserHistory($this, $user));
|
|
}
|
|
}
|
|
|
|
$this->user = $user;
|
|
|
|
return $this;
|
|
}
|
|
|
|
private function addStepHistory(AccompanyingPeriodStepHistory $stepHistory): self
|
|
{
|
|
if (!$this->stepHistories->contains($stepHistory)) {
|
|
$this->stepHistories[] = $stepHistory;
|
|
$stepHistory->setPeriod($this);
|
|
$this->ensureStepContinuity();
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
private function bootPeriod(): void
|
|
{
|
|
// first location history
|
|
$locationHistory = new AccompanyingPeriodLocationHistory();
|
|
$locationHistory
|
|
->setStartDate(new DateTimeImmutable('now'))
|
|
->setPersonLocation($this->getPersonLocation())
|
|
->setAddressLocation($this->getAddressLocation());
|
|
$this->addLocationHistory($locationHistory);
|
|
}
|
|
|
|
private function ensureStepContinuity(): void
|
|
{
|
|
// ensure continuity of histories
|
|
$criteria = new Criteria();
|
|
$criteria->orderBy(['startDate' => Criteria::ASC, 'id' => Criteria::ASC]);
|
|
|
|
/** @var Iterator $steps */
|
|
$steps = $this->getStepHistories()->matching($criteria)->getIterator();
|
|
$steps->rewind();
|
|
|
|
// we set the start date of the first step as the opening date, only if it is
|
|
// not greater than the end date
|
|
/** @var AccompanyingPeriodStepHistory $current */
|
|
$current = $steps->current();
|
|
|
|
if (null === $current) {
|
|
return;
|
|
}
|
|
|
|
if ($this->getOpeningDate()->format('Y-m-d') !== $current->getStartDate()->format('Y-m-d')
|
|
&& ($this->getOpeningDate() <= $current->getEndDate() || null === $current->getEndDate())) {
|
|
$current->setStartDate(DateTimeImmutable::createFromMutable($this->getOpeningDate()));
|
|
}
|
|
|
|
// then we set all the end date to the start date of the next one
|
|
do {
|
|
/** @var AccompanyingPeriodStepHistory $current */
|
|
$current = $steps->current();
|
|
$steps->next();
|
|
|
|
if ($steps->valid()) {
|
|
$next = $steps->current();
|
|
$current->setEndDate($next->getStartDate());
|
|
}
|
|
} while ($steps->valid());
|
|
}
|
|
|
|
private function setRequestorPerson(?Person $requestorPerson = null): self
|
|
{
|
|
$this->requestorPerson = $requestorPerson;
|
|
|
|
return $this;
|
|
}
|
|
|
|
private function setRequestorThirdParty(?ThirdParty $requestorThirdParty = null): self
|
|
{
|
|
$this->requestorThirdParty = $requestorThirdParty;
|
|
|
|
return $this;
|
|
}
|
|
}
|