Add attachments to workflow

This commit is contained in:
2025-02-03 21:15:00 +00:00
parent 9e191f1b5b
commit 37227a3aeb
106 changed files with 3455 additions and 619 deletions

View File

@@ -87,12 +87,19 @@ class EntityWorkflow implements TrackCreationInterface, TrackUpdateInterface
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::TEXT)]
private string $workflowName;
/**
* @var Collection<int, EntityWorkflowAttachment>
*/
#[ORM\OneToMany(mappedBy: 'entityWorkflow', targetEntity: EntityWorkflowAttachment::class, cascade: ['remove'], orphanRemoval: true)]
private Collection $attachments;
public function __construct()
{
$this->subscriberToFinal = new ArrayCollection();
$this->subscriberToStep = new ArrayCollection();
$this->comments = new ArrayCollection();
$this->steps = new ArrayCollection();
$this->attachments = new ArrayCollection();
$initialStep = new EntityWorkflowStep();
$initialStep
@@ -142,6 +149,35 @@ class EntityWorkflow implements TrackCreationInterface, TrackUpdateInterface
return $this;
}
/**
* @return $this
*
* @internal use @{EntityWorkflowAttachement::__construct} instead
*/
public function addAttachment(EntityWorkflowAttachment $attachment): self
{
if (!$this->attachments->contains($attachment)) {
$this->attachments[] = $attachment;
}
return $this;
}
/**
* @return Collection<int, EntityWorkflowAttachment>
*/
public function getAttachments(): Collection
{
return $this->attachments;
}
public function removeAttachment(EntityWorkflowAttachment $attachment): self
{
$this->attachments->removeElement($attachment);
return $this;
}
public function getComments(): Collection
{
return $this->comments;
@@ -356,6 +392,17 @@ class EntityWorkflow implements TrackCreationInterface, TrackUpdateInterface
return $this->getCurrentStep()->isOnHoldByUser($user);
}
public function isUserInvolved(User $user): bool
{
foreach ($this->getSteps() as $step) {
if ($step->getAllDestUser()->contains($user)) {
return true;
}
}
return false;
}
public function isUserSubscribedToFinal(User $user): bool
{
return $this->subscriberToFinal->contains($user);
@@ -420,7 +467,7 @@ class EntityWorkflow implements TrackCreationInterface, TrackUpdateInterface
}
/**
* Method use by marking store.
* Method used by marking store.
*
* @return $this
*/

View File

@@ -0,0 +1,80 @@
<?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\MainBundle\Entity\Workflow;
use Chill\DocStoreBundle\Entity\StoredObject;
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\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity()]
#[ORM\Table(name: 'chill_main_workflow_entity_attachment')]
#[ORM\UniqueConstraint(name: 'unique_generic_doc_by_workflow', columns: ['relatedGenericDocKey', 'relatedGenericDocIdentifiers', 'entityworkflow_id'])]
class EntityWorkflowAttachment implements TrackCreationInterface, TrackUpdateInterface
{
use TrackCreationTrait;
use TrackUpdateTrait;
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: Types::INTEGER)]
private ?int $id = null;
public function __construct(
#[ORM\Column(name: 'relatedGenericDocKey', type: Types::STRING, length: 255, nullable: false)]
private string $relatedGenericDocKey,
#[ORM\Column(name: 'relatedGenericDocIdentifiers', type: Types::JSON, nullable: false, options: ['jsonb' => true])]
private array $relatedGenericDocIdentifiers,
#[ORM\ManyToOne(targetEntity: EntityWorkflow::class, inversedBy: 'attachments')]
#[ORM\JoinColumn(nullable: false, name: 'entityworkflow_id')]
private EntityWorkflow $entityWorkflow,
/**
* Stored object related to the generic doc.
*
* This is a story to keep track more easily to stored object
*/
#[ORM\ManyToOne(targetEntity: StoredObject::class)]
#[ORM\JoinColumn(nullable: false, name: 'storedobject_id')]
private StoredObject $proxyStoredObject,
) {
$this->entityWorkflow->addAttachment($this);
}
public function getId(): ?int
{
return $this->id;
}
public function getEntityWorkflow(): EntityWorkflow
{
return $this->entityWorkflow;
}
public function getRelatedGenericDocIdentifiers(): array
{
return $this->relatedGenericDocIdentifiers;
}
public function getRelatedGenericDocKey(): string
{
return $this->relatedGenericDocKey;
}
public function getProxyStoredObject(): StoredObject
{
return $this->proxyStoredObject;
}
}

View File

@@ -17,6 +17,11 @@ use Chill\MainBundle\Doctrine\Model\TrackUpdateInterface;
use Chill\MainBundle\Doctrine\Model\TrackUpdateTrait;
use Doctrine\ORM\Mapping as ORM;
/**
* Contains comment for entity workflow.
*
* **NOTE**: for now, this class is not in used. Comments are, for now, stored in the EntityWorkflowStep.
*/
#[ORM\Entity]
#[ORM\Table('chill_main_workflow_entity_comment')]
class EntityWorkflowComment implements TrackCreationInterface, TrackUpdateInterface

View File

@@ -16,9 +16,18 @@ use Chill\MainBundle\Entity\UserGroup;
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;
/**
* A step for each EntityWorkflow.
*
* The step contains the history of position. The current one is the one which transitionAt or transitionAfter is NULL.
*
* The comments field is populated by the comment of the one who apply the transition, it means that the comment for the
* "next" step is stored in the EntityWorkflowStep in the previous step.
*
* DestUsers are the one added at the transition. DestUserByAccessKey are the users who obtained permission after having
* clicked on a link to get access (email notification to groups).
*/
#[ORM\Entity]
#[ORM\Table('chill_main_workflow_entity_step')]
class EntityWorkflowStep
@@ -80,6 +89,11 @@ class EntityWorkflowStep
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::INTEGER)]
private ?int $id = null;
/**
* If this is the final step.
*
* This property is filled by a listener.
*/
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::BOOLEAN, options: ['default' => false])]
private bool $isFinal = false;
@@ -254,6 +268,11 @@ class EntityWorkflowStep
return $this->ccUser;
}
/**
* This is the comment from the one who apply the transition.
*
* It means that it must be saved when the user apply a transition.
*/
public function getComment(): string
{
return $this->comment;
@@ -346,6 +365,9 @@ class EntityWorkflowStep
return $this->transitionByEmail;
}
/**
* @return bool true if this is the end of the EntityWorkflow
*/
public function isFinal(): bool
{
return $this->isFinal;
@@ -367,6 +389,9 @@ class EntityWorkflowStep
return false;
}
/**
* @return bool if the EntityWorkflowStep is waiting for a transition, and is not the final step
*/
public function isWaitingForTransition(): bool
{
if (null !== $this->transitionAfter) {
@@ -506,26 +531,6 @@ class EntityWorkflowStep
return $this->holdsOnStep;
}
#[Assert\Callback]
public function validateOnCreation(ExecutionContextInterface $context, mixed $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();
}
}
}
public function addOnHold(EntityWorkflowStepHold $onHold): self
{
if (!$this->holdsOnStep->contains($onHold)) {

View File

@@ -53,6 +53,7 @@ class EntityWorkflowStepSignature implements TrackCreationInterface, TrackUpdate
public function __construct(
#[ORM\ManyToOne(targetEntity: EntityWorkflowStep::class, inversedBy: 'signatures')]
#[ORM\JoinColumn(nullable: false)]
private EntityWorkflowStep $step,
User|Person $signer,
) {