<?php
namespace App\Controller\Api;
use App\Enum\DocumentTypeOrganizationEnum;
use App\Repository\OrganizationRepository;
use App\Service\OrganizationUtils;
use Doctrine\ORM\OptimisticLockException;
use Doctrine\ORM\ORMException;
use Evo\Infrastructure\MappingORM\Document;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Serializer\Exception\ExceptionInterface;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
final class CreateOrUpdateDocumentAction
{
private OrganizationUtils $organizationUtils;
private OrganizationRepository $organizationRepository;
private TranslatorInterface $translator;
public function __construct(
OrganizationUtils $organizationUtils,
OrganizationRepository $organizationRepository,
TranslatorInterface $translator
) {
$this->organizationUtils = $organizationUtils;
$this->organizationRepository = $organizationRepository;
$this->translator = $translator;
}
/**
* @throws ExceptionInterface
* @throws ORMException
* @throws OptimisticLockException
*/
public function __invoke(Request $request, SerializerInterface $serializer): Document
{
$currentDocument = $request->attributes->get('data');
$arrayDocument = $request->request->all();
if (!$arrayDocument) {
$arrayDocument = json_decode($request->getContent(), true);
}
if (!$currentDocument->getId() && (!isset($arrayDocument['type']) || !$arrayDocument['type'])) {
throw new BadRequestHttpException('"Type" est requis');
}
if (!isset($arrayDocument['organization']) || !$documents = $this->generate($arrayDocument)) {
$documentFile = $request->files->get('documentFile');
if (!$currentDocument->getId() && !$documentFile) {
throw new BadRequestHttpException('"documentFile" is required');
}
/** @var Document $document */
$document = $serializer->denormalize(
$arrayDocument,
Document::class,
null,
[AbstractNormalizer::OBJECT_TO_POPULATE => $currentDocument]
);
if ($documentFile) {
$document->setPath(null);
$document->setAwsPath(null);
$document->setDocumentFile($documentFile);
}
$documents = [$document];
}
return $documents[0];
}
/**
* @param array<string, array<bool|float|int|string>|bool|float|int|string> $arrayDocument
*
* @throws ORMException
* @throws OptimisticLockException
*
* @return array<Document|mixed>
*/
private function generate(array $arrayDocument): array
{
$documents = [];
$organization = $this->organizationRepository->find((int) basename($arrayDocument['organization']));
if (null !== $organization) {
switch (true) {
case isset($arrayDocument['isAbleToGenerate'], $arrayDocument['type']) && 'true' == $arrayDocument['isAbleToGenerate']:
$docsToGenerate = [$arrayDocument['type']];
$documents[] = $this->organizationUtils->generateDocs(
$organization,
DocumentTypeOrganizationEnum::DOMICILIATION_CONTRACT == $arrayDocument['type'],
$docsToGenerate,
true
);
break;
case isset($arrayDocument['isPappersAbleToGenerate']) && 'true' == $arrayDocument['isPappersAbleToGenerate']:
$trans = DocumentTypeOrganizationEnum::getReadableValue($arrayDocument['type']);
$document = new Document();
$document
->setType($arrayDocument['type'])
->setStatus($arrayDocument['status'])
->setOrganization($organization)
->setName($this->translator->trans($trans));
$organization->addDocument($document);
$documents[] = $document;
break;
}
}
return $documents;
}
}