<?php
namespace App\Controller\Participation;
use App\Controller\APIController;
use App\Form\Participation\OdrParticipationType;
use App\Form\User\UserRegisterType;
use App\Manager\Participation\ParticipationOdrManager;
use App\Manager\ParticipationManager;
use App\Manager\User\UserManager;
use App\Model\Operation\Odr;
use App\Model\Participation\Odr as ParticipationOdr;
use App\Model\State;
use App\Model\User\Identity;
use App\Model\User\User;
use App\Security\Odr\OdrVoter;
use Exception;
use JMS\Serializer\DeserializationContext;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Serializer;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
/**
* Class OdrController.
*
* @Route("/offre-de-remboursement")
*/
class OdrController extends APIController
{
/**
* @Route("/inscription-au-club", name="kiwi_operation_odr_register_user")
*/
public function registerOdrOffer(Request $request)
{
$user = new User();
$form = $this->createForm(UserRegisterType::class, $user);
$user->setIdentity(
(new Identity())
->setFirstName('')
->setLastName('')
);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$encoders = [new JsonEncoder()];
$normalizers = [new ObjectNormalizer()];
$serializer = new Serializer($normalizers, $encoders);
$userRequest = $request->request->get('user_register');
$json = $serializer->serialize($form->getData(), 'json', [AbstractObjectNormalizer::SKIP_NULL_VALUES => true]);
$response = $this->APIKiwi->register($json);
try {
$user = $this->serializer->deserialize($response->getContent(), User::class, 'json', DeserializationContext::create()->setGroups(['get_user']));
$this->requestStack->getSession()->set('kiwi_register_odr_user_id', $user->getId());
$this->requestStack->getSession()->set('kiwi_register_odr_email', $user->getEmail());
$response = $this->APIKiwi->postLoginAfterRegistration(['email' => $userRequest['email']['first'], 'password' => $userRequest['plainPassword']['first']]);
$apiToken = $this->decodeContent($response)['token'];
$this->setTokenStorage($user, $apiToken);
return $this->redirectToRoute('kiwi_operation_odr_form_participation_user');
} catch (ClientExceptionInterface $e) {
$this->catchRegisterError($response, $e);
} catch (Exception $e) {
$this->logger->error(sprintf('%s : %s', get_class($e), $e->getMessage()), $e->getTrace());
$this->addFlash('warning', $this->translator->trans('api.validation.errors.generic', [], 'api'));
}
}
$odrResp = $this->APIKiwi->getPublicKiwi('odr/'. $this->requestStack->getSession()->get('kiwi_operation_odr_id'));
return $this->render('operation/odr/register_from_odr.html.twig', [
'form' => $form->createView(),
'odr' => $this->deserialize($odrResp->getContent(), Odr::class, 'get_odr'),
]);
}
/**
* @Route("/formulaire-participation", name="kiwi_operation_odr_form_participation_user")
* @IsGranted("IS_AUTHENTICATED_FULLY")
* @throws Exception
* @throws TransportExceptionInterface
*/
public function participationForm(Request $request, UserManager $userManager, ParticipationOdrManager $participationOdrManager, ParticipationManager $participationManager)
{
$userInterface = $this->getUser();
$user = $this->getUserData();
$odrId = $this->requestStack->getSession()->get('kiwi_operation_odr_id');
$offerResp = $participationOdrManager->getOdrInformation($odrId);
$odrWithRelations = $this->deserialize($offerResp->getContent(), Odr::class, 'get_odrs');
$nbParticipationsUser = $this->APIKiwi->getKiwi(['path' => '/participation-odrs/user/operation/'.$odrId.'?reparticipation=false', 'token' => $this->getUser()->getToken()])->getContent(); //Retourne le nombre de participation de l'utilisateur à une opération
$nbParticipations = $this->APIKiwi->getPublicKiwi('get-nb-participation-odr/'.$odrId)->getContent(); //Retourne le nombre de participation totale d'une opération
if ($nbParticipations >= $odrWithRelations->getMaxParticipationPerMonth()) {
$this->flashBag->add('danger', 'Cette offre est épuisé');
return $this->redirectToRoute('kiwi_operation_odr_show', ['odrId' => $odrId]);
}
if ('MONTHLY' === $odrWithRelations->getPeriodicity()) {
if (intval($nbParticipationsUser) >= $odrWithRelations->getMaxPartByUser()) {
$this->flashBag->add('danger', 'Vous avez atteint votre quotas mensuel de participation pour cette offre.');
return $this->redirectToRoute('kiwi_operation_odr_show', ['odrId' => $odrId]);
}
} else {
if (intval($nbParticipationsUser) >= $odrWithRelations->getMaxPartByUser()) {
$this->flashBag->add('danger', 'Vous avez atteint votre quotas global de participation pour cette offre.');
return $this->redirectToRoute('kiwi_operation_odr_show', ['odrId' => $odrId]);
}
}
return $this->buildParticipationPage($request, $userManager, $participationOdrManager, $participationManager, $user, $userInterface, $odrWithRelations);
}
private function catchRegisterError($response, $e)
{
$content = json_decode($response->getContent(false), true);
if (isset($content['@type']) && 'ConstraintViolationList' === $content['@type'] && isset($content['violations'])) {
foreach ($content['violations'] as $violation) {
$this->addFlash(
'warning',
sprintf(
'%s : %s',
$this->translator->trans(sprintf('api.validation.properties.%s', $violation['propertyPath']), [], 'api'),
$this->translator->trans(sprintf('api.validation.codes.%s', $violation['code']), [], 'api')
)
);
}
} else {
$this->logger->error(sprintf('%s : %s', 'ClientException', $e->getMessage()), $e->getTrace());
$this->addFlash('warning', $this->translator->trans('api.validation.errors.generic', [], 'api'));
}
}
/**
* @Route("/recapitulatif", name="kiwi_participation_recap_participation_odr")
* @IsGranted("IS_AUTHENTICATED_FULLY")
* @throws Exception|TransportExceptionInterface
*/
public function recap()
{
$this->requestStack->getSession()->set('kiwi_target_path', 'kiwi_participation_recap_participation_odr');
$iban = $this->requestStack->getSession()->get('kiwi_participation_iban_bic');
$ibanStart = substr($iban['accountNumber'], 0, 4);
$ibanEnd = substr($iban['accountNumber'], -4);
$odrResp = $this->APIKiwi->getPublicKiwi('odr/'. $this->requestStack->getSession()->get('kiwi_operation_odr_id'));
return $this->render('participation/odr/recap.html.twig', [
'user' => $this->APIKiwi->getUserData($this->getUser()),
'odr' => $this->deserialize($odrResp->getContent(), Odr::class, 'get_odr'),
'eans' => $this->requestStack->getSession()->get('kiwi_participation_eans'),
'medias' => $this->requestStack->getSession()->get('kiwi_participation_odr_medias'),
'iban' => str_pad($ibanStart, strlen($iban['accountNumber']) - 8, '*').$ibanEnd,
'bic' => $iban['bic'],
]);
}
/**
* @Route("/confirmation", name="kiwi_participation_confirm_participation_odr")
* @IsGranted("IS_AUTHENTICATED_FULLY")
*/
public function confirmParticipation(ParticipationOdrManager $participationOdrManager)
{
$participationId = $this->requestStack->getSession()->get('kiwi_participation_participation_id');
$user = $this->getUser();
$stateResp = $this->APIKiwi->getKiwi(['path' => '/states?label=participation_progress', 'token' => $user->getToken()]);
$state = $this->batchDeserialize(json_decode($stateResp->getContent(), true)['hydra:member'], State::class, 'get_states')[0];
if ( $this->requestStack->getSession()->has('kiwi_participation_nct_id')) {
$participationOdrManager->confirmParticipation($user, $participationId, $this->requestStack->getSession()->get('kiwi_participation_nct_id'), $state->getId(), true, $this->requestStack->getSession()->get('kiwi_participation_token'));
} else {
$participationOdrManager->confirmParticipation($user, $participationId, null, $state->getId(), false, null);
}
$odrResp = $this->APIKiwi->getPublicKiwi('odr/'. $this->requestStack->getSession()->get('kiwi_operation_odr_id'));
$odr = $this->deserialize($odrResp->getContent(), Odr::class, 'get_odr');
$participationOdrManager->postParticipationSmp($user, $participationId);
if ( $this->requestStack->getSession()->has('kiwi_register_odr_user_id')) {
$this->requestStack->getSession()->clear();
return $this->render('participation/odr/register_confirmation.html.twig', [
'odr' => $this->deserialize($odrResp->getContent(), Odr::class, 'get_odr'),
]);
}
//Passe l'ancienne participation NCT au status participation_edited
if ( $this->requestStack->getSession()->has('kiwi_participation_nct_id')) {
$participationNctId = $this->requestStack->getSession()->get('kiwi_participation_nct_id');
$stateResp = $this->APIKiwi->getKiwi(['path' => '/states?label=participation_edited', 'token' => $user->getToken()]);
$state = $this->batchDeserialize(json_decode($stateResp->getContent(), true)['hydra:member'], State::class, 'get_states')[0];
$participationOdrManager->confirmParticipation($user, $participationNctId, null, $state->getId(), false, null);
}
$this->requestStack->getSession()->clear();
return $this->render('participation/odr/confirmation.html.twig', [
'odr' => $odr,
]);
}
/**
* @Route("/participation", name="participation_odr")
* @IsGranted("IS_AUTHENTICATED_FULLY")
*/
public function index(): Response
{
$this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
$userInterface = $this->getUser();
$participations = $this->APIKiwi->getKiwi(['path' => '/participation-odrs/user', 'token' => $userInterface->getToken()]);
$template = isset($_ENV['PROJECT_TYPE']) && 'step' === $_ENV['PROJECT_TYPE'] ? 'participation/odr/index_tabs.html.twig' : 'participation/odr/index.html.twig';
return $this->render($template, [
'participations' => $this->batchDeserialize(json_decode($participations->getContent(), true)['hydra:member'], ParticipationOdr::class, 'get_participation_odrs'),
]);
}
/**
* @Route("/participation/{participationId}/operation/{odrId}", name="kiwi_show_participation_id")
* @IsGranted("IS_AUTHENTICATED_FULLY")
*/
public function show($participationId, $odrId, ParticipationOdrManager $participationOdrManager): Response
{
$this->requestStack->getSession()->set('_target_path', 'kiwi_show_participation_id');
$this->requestStack->getSession()->set('_target_path_params', ['participationId' => $participationId, 'odrId' => $odrId]);
$this->denyAccessUnlessGranted(OdrVoter::GET_ODR_DELIVERY);
$user = $this->getUser();
$odrResp = $this->APIKiwi->getPublicKiwi('operation-odr/'.$odrId);
$participationResp = $participationOdrManager->getParticipationIdByUser($user, $participationId);
$participation = $this->deserialize($participationResp->getContent(), ParticipationOdr::class, 'get_participation_odr_by_id');
$this->requestStack->getSession()->set('kiwi_operation_odr_id', $odrId);
if (State::PARTICIPATION_UNCONFORMED_TEMP == $participation->getState()->getLabel()) {
$this->requestStack->getSession()->set('kiwi_participation_nct_id', $participationId);
}
return $this->render('participation/odr/detail_participation.html.twig', [
'user' => $this->APIKiwi->getUserData($this->getUser()),
'odr' => $this->deserialize($odrResp->getContent(), Odr::class, 'get_odr'),
'participation' => $participation,
]);
}
/**
* @Route("/formulaire-reparticipation/{participationId}", name="kiwi_operation_odr_form_reparticipation_user")
* @IsGranted("IS_AUTHENTICATED_FULLY")
*/
public function reparticipationForm(Request $request, UserManager $userManager, $participationId, ParticipationOdrManager $participationOdrManager, ParticipationManager $participationManager)
{
$userInterface = $this->getUser();
$user = $this->getUserData();
$odrId = $this->requestStack->getSession()->get('kiwi_operation_odr_id');
$offerResp = $participationOdrManager->getOdrInformation($odrId);
$odrWithRelations = $this->deserialize($offerResp->getContent(), Odr::class, 'get_odrs');
$participationResp = $participationOdrManager->getReParticipationIdByUser($userInterface, $participationId);
$participation = $this->deserialize($participationResp->getContent(), ParticipationOdr::class, 'get_participation_odr_by_id');
return $this->buildParticipationPage($request, $userManager, $participationOdrManager, $participationManager, $user, $userInterface, $odrWithRelations, true, $participation);
}
private function buildParticipationPage(Request $request, UserManager $userManager, ParticipationOdrManager $participationOdrManager, ParticipationManager $participationManager, $user, $userInterface, $odrWithRelations, $edit = false, $participation = null)
{
$form = $this->createForm(OdrParticipationType::class, [
'user' => $user,
'eans' => $odrWithRelations->getDetailsOdr()->getEans(),
'edit' => $edit,
'participation' => $participation,
]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$data = $form->getData();
$address = [
'street' => $data['street'],
'complement' => $data['complement'],
'postalCode' => $data['postalCode'],
'city' => $data['city'],
];
$eans = $data['eans'];
$iban = null;
if (!array_key_exists('editIban', $data)) {
$iban = $participationOdrManager->setIban($data['accountNumber'], $data['bic']);
} else {
if ($data['editIban'] && !$edit) {
$iban = $participationOdrManager->setIban($data['accountNumber'], $data['bic']);
}
}
if ($participation) {
$iban = $participationOdrManager->setIban($participation->getIban(), $participation->getBic());
$this->requestStack->getSession()->set('kiwi_participation_token', $participation->getToken());
}
$this->requestStack->getSession()->set('kiwi_participation_eans', $eans);
$this->requestStack->getSession()->set('kiwi_target_path', 'kiwi_participation_recap_participation_odr');
if (!$iban) {
$this->requestStack->getSession()->set('kiwi_participation_iban_bic', $participationOdrManager->setIban($user->getIbans()[0]->getHiddenAccountNumber(), $user->getIbans()[0]->getBic()));
} else {
$this->requestStack->getSession()->set('kiwi_participation_iban_bic', $iban);
}
if ((empty($user->getSiret()) || empty($user->getCompanyName()) || empty($user->getIdentity()->getLastName()) || empty($user->getIdentity()->getFirstName())) || empty($user->getPhoneNumber())) {
if (!array_key_exists('phoneNumber', $data)) {
$data['phoneNumber'] = $user->getPhoneNumber();
}
$user->getIdentity()
->setLastName($data['lastName'])
->setFirstName($data['firstName']);
$user
->setSiret($data['siret'])
->setCompanyName($data['companyName'])
->setPhoneNumber($data['phoneNumber']);
$userManager->sendCreateOrUpdateDataCustomerToSalesforce($userInterface);
$userManager->requestUser($userInterface, '/users/' . $userInterface->getId(), $user, 'put_user_general');
}
$data = $participationOdrManager->setDeliveryInformation($data, $address, $user);
$data['user'] = '/api/users/'.$userInterface->getId();
$userManager->createOrUpdateDelivery($user, $userInterface, $data);
//Participation
$filesArray = $participationManager->postFiles($userInterface, $request->files->get('odr_participation')['file']);
$this->requestStack->getSession()->set('kiwi_participation_odr_medias', $filesArray);
$participation = $participationOdrManager->postParticipation($userInterface, $odrWithRelations->getId(), $eans, $filesArray, $iban);
$participationId = substr($participation[0], (strrpos($participation[0], '/') + 1));
$this->requestStack->getSession()->set('kiwi_participation_participation_id', $participationId);
return $this->redirectToRoute('kiwi_participation_recap_participation_odr');
}
$odrResp = $this->APIKiwi->getPublicKiwi('odr/'. $this->requestStack->getSession()->get('kiwi_operation_odr_id'));
return $this->render('operation/odr/address_delivery.html.twig', [
'form' => $form->createView(),
'odr' => $this->deserialize($odrResp->getContent(), Odr::class, 'get_odr'),
]);
}
}