<?php
namespace App\Controller\Api;
use App\Enum\LetterStatusEnum;
use App\Enum\LetterTypeEnum;
use App\Enum\OrganizationForwardingFrequencyEnum;
use App\Message\ResendLetterMessage;
use App\Repository\LetterRepository;
use App\Repository\OrganizationRepository;
use App\Service\EncryptorDataUtils;
use App\Service\LetterFilesService;
use App\Service\OrganizationUtils;
use App\Service\UserChecker;
use App\Traits\SentryNotifyTrait;
use App\Utils\UserUtils;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Query\QueryException;
use Evo\Infrastructure\MappingORM\Letter;
use Evo\Infrastructure\MappingORM\LetterForward;
use Evo\Infrastructure\MappingORM\Organization;
use Evo\Infrastructure\MappingORM\User;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Messenger\Bridge\AmazonSqs\Transport\AmazonSqsFifoStamp;
use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
/**
* @Route("/letter")
*/
class LetterController extends AbstractController
{
use SentryNotifyTrait;
private OrganizationUtils $organizationUtils;
private LetterFilesService $letterFilesService;
private EncryptorDataUtils $encryptor;
private UserChecker $userChecker;
private EntityManagerInterface $entityManager;
private UserUtils $userUtils;
private MessageBusInterface $bus;
private LetterRepository $letterRepository;
private UrlGeneratorInterface $router;
/**
* LetterController constructor.
*/
public function __construct(
OrganizationUtils $organizationUtils,
EncryptorDataUtils $encryptor,
LetterFilesService $letterFilesService,
UserChecker $userChecker,
UserUtils $userUtils,
EntityManagerInterface $entityManager,
MessageBusInterface $bus,
LetterRepository $letterRepository,
UrlGeneratorInterface $router
) {
$this->organizationUtils = $organizationUtils;
$this->letterFilesService = $letterFilesService;
$this->encryptor = $encryptor;
$this->userUtils = $userUtils;
$this->userChecker = $userChecker;
$this->entityManager = $entityManager;
$this->bus = $bus;
$this->letterRepository = $letterRepository;
$this->router = $router;
}
/**
* @Route("/get-types", name="app_letter_get_types", methods={"GET"})
*
* @return JsonResponse
*/
public function getTypes(TranslatorInterface $translator)
{
$letterTypes = [];
$letterEnums = LetterTypeEnum::getChoices();
foreach ($letterEnums as $key => $value) {
$letterTypes[$translator->trans($key)] = $value;
}
return $this->json($letterTypes);
}
/**
* @Route("/get-status-translations", name="app_letter_get_status_translations", methods={"GET"})
*
* @return JsonResponse
*/
public function getStatusTranslations(TranslatorInterface $translator)
{
$letterStatus = [];
$letterEnums = LetterStatusEnum::getChoices();
foreach ($letterEnums as $key => $value) {
$letterStatus[$value] = $translator->trans($key);
}
return $this->json($letterStatus);
}
/**
* @Route("/redirect-all-by-organization/{id}", name="app_letter_redirect_all_by_organization", methods={"GET"})
*
* @return JsonResponse
*/
public function redirectAllByOrganization($id)
{
$em = $this->getDoctrine()->getManager();
$organizations = $em->getRepository(Organization::class)->findBy(['id' => $id]);
$this->forwardLetters($organizations, true);
return $this->json(['ok']);
}
private function forwardLetters(array $organizations, bool $isCheckReex = false): bool
{
$em = $this->getDoctrine()->getManager();
/** @var Organization $organization */
foreach ($organizations as $organization) {
if ($this->organizationUtils->hasReexpedition($organization) || $isCheckReex) {
$letters = $em->getRepository(Letter::class)->getLetterToForward($organization->getId(), new \DateTime());
$letterForward = new LetterForward();
$letterForward->setOrganization($organization);
$letterForward->setIsDone(true);
/** @var Letter $letter */
foreach ($letters as $letter) {
$letter->setStatus(LetterStatusEnum::SENT);
$em->persist($letter);
$letterForward->addLetter($letter);
}
if (count($letterForward->getLetters()) > 0) {
$em->persist($letterForward);
$em->flush();
}
}
}
return true;
}
/**
* @Route("/resend-letter-organizations/{postalCode}/{frequency}/{isDomisimple}", name="app_letter_weekly_redirect_all_organizations", methods={"GET"})
*
* @throws QueryException
*/
public function weeklyRedirectByOrganization(Request $request, int $postalCode, string $frequency, bool $isDomisimple = false): JsonResponse
{
$dateString = $request->query->get('datetime', (new \DateTime())->format('Y-m-d H:i:s'));
$date = new \DateTime($dateString);
/** @var OrganizationRepository $orgaRepo */
$orgaRepo = $this->entityManager->getRepository(Organization::class);
$organizations = $orgaRepo->findByForwardable($date, $postalCode, OrganizationForwardingFrequencyEnum::getEnum($frequency));
$organizationsCount = iterator_count(
$orgaRepo->findByForwardable($date, $postalCode, OrganizationForwardingFrequencyEnum::getEnum($frequency))
);
foreach ($organizations as $organization) {
$this->bus->dispatch(
(new Envelope(new ResendLetterMessage(
$date,
$organization['id'],
$organization['forwardingFrequency'],
$organization['legalName'],
$organization['bal'],
$organization['statusInvoicePayed'],
$organization['uniqId'],
)))->with(
new AmazonSqsFifoStamp('Letter', uniqid('', true))
)
);
}
// envoi d'un message de fin avec nombre initial d'orga a traité + nombre restant qui devrait etre 0
$this->bus->dispatch(
(new Envelope(new ResendLetterMessage(
$date,
'END',
OrganizationForwardingFrequencyEnum::WEEKLY,
null,
null,
null,
null,
$postalCode,
$organizationsCount
)))->with(
new AmazonSqsFifoStamp('Letter', uniqid('', true))
)
);
return $this->json(["La réexpédition a débuté, $organizationsCount organisation(s) en cours de traitement."]);
}
/**
* @Route("/domisimple-redirect-all-organizations/{postalCode}/list", name="app_letter_domisimple_redirect_all_organizations_list", methods={"GET"})
*/
public function domisimpleRedirectByOrganizationList(int $postalCode): JsonResponse
{
$em = $this->getDoctrine()->getManager();
$organizations = $em->getRepository(Organization::class)->findByForwardable(
new \DateTime('now'),
$postalCode,
OrganizationForwardingFrequencyEnum::QUARTERLY,
true
);
return $this->json($organizations);
}
/**
* @Route("/view/{id}/type/{type}/{token}", name="app_letter_view", methods={"GET"})
*
* @return JsonResponse
*/
public function viewDocument(Request $request, $id, $type, $token = null)
{
$repository = $this->entityManager->getRepository(Letter::class);
/** @var User $user */
$user = $this->userChecker->checkUserByToken($token);
$id = $this->encryptor->decrypt($id);
/** @var Letter $letter */
$letter = $repository->find($id);
if (!$user || !$letter) {
return $this->json(['result' => 'Document not found'], Response::HTTP_NOT_FOUND);
}
$prescriberOrganizations = $this->userUtils->getOrganizationPrescribersID($user);
$organization = $letter->getOrganization();
if ($organization
&& (in_array($user, $organization->getUsers())
|| in_array('ROLE_ADMIN', $user->getRoles()) || ($organization->getPrescriber() && in_array($organization->getPrescriber()->getId(), $prescriberOrganizations)))) {
if ($request->query->get('download')) {
$this->letterFilesService->downloadLetter($letter->getContentPathAWS());
}
$this->letterFilesService->viewLetter($letter, $type);
}
return $this->json(['result' => 'Document not found'], Response::HTTP_NOT_FOUND);
}
/**
* @Route("/get-nbr-letter/{type}/{orgaId}", name="app_letter_parcel", methods={"GET"})
*/
public function letterParcel(string $type, int $orgaId, LetterRepository $letterRepository): JsonResponse
{
$arrStatus = $this->convertStatusToArray($type);
$result = $letterRepository->getNumberLetterOrParcel($arrStatus, $orgaId);
return $this->json(['result' => count($result)], Response::HTTP_OK);
}
private function convertStatusToArray(string $status): array
{
return explode(',', $status);
}
/**
* @Route("/zapier", name="app_letter_invoice", methods={"GET"})
*/
public function getLastLetterByOrganisation(): JsonResponse
{
$userRepository = $this->entityManager->getRepository(User::class);
$organizations = $userRepository->getOrganizationsByUser($this->getUser()->getUsername());
if (is_array($organizations) && !empty($organizations)) {
$letter = $this->letterRepository->getLastLetterWithOrganization($organizations);
if (is_array($letter) && !empty($letter)) {
$url = $this->router->generate(
'app_letter_view',
['id' => $this->encryptor->encrypt($letter['id']), 'type' => 'recto'],
UrlGeneratorInterface::ABSOLUTE_URL
);
$letter['contentUrl'] = $url;
$letter['createdAt'] = $letter['createdAt']->format('d/m/Y');
return new JsonResponse([$letter]);
}
return new JsonResponse(['error' => 'Letter not found']);
}
return new JsonResponse(['error' => 'Organization not found']);
}
}