setState(EntityWorkflowSignatureStateEnum::SIGNED) ->setZoneSignatureIndex($atIndex) ->setStateDate($this->clock->now()); $this->logger->info(self::LOG_PREFIX.'Mark signature entity as signed', ['signatureId' => $signature->getId(), 'index' => (string) $atIndex]); $this->messageBus->dispatch(new PostSignatureStateChangeMessage((int) $signature->getId())); } public function markSignatureAsCanceled(EntityWorkflowStepSignature $signature): void { $signature ->setState(EntityWorkflowSignatureStateEnum::CANCELED) ->setStateDate($this->clock->now()); $this->logger->info(self::LOG_PREFIX.'Mark signature entity as canceled', ['signatureId' => $signature->getId()]); $this->messageBus->dispatch(new PostSignatureStateChangeMessage((int) $signature->getId())); } public function markSignatureAsRejected(EntityWorkflowStepSignature $signature): void { $signature ->setState(EntityWorkflowSignatureStateEnum::REJECTED) ->setStateDate($this->clock->now()); $this->logger->info(self::LOG_PREFIX.'Mark signature entity as rejected', ['signatureId' => $signature->getId()]); $this->messageBus->dispatch(new PostSignatureStateChangeMessage((int) $signature->getId())); } /** * Executed after a signature has a new state. * * This should be executed only by a system user (without any user registered) */ public function onPostMark(EntityWorkflowStepSignature $signature): void { if (!EntityWorkflowStepSignature::isAllSignatureNotPendingForStep($signature->getStep())) { $this->logger->info(self::LOG_PREFIX.'This is not the last signature, skipping transition to another place', ['signatureId' => $signature->getId()]); return; } $this->logger->debug(self::LOG_PREFIX.'Continuing the process to find a transition', ['signatureId' => $signature->getId()]); $entityWorkflow = $signature->getStep()->getEntityWorkflow(); $workflow = $this->registry->get($entityWorkflow, $entityWorkflow->getWorkflowName()); $metadataStore = $workflow->getMetadataStore(); // find a transition $marking = $workflow->getMarking($entityWorkflow); $places = $marking->getPlaces(); $transition = null; foreach ($places as $place => $int) { $metadata = $metadataStore->getPlaceMetadata($place); if (array_key_exists('onSignatureCompleted', $metadata)) { $transition = $metadata['onSignatureCompleted']['transitionName']; } } if (null === $transition) { $this->logger->info(self::LOG_PREFIX.'The transition is not configured, will not apply a transition', ['signatureId' => $signature->getId()]); return; } $previousUser = $this->getPreviousSender($signature->getStep()); if (null === $previousUser) { $this->logger->info(self::LOG_PREFIX.'No previous user, will not apply a transition', ['signatureId' => $signature->getId()]); return; } $transitionDto = new WorkflowTransitionContextDTO($entityWorkflow); $transitionDto->futureDestUsers[] = $previousUser; $workflow->apply($entityWorkflow, $transition, [ 'context' => $transitionDto, 'transitionAt' => $this->clock->now(), 'transition' => $transition, ]); $this->logger->info(self::LOG_PREFIX.'Transition automatically applied', ['signatureId' => $signature->getId()]); } private function getPreviousSender(EntityWorkflowStep $entityWorkflowStep): ?User { $stepsChained = $entityWorkflowStep->getEntityWorkflow()->getStepsChained(); foreach ($stepsChained as $stepChained) { if ($stepChained === $entityWorkflowStep) { if (null === $previous = $stepChained->getPrevious()) { return null; } if (null !== $previousUser = $previous->getTransitionBy()) { return $previousUser; } return $this->getPreviousSender($previous); } } throw new \LogicException('no same step found'); } }