src/EventSubscriber/Doctrine/DocumentSubscriber.php line 715

Open in your IDE?
  1. <?php
  2. namespace App\EventSubscriber\Doctrine;
  3. use App\Enum\ActivityLogCategoryEnum;
  4. use App\Enum\ActivityLogMethodEnum;
  5. use App\Enum\DocumentStatusEnum;
  6. use App\Enum\DocumentTypeEnum;
  7. use App\Enum\DocumentTypeOrganizationEnum;
  8. use App\Enum\DocumentTypeUserEnum;
  9. use App\Enum\OrganizationStatusEnum;
  10. use App\Enum\SignatoryEnum;
  11. use App\Service\DocumentFilesService;
  12. use App\Service\DocumentUtils;
  13. use App\Service\LegalRepresentativeUtils;
  14. use App\Service\OrganizationUtils;
  15. use App\Service\PersonUtils;
  16. use App\Service\SegmentAPI;
  17. use App\Service\SubscriptionUtils;
  18. use App\Traits\SentryNotifyTrait;
  19. use Doctrine\Common\EventSubscriber;
  20. use Doctrine\ORM\EntityManagerInterface;
  21. use Doctrine\ORM\Event\PreUpdateEventArgs;
  22. use Doctrine\Persistence\Event\LifecycleEventArgs;
  23. use Evo\Domain\Core\SignatureServiceInterface;
  24. use Evo\Domain\PappersActivityLogWrapper\Service\PappersActivityLogWrapperService;
  25. use Evo\Infrastructure\MappingORM\ActivityLog;
  26. use Evo\Infrastructure\MappingORM\Document;
  27. use Evo\Infrastructure\MappingORM\LegalRepresentative;
  28. use Evo\Infrastructure\MappingORM\Organization;
  29. use Evo\Infrastructure\MappingORM\ProcessYousign;
  30. use Evo\Infrastructure\MappingORM\Signature;
  31. use Evo\Infrastructure\MappingORM\User;
  32. use Evo\Infrastructure\PdfGenerator\PathGenerator;
  33. use Evo\Infrastructure\PdfGenerator\PdfGenerator;
  34. use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
  35. use Symfony\Component\HttpFoundation\Request;
  36. use Symfony\Component\HttpFoundation\RequestStack;
  37. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  38. use Symfony\Component\HttpKernel\KernelInterface;
  39. use Symfony\Component\Mercure\HubInterface;
  40. use Symfony\Component\Mercure\Update;
  41. use Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken;
  42. use Symfony\Component\Security\Core\Security;
  43. use Symfony\Component\Security\Core\User\UserInterface;
  44. use Symfony\Contracts\Translation\TranslatorInterface;
  45. class DocumentSubscriber implements EventSubscriber
  46. {
  47.     use SentryNotifyTrait;
  48.     public const CHANGE_STATUS_KEY 'CHANGEMENT DE STATUT';
  49.     public const LEGAL_REPRESENTATIVE_KEY 'REPRÉSENTANT LÉGAL';
  50.     public const SERVICE_NAME '[DOCUMENT SUBSCRIBER] :: ';
  51.     public const CREATION_KEY 'CREATION DOCUMENT';
  52.     public const GENERATED_DOCUMENTS = [
  53.         DocumentTypeEnum::DNC1,
  54.         DocumentTypeEnum::DNC2,
  55.         DocumentTypeEnum::HQ_OWNER,
  56.         DocumentTypeEnum::KOAH_POWER_OF_ATTORNEY,
  57.         DocumentTypeEnum::SUBSCRIBERS_LIST,
  58.         DocumentTypeEnum::DOMICILIATION_CONTRACT,
  59.         DocumentTypeEnum::DOMICILIATION_CERTIFICATE,
  60.         DocumentTypeEnum::NOTICE_OF_TERMINATION,
  61.     ];
  62.     private OrganizationUtils $organizationUtils;
  63.     private ?string $filePath null;
  64.     private ?string $relativePath null;
  65.     private DocumentUtils $documentUtils;
  66.     private KernelInterface $kernel;
  67.     private SignatureServiceInterface $yousignAPI;
  68.     private PersonUtils $personUtils;
  69.     private SessionInterface $session;
  70.     private SegmentAPI $segmentAPI;
  71.     private EntityManagerInterface $em;
  72.     private ParameterBagInterface $params;
  73.     private TranslatorInterface $translator;
  74.     private Security $security;
  75.     private LegalRepresentativeUtils $legalRepresentativeUtils;
  76.     private RequestStack $requestStack;
  77.     private HubInterface $hub;
  78.     private DocumentFilesService $documentFilesService;
  79.     private PdfGenerator $pdfGenerator;
  80.     private PappersActivityLogWrapperService $pappersActivityLogWrapperService;
  81.     public function __construct(
  82.         OrganizationUtils $organizationUtils,
  83.         DocumentUtils $documentUtils,
  84.         PersonUtils $personUtils,
  85.         SignatureServiceInterface $yousignAPI,
  86.         SessionInterface $session,
  87.         KernelInterface $appKernel,
  88.         SegmentAPI $segmentAPI,
  89.         EntityManagerInterface $em,
  90.         TranslatorInterface $translator,
  91.         ParameterBagInterface $params,
  92.         LegalRepresentativeUtils $legalRepresentativeUtils,
  93.         Security $security,
  94.         RequestStack $requestStack,
  95.         HubInterface $hub,
  96.         PdfGenerator $documentGenerator,
  97.         PappersActivityLogWrapperService $pappersActivityLogWrapperService,
  98.         DocumentFilesService $documentFilesService
  99.     ) {
  100.         $this->yousignAPI $yousignAPI;
  101.         $this->translator $translator;
  102.         $this->params $params;
  103.         $this->session $session;
  104.         $this->organizationUtils $organizationUtils;
  105.         $this->documentUtils $documentUtils;
  106.         $this->personUtils $personUtils;
  107.         $this->kernel $appKernel;
  108.         $this->em $em;
  109.         $this->segmentAPI $segmentAPI;
  110.         $this->security $security;
  111.         $this->legalRepresentativeUtils $legalRepresentativeUtils;
  112.         $this->requestStack $requestStack;
  113.         $this->hub $hub;
  114.         $this->pdfGenerator $documentGenerator;
  115.         $this->pappersActivityLogWrapperService $pappersActivityLogWrapperService;
  116.         $this->documentFilesService $documentFilesService;
  117.     }
  118.     public function getSubscribedEvents(): array
  119.     {
  120.         return [
  121.             'prePersist',
  122.             'postPersist',
  123.             'postUpdate',
  124.             'preUpdate',
  125.             'postRemove',
  126.         ];
  127.     }
  128.     public function postRemove(LifecycleEventArgs $args): void
  129.     {
  130.         /** @var Document $entity */
  131.         $entity $args->getObject();
  132.         if (!$entity instanceof Document) {
  133.             return;
  134.         }
  135.         $this->updateStatusDomicialitionForOrganizations($entity);
  136.     }
  137.     public function preUpdate(PreUpdateEventArgs $args): void
  138.     {
  139.         $entity $args->getObject();
  140.         if (!$entity instanceof Document) {
  141.             return;
  142.         }
  143.         if ($entity->isBypassSubscriber()) {
  144.             return;
  145.         }
  146.         $changeset $args->getEntityChangeSet();
  147.         if ((=== count($changeset) && (isset($changeset['status'])))
  148.             || (isset($changeset['status'], $changeset['expirationDate']) && === count($changeset))
  149.         ) {
  150.             return;
  151.         }
  152.         if (isset($changeset['yousignLink']) || isset($changeset['path']) || isset($changeset['awsPath'])) {
  153.             return;
  154.         }
  155.         $this->initName($entity, isset($changeset['type']));
  156.         if (DocumentStatusEnum::UNDER_VALIDATION === $entity->getStatus() && DocumentTypeOrganizationEnum::POSTAL_POWER_OF_ATTORNEY === $entity->getType()) {
  157.             $entity->setAwaitingValidationDate(new \DateTime());
  158.             $this->segmentAPI->trackDocumentUnderValidation($entity);
  159.         }
  160.     }
  161.     public function postUpdate(LifecycleEventArgs $args): void
  162.     {
  163.         $impersonatorUser null;
  164.         /** @var Document $entity */
  165.         $entity $args->getObject();
  166.         if (!$entity instanceof Document) {
  167.             return;
  168.         }
  169.         if ($entity->isBypassSubscriber()) {
  170.             return;
  171.         }
  172.         try {
  173.             $this->sendPushMercureForContratBoth($entity);
  174.         } catch (\Exception $e) {
  175.             $this->captureSentryException($e);
  176.         }
  177.         $request $this->requestStack->getCurrentRequest();
  178.         $uow $args->getObjectManager()->getUnitOfWork();
  179.         $uow->computeChangeSets();
  180.         $changeset $uow->getEntityChangeSet($entity);
  181.         $organization $entity->getOrganization();
  182.         $person $entity->getPerson();
  183.         if (isset($changeset['status'])) {
  184.             if (DocumentStatusEnum::NOT_APPROVED === $changeset['status'][1]) {
  185.                 $params = [];
  186.                 if (DocumentTypeOrganizationEnum::RIB === $entity->getType() && ($organization || $person)) {
  187.                     $params SubscriptionUtils::getSubscriptionDataToSegment($organization);
  188.                 }
  189.                 $precisionReason null;
  190.                 if ($request instanceof Request && $request->request) {
  191.                     $precisionReason $request->request->get('precision_reason');
  192.                     $data json_decode($request->getContent(), true);
  193.                     $precisionReason $data['precision_reason'] ?? $precisionReason;
  194.                 }
  195.                 $this->segmentAPI->trackRejectedDocument($entity$params$precisionReason);
  196.             } elseif (DocumentStatusEnum::APPROVED === $changeset['status'][1]) {
  197.                 // reset message rejection if document is approved
  198.                 $document $entity->resetDocumentRejectionMessage();
  199.                 try {
  200.                     $this->em->persist($document);
  201.                     if (
  202.                         in_array($entity->getType(), [DocumentTypeEnum::STATUSDocumentTypeEnum::KBISDocumentTypeEnum::DBE])
  203.                         && $document->isDocumentOfOrganization()
  204.                     ) {
  205.                         $this->pappersActivityLogWrapperService->updateStatusToProcessed($organization);
  206.                     }
  207.                     $this->em->flush();
  208.                 } catch (\Exception $e) {
  209.                     $this->captureSentryException($e);
  210.                 }
  211.                 if (DocumentTypeOrganizationEnum::DOMICILIATION_CONTRACT !== $entity->getType() && ($organization || $person)) {
  212.                     if (DocumentTypeOrganizationEnum::RIB === $entity->getType()) {
  213.                         $params SubscriptionUtils::getSubscriptionDataToSegment($organization);
  214.                     } else {
  215.                         $params = [];
  216.                     }
  217.                     $this->segmentAPI->trackApprovedDocument($entity$params);
  218.                 }
  219.             }
  220.         }
  221.         if (isset($changeset['type'])) {
  222.             $this->createActivityLogForTypeHasChanged($entity$changeset$impersonatorUser$request);
  223.         }
  224.         $this->updateStatusDomicialitionForOrganizations($entity);
  225.         if (DocumentTypeEnum::OTHER !== $entity->getType()
  226.             || $this->documentUtils->isHavingSimilarDocuments($entity->getOrganization(), $entity)) {
  227.             $this->documentUtils->removeSimilarDocuments($entityDocumentTypeEnum::OTHER === $entity->getType());
  228.         }
  229.         if (isset($changeset['status'])) {
  230.             $changeset $this->createActivityLogForStatusChanged($entity$changeset$impersonatorUser$request);
  231.         }
  232.         if (=== (is_countable($changeset) ? count($changeset) : 0) && isset($changeset['status']) && DocumentStatusEnum::APPROVED === $changeset['status'][1]) {
  233.             $this->organizationUtils->generateOnlyDomiciliationCertificate($entity);
  234.             return;
  235.         }
  236.         if (=== (is_countable($changeset) ? count($changeset) : 0) && (isset($changeset['status']))) {
  237.             return;
  238.         }
  239.         /* return if yousignLink | yousignError | path | awsPath is updated */
  240.         if (isset($changeset['yousignLink']) || isset($changeset['yousignError']) || isset($changeset['path']) || isset($changeset['awsPath'])) {
  241.             return;
  242.         }
  243.         $this->signatureRequestYousign($entity);
  244.         /*
  245.          * Génération documents à l'exception { changement de la propriété "path" }
  246.          */
  247.         $changeset $this->generateDocsIfNecessary($changeset$entity);
  248.         if (isset($changeset['signedBy'])) {
  249.             if (SignatoryEnum::BOTH === $changeset['signedBy'][1]) {
  250.                 $this->segmentAPI->trackApprovedDocument($entity);
  251.             }
  252.             $this->createActivityLogForSignedByChanged($entity$changeset$impersonatorUser$request);
  253.         }
  254.     }
  255.     private function updateStatusDomicialitionForOrganizations(Document $document): void
  256.     {
  257.         if (null !== $document->getPerson()) {
  258.             /** @var LegalRepresentative $legalRepresentative */
  259.             foreach ($document->getPerson()->getLegalRepresentatives() as $legalRepresentative) {
  260.                 $organizations $legalRepresentative->getOrganizations();
  261.                 /** @var Organization $organization */
  262.                 foreach ($organizations as $organization) {
  263.                     $status $this->organizationUtils->checkStatusDomiciliation($organization);
  264.                     if ($status && $status !== $organization->getStatus()) {
  265.                         $organization->setStatus($status);
  266.                         $this->em->persist($organization);
  267.                         $this->em->flush();
  268.                     }
  269.                 }
  270.             }
  271.         } elseif (null !== $document->getOrganization()) {
  272.             /** @var Organization $organization */
  273.             $organization $document->getOrganization();
  274.             $status $this->organizationUtils->checkStatusDomiciliation($organization);
  275.             if ($status && $status !== $organization->getStatus()) {
  276.                 $organization->setStatus($status);
  277.                 $this->em->persist($organization);
  278.                 $this->em->flush();
  279.             }
  280.         }
  281.     }
  282.     public function prePersist(LifecycleEventArgs $args): void
  283.     {
  284.         $entity $args->getObject();
  285.         if (!$entity instanceof Document) {
  286.             return;
  287.         }
  288.         if ($entity->isBypassSubscriber()) {
  289.             return;
  290.         }
  291.         $request $this->requestStack->getCurrentRequest();
  292.         $arrayDocument null !== $request $request->request->all() : [];
  293.         $mustGeneratedByPappers $arrayDocument
  294.             && $entity->isDocumentOfOrganization()
  295.             && isset($arrayDocument['isPappersAbleToGenerate'])
  296.             && 'true' === $arrayDocument['isPappersAbleToGenerate'];
  297.         $this->initName($entity);
  298.         if (DocumentTypeOrganizationEnum::DOMICILIATION_CONTRACT === $entity->getType()) {
  299.             $entity->setStatus(DocumentStatusEnum::APPROVED);
  300.         }
  301.         if (null !== $entity->getDocumentFile() || DocumentTypeOrganizationEnum::DOMICILIATION_CONTRACT_LARAVEL === $entity->getType()) {
  302.             return;
  303.         }
  304.         if (!$mustGeneratedByPappers && $entity->isDocumentOfOrganization()) {
  305.             $this->pdfGenerator->generate($entity);
  306.         }
  307.         $entity->setIsFromPappers($entity->getIsFromPappers() || $entity->isTemporaryFileForPappers());
  308.         if ($mustGeneratedByPappers) {
  309.             $isGenerated $this->organizationUtils->generateDocsFromPappers($entity->getOrganization(), $entity);
  310.             if ($isGenerated) {
  311.                 $entity->setIsFromPappers(true);
  312.             }
  313.         }
  314.     }
  315.     public function postPersist(LifecycleEventArgs $args): void
  316.     {
  317.         $entity $args->getObject();
  318.         if (!$entity instanceof Document) {
  319.             return;
  320.         }
  321.         if ($entity->isBypassSubscriber()) {
  322.             return;
  323.         }
  324.         $this->updateStatusDomicialitionForOrganizations($entity);
  325.         if (null === $entity->getPerson() && null === $entity->getOrganization()) {
  326.             $this->sendSentryMessage(self::SERVICE_NAME.'Document Orphelin [postPersist] #'.$entity->getId(), 'debug');
  327.         } else {
  328.             if (DocumentTypeEnum::OTHER !== $entity->getType()
  329.                 || $this->documentUtils->isHavingSimilarDocuments($entity->getOrganization(), $entity)) {
  330.                 $this->documentUtils->removeSimilarDocuments($entityDocumentTypeEnum::OTHER === $entity->getType());
  331.             }
  332.             if ($entity->getId()) {
  333.                 $this->signatureRequestYousign($entity);
  334.             }
  335.         }
  336.         if (DocumentStatusEnum::APPROVED === $entity->getStatus() && DocumentTypeOrganizationEnum::RIB !== $entity->getType()) {
  337.             $this->segmentAPI->trackApprovedDocument($entity);
  338.         }
  339.         if (DocumentStatusEnum::TO_APPROVE === $entity->getStatus() && DocumentTypeOrganizationEnum::RIB !== $entity->getType()) {
  340.             $this->segmentAPI->trackNewDocument($entity);
  341.         }
  342.         if (DocumentStatusEnum::NOT_APPROVED === $entity->getStatus() && DocumentTypeOrganizationEnum::RIB !== $entity->getType()) {
  343.             $this->segmentAPI->trackRejectedDocument($entity);
  344.         }
  345.         if ($entity->getOrganization() && $this->organizationUtils->checkGenerateCertificateDomiciliation($entity->getOrganization())) {
  346.             $aDocs[] = DocumentTypeOrganizationEnum::DOMICILIATION_CERTIFICATE;
  347.             $this->organizationUtils->generateDocs($entity->getOrganization(), false$aDocs);
  348.         }
  349.         // create activity log for non generated file only
  350.         if (null === $entity->getOrganization() || !in_array($entity->getType(), self::GENERATED_DOCUMENTStrue)) {
  351.             $request $this->requestStack->getCurrentRequest();
  352.             $token $this->security->getToken();
  353.             if ($token instanceof SwitchUserToken) {
  354.                 $impersonatorUser $token->getOriginalToken()->getUser();
  355.             }
  356.             $user $request instanceof Request $impersonatorUser ?? $this->security->getUser() : null;
  357.             $person $entity->getPerson();
  358.             $legalRepresentative $person $person->getLegalRepresentative() : null;
  359.             $activityLog ActivityLog::create(
  360.                 $user,
  361.                 ActivityLogMethodEnum::CREATE,
  362.                 self::CREATION_KEY,
  363.                 ActivityLogCategoryEnum::DOCUMENTS,
  364.                 [],
  365.                 $entity->getOrganization(),
  366.                 $legalRepresentative,
  367.                 $this->translator->trans('enum.document.'.$entity->getType())
  368.             );
  369.             try {
  370.                 $this->em->persist($activityLog);
  371.                 $this->em->flush();
  372.             } catch (\Exception $e) {
  373.                 $this->captureSentryException($e);
  374.             }
  375.             $activityWithStatus ActivityLog::create(
  376.                 $user,
  377.                 ActivityLogMethodEnum::UPDATE,
  378.                 'DOCUMENT '.$this->translator->trans(DocumentTypeEnum::getReadableValue($entity->getType())),
  379.                 ActivityLogCategoryEnum::DOCUMENTS,
  380.                 [
  381.                     self::CHANGE_STATUS_KEY => [
  382.                         '-' => $this->translator->trans(DocumentStatusEnum::getReadableValue($entity->getStatus())),
  383.                     ],
  384.                 ],
  385.                 $entity->getOrganization(),
  386.                 $legalRepresentative,
  387.                 null
  388.             );
  389.             try {
  390.                 $this->em->persist($activityWithStatus);
  391.                 $this->em->flush();
  392.             } catch (\Exception $e) {
  393.                 $this->captureSentryException($e);
  394.             }
  395.         }
  396.     }
  397.     private function signatureRequestYousign(Document $entity): void
  398.     {
  399.         if (DocumentTypeOrganizationEnum::DOMICILIATION_CONTRACT !== $entity->getType()) {
  400.             return;
  401.         }
  402.         if (!$this->documentFilesService->isFileExist(PathGenerator::generatePathForDocument($entity))) {
  403.             return;
  404.         }
  405.         if (!$entity->getOrganization()) {
  406.             return;
  407.         }
  408.         if ($entity->getOrganization()->getProcessYousign()) {
  409.             return;
  410.         }
  411.         /** @var Organization $organization */
  412.         $organization $entity->getOrganization();
  413.         $user $this->em->getRepository(User::class)->findOneBy(['email' => 'william@digidom.pro']);
  414.         $signers = [];
  415.         if ($user) {
  416.             switch ($entity->getOrganization()->getStatus()) {
  417.                 case OrganizationStatusEnum::NEW_PAYMENT:
  418.                     $status 'validation-client';
  419.                     break;
  420.                 case OrganizationStatusEnum::DOCS_MISSING:
  421.                     $status 'non-urgent-client';
  422.                     break;
  423.                 default:
  424.                     $status 'autres';
  425.                     break;
  426.             }
  427.             $redirectTo getenv('URL_NEW_ADMIN').'/kyc/'.$status;
  428.             $signers[] = $this->yousignAPI->getSignerData($user, [
  429.                 'success' => $redirectTo,
  430.                 'error' => $redirectTo,
  431.             ]);
  432.         }
  433.         $legalRepresentative $this->legalRepresentativeUtils->getFirstPhysicalRepresentative($organization);
  434.         if ($legalRepresentative && in_array($entity->getOrganization()->getStatus(), [
  435.                 OrganizationStatusEnum::NEW,
  436.                 OrganizationStatusEnum::NEW_PAYMENT,
  437.                 OrganizationStatusEnum::DOCS_MISSING,
  438.                 OrganizationStatusEnum::DOCS_EXPIRED,
  439.                 OrganizationStatusEnum::OK,
  440.             ], true)) {
  441.             $signature $this->em->getRepository(Signature::class)
  442.                 ->findOneBy(['legalRepresentative' => $legalRepresentative]);
  443.             if (!$signature) {
  444.                 $signature = new Signature();
  445.                 $signature->setLegalRepresentative($legalRepresentative);
  446.             }
  447.             try {
  448.                 $signer null;
  449.                 $signatureRequest $this->yousignAPI->createProcedure(
  450.                     'Signature contrat de domiciliation #'.$organization->getId().' ('.$entity->getCreatedAt()->format('d-m-Y H:i:s').')',
  451.                     PathGenerator::generatePathForDocument($entity),
  452.                     $entity->getOrganization()->getId().'-'.$legalRepresentative->getId()
  453.                 );
  454.                 if ($this->yousignAPI->isResponseValid($signatureRequest)) {
  455.                     try {
  456.                         $this->yousignAPI->addMetadataToSignatureRequest($signatureRequest['id'], [
  457.                             'organizationId' => $organization->getId(),
  458.                             'legalRepresentativeId' => $legalRepresentative->getId(),
  459.                             'documentType' => DocumentTypeOrganizationEnum::DOMICILIATION_CONTRACT,
  460.                         ]);
  461.                     } catch (\Exception $e) {
  462.                         // do nothing
  463.                     }
  464.                     $redirectToSuccess $this->params->get('uri_tunnel').'/contrat/'.$organization->getId().'?signed=true';
  465.                     $redirectToCancel $this->params->get('uri_tunnel').'/contrat/'.$organization->getId().'?signed=false';
  466.                     $signers[] = $this->yousignAPI->getSignerData($legalRepresentative, [
  467.                         'success' => $redirectToSuccess,
  468.                         'error' => $redirectToCancel,
  469.                     ]);
  470.                     foreach ($signers as $signerData) {
  471.                         $signer $this->yousignAPI->addSigner($signatureRequest['id'], $signerData);
  472.                         if (!$this->yousignAPI->isResponseValid($signer)) {
  473.                             $this->sendSentryMessage(
  474.                                 self::SERVICE_NAME.' Signer: '.$signer.' #'.$organization->getId()
  475.                             );
  476.                             break;
  477.                         }
  478.                     }
  479.                 }
  480.                 if (is_string($signatureRequest)) {
  481.                     $entity->setYousignError($signatureRequest);
  482.                 }
  483.                 if ($this->yousignAPI->isResponseValid($signatureRequest) && $this->yousignAPI->isResponseValid($signer)) {
  484.                     $procedure = (new ProcessYousign())
  485.                     ->setSignatureRequestId($signatureRequest['id'])
  486.                     ->setExternalFileId($signatureRequest['documents'][0]['id'])
  487.                     ->setOrganization($organization)
  488.                     ->setLastUploadedFileAt(new \DateTime())
  489.                     ->addSignature($signature);
  490.                     $this->em->persist($procedure);
  491.                     $this->em->flush();
  492.                 }
  493.             } catch (\Exception $e) {
  494.                 $this->captureSentryException($e);
  495.             }
  496.         }
  497.     }
  498.     private function getReadableDocumentType(string $type): string
  499.     {
  500.         if (DocumentTypeUserEnum::isValueExist($type)) {
  501.             $trans DocumentTypeUserEnum::getReadableValue($type);
  502.         } else {
  503.             $trans DocumentTypeOrganizationEnum::getReadableValue($type);
  504.         }
  505.         return $trans;
  506.     }
  507.     private function initName(Document $entitybool $typeHasChanged false): void
  508.     {
  509.         if ($typeHasChanged || null === $entity->getName()) {
  510.             $type $entity->getType();
  511.             $trans $this->getReadableDocumentType($type);
  512.             $entity->setName($this->translator->trans($trans));
  513.         }
  514.         if (!$typeHasChanged) {
  515.             return;
  516.         }
  517.         $extension explode('.'$entity->getPath());
  518.         $extension end($extension);
  519.         try {
  520.             if ($entity->getPath()) {
  521.                 $this->documentFilesService->copyFile(
  522.                     $entity->getPath(),
  523.                     PathGenerator::generatePathForDocument($entity$extensiontrue)
  524.                 );
  525.             }
  526.         } catch (\Exception $e) {
  527.             // do nothing
  528.         }
  529.         $entity->setPath(PathGenerator::generatePathForDocument($entity$extensiontrue));
  530.     }
  531.     private function sendPushMercureForContratBoth(Document $entity): void
  532.     {
  533.         if (
  534.             DocumentTypeOrganizationEnum::DOMICILIATION_CONTRACT === $entity->getType()
  535.             && null !== $entity->getOrganization()
  536.             && SignatoryEnum::BOTH === $entity->getSignedBy()
  537.         ) {
  538.             $update = new Update(
  539.                 'http://api.digidom.pro/signal/kyc/finished',
  540.                 json_encode([
  541.                     'organizationId' => $entity->getOrganization()->getId(),
  542.                     'status' => 'signed_by_both',
  543.                 ], JSON_THROW_ON_ERROR)
  544.             );
  545.             $this->hub->publish($update);
  546.         }
  547.     }
  548.     private function createActivityLog(Document $entity, array $changesetstring $changeType, ?UserInterface $impersonatorUser, ?Request $requeststring $key null): array
  549.     {
  550.         $token $this->security->getToken();
  551.         if ($token instanceof SwitchUserToken) {
  552.             $impersonatorUser $token->getOriginalToken()->getUser();
  553.         }
  554.         $user $request instanceof Request $impersonatorUser ?? $this->security->getUser() : null;
  555.         $logs = [];
  556.         $changeLogTitle 'DOCUMENT '.$this->translator->trans(DocumentTypeEnum::getReadableValue($entity->getType()));
  557.         switch ($changeType) {
  558.             case 'status':
  559.                 $oldStatus = isset($changeset['status'][0]) ? $this->translator->trans(DocumentStatusEnum::getReadableValue($changeset['status'][0])) : '-';
  560.                 $newStatus $changeset['status'][1] ?? null;
  561.                 $logs[$key ?? self::CHANGE_STATUS_KEY] = [
  562.                     $oldStatus => $this->translator->trans(DocumentStatusEnum::getReadableValue($newStatus)),
  563.                 ];
  564.                 break;
  565.             case 'type':
  566.                 $logs[$key ?? 'CHANGEMENT DE TYPE'] = [
  567.                     $this->translator->trans(DocumentTypeEnum::getReadableValue($changeset['type'][0])) => $this->translator->trans(DocumentTypeEnum::getReadableValue($entity->getType())),
  568.                 ];
  569.                 break;
  570.             case 'signedBy':
  571.                 $logs[$key ?? 'SIGNÉ PAR'] = [
  572.                     (!empty($changeset['signedBy'][0])) ? $this->translator->trans(SignatoryEnum::getReadableValue($changeset['signedBy'][0])) : '-' => (!empty($changeset['signedBy'][1])) ? $this->translator->trans(SignatoryEnum::getReadableValue($entity->getSignedBy())) : '-',
  573.                     ];
  574.         }
  575.         if ($entity->isDocumentOfPerson()) {
  576.             $logs[self::LEGAL_REPRESENTATIVE_KEY] = [
  577.                 '' => $entity->getPerson()->getFullName(),
  578.             ];
  579.         }
  580.         $hasRejectedMessage = isset($newStatus) && DocumentStatusEnum::NOT_APPROVED === $newStatus && null !== $entity->getRejectionMessage();
  581.         $activityLog ActivityLog::create(
  582.             $user,
  583.             ActivityLogMethodEnum::UPDATE,
  584.             $changeLogTitle,
  585.             ActivityLogCategoryEnum::DOCUMENTS,
  586.             $logs,
  587.             $entity->isDocumentOfOrganization() ? $entity->getOrganization() : null,
  588.             $entity->isDocumentOfPerson() ? $entity->getPerson()->getLegalRepresentative() : null,
  589.             $hasRejectedMessage $entity->getRejectionMessage()->getDescription() : null
  590.         );
  591.         try {
  592.             $this->em->persist($activityLog);
  593.             $this->em->flush();
  594.         } catch (\Exception $e) {
  595.             $this->captureSentryException($e);
  596.         }
  597.         return $changeset;
  598.     }
  599.     private function createActivityLogForSignedByChanged(Document $entity, array $changeset, ?UserInterface $impersonatorUser, ?Request $request null): array
  600.     {
  601.         return $this->createActivityLog($entity$changeset'signedBy'$impersonatorUser$request);
  602.     }
  603.     private function createActivityLogForTypeHasChanged(Document $entity, array $changeset, ?UserInterface $impersonatorUser, ?Request $request null): void
  604.     {
  605.         $this->createActivityLog($entity$changeset'type'$impersonatorUser$request);
  606.     }
  607.     private function createActivityLogForStatusChanged(Document $entity, array $changeset, ?UserInterface $impersonatorUser, ?Request $request null): array
  608.     {
  609.         return $this->createActivityLog($entity$changeset'status'$impersonatorUser$request);
  610.     }
  611.     private function generateDocsIfNecessary($changesetDocument $entity)
  612.     {
  613.         if ((!empty($changeset) && !isset($changeset['path'])) && !$this->session->has('locked')) {
  614.             $this->session->set('locked'1);
  615.             if (null !== $entity->getPerson()) {
  616.                 $organizations $this->personUtils->getOrganizations($entity->getPerson());
  617.                 $organizationsOfLRParent $this->personUtils->getOrganizationsParentOfLR($entity->getPerson());
  618.                 $organizations array_merge_recursive($organizations$organizationsOfLRParent);
  619.                 $organizationIDFinished = [];
  620.                 /** @var Organization $organization */
  621.                 foreach ($organizations as $organization) {
  622.                     if (!in_array($organization->getId(), $organizationIDFinished)) {
  623.                         $this->organizationUtils->generateDocs($organizationfalse);
  624.                         $organizationIDFinished[] = $organization->getId();
  625.                     }
  626.                 }
  627.             } elseif (null !== $entity->getOrganization()) {
  628.                 $this->organizationUtils->generateDocs($entity->getOrganization(), false);
  629.             }
  630.         }
  631.         return $changeset;
  632.     }
  633. }