<?php
namespace App\Controller\Api;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Paginator;
use App\Enum\ActivityLogCategoryEnum;
use App\Enum\ActivityLogMethodEnum;
use App\Enum\OrganizationStatusEnum;
use App\Enum\SubscriptionPackEnum;
use App\Repository\LetterRepository;
use App\Repository\OrganizationRepository;
use App\Repository\UserRepository;
use App\Service\SubscriptionUtils;
use App\Utils\SegmentUtils;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\ORMException;
use Evo\Infrastructure\MappingORM\ActivityLog;
use Evo\Infrastructure\MappingORM\Letter;
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\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken;
use Symfony\Component\Security\Core\Security;
/**
* @Route("/user")
*/
class UserController extends AbstractController
{
private EntityManagerInterface $em;
private Security $security;
private SubscriptionUtils $subscriptionUtils;
public function __construct(
EntityManagerInterface $entityManager,
Security $security,
SubscriptionUtils $subscriptionUtils
) {
$this->em = $entityManager;
$this->security = $security;
$this->subscriptionUtils = $subscriptionUtils;
}
/**
* @Route("/{user_id}/get-organizations-list", name="app_user_organizations_list", methods={"GET"})
*
* @return JsonResponse
*/
public function getOrganizationsByUserId($user_id)
{
/** @var UserRepository $userRepository */
$userRepository = $this->em->getRepository(User::class);
/** @var OrganizationRepository $organizationRepository */
$organizationRepository = $this->em->getRepository(Organization::class);
$organizationList = [];
if (is_numeric($user_id)) {
$organizations = $userRepository->getOrganizationsList($user_id);
foreach ($organizations as $organizationID) {
$organization = $organizationRepository->find($organizationID);
if (null !== $organization) {
$subscription = SubscriptionUtils::getDomSubscription($organization);
$organizationList[] = [
'id' => $organization->getId(),
'legalName' => $organization->getLegalName(),
'status' => $organization->getStatus(),
'statusInvoicePayed' => $organization->getStatusInvoicePayed(),
'dateMaxUnpaid' => $organization->getDateMaxUnpaid(),
'uniqId' => $organization->getUniqId(),
'terminationReason' => $organization->getTerminationReason(),
'terminationDate' => $organization->getTerminationDate(),
'invoiceToken' => $organization->getInvoiceToken(),
'isNewDomiciliation' => $organization->getIsNewDomiciliation(),
'isNewImmatriculation' => $organization->getIsNewImmatriculation(),
'statusImmatriculation' => $organization->getStatusImmatriculation(),
'domiciliationStartDate' => $organization->getDomiciliationStartDate(),
'historyNavTunnel' => $organization->getHistoryNavTunnel(),
'subscription_id' => null !== $subscription ? $subscription->getId() : null,
'isInvalidEmail' => $organization->getIsInvalidEmail(),
'blockingReason' => null !== $subscription ? $subscription->getBlockingReason() : null,
'isInvalidPhoneNumber' => $organization->getIsInvalidPhoneNumber(),
'hasServiceBlocked' => $subscription && $subscription->isHasBlockedService(),
];
}
}
return $this->json($organizationList);
}
throw new \InvalidArgumentException('No user found.');
}
/**
* @Route(
* name="app_user_letters_list",
* path="/{user_id}/get-letters-list",
* defaults={
* "_api_resource_class"=Letter::class,
* "_api_collection_operation_name"="get"
* }
* )
*
* @return Paginator
*/
public function getLettersByUserId(Request $request, LetterRepository $letterRepository, $user_id, int $page = 1)
{
if (is_numeric($user_id)) {
$page = (int) $request->query->get('page', 1);
return $letterRepository->getLettersByOrganization($user_id, $page);
}
throw new \InvalidArgumentException('No user found.');
}
/**
* @Route("/{user_id}/get-active-organizations-list", name="app_user_active_organizations", methods={"GET"})
*
* @return JsonResponse
*/
public function countActiveOrganizations($user_id)
{
$count = 0;
$list = [];
/** @var User $user */
$user = $this->em->getRepository(User::class)->findOneBy(['id' => $user_id]);
if ($user) {
foreach ($user->getOrganizations() as $organization) {
if (!in_array($organization->getStatus(), [
OrganizationStatusEnum::NEW,
OrganizationStatusEnum::LOST,
OrganizationStatusEnum::CANCELLED,
])) {
++$count;
} elseif (OrganizationStatusEnum::NEW === $organization->getStatus() &&
$organization->getStatusImmatriculation() &&
OrganizationStatusEnum::NEW !== $organization->getStatusImmatriculation()
) {
++$count;
}
}
return $this->json([
'count' => $count,
'list' => $list,
]);
}
return $this->json([
'error' => 'User not found',
]);
}
/**
* @Route(
* "/{id}/unlink/organization",
* name="app_user_unlink_organization",
* methods={"POST"}
* )
*
* @throws ORMException
* @throws \JsonException
*/
public function unLinkToOrgananization(int $id, Request $request): JsonResponse
{
$query = json_decode($request->getContent(), true, 512, JSON_THROW_ON_ERROR);
$user = $this->em->getReference(User::class, $id);
$organizationId = $query['organizationId'];
if (null === $organizationId) {
return new JsonResponse(['message' => 'OrganizationId is required'], Response::HTTP_BAD_REQUEST);
}
$organization = $this->em->getReference(Organization::class, $organizationId);
if (!$organization || !$user) {
return new JsonResponse(['message' => 'User or organization not found'], Response::HTTP_NOT_FOUND);
}
$token = $this->security->getToken();
if ($token instanceof SwitchUserToken) {
$impersonatorUser = $token->getOriginalToken()->getUser();
}
$userActivityLog = $impersonatorUser ?? $this->security->getUser();
$activityLog = ActivityLog::create(
$userActivityLog,
ActivityLogMethodEnum::REMOVE,
'SUPPRESSION USER ID: '.$id,
ActivityLogCategoryEnum::USER,
[],
$organization,
null,
$user->getFullName()
);
$organization->removeUser($user);
try {
$this->em->persist($activityLog);
$this->em->persist($organization);
$this->em->flush();
} catch (\Exception $exception) {
return new JsonResponse(['message' => 'An error occured when trying to dissociate user of organization'], Response::HTTP_OK);
}
return new JsonResponse(['message' => 'User dissociate to the organization'], Response::HTTP_OK);
}
/**
* @Route("/{user_id}/get-main-pack", name="app_user_main_pack", methods={"GET"})
*/
public function getUserMainPack($user_id): JsonResponse
{
/** @var User $user */
$user = $this->em->getRepository(User::class)->findOneBy(['id' => $user_id]);
if ($user) {
$packsPriorities = [
SubscriptionPackEnum::DOMISIMPLE => 1,
SubscriptionPackEnum::DOMISCAN => 2,
SubscriptionPackEnum::DIGIPACK => 3,
SubscriptionPackEnum::SCANPACK => 4,
SubscriptionPackEnum::COMPTAPACK => 5,
];
$mainPack = '';
foreach ($user->getOrganizations() as $organization) {
$subscription = SubscriptionUtils::getDomSubscription($organization);
$pack = $this->subscriptionUtils->getPackUniqueKey($subscription);
if ('' !== $pack && (empty($mainPack)
|| (
isset($packsPriorities[$mainPack], $packsPriorities[$pack])
&& $packsPriorities[$mainPack] < $packsPriorities[$pack]
))) {
$mainPack = $pack;
}
}
$mainPack = empty($mainPack) ? '' : SegmentUtils::PACK_LABELS[mb_strtoupper($mainPack)];
return $this->json([
'main_pack' => $mainPack,
]);
}
return $this->json([
'error' => 'User not found',
]);
}
/**
* @Route("/find-by-email", name="app_user_find_by_email", methods={"POST"})
*
* @return JsonResponse
*/
public function findByEmail(Request $request)
{
$query = json_decode($request->getContent(), true, 512, JSON_THROW_ON_ERROR);
$email = $query['email'];
/** @var User $user */
$user = $this->em->getRepository(User::class)->findOneBy(['email' => $email]);
if ($user) {
return $this->json([
'success' => true,
'id' => $user->getId(),
'uniqId' => $user->getUniqId(),
]);
}
return $this->json([
'success' => false,
]);
}
/**
* @Route("/get-organization-by-user", name="app_organizations_by_user", methods={"GET"})
*
* @return JsonResponse
*/
public function getOrganizationsByUserEmail()
{
/** @var UserRepository $userRepository */
$userRepository = $this->em->getRepository(User::class);
/** @var OrganizationRepository $organizationRepository */
$organizationRepository = $this->em->getRepository(Organization::class);
$organizationList = [];
if ($this->getUser()) {
$organizations = $userRepository->getOrganizationsByUser($this->getUser()->getUsername());
foreach ($organizations as $organizationID) {
$organization = $organizationRepository->find($organizationID);
if (null !== $organization) {
$organizationList[] = [
'id' => $organization->getId(),
'legalName' => $organization->getLegalName(),
];
}
}
return $this->json($organizationList);
}
return new JsonResponse(['error' => 'No user found.'], Response::HTTP_NOT_FOUND);
}
}