Commit ad6e0143 by Yvon

refactor PaymentStatusExtension and connect new controller handling recurring…

refactor PaymentStatusExtension and connect new controller handling recurring notifications to payment processing logic
parent 268108a6
......@@ -129,6 +129,10 @@ services:
public: true
arguments: ['@app.utils.custom_entity_manager', '@security.helper', '@app.utils.operations']
app.utils.payment:
class: App\Utils\PaymentUtils
autowire: true
app.twig.main.extension:
class: App\Twig\AppExtension
autowire: false
......
......@@ -2,26 +2,26 @@
namespace App\Controller;
use App\Entity\GlobalParameter;
use App\Entity\Payment;
use App\Entity\User;
use App\Security\LoginAuthenticator;
use App\Utils\PaymentUtils;
use Doctrine\ORM\EntityManagerInterface;
use Payum\Core\Payum;
use Payum\Core\Request\GetHumanStatus;
use Payum\Core\Request\Notify;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\Form;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Translation\TranslatorInterface;
use Payum\Core\Payum;
use Payum\Core\Request\Notify;
use Payum\Core\Request\GetHumanStatus;
use App\Entity\Flux;
use App\Entity\Payment;
use App\Entity\User;
use App\Entity\GlobalParameter;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
use App\Security\LoginAuthenticator;
use Symfony\Component\Security\Guard\GuardAuthenticatorHandler;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
use Symfony\Component\Translation\TranslatorInterface;
/**
* Gestion des paiements avec Payum
* Gestion des paiements avec Payum.
*/
class PaymentController extends AbstractController
{
......@@ -30,22 +30,25 @@ class PaymentController extends AbstractController
protected $payum;
protected $authenticator;
protected $guardHandler;
protected $paymentUtils;
public function __construct(EntityManagerInterface $em,
TranslatorInterface $translator,
LoginAuthenticator $authenticator,
GuardAuthenticatorHandler $guardHandler,
Payum $payum)
Payum $payum,
PaymentUtils $paymentUtils)
{
$this->em = $em;
$this->translator = $translator;
$this->payum = $payum;
$this->authenticator = $authenticator;
$this->guardHandler = $guardHandler;
$this->paymentUtils = $paymentUtils;
}
/**
* Crée une instance de Payment, les tokens associés, et redirige vers la page de paiement
* Crée une instance de Payment, les tokens associés, et redirige vers la page de paiement.
*/
public function preparePaymentAction(Form $form, $type, $extra_data = null)
{
......@@ -71,20 +74,21 @@ class PaymentController extends AbstractController
],
'expediteur' => ['id'],
'destinataire' => ['id'],
'operateur' => ['id']]
'operateur' => ['id'], ],
]);
$jsondata = $serializer->serialize($data, 'json');
// Prepare CB Payment
if ($this->em->getRepository(GlobalParameter::class)->val(GlobalParameter::USE_PAYZEN) === 'true') {
$gatewayName = 'payzen';
if ('true' === $this->em->getRepository(GlobalParameter::class)->val(GlobalParameter::USE_PAYZEN)) {
$gatewayName = 'payzen';
} else {
$this->addFlash(
$this->addFlash(
'error',
$this->translator->trans('Une erreur est survenue due à la configuration du paiement dans l\'application. Il est pour l\'instant impossible de payer par CB, merci de contacter votre monnaie locale.')
);
return $this->redirectToRoute('index');
return $this->redirectToRoute('index');
}
$storage = $this->payum->getStorage('App\Entity\Payment');
......@@ -100,8 +104,8 @@ class PaymentController extends AbstractController
$payment->setExtraData($extra_data);
}
if ($type == Payment::TYPE_ADHESION) {
$payment->setTotalAmount($form->get('cotisation')->get('montant')->getData()*100); // 1.23 EUR
if (Payment::TYPE_ADHESION == $type) {
$payment->setTotalAmount($form->get('cotisation')->get('montant')->getData() * 100); // 1.23 EUR
$payment->setClientId('Nouvel adhérent');
$payment->setClientEmail($form->get('user')->get('email')->getData());
} else {
......@@ -115,11 +119,11 @@ class PaymentController extends AbstractController
$payment->setClientEmail($this->getUser()->getEmail());
}
if ($type == Payment::TYPE_PAIEMENT_RECURRENT_COTISATION_TAV) {
$payment->setRecurrenceAmount($form->get('montant')->getData() * 100);
$payment->setIsRecurrent(true);
$payment->setRecurrenceMonthsCount($form->get('nombreMois')->getData());
$payment->setRecurrenceMonthDay($form->get('jourPrelevement')->getData());
if (Payment::TYPE_PAIEMENT_RECURRENT_COTISATION_TAV == $type) {
$payment->setRecurrenceAmount($form->get('montant')->getData() * 100);
$payment->setIsRecurrent(true);
$payment->setRecurrenceMonthsCount($form->get('nombreMois')->getData());
$payment->setRecurrenceMonthDay($form->get('jourPrelevement')->getData());
}
$storage->update($payment);
......@@ -144,29 +148,50 @@ class PaymentController extends AbstractController
}
/**
* Collects payzen recurring payment payment occurence in place of default payum system.
*
* Payum default controler is not able to catch URL recurring payment notifications
* because payzen actual used URL has shape /payment/notify instead of /payment/notify/token.
*
* @param Request $request
*
* @return Response
* @Route("/payment/notify", name="notify_recurring_payment")
*/
public function notifyRecurringPaymentAction(Request $request)
{
$vads_cust_email = $request->request->get("vads_cust_email");
$vads_cust_email = $request->request->get('vads_cust_email');
//Look for recurring payments from this client.
$recurringPayments = $this->em->getRepository(Payment::class)->findBy([
'isRecurrent' => true,
'clientEmail' => $vads_cust_email,
]);
if(!$recurringPayments) {
return new Response("No recurring payments with email " . $vads_cust_email);
if (!$recurringPayments) {
//return error
return new Response('No recurring payments with email ' . $vads_cust_email, 405);
}
$vads_identifier = $request->request->get("vads_identifier");
foreach($recurringPayments as $rp) {
if($rp->getDetails()['vads_identifier'] == $vads_identifier) {
return new Response("Found matching recurring payment !");
$vads_identifier = $request->request->get('vads_identifier');
$vads_trans_status = $request->request->get('vads_trans_status');
$new_status = strtolower($vads_trans_status);
foreach ($recurringPayments as $payment) {
//Just look for one valid payment.
if ($payment->getDetails()['vads_identifier'] == $vads_identifier) {
if (
GetHumanStatus::STATUS_CAPTURED == $new_status
|| GetHumanStatus::STATUS_AUTHORIZED == $new_status
) {
$this->paymentUtils->handlePayzenNotificationCore($payment);
$this->em->flush();
}
return new Response('Recurring payment occurence taken into account.', 200);
}
}
return new Response("No recurring payments with vads_identifier " . $vads_identifier);
//return error
return new Response('No recurring payments with vads_identifier ' . $vads_identifier, 405);
}
/**
......@@ -179,6 +204,9 @@ class PaymentController extends AbstractController
* Pour plus de clarté, on gagne à modifier finalement l'URL de retour Payzen dans le backoffice de sorte
* à pointer vers notifyAction également (INSTALL.md modifié).
*
* Comme si ce n'était pas assez compliqué comme ça, les notifications de paiement récurrents n'arrivent
* cependant pas à NotifyController et on les capte ici avec le controller notifyRecurringPaymentAction.
*
* @Route("/payment/done/", name="payment_done")
*/
public function doneAction(Request $request)
......@@ -199,7 +227,7 @@ class PaymentController extends AbstractController
//so we should not be handling recurring payment after the initial payement.
//We must indeed prevent a user from a browser reload e.g.
if ($payment->getStatus() == GetHumanStatus::STATUS_NEW) {
if (GetHumanStatus::STATUS_NEW == $payment->getStatus()) {
// No notification arrived at this point : execute Notify action
// Recurring payment should not trigger notify action here except on initial payment
// as only Payzen agent is allowed to trigger occurences after the first one
......@@ -213,50 +241,48 @@ class PaymentController extends AbstractController
}
// Set flash message according to payment status
if ($payment->getStatus() == GetHumanStatus::STATUS_CAPTURED || $payment->getStatus() == GetHumanStatus::STATUS_AUTHORIZED) {
$type = $payment->getDescription();
if (GetHumanStatus::STATUS_CAPTURED == $payment->getStatus() || GetHumanStatus::STATUS_AUTHORIZED == $payment->getStatus()) {
$type = $payment->getDescription();
if (Payment::TYPE_ACHAT_MONNAIE_ADHERENT == $type || Payment::TYPE_ACHAT_MONNAIE_PRESTA == $type) {
$this->addFlash(
if (Payment::TYPE_ACHAT_MONNAIE_ADHERENT == $type || Payment::TYPE_ACHAT_MONNAIE_PRESTA == $type) {
$this->addFlash(
'success',
$this->translator->trans('Achat de monnaie locale bien effectué !')
);
} else if (Payment::TYPE_COTISATION_ADHERENT == $type || Payment::TYPE_COTISATION_PRESTA == $type) {
$this->addFlash(
} elseif (Payment::TYPE_COTISATION_ADHERENT == $type || Payment::TYPE_COTISATION_PRESTA == $type) {
$this->addFlash(
'success',
$this->translator->trans('Cotisation bien reçue. Merci !')
);
} else if (Payment::TYPE_ADHESION == $type) {
$this->addFlash(
} elseif (Payment::TYPE_ADHESION == $type) {
$this->addFlash(
'success',
$this->translator->trans('Votre adhésion a bien été prise en compte, bienvenue !')
);
// Connect new user
return $this->guardHandler
// Connect new user
return $this->guardHandler
->authenticateUserAndHandleSuccess(
$this->em->getRepository(User::class)->findOneBy(array('id' => $payment->getClientId())),
$this->em->getRepository(User::class)->findOneBy(['id' => $payment->getClientId()]),
$request,
$this->authenticator,
'main'
);
} else if (Payment::TYPE_PAIEMENT_COTISATION_TAV == $type || Payment::TYPE_PAIEMENT_RECURRENT_COTISATION_TAV) {
$this->addFlash(
} elseif (Payment::TYPE_PAIEMENT_COTISATION_TAV == $type || Payment::TYPE_PAIEMENT_RECURRENT_COTISATION_TAV) {
$this->addFlash(
'success',
$this->translator->trans('Cotisation payée !')
);
}
} else if ($payment->getStatus() == GetHumanStatus::STATUS_CANCELED ||
$payment->getStatus() == GetHumanStatus::STATUS_EXPIRED ||
$payment->getStatus() == GetHumanStatus::STATUS_FAILED)
{
$this->addFlash(
}
} elseif (GetHumanStatus::STATUS_CANCELED == $payment->getStatus() ||
GetHumanStatus::STATUS_EXPIRED == $payment->getStatus() ||
GetHumanStatus::STATUS_FAILED == $payment->getStatus()) {
$this->addFlash(
'error',
$this->translator->trans('La transaction a été annulée.')
);
}
}
return $this->redirectToRoute('index');
}
}
......@@ -2,38 +2,20 @@
namespace App\EventListener;
use App\Utils\OperationUtils;
use App\Utils\PaymentUtils;
use App\Utils\TAVCotisationUtils;
use Doctrine\ORM\EntityManagerInterface;
use FOS\UserBundle\Model\UserManagerInterface;
use Payum\Core\Extension\Context;
use Payum\Core\Extension\ExtensionInterface;
use Payum\Core\Model\PaymentInterface;
use Payum\Core\Request\Generic;
use Payum\Core\Request\GetHumanStatus;
use Payum\Core\Request\GetStatusInterface;
use Payum\Core\Bridge\Symfony\Event\ExecuteEvent;
use Doctrine\ORM\EntityManagerInterface;
use FOS\UserBundle\Model\UserManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use App\Events\MLCEvents;
use App\Events\FluxEvent;
use App\Entity\Flux;
use App\Entity\Payment;
use App\Entity\PaymentToken;
use App\Entity\Siege;
use App\Entity\User;
use App\Entity\Adherent;
use App\Entity\Prestataire;
use App\Entity\Geoloc;
use App\Entity\Groupe;
use App\Entity\Usergroup;
use App\Entity\AchatMonnaieAdherent;
use App\Entity\AchatMonnaiePrestataire;
use App\Entity\CotisationAdherent;
use App\Entity\CotisationPrestataire;
use App\Entity\Don;
use App\Utils\OperationUtils;
use App\Utils\TAVCotisationUtils;
class PaymentStatusExtension implements ExtensionInterface
{
......@@ -44,6 +26,7 @@ class PaymentStatusExtension implements ExtensionInterface
private $operationUtils;
private $tavCotisationsUtils;
private $container;
private $paymentUtils;
/**
* PaymentStatusExtension constructor.
......@@ -51,13 +34,14 @@ class PaymentStatusExtension implements ExtensionInterface
* @param EntityManagerInterface $em
*/
public function __construct(
EntityManagerInterface $em,
EventDispatcherInterface $eventDispatcher,
SerializerInterface $serializer,
EntityManagerInterface $em,
EventDispatcherInterface $eventDispatcher,
SerializerInterface $serializer,
UserManagerInterface $userManager,
OperationUtils $operationUtils,
TAVCotisationUtils $tavCotisationsUtils,
ContainerInterface $container
ContainerInterface $container,
PaymentUtils $paymentUtils
) {
$this->em = $em;
$this->eventDispatcher = $eventDispatcher;
......@@ -66,6 +50,7 @@ class PaymentStatusExtension implements ExtensionInterface
$this->operationUtils = $operationUtils;
$this->tavCotisationsUtils = $tavCotisationsUtils;
$this->container = $container;
$this->paymentUtils = $paymentUtils;
}
/**
......@@ -95,228 +80,35 @@ class PaymentStatusExtension implements ExtensionInterface
// Get current & new status
$context->getGateway()->execute($status = new GetHumanStatus($payment));
$current_payment_status = $payment->getStatus();
$current_payment_is_recurrent = $payment->getIsRecurrent();
// Payment can be captured if it hasn't been captured before
// Allow STATUS_CAPTURED and STATUS_AUTHORIZED for recurrent payment only.
if ($current_payment_status !== GetHumanStatus::STATUS_CAPTURED
&& $current_payment_status != GetHumanStatus::STATUS_AUTHORIZED
|| $current_payment_is_recurrent)
{
// If payment succesful, persist serialized 'Flux' stored in payment
if ($status->getValue() == GetHumanStatus::STATUS_CAPTURED
|| $status->getValue() == GetHumanStatus::STATUS_AUTHORIZED)
{
$flux_array = json_decode($payment->getFluxData(), true);
$type = $payment->getDescription();
if (Payment::TYPE_ACHAT_MONNAIE_ADHERENT == $type) {
$flux = $this->serializer->deserialize(
$payment->getFluxData(),
AchatMonnaieAdherent::class,
'json',
['disable_type_enforcement' => true]
);
$exp = $this->em->getRepository(Siege::class)->find($flux_array['expediteur']);
$flux->setExpediteur($exp);
$dest = $this->em->getRepository(Adherent::class)->find($flux_array['destinataire']);
$flux->setDestinataire($dest);
$op = $this->em->getRepository(User::class)->find($flux_array['operateur']);
$flux->setOperateur($op);
$flux->setReconverti(true);
if (null != $flux->getDon()) {
$flux->getDon()->setType(Don::TYPE_DON_ADHERENT);
$flux->getDon()->setOperateur($op);
$flux->getDon()->setExpediteur($dest);
$flux->getDon()->setDestinataire($this->em->getRepository(Prestataire::class)->findOneBy(['mlc' => true]));
}
} else if (Payment::TYPE_ACHAT_MONNAIE_PRESTA == $type) {
$flux = $this->serializer->deserialize(
$payment->getFluxData(),
AchatMonnaiePrestataire::class,
'json',
['disable_type_enforcement' => true]
);
$exp = $this->em->getRepository(Siege::class)->find($flux_array['expediteur']);
$flux->setExpediteur($exp);
$dest = $this->em->getRepository(Prestataire::class)->find($flux_array['destinataire']);
$flux->setDestinataire($dest);
$op = $this->em->getRepository(User::class)->find($flux_array['operateur']);
$flux->setOperateur($op);
$flux->setReconverti(true);
if (null != $flux->getDon()) {
$flux->getDon()->setType(Don::TYPE_DON_PRESTATAIRE);
$flux->getDon()->setOperateur($op);
$flux->getDon()->setExpediteur($dest);
$flux->getDon()->setDestinataire($this->em->getRepository(Prestataire::class)->findOneBy(['mlc' => true]));
}
} else if (Payment::TYPE_COTISATION_ADHERENT == $type) {
$flux = $this->serializer->deserialize(
$payment->getFluxData(),
CotisationAdherent::class,
'json',
['disable_type_enforcement' => true]
);
$exp = $this->em->getRepository(Adherent::class)->find($flux_array['expediteur']);
$flux->setExpediteur($exp);
$dest = $this->em->getRepository(Prestataire::class)->find($flux_array['destinataire']);
$flux->setDestinataire($dest);
$op = $this->em->getRepository(User::class)->find($flux_array['operateur']);
$flux->setOperateur($op);
$flux->setRecu(true);
if (null != $flux->getDon()) {
$flux->getDon()->setType(Don::TYPE_DON_ADHERENT);
$flux->getDon()->setOperateur($op);
$flux->getDon()->setExpediteur($exp);
$flux->getDon()->setDestinataire($this->em->getRepository(Prestataire::class)->findOneBy(['mlc' => true]));
}
} else if (Payment::TYPE_COTISATION_PRESTA == $type) {
$flux = $this->serializer->deserialize(
$payment->getFluxData(),
CotisationPrestataire::class,
'json',
['disable_type_enforcement' => true]
);
$exp = $this->em->getRepository(Prestataire::class)->find($flux_array['expediteur']);
$flux->setExpediteur($exp);
$dest = $this->em->getRepository(Prestataire::class)->find($flux_array['destinataire']);
$flux->setDestinataire($dest);
$op = $this->em->getRepository(User::class)->find($flux_array['operateur']);
$flux->setOperateur($op);
$flux->setRecu(true);
if (null != $flux->getDon()) {
$flux->getDon()->setType(Don::TYPE_DON_PRESTATAIRE);
$flux->getDon()->setOperateur($op);
$flux->getDon()->setExpediteur($exp);
$flux->getDon()->setDestinataire($this->em->getRepository(Prestataire::class)->findOneBy(['mlc' => true]));
}
} else if (Payment::TYPE_ADHESION == $type) {
$new_adherent_data = json_decode($payment->getExtraData());
$adherent = new Adherent();
$user = $this->userManager->createUser();
$usergroup = $this->em->getRepository(Usergroup::class)->findOneByName('Adherent');
$group = $this->em->getRepository(Groupe::class)->findOneBy(array('id' => $new_adherent_data->groupe->id));
$user->setEmail($new_adherent_data->user->email);
$user->setUsername($new_adherent_data->user->username);
$user->setFirstname($new_adherent_data->user->firstname);
$user->setLastname($new_adherent_data->user->lastname);
$user->setPlainPassword($new_adherent_data->user->plainPassword);
$user->setEnabled(true);
$user->addPossiblegroup($usergroup);
$user->addGroup($usergroup);
$user->addRole('ROLE_ADHERENT');
$user->setAdherent($adherent);
$adherent->setEcompte('0');
$adherent->setUser($user);
$adherent->setGroupe($group);
if ($adherent->getGeoloc() == null) {
$geoloc = new Geoloc();
$geoloc->setAdresse($new_adherent_data->geoloc->adresse);
$geoloc->setCpostal($new_adherent_data->geoloc->cpostal);
$geoloc->setVille($new_adherent_data->geoloc->ville);
$adherent->setGeoloc($geoloc);
}
$this->em->persist($adherent);
$this->em->flush();
// Create first cotisation
$flux = $this->serializer->deserialize(
$payment->getFluxData(),
CotisationAdherent::class,
'json',
['disable_type_enforcement' => true]
);
$flux->setOperateur($user);
$flux->setExpediteur($adherent);
$flux->setDestinataire($this->em->getRepository(Prestataire::class)->findOneBy(array('mlc' => true)));
$flux->setRole('Adherent');
$flux->setRecu(true);
// Update payment with new user id, remove user data
$payment->setClientId($user->getId());
$payment->setExtraData('');
$this->em->persist($payment);
} else if (Payment::TYPE_PAIEMENT_COTISATION_TAV == $type || Payment::TYPE_PAIEMENT_RECURRENT_COTISATION_TAV) {
// TODO deal with recurrent payment (don only on first payment...)
$flux = $this->serializer->deserialize(
$payment->getFluxData(),
AchatMonnaieAdherent::class,
'json',
['disable_type_enforcement' => true]
);
$exp = $this->em->getRepository(Siege::class)->find($flux_array['expediteur']);
$flux->setExpediteur($exp);
$dest = $this->em->getRepository(Adherent::class)->find($flux_array['destinataire']);
$flux->setDestinataire($dest);
$op = $this->em->getRepository(User::class)->find($flux_array['operateur']);
$flux->setOperateur($op);
$flux->setReconverti(true);
//For recurrent payment: save don only for first payment, otherwise remove don
//Use current payment status to decide (if first payment -> add don, if not -> remove don)
if (null != $flux->getDon() && $current_payment_status === GetHumanStatus::STATUS_NEW) {
$flux->getDon()->setType(Don::TYPE_DON_ADHERENT);
$flux->getDon()->setOperateur($op);
$flux->getDon()->setExpediteur($dest);
$flux->getDon()->setDestinataire($this->em->getRepository(Prestataire::class)->findOneBy(['mlc' => true]));
} else {
$flux->setDon(null);
}
} else {
// Bad request
}
$this->em->persist($flux);
$this->operationUtils->executeOperations($flux);
if (Payment::TYPE_PAIEMENT_COTISATION_TAV == $type || Payment::TYPE_PAIEMENT_RECURRENT_COTISATION_TAV) {
// Create new flux for cotisation, depending on process
if ($this->container->getParameter('household_based_allowance')) {
$this->tavCotisationsUtils->applyHouseholdAllowance($flux);
} else {
$this->tavCotisationsUtils->applyTauxCotisation($flux);
}
}
$new_status = $status->getValue();
if (
GetHumanStatus::STATUS_CAPTURED !== $current_payment_status
&& GetHumanStatus::STATUS_AUTHORIZED != $current_payment_status
|| $current_payment_is_recurrent
) {
if (
GetHumanStatus::STATUS_CAPTURED == $new_status
|| GetHumanStatus::STATUS_AUTHORIZED == $new_status
) {
$this->paymentUtils->handlePayzenNotificationCore($payment);
// Invalidate (delete) notify token after payment is captured
// For recurrent payment: don't delete notify token because we'll be notified on next recurrence payments
if(!$current_payment_is_recurrent) {
if (!$current_payment_is_recurrent) {
$this->em->remove($token);
}
$this->em->flush();
}
}
//Update status
// Update payment status with status received in payzen response
$payment->setStatus($status->getValue());
$payment->setStatus($new_status);
//Flush
$this->em->persist($payment);
$this->em->flush();
}
......
<?php
namespace App\Utils;
use App\Entity\AchatMonnaieAdherent;
use App\Entity\AchatMonnaiePrestataire;
use App\Entity\Adherent;
use App\Entity\CotisationAdherent;
use App\Entity\CotisationPrestataire;
use App\Entity\Don;
use App\Entity\Geoloc;
use App\Entity\Groupe;
use App\Entity\Payment;
use App\Entity\Prestataire;
use App\Entity\Siege;
use App\Entity\User;
use App\Entity\Usergroup;
use Doctrine\ORM\EntityManagerInterface;
use FOS\UserBundle\Model\UserManagerInterface;
use Payum\Core\Request\GetHumanStatus;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Serializer\SerializerInterface;
class PaymentUtils
{
private $em;
private $serializer;
private $userManager;
private $operationUtils;
private $tavCotisationsUtils;
private $container;
/**
* PaymentUtils constructor.
*/
public function __construct(
EntityManagerInterface $em,
SerializerInterface $serializer,
UserManagerInterface $userManager,
OperationUtils $operationUtils,
TAVCotisationUtils $tavCotisationsUtils,
ContainerInterface $container
) {
$this->em = $em;
$this->serializer = $serializer;
$this->userManager = $userManager;
$this->operationUtils = $operationUtils;
$this->tavCotisationsUtils = $tavCotisationsUtils;
$this->container = $container;
}
/**
* @param $payment
* @return void
* @throws \Exception
*/
public function handlePayzenNotificationCore($payment): void
{
$current_payment_status = $payment->getStatus();
// Payment can be captured if it hasn't been captured before
// Allow STATUS_CAPTURED and STATUS_AUTHORIZED for recurrent payment only.
$flux_array = json_decode($payment->getFluxData(), true);
$type = $payment->getDescription();
if (Payment::TYPE_ACHAT_MONNAIE_ADHERENT == $type) {
$flux = $this->serializer->deserialize(
$payment->getFluxData(),
AchatMonnaieAdherent::class,
'json',
['disable_type_enforcement' => true]
);
$exp = $this->em->getRepository(Siege::class)->find($flux_array['expediteur']);
$flux->setExpediteur($exp);
$dest = $this->em->getRepository(Adherent::class)->find($flux_array['destinataire']);
$flux->setDestinataire($dest);
$op = $this->em->getRepository(User::class)->find($flux_array['operateur']);
$flux->setOperateur($op);
$flux->setReconverti(true);
if (null != $flux->getDon()) {
$flux->getDon()->setType(Don::TYPE_DON_ADHERENT);
$flux->getDon()->setOperateur($op);
$flux->getDon()->setExpediteur($dest);
$flux->getDon()->setDestinataire($this->em->getRepository(Prestataire::class)->findOneBy(['mlc' => true]));
}
} else if (Payment::TYPE_ACHAT_MONNAIE_PRESTA == $type) {
$flux = $this->serializer->deserialize(
$payment->getFluxData(),
AchatMonnaiePrestataire::class,
'json',
['disable_type_enforcement' => true]
);
$exp = $this->em->getRepository(Siege::class)->find($flux_array['expediteur']);
$flux->setExpediteur($exp);
$dest = $this->em->getRepository(Prestataire::class)->find($flux_array['destinataire']);
$flux->setDestinataire($dest);
$op = $this->em->getRepository(User::class)->find($flux_array['operateur']);
$flux->setOperateur($op);
$flux->setReconverti(true);
if (null != $flux->getDon()) {
$flux->getDon()->setType(Don::TYPE_DON_PRESTATAIRE);
$flux->getDon()->setOperateur($op);
$flux->getDon()->setExpediteur($dest);
$flux->getDon()->setDestinataire($this->em->getRepository(Prestataire::class)->findOneBy(['mlc' => true]));
}
} else if (Payment::TYPE_COTISATION_ADHERENT == $type) {
$flux = $this->serializer->deserialize(
$payment->getFluxData(),
CotisationAdherent::class,
'json',
['disable_type_enforcement' => true]
);
$exp = $this->em->getRepository(Adherent::class)->find($flux_array['expediteur']);
$flux->setExpediteur($exp);
$dest = $this->em->getRepository(Prestataire::class)->find($flux_array['destinataire']);
$flux->setDestinataire($dest);
$op = $this->em->getRepository(User::class)->find($flux_array['operateur']);
$flux->setOperateur($op);
$flux->setRecu(true);
if (null != $flux->getDon()) {
$flux->getDon()->setType(Don::TYPE_DON_ADHERENT);
$flux->getDon()->setOperateur($op);
$flux->getDon()->setExpediteur($exp);
$flux->getDon()->setDestinataire($this->em->getRepository(Prestataire::class)->findOneBy(['mlc' => true]));
}
} else if (Payment::TYPE_COTISATION_PRESTA == $type) {
$flux = $this->serializer->deserialize(
$payment->getFluxData(),
CotisationPrestataire::class,
'json',
['disable_type_enforcement' => true]
);
$exp = $this->em->getRepository(Prestataire::class)->find($flux_array['expediteur']);
$flux->setExpediteur($exp);
$dest = $this->em->getRepository(Prestataire::class)->find($flux_array['destinataire']);
$flux->setDestinataire($dest);
$op = $this->em->getRepository(User::class)->find($flux_array['operateur']);
$flux->setOperateur($op);
$flux->setRecu(true);
if (null != $flux->getDon()) {
$flux->getDon()->setType(Don::TYPE_DON_PRESTATAIRE);
$flux->getDon()->setOperateur($op);
$flux->getDon()->setExpediteur($exp);
$flux->getDon()->setDestinataire($this->em->getRepository(Prestataire::class)->findOneBy(['mlc' => true]));
}
} else if (Payment::TYPE_ADHESION == $type) {
$new_adherent_data = json_decode($payment->getExtraData());
$adherent = new Adherent();
$user = $this->userManager->createUser();
$usergroup = $this->em->getRepository(Usergroup::class)->findOneByName('Adherent');
$group = $this->em->getRepository(Groupe::class)->findOneBy(array('id' => $new_adherent_data->groupe->id));
$user->setEmail($new_adherent_data->user->email);
$user->setUsername($new_adherent_data->user->username);
$user->setFirstname($new_adherent_data->user->firstname);
$user->setLastname($new_adherent_data->user->lastname);
$user->setPlainPassword($new_adherent_data->user->plainPassword);
$user->setEnabled(true);
$user->addPossiblegroup($usergroup);
$user->addGroup($usergroup);
$user->addRole('ROLE_ADHERENT');
$user->setAdherent($adherent);
$adherent->setEcompte('0');
$adherent->setUser($user);
$adherent->setGroupe($group);
if ($adherent->getGeoloc() == null) {
$geoloc = new Geoloc();
$geoloc->setAdresse($new_adherent_data->geoloc->adresse);
$geoloc->setCpostal($new_adherent_data->geoloc->cpostal);
$geoloc->setVille($new_adherent_data->geoloc->ville);
$adherent->setGeoloc($geoloc);
}
$this->em->persist($adherent);
$this->em->flush();
// Create first cotisation
$flux = $this->serializer->deserialize(
$payment->getFluxData(),
CotisationAdherent::class,
'json',
['disable_type_enforcement' => true]
);
$flux->setOperateur($user);
$flux->setExpediteur($adherent);
$flux->setDestinataire($this->em->getRepository(Prestataire::class)->findOneBy(array('mlc' => true)));
$flux->setRole('Adherent');
$flux->setRecu(true);
// Update payment with new user id, remove user data
$payment->setClientId($user->getId());
$payment->setExtraData('');
$this->em->persist($payment);
} else if (Payment::TYPE_PAIEMENT_COTISATION_TAV == $type || Payment::TYPE_PAIEMENT_RECURRENT_COTISATION_TAV) {
$flux = $this->serializer->deserialize(
$payment->getFluxData(),
AchatMonnaieAdherent::class,
'json',
['disable_type_enforcement' => true]
);
$exp = $this->em->getRepository(Siege::class)->find($flux_array['expediteur']);
$flux->setExpediteur($exp);
$dest = $this->em->getRepository(Adherent::class)->find($flux_array['destinataire']);
$flux->setDestinataire($dest);
$op = $this->em->getRepository(User::class)->find($flux_array['operateur']);
$flux->setOperateur($op);
$flux->setReconverti(true);
//For recurrent payment: save don only for first payment, otherwise remove don
//Use current payment status to decide (if first payment -> add don, if not -> remove don)
if (null != $flux->getDon() && $current_payment_status === GetHumanStatus::STATUS_NEW) {
$flux->getDon()->setType(Don::TYPE_DON_ADHERENT);
$flux->getDon()->setOperateur($op);
$flux->getDon()->setExpediteur($dest);
$flux->getDon()->setDestinataire($this->em->getRepository(Prestataire::class)->findOneBy(['mlc' => true]));
} else {
$flux->setDon(null);
}
} else {
// Bad request
}
$this->em->persist($flux);
$this->operationUtils->executeOperations($flux);
if (Payment::TYPE_PAIEMENT_COTISATION_TAV == $type || Payment::TYPE_PAIEMENT_RECURRENT_COTISATION_TAV) {
// Create new flux for cotisation, depending on process
if ($this->container->getParameter('household_based_allowance')) {
$this->tavCotisationsUtils->applyHouseholdAllowance($flux);
} else {
$this->tavCotisationsUtils->applyTauxCotisation($flux);
}
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment