mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-08-20 22:53:49 +00:00
Merge conflicts fixed
This commit is contained in:
@@ -42,10 +42,16 @@ class Address
|
||||
*/
|
||||
private $buildingName;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="boolean")
|
||||
* @Groups({"write"})
|
||||
*/
|
||||
private bool $confidential = false;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*
|
||||
* @ORM\Column(type="string", length=16, nullable=true)
|
||||
* @ORM\Column(type="string", length=255, nullable=true)
|
||||
* @Groups({"write"})
|
||||
*/
|
||||
private $corridor;
|
||||
@@ -78,7 +84,7 @@ class Address
|
||||
/**
|
||||
* @var string|null
|
||||
*
|
||||
* @ORM\Column(type="string", length=16, nullable=true)
|
||||
* @ORM\Column(type="string", length=255, nullable=true)
|
||||
* @Groups({"write"})
|
||||
*/
|
||||
private $flat;
|
||||
@@ -86,7 +92,7 @@ class Address
|
||||
/**
|
||||
* @var string|null
|
||||
*
|
||||
* @ORM\Column(type="string", length=16, nullable=true)
|
||||
* @ORM\Column(type="string", length=255, nullable=true)
|
||||
* @Groups({"write"})
|
||||
*/
|
||||
private $floor;
|
||||
@@ -143,7 +149,7 @@ class Address
|
||||
/**
|
||||
* @var string|null
|
||||
*
|
||||
* @ORM\Column(type="string", length=16, nullable=true)
|
||||
* @ORM\Column(type="string", length=255, nullable=true)
|
||||
* @Groups({"write"})
|
||||
*/
|
||||
private $steps;
|
||||
@@ -192,6 +198,7 @@ class Address
|
||||
return (new Address())
|
||||
->setAddressReference($original->getAddressReference())
|
||||
->setBuildingName($original->getBuildingName())
|
||||
->setConfidential($original->getConfidential())
|
||||
->setCorridor($original->getCorridor())
|
||||
->setCustoms($original->getCustoms())
|
||||
->setDistribution($original->getDistribution())
|
||||
@@ -229,6 +236,11 @@ class Address
|
||||
return $this->buildingName;
|
||||
}
|
||||
|
||||
public function getConfidential(): bool
|
||||
{
|
||||
return $this->confidential;
|
||||
}
|
||||
|
||||
public function getCorridor(): ?string
|
||||
{
|
||||
return $this->corridor;
|
||||
@@ -369,6 +381,13 @@ class Address
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setConfidential(bool $confidential): self
|
||||
{
|
||||
$this->confidential = $confidential;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setCorridor(?string $corridor): self
|
||||
{
|
||||
$this->corridor = $corridor;
|
||||
|
@@ -20,10 +20,9 @@ use Doctrine\ORM\Mapping as ORM;
|
||||
class CommentEmbeddable
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
* @ORM\Column(type="text", nullable=true)
|
||||
*/
|
||||
private $comment;
|
||||
private ?string $comment = null;
|
||||
|
||||
/**
|
||||
* @var DateTime
|
||||
@@ -39,10 +38,7 @@ class CommentEmbeddable
|
||||
*/
|
||||
private $userId;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getComment()
|
||||
public function getComment(): ?string
|
||||
{
|
||||
return $this->comment;
|
||||
}
|
||||
@@ -68,9 +64,6 @@ class CommentEmbeddable
|
||||
return empty($this->getComment());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $comment
|
||||
*/
|
||||
public function setComment(?string $comment)
|
||||
{
|
||||
$this->comment = $comment;
|
||||
|
@@ -64,7 +64,7 @@ class Location implements TrackCreationInterface, TrackUpdateInterface
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=255, nullable=true)
|
||||
* @Serializer\Groups({"read", "write"})
|
||||
* @Serializer\Groups({"read", "write", "docgen:read"})
|
||||
*/
|
||||
private ?string $email = null;
|
||||
|
||||
|
@@ -67,6 +67,12 @@ class LocationType
|
||||
*/
|
||||
private ?string $defaultFor = null;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="boolean")
|
||||
* @Serializer\Groups({"read"})
|
||||
*/
|
||||
private bool $editableByUsers = true;
|
||||
|
||||
/**
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue
|
||||
@@ -107,6 +113,11 @@ class LocationType
|
||||
return $this->defaultFor;
|
||||
}
|
||||
|
||||
public function getEditableByUsers(): ?bool
|
||||
{
|
||||
return $this->editableByUsers;
|
||||
}
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
@@ -152,6 +163,13 @@ class LocationType
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setEditableByUsers(bool $editableByUsers): self
|
||||
{
|
||||
$this->editableByUsers = $editableByUsers;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setTitle(array $title): self
|
||||
{
|
||||
$this->title = $title;
|
||||
|
@@ -17,11 +17,15 @@ use DateTimeInterface;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
||||
/**
|
||||
* @ORM\Entity
|
||||
* @ORM\Table(
|
||||
* name="chill_main_notification",
|
||||
* indexes={
|
||||
* @ORM\Index(name="chill_main_notification_related_entity_idx", columns={"relatedentityclass", "relatedentityid"})
|
||||
* }
|
||||
* )
|
||||
* @ORM\HasLifecycleCallbacks
|
||||
*/
|
||||
@@ -32,6 +36,7 @@ class Notification implements TrackUpdateInterface
|
||||
/**
|
||||
* @ORM\ManyToMany(targetEntity=User::class)
|
||||
* @ORM\JoinTable(name="chill_main_notification_addresses_user")
|
||||
* @Assert\Count(min="1", minMessage="notification.At least one addressee")
|
||||
*/
|
||||
private Collection $addressees;
|
||||
|
||||
@@ -80,6 +85,7 @@ class Notification implements TrackUpdateInterface
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="text", options={"default": ""})
|
||||
* @Assert\NotBlank(message="notification.Title must be defined")
|
||||
*/
|
||||
private string $title = '';
|
||||
|
||||
@@ -286,9 +292,9 @@ class Notification implements TrackUpdateInterface
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setMessage(string $message): self
|
||||
public function setMessage(?string $message): self
|
||||
{
|
||||
$this->message = $message;
|
||||
$this->message = (string) $message;
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -314,9 +320,9 @@ class Notification implements TrackUpdateInterface
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setTitle(string $title): Notification
|
||||
public function setTitle(?string $title): Notification
|
||||
{
|
||||
$this->title = $title;
|
||||
$this->title = (string) $title;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
166
src/Bundle/ChillMainBundle/Entity/ResidentialAddress.php
Normal file
166
src/Bundle/ChillMainBundle/Entity/ResidentialAddress.php
Normal file
@@ -0,0 +1,166 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\MainBundle\Entity;
|
||||
|
||||
use Chill\MainBundle\Entity\Embeddable\CommentEmbeddable;
|
||||
use Chill\MainBundle\Repository\ResidentialAddressRepository;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
||||
use DateTimeImmutable;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* @ORM\Entity(repositoryClass=ResidentialAddressRepository::class)
|
||||
* @ORM\Table(name="chill_main_residential_address")
|
||||
*/
|
||||
class ResidentialAddress
|
||||
{
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity=Address::class)
|
||||
* @ORM\JoinColumn(nullable=true)
|
||||
*/
|
||||
private ?Address $address = null;
|
||||
|
||||
/**
|
||||
* @ORM\Embedded(class="Chill\MainBundle\Entity\Embeddable\CommentEmbeddable", columnPrefix="residentialAddressComment_")
|
||||
*/
|
||||
private CommentEmbeddable $comment;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="datetime_immutable", nullable=true)
|
||||
*/
|
||||
private ?DateTimeImmutable $endDate = null;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity=Person::class)
|
||||
* @ORM\JoinColumn(nullable=true)
|
||||
*/
|
||||
private ?Person $hostPerson = null;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity=ThirdParty::class)
|
||||
* @ORM\JoinColumn(nullable=true)
|
||||
*/
|
||||
private ?ThirdParty $hostThirdParty = null;
|
||||
|
||||
/**
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue
|
||||
* @ORM\Column(type="integer")
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity=Person::class)
|
||||
* @ORM\JoinColumn(nullable=false)
|
||||
*/
|
||||
private Person $person;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="datetime_immutable")
|
||||
*/
|
||||
private ?DateTimeImmutable $startDate = null;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->comment = new CommentEmbeddable();
|
||||
}
|
||||
|
||||
public function getAddress(): ?Address
|
||||
{
|
||||
return $this->address;
|
||||
}
|
||||
|
||||
public function getComment(): CommentEmbeddable
|
||||
{
|
||||
return $this->comment;
|
||||
}
|
||||
|
||||
public function getEndDate(): ?DateTimeImmutable
|
||||
{
|
||||
return $this->endDate;
|
||||
}
|
||||
|
||||
public function getHostPerson(): ?Person
|
||||
{
|
||||
return $this->hostPerson;
|
||||
}
|
||||
|
||||
public function getHostThirdParty(): ?ThirdParty
|
||||
{
|
||||
return $this->hostThirdParty;
|
||||
}
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getPerson(): ?Person
|
||||
{
|
||||
return $this->person;
|
||||
}
|
||||
|
||||
public function getStartDate(): ?DateTimeImmutable
|
||||
{
|
||||
return $this->startDate;
|
||||
}
|
||||
|
||||
public function setAddress(?Address $address): self
|
||||
{
|
||||
$this->address = $address;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setComment(CommentEmbeddable $comment): self
|
||||
{
|
||||
$this->comment = $comment;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setEndDate(?DateTimeImmutable $endDate): self
|
||||
{
|
||||
$this->endDate = $endDate;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setHostPerson(?Person $hostPerson): self
|
||||
{
|
||||
$this->hostPerson = $hostPerson;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setHostThirdParty(?ThirdParty $hostThirdParty): self
|
||||
{
|
||||
$this->hostThirdParty = $hostThirdParty;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setPerson(?Person $person): self
|
||||
{
|
||||
$this->person = $person;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setStartDate(DateTimeImmutable $startDate): self
|
||||
{
|
||||
$this->startDate = $startDate;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@@ -97,6 +97,11 @@ class User implements AdvancedUserInterface
|
||||
*/
|
||||
private ?Center $mainCenter = null;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity=Location::class)
|
||||
*/
|
||||
private ?Location $mainLocation = null;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity=Scope::class)
|
||||
*/
|
||||
@@ -228,6 +233,11 @@ class User implements AdvancedUserInterface
|
||||
return $this->mainCenter;
|
||||
}
|
||||
|
||||
public function getMainLocation(): ?Location
|
||||
{
|
||||
return $this->mainLocation;
|
||||
}
|
||||
|
||||
public function getMainScope(): ?Scope
|
||||
{
|
||||
return $this->mainScope;
|
||||
@@ -405,6 +415,13 @@ class User implements AdvancedUserInterface
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setMainLocation(?Location $mainLocation): User
|
||||
{
|
||||
$this->mainLocation = $mainLocation;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setMainScope(?Scope $mainScope): User
|
||||
{
|
||||
$this->mainScope = $mainScope;
|
||||
|
461
src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflow.php
Normal file
461
src/Bundle/ChillMainBundle/Entity/Workflow/EntityWorkflow.php
Normal file
@@ -0,0 +1,461 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\MainBundle\Entity\Workflow;
|
||||
|
||||
use Chill\MainBundle\Doctrine\Model\TrackCreationInterface;
|
||||
use Chill\MainBundle\Doctrine\Model\TrackCreationTrait;
|
||||
use Chill\MainBundle\Doctrine\Model\TrackUpdateInterface;
|
||||
use Chill\MainBundle\Doctrine\Model\TrackUpdateTrait;
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\MainBundle\Workflow\Validator\EntityWorkflowCreation;
|
||||
use DateTimeInterface;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Iterator;
|
||||
use RuntimeException;
|
||||
use Symfony\Component\Serializer\Annotation as Serializer;
|
||||
use function count;
|
||||
use function is_array;
|
||||
|
||||
/**
|
||||
* @ORM\Entity
|
||||
* @ORM\Table("chill_main_workflow_entity")
|
||||
* @EntityWorkflowCreation(groups={"creation"})
|
||||
* @Serializer\DiscriminatorMap(typeProperty="type", mapping={
|
||||
* "entity_workflow": EntityWorkflow::class
|
||||
* })
|
||||
*/
|
||||
class EntityWorkflow implements TrackCreationInterface, TrackUpdateInterface
|
||||
{
|
||||
use TrackCreationTrait;
|
||||
|
||||
use TrackUpdateTrait;
|
||||
|
||||
/**
|
||||
* @ORM\OneToMany(targetEntity=EntityWorkflowComment::class, mappedBy="entityWorkflow", orphanRemoval=true)
|
||||
*
|
||||
* @var Collection|EntityWorkflowComment[]
|
||||
*/
|
||||
private Collection $comments;
|
||||
|
||||
/**
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue
|
||||
* @ORM\Column(type="integer")
|
||||
*/
|
||||
private ?int $id = null;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=255)
|
||||
*/
|
||||
private string $relatedEntityClass = '';
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="integer")
|
||||
*/
|
||||
private int $relatedEntityId;
|
||||
|
||||
/**
|
||||
* @ORM\OneToMany(targetEntity=EntityWorkflowStep::class, mappedBy="entityWorkflow", orphanRemoval=true, cascade={"persist"})
|
||||
* @ORM\OrderBy({"transitionAt": "ASC", "id": "ASC"})
|
||||
*
|
||||
* @var Collection|EntityWorkflowStep[]
|
||||
*/
|
||||
private Collection $steps;
|
||||
|
||||
/**
|
||||
* @var null|array|EntityWorkflowStep[]
|
||||
*/
|
||||
private ?array $stepsChainedCache = null;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToMany(targetEntity=User::class)
|
||||
* @ORM\JoinTable(name="chill_main_workflow_entity_subscriber_to_final")
|
||||
*
|
||||
* @var Collection|User[]
|
||||
*/
|
||||
private Collection $subscriberToFinal;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToMany(targetEntity=User::class)
|
||||
* @ORM\JoinTable(name="chill_main_workflow_entity_subscriber_to_step")
|
||||
*
|
||||
* @var Collection|User[]
|
||||
*/
|
||||
private Collection $subscriberToStep;
|
||||
|
||||
/**
|
||||
* a step which will store all the transition data.
|
||||
*/
|
||||
private ?EntityWorkflowStep $transitionningStep = null;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="text")
|
||||
*/
|
||||
private string $workflowName;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->subscriberToFinal = new ArrayCollection();
|
||||
$this->subscriberToStep = new ArrayCollection();
|
||||
$this->comments = new ArrayCollection();
|
||||
$this->steps = new ArrayCollection();
|
||||
|
||||
$initialStep = new EntityWorkflowStep();
|
||||
$initialStep
|
||||
->setCurrentStep('initial');
|
||||
$this->addStep($initialStep);
|
||||
}
|
||||
|
||||
public function addComment(EntityWorkflowComment $comment): self
|
||||
{
|
||||
if (!$this->comments->contains($comment)) {
|
||||
$this->comments[] = $comment;
|
||||
$comment->setEntityWorkflow($this);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal You should prepare a step and run a workflow transition instead of manually adding a step
|
||||
*/
|
||||
public function addStep(EntityWorkflowStep $step): self
|
||||
{
|
||||
if (!$this->steps->contains($step)) {
|
||||
$this->steps[] = $step;
|
||||
$step->setEntityWorkflow($this);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addSubscriberToFinal(User $user): self
|
||||
{
|
||||
if (!$this->subscriberToFinal->contains($user)) {
|
||||
$this->subscriberToFinal[] = $user;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addSubscriberToStep(User $user): self
|
||||
{
|
||||
if (!$this->subscriberToStep->contains($user)) {
|
||||
$this->subscriberToStep[] = $user;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getComments(): Collection
|
||||
{
|
||||
return $this->comments;
|
||||
}
|
||||
|
||||
public function getCurrentStep(): ?EntityWorkflowStep
|
||||
{
|
||||
$step = $this->steps->last();
|
||||
|
||||
if (false !== $step) {
|
||||
return $step;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getCurrentStepChained(): ?EntityWorkflowStep
|
||||
{
|
||||
$steps = $this->getStepsChained();
|
||||
$currentStep = $this->getCurrentStep();
|
||||
|
||||
foreach ($steps as $step) {
|
||||
if ($step === $currentStep) {
|
||||
return $step;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getCurrentStepCreatedAt(): ?DateTimeInterface
|
||||
{
|
||||
if (null !== $previous = $this->getPreviousStepIfAny()) {
|
||||
return $previous->getTransitionAt();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getCurrentStepCreatedBy(): ?User
|
||||
{
|
||||
if (null !== $previous = $this->getPreviousStepIfAny()) {
|
||||
return $previous->getTransitionBy();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getRelatedEntityClass(): string
|
||||
{
|
||||
return $this->relatedEntityClass;
|
||||
}
|
||||
|
||||
public function getRelatedEntityId(): int
|
||||
{
|
||||
return $this->relatedEntityId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used by MarkingStore.
|
||||
*
|
||||
* get a string representation of the step
|
||||
*/
|
||||
public function getStep(): string
|
||||
{
|
||||
return $this->getCurrentStep()->getCurrentStep();
|
||||
}
|
||||
|
||||
public function getStepAfter(EntityWorkflowStep $step): ?EntityWorkflowStep
|
||||
{
|
||||
$iterator = $this->steps->getIterator();
|
||||
|
||||
if ($iterator instanceof Iterator) {
|
||||
$iterator->rewind();
|
||||
|
||||
while ($iterator->valid()) {
|
||||
$curStep = $iterator->current();
|
||||
|
||||
if ($curStep === $step) {
|
||||
$iterator->next();
|
||||
|
||||
if ($iterator->valid()) {
|
||||
return $iterator->current();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
$iterator->next();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ArrayCollection|Collection
|
||||
*/
|
||||
public function getSteps()
|
||||
{
|
||||
return $this->steps;
|
||||
}
|
||||
|
||||
public function getStepsChained(): array
|
||||
{
|
||||
if (is_array($this->stepsChainedCache)) {
|
||||
return $this->stepsChainedCache;
|
||||
}
|
||||
|
||||
$iterator = $this->steps->getIterator();
|
||||
$current = null;
|
||||
$steps = [];
|
||||
|
||||
$iterator->rewind();
|
||||
|
||||
do {
|
||||
$previous = $current;
|
||||
$current = $iterator->current();
|
||||
$steps[] = $current;
|
||||
|
||||
$current->setPrevious($previous);
|
||||
|
||||
$iterator->next();
|
||||
|
||||
if ($iterator->valid()) {
|
||||
$current->setNext($iterator->current());
|
||||
} else {
|
||||
$current->setNext(null);
|
||||
}
|
||||
} while ($iterator->valid());
|
||||
|
||||
$this->stepsChainedCache = $steps;
|
||||
|
||||
return $steps;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ArrayCollection|Collection
|
||||
*/
|
||||
public function getSubscriberToFinal()
|
||||
{
|
||||
return $this->subscriberToFinal;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ArrayCollection|Collection
|
||||
*/
|
||||
public function getSubscriberToStep()
|
||||
{
|
||||
return $this->subscriberToStep;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the step which is transitionning. Should be called only by event which will
|
||||
* concern the transition.
|
||||
*/
|
||||
public function getTransitionningStep(): ?EntityWorkflowStep
|
||||
{
|
||||
return $this->transitionningStep;
|
||||
}
|
||||
|
||||
public function getWorkflowName(): string
|
||||
{
|
||||
return $this->workflowName;
|
||||
}
|
||||
|
||||
public function isFinal(): bool
|
||||
{
|
||||
$steps = $this->getStepsChained();
|
||||
|
||||
if (1 === count($steps)) {
|
||||
// the initial step cannot be finalized
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @var EntityWorkflowStep $last */
|
||||
$last = end($steps);
|
||||
|
||||
return $last->isFinal();
|
||||
}
|
||||
|
||||
public function isFreeze(): bool
|
||||
{
|
||||
$steps = $this->getStepsChained();
|
||||
|
||||
if (1 === count($steps)) {
|
||||
// the initial step cannot be finalized
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @var EntityWorkflowStep $last */
|
||||
$last = end($steps);
|
||||
|
||||
return $last->getPrevious()->isFreezeAfter();
|
||||
}
|
||||
|
||||
public function isUserSubscribedToFinal(User $user): bool
|
||||
{
|
||||
return $this->subscriberToFinal->contains($user);
|
||||
}
|
||||
|
||||
public function isUserSubscribedToStep(User $user): bool
|
||||
{
|
||||
return $this->subscriberToStep->contains($user);
|
||||
}
|
||||
|
||||
public function prepareStepBeforeTransition(EntityWorkflowStep $step): self
|
||||
{
|
||||
$this->transitionningStep = $step;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function removeComment(EntityWorkflowComment $comment): self
|
||||
{
|
||||
if ($this->comments->removeElement($comment)) {
|
||||
$comment->setEntityWorkflow(null);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function removeStep(EntityWorkflowStep $step): self
|
||||
{
|
||||
if ($this->steps->removeElement($step)) {
|
||||
$step->setEntityWorkflow(null);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function removeSubscriberToFinal(User $user): self
|
||||
{
|
||||
$this->subscriberToFinal->removeElement($user);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function removeSubscriberToStep(User $user): self
|
||||
{
|
||||
$this->subscriberToStep->removeElement($user);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setRelatedEntityClass(string $relatedEntityClass): EntityWorkflow
|
||||
{
|
||||
$this->relatedEntityClass = $relatedEntityClass;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setRelatedEntityId(int $relatedEntityId): EntityWorkflow
|
||||
{
|
||||
$this->relatedEntityId = $relatedEntityId;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method use by marking store.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setStep(string $step): self
|
||||
{
|
||||
$newStep = new EntityWorkflowStep();
|
||||
$newStep->setCurrentStep($step);
|
||||
|
||||
// copy the freeze
|
||||
if ($this->getCurrentStep()->isFreezeAfter()) {
|
||||
$newStep->setFreezeAfter(true);
|
||||
}
|
||||
|
||||
$this->addStep($newStep);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setWorkflowName(string $workflowName): EntityWorkflow
|
||||
{
|
||||
$this->workflowName = $workflowName;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
private function getPreviousStepIfAny(): ?EntityWorkflowStep
|
||||
{
|
||||
if (1 === count($this->steps)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->steps->get($this->steps->count() - 2);
|
||||
}
|
||||
}
|
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\MainBundle\Entity\Workflow;
|
||||
|
||||
use Chill\MainBundle\Doctrine\Model\TrackCreationInterface;
|
||||
use Chill\MainBundle\Doctrine\Model\TrackCreationTrait;
|
||||
use Chill\MainBundle\Doctrine\Model\TrackUpdateInterface;
|
||||
use Chill\MainBundle\Doctrine\Model\TrackUpdateTrait;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* @ORM\Entity
|
||||
* @ORM\Table("chill_main_workflow_entity_comment")
|
||||
*/
|
||||
class EntityWorkflowComment implements TrackCreationInterface, TrackUpdateInterface
|
||||
{
|
||||
use TrackCreationTrait;
|
||||
|
||||
use TrackUpdateTrait;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="text", options={"default": ""})
|
||||
*/
|
||||
private string $comment = '';
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity=EntityWorkflow::class, inversedBy="comments")
|
||||
*/
|
||||
private ?EntityWorkflow $entityWorkflow = null;
|
||||
|
||||
/**
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue
|
||||
* @ORM\Column(type="integer")
|
||||
*/
|
||||
private ?int $id = null;
|
||||
|
||||
public function getComment(): string
|
||||
{
|
||||
return $this->comment;
|
||||
}
|
||||
|
||||
public function getEntityWorkflow(): ?EntityWorkflow
|
||||
{
|
||||
return $this->entityWorkflow;
|
||||
}
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function setComment(string $comment): self
|
||||
{
|
||||
$this->comment = $comment;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal use @see{EntityWorkflow::addComment}
|
||||
*/
|
||||
public function setEntityWorkflow(?EntityWorkflow $entityWorkflow): self
|
||||
{
|
||||
$this->entityWorkflow = $entityWorkflow;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@@ -0,0 +1,336 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\MainBundle\Entity\Workflow;
|
||||
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use DateTimeImmutable;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||
use function count;
|
||||
use function in_array;
|
||||
|
||||
/**
|
||||
* @ORM\Entity
|
||||
* @ORM\Table("chill_main_workflow_entity_step")
|
||||
*/
|
||||
class EntityWorkflowStep
|
||||
{
|
||||
/**
|
||||
* @ORM\Column(type="text", options={"default": ""})
|
||||
*/
|
||||
private string $comment = '';
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="text")
|
||||
*/
|
||||
private ?string $currentStep = '';
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="json")
|
||||
*/
|
||||
private array $destEmail = [];
|
||||
|
||||
/**
|
||||
* @ORM\ManyToMany(targetEntity=User::class)
|
||||
* @ORM\JoinTable(name="chill_main_workflow_entity_step_user")
|
||||
*/
|
||||
private Collection $destUser;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity=EntityWorkflow::class, inversedBy="steps")
|
||||
*/
|
||||
private ?EntityWorkflow $entityWorkflow = null;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="boolean", options={"default": false})
|
||||
*/
|
||||
private bool $freezeAfter = false;
|
||||
|
||||
/**
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue
|
||||
* @ORM\Column(type="integer")
|
||||
*/
|
||||
private ?int $id = null;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="boolean", options={"default": false})
|
||||
*/
|
||||
private bool $isFinal = false;
|
||||
|
||||
/**
|
||||
* filled by @see{EntityWorkflow::getStepsChained}.
|
||||
*/
|
||||
private ?EntityWorkflowStep $next = null;
|
||||
|
||||
/**
|
||||
* filled by @see{EntityWorkflow::getStepsChained}.
|
||||
*/
|
||||
private ?EntityWorkflowStep $previous = null;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="text", nullable=true, options={"default": null})
|
||||
*/
|
||||
private ?string $transitionAfter = null;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="datetime_immutable")
|
||||
*/
|
||||
private ?DateTimeImmutable $transitionAt = null;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity=User::class)
|
||||
* @ORM\JoinColumn(nullable=true)
|
||||
*/
|
||||
private ?User $transitionBy = null;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="text", nullable=true)
|
||||
*/
|
||||
private ?string $transitionByEmail = null;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->destUser = new ArrayCollection();
|
||||
}
|
||||
|
||||
public function addDestEmail(string $email): self
|
||||
{
|
||||
if (!in_array($email, $this->destEmail, true)) {
|
||||
$this->destEmail[] = $email;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addDestUser(User $user): self
|
||||
{
|
||||
if (!$this->destUser->contains($user)) {
|
||||
$this->destUser[] = $user;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getComment(): string
|
||||
{
|
||||
return $this->comment;
|
||||
}
|
||||
|
||||
public function getCurrentStep(): ?string
|
||||
{
|
||||
return $this->currentStep;
|
||||
}
|
||||
|
||||
public function getDestEmail(): array
|
||||
{
|
||||
return $this->destEmail;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ArrayCollection|Collection
|
||||
*/
|
||||
public function getDestUser()
|
||||
{
|
||||
return $this->destUser;
|
||||
}
|
||||
|
||||
public function getEntityWorkflow(): ?EntityWorkflow
|
||||
{
|
||||
return $this->entityWorkflow;
|
||||
}
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getNext(): ?EntityWorkflowStep
|
||||
{
|
||||
return $this->next;
|
||||
}
|
||||
|
||||
public function getPrevious(): ?EntityWorkflowStep
|
||||
{
|
||||
return $this->previous;
|
||||
}
|
||||
|
||||
public function getTransitionAfter(): ?string
|
||||
{
|
||||
return $this->transitionAfter;
|
||||
}
|
||||
|
||||
public function getTransitionAt(): ?DateTimeImmutable
|
||||
{
|
||||
return $this->transitionAt;
|
||||
}
|
||||
|
||||
public function getTransitionBy(): ?User
|
||||
{
|
||||
return $this->transitionBy;
|
||||
}
|
||||
|
||||
public function getTransitionByEmail(): ?string
|
||||
{
|
||||
return $this->transitionByEmail;
|
||||
}
|
||||
|
||||
public function isFinal(): bool
|
||||
{
|
||||
return $this->isFinal;
|
||||
}
|
||||
|
||||
public function isFreezeAfter(): bool
|
||||
{
|
||||
return $this->freezeAfter;
|
||||
}
|
||||
|
||||
public function removeDestEmail(string $email): self
|
||||
{
|
||||
$this->destEmail = array_filter($this->destEmail, static function (string $existing) use ($email) {
|
||||
return $email !== $existing;
|
||||
});
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function removeDestUser(User $user): self
|
||||
{
|
||||
$this->destUser->removeElement($user);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setComment(?string $comment): EntityWorkflowStep
|
||||
{
|
||||
$this->comment = (string) $comment;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setCurrentStep(?string $currentStep): EntityWorkflowStep
|
||||
{
|
||||
$this->currentStep = $currentStep;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setDestEmail(array $destEmail): EntityWorkflowStep
|
||||
{
|
||||
$this->destEmail = $destEmail;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal use @see(EntityWorkflow::addStep} instead
|
||||
*/
|
||||
public function setEntityWorkflow(?EntityWorkflow $entityWorkflow): EntityWorkflowStep
|
||||
{
|
||||
$this->entityWorkflow = $entityWorkflow;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setFreezeAfter(bool $freezeAfter): EntityWorkflowStep
|
||||
{
|
||||
$this->freezeAfter = $freezeAfter;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setIsFinal(bool $isFinal): EntityWorkflowStep
|
||||
{
|
||||
$this->isFinal = $isFinal;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return EntityWorkflowStep
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public function setNext(?EntityWorkflowStep $next): self
|
||||
{
|
||||
$this->next = $next;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return EntityWorkflowStep
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public function setPrevious(?EntityWorkflowStep $previous): self
|
||||
{
|
||||
$this->previous = $previous;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setTransitionAfter(?string $transitionAfter): EntityWorkflowStep
|
||||
{
|
||||
$this->transitionAfter = $transitionAfter;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setTransitionAt(?DateTimeImmutable $transitionAt): EntityWorkflowStep
|
||||
{
|
||||
$this->transitionAt = $transitionAt;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setTransitionBy(?User $transitionBy): EntityWorkflowStep
|
||||
{
|
||||
$this->transitionBy = $transitionBy;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setTransitionByEmail(?string $transitionByEmail): EntityWorkflowStep
|
||||
{
|
||||
$this->transitionByEmail = $transitionByEmail;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Assert\Callback
|
||||
*
|
||||
* @param mixed $payload
|
||||
*/
|
||||
public function validateOnCreation(ExecutionContextInterface $context, $payload): void
|
||||
{
|
||||
return;
|
||||
|
||||
if ($this->isFinalizeAfter()) {
|
||||
if (0 !== count($this->getDestUser())) {
|
||||
$context->buildViolation('workflow.No dest users when the workflow is finalized')
|
||||
->atPath('finalizeAfter')
|
||||
->addViolation();
|
||||
}
|
||||
} else {
|
||||
if (0 === count($this->getDestUser())) {
|
||||
$context->buildViolation('workflow.The next step must count at least one dest')
|
||||
->atPath('finalizeAfter')
|
||||
->addViolation();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user