<?php
namespace Acme\SudcmsBundle\Controller\Front;
use Acme\SudcmsBundle\Entity\ApiSettings;
use Acme\SudcmsBundle\Entity\Cure;
use Acme\SudcmsBundle\Entity\CureOrder;
use Acme\SudcmsBundle\Entity\CureProductOrder;
use Acme\SudcmsBundle\Entity\CureProductSoinsOrder;
use Acme\SudcmsBundle\Entity\EcoCustomers;
use Acme\SudcmsBundle\Entity\EcoDiscountOrders;
use Acme\SudcmsBundle\Entity\EcoOrders;
use Acme\SudcmsBundle\Entity\EcoPlanning;
use Acme\SudcmsBundle\Entity\EcoProductsBundle;
use Acme\SudcmsBundle\Entity\EcoProductsReferences;
use Acme\SudcmsBundle\Entity\EcoSettings;
use Acme\SudcmsBundle\Entity\EcoShippingCarriers;
use Acme\SudcmsBundle\Entity\Site;
use Acme\SudcmsBundle\Entity\SiteCoordonnees;
use Acme\SudcmsBundle\EventListener\BaseListener;
use Acme\SudcmsBundle\Repository\EcoCustomersAddressesRepository;
use Acme\SudcmsBundle\Repository\EcoCustomersRepository;
use Acme\SudcmsBundle\Repository\EcoDiscountRepository;
use Acme\SudcmsBundle\Repository\EcoOrdersProductsRepository;
use Acme\SudcmsBundle\Repository\EcoOrdersRepository;
use Acme\SudcmsBundle\Repository\SiteCoordonneesRepository;
use Acme\SudcmsBundle\Service\ApiLogsService;
use Acme\SudcmsBundle\Service\ApiService;
use Acme\SudcmsBundle\Service\Ecommerce\BasketService;
use Acme\SudcmsBundle\Service\Ecommerce\DiscountService;
use Acme\SudcmsBundle\Service\Ecommerce\LoyaltySystemService;
use Acme\SudcmsBundle\Service\Ecommerce\OrderService;
use Acme\SudcmsBundle\Service\Ecommerce\PayboxService;
use Acme\SudcmsBundle\Service\MailerService;
use Acme\SudcmsBundle\Service\OtideaUtils;
use DateTime;
use DateTimeZone;
use Doctrine\ORM\EntityManagerInterface;
use Exception;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\Routing\Annotation\Route;
use Throwable;
use const SITE_NAME;
#[Route(path: '/panier')]
class FrontBasketController extends AbstractController
{
private $session;
private $orderService;
private $entityManager;
private $mailerService;
private $otideaUtils;
private $loyaltySystem;
private $basketService;
private $baseListener;
private $repoDiscount;
private $discountService;
private $currentUserConnected;
private ApiService $apiService;
private ApiLogsService $logsService;
private Site $site;
private array $recipients = [
[
"nom" => "Otidea",
"prenom" => "Debug",
"email" => "mail@otidea.com",
"type" => 'to'
]
];
private ?ApiSettings $apiSettings;
public function __construct(
EntityManagerInterface $entityManager,
OrderService $orderService,
MailerService $mailerService,
OtideaUtils $otideaUtils,
LoyaltySystemService $loyaltySystem,
BasketService $basketService,
BaseListener $baseListener,
EcoDiscountRepository $repoDiscount,
DiscountService $discountService,
ApiService $apiService,
ApiLogsService $logsService
) {
$this->session = new Session();
$this->entityManager = $entityManager;
$this->orderService = $orderService;
$this->mailerService = $mailerService;
$this->otideaUtils = $otideaUtils;
$this->loyaltySystem = $loyaltySystem;
$this->basketService = $basketService;
$this->baseListener = $baseListener;
$this->repoDiscount = $repoDiscount;
$this->discountService = $discountService;
$this->currentUserConnected = $otideaUtils->getUserConnected();
$this->apiService = $apiService;
$this->logsService = $logsService;
$this->site = $this->entityManager->getRepository(Site::class)->findOneBy(
['id' => defined('CURRENT_SITE_ID') ? CURRENT_SITE_ID : 1]
);
$this->apiSettings = $this->entityManager->getRepository(ApiSettings::class)->findOneBy(
['siteId' => CURRENT_SITE_ID]
);
if (!IS_ECOMMERCE) {
header('Location: ' . WEBSITEROOT);
exit;
}
}
private function validateSession()
{
$customerIdOdyssee = $this->session->get('customerIdOdyssee');
if ($this->session->has('order_id')) {
$order = $this->entityManager->getRepository(EcoOrders::class)->find($this->session->get('order_id'));
if (!is_string($this->session->get('order_id')) && $this->session->get('order_id') == 0) {
$this->session->remove('order_id');
return $this->redirectToRoute('front_basket_index');
}
//Vérification de la commande en cours, si le statut n'est pas failure on supprime toutes les sessions
//pour éviter de modifier une commande validée
if (($order && $order->getOrderStatus() != 'failure') || $this->session->get('order_valid') == 'valid') {
//Suppression des sessions
$this->session->remove('basket');
$this->session->remove('order_id');
$this->session->remove('order_valid');
$this->session->remove('carrier_id');
$this->session->remove('discount_id');
$this->session->remove('loyalty_point_used');
$this->session->remove('giftText');
$this->session->remove('cgv');
$this->session->remove('customerIdOdyssee');
$this->session->remove('cureIdForAssociatedProducts');
return $this->redirectToRoute('front_basket_index');
}
}
$this->session->set('customerIdOdyssee', $customerIdOdyssee);
return null;
}
#[Route(path: '/', name: 'front_basket_index')]
public function index(
Request $request,
BasketService $basketService,
EcoDiscountRepository $repoDiscount,
LoyaltySystemService $loyaltySystem
): Response {
//Valider les sessions
$this->validateSession();
//Affichage popup
$this->displayPopup();
// //Appliquer un code de réduction
// if ($request->isMethod('POST') && $request->get('discount_code')) {
//
// $articles = $basketService->getFormatedBasketProducts();
// $ds->initService($articles, $this->session->has('customer') ? $this->session->get('customer') : null);
// $discount = $ds->discountValidation($request->get('discount_code'));
//
// if($discount['status']){
// $this->session->set('discount_id', $ds->discount_id);
// $basketService->applyDiscountBasket($request->get('discount_code'));
// } else {
// $this->otideaUtils->createPopup(["title" => 'Problème avec votre remise',
// "message" => $discount['message'],
// "btn2" => null]
// );
// }
// }
$discount = null;
if ($this->session->has('discount_id') && $this->session->get('discount_id') > 0) {
$discount = $repoDiscount->find($this->session->get('discount_id'));
}
//Remise fidélité
if ($this->currentUserConnected != null) {
$loyaltySystem->init($this->currentUserConnected->getId());
}
$now = new \DateTime('', new DateTimeZone('Europe/Paris'));
$now->format('Y-m-d H:i:s');
$currentSaisonStart = $this->apiSettings->getCurrentYearStartDate();
$currentSaisonEnd = $this->apiSettings->getCurrentYearEndDate();
$nextSaisonStart = $this->apiSettings->getNextYearStartDate();
$nextSaisonEnd = $this->apiSettings->getNextYearEndDate();
$startYear = $currentSaisonStart->format('Y');
$endYear = $nextSaisonEnd->format('Y');
$datesExcluded = [];
// Parcourir toutes les dates de l'année en cours
for ($year = $startYear; $year <= $endYear; $year++) {
for ($month = 1; $month <= 12; $month++) {
$daysInMonth = cal_days_in_month(CAL_GREGORIAN, $month, $year);
for ($day = 1; $day <= $daysInMonth; $day++) {
// Date du jour testé
$dateActuelle = new DateTime("$year-$month-$day");
// Si la date est en dehors des saisons en cours et à venir
if (($dateActuelle < $currentSaisonStart || $dateActuelle > $currentSaisonEnd) &&
($dateActuelle < $nextSaisonStart || $dateActuelle > $nextSaisonEnd)) {
$datesExcluded[] = $dateActuelle->format('Y-m-d');
}
}
}
}
$allSoinsReservation = false;
$basketHasSoin = false;
foreach ($this->session->get('basket') as $item) {
if (!is_string($item['referenceObject']) && $item['referenceObject']->getTypeOdyssee() == "soin") {
$basketHasSoin = true;
}
if (!is_string($item['referenceObject']) && $item['referenceObject']->getIsReservable(
) === true && $item['referenceObject']->getTypeOdyssee() == "soin") {
$allSoinsReservation = true;
}
}
if ($this->currentUserConnected == null) {
return $this->redirectToRoute('front_app_login');
} else {
$odysseeCustomers = $this->apiService->rechercherClient(
adrCourriel: $this->currentUserConnected->getAuthUserId()->getEmail()
);
}
$isCure = false;
foreach ($this->session->get('basket') as $key => $basket) {
if (strpos($key, 'CURE') === 0) {
$isCure = true;
}
}
return $this->render('@main-app/front/front_basket/basket.html.twig', [
'isCure' => $isCure,
'basket' => $this->session->get('basket'),
'subtotal' => $basketService->getSubtotal(),
'defaultShippingFees' => $basketService->getDefaultShippingFees(),
'discount' => $discount,
'loyaltyDiscount' => $loyaltySystem->getTotalDiscount(),
'loyaltyPoints' => $loyaltySystem->getTotalPoint(),
'step' => 'basket',
'datesExcluded' => $datesExcluded,
'startYear' => $startYear,
'endYear' => $endYear,
'basketHasSoin' => $basketHasSoin,
'odysseeCustomers' => $odysseeCustomers,
'allSoinsReservation' => $allSoinsReservation
]);
}
/**
* @throws Throwable
*/
#[Route(path: '/livraison/{carrier_id}', name: 'front_basket_delivery', defaults: ['carrier_id' => 1])]
public function delivery(
Request $request,
EcoCustomersRepository $repoCustomers,
BasketService $basketService,
EcoCustomersAddressesRepository $repoAddress,
OtideaUtils $otideaUtils,
EcoDiscountRepository $repoDiscount,
ApiService $api,
$carrier_id = 1
): Response {
//Valider les sessions
$this->validateSession();
if (ODYSSEE_TYPE == 'CURE') {
$carrier_id = 'cure';
}
if ((ODYSSEE_TYPE == 'SPA' && (!$this->session->get('customerIdOdyssee') || ($request->get(
'valueCustomerIdOdyssee'
) && $this->session->get('customerIdOdyssee') != $request->get('valueCustomerIdOdyssee'))))) {
$this->session->set('customerIdOdyssee', $request->get('valueCustomerIdOdyssee'));
}
// Si la connexion à Odyssee est impossible, on redirige vers la page d'accueil
if (!$api->testConnexion()) {
$this->addFlash('danger', 'Une erreur est survenue, veuillez réessayer ultérieurement.');
return $this->redirectToRoute('front_home');
}
//Si l'utilisateur n'est pas connecté
if (!$this->currentUserConnected || $this->currentUserConnected === null) {
$this->session->set('returnToBasket', true);
return $this->redirectToRoute('front_app_login');
}
$patient = $this->getUser()->getCustomer()[0]->getOdysseeReference();
$odysseeCustomer = $api->rechercherClient(idOdyssee: (int)$patient)[0];
//Enregistrement du message cadeau
$this->giftText($request);
//Vérification du choix de la glacière
if ($request->get('valueGlaciere') != null) {
$this->session->set('valueGlaciere', $request->get('valueGlaciere'));
}
//Vérification de l'acceptation des CGV
if ($request->get('cgv') == null && $this->session->get('cgv') == null) {
$this->session->set('displayPopup', 'cgv-error');
return $this->redirectToRoute('front_basket_index');
} else {
if ($request->get('cgv') != null && $this->session->get('cgv') == null) {
$this->session->set('cgv', $request->get('cgv'));
}
}
// <-- DEBUT --> Récupération carrierList
$customer = $repoCustomers->find($this->currentUserConnected->getId());
$carrierList = $basketService->getCarriersList($this->currentUserConnected);
// <-- FIN --> Récupération carrierList
// <-- DEBUT --> Récupération planning
$now = new \DateTime('', new DateTimeZone('Europe/Paris'));
$now->format('Y-m-d H:i:s');
// <-- FIN --> Récupération planning
// <-- DEBUT --> Récupération remise
$discount = null;
if ($this->session->has('discount_id') && $this->session->get('discount_id') > 0) {
$discount = $repoDiscount->find($this->session->get('discount_id'));
}
// <-- FIN --> Récupération remise
// Vérifie si il y a des produits dans le panier qui ne sont pas des cures et si il y en à au moins un de non livrable
$basketAsProduct = false;
$basketAsProductNotDeliverable = false;
foreach ($this->session->get('basket') as $items) {
if (!is_string($items['referenceObject'])) {
$basketAsProduct = true;
if ($items['productObject']->getIsDeliverable() !== 'livrable') {
$basketAsProductNotDeliverable = true;
}
}
}
$this->session->set('cureIdForAssociatedProducts', null);
// Par défaut sur une CURE, on définie la date de début
if ($this->session->get('basket')) {
$firstProductInBasket = $this->session->get('basket')[array_key_first(
$this->session->get('basket')
)]['productObject'];
} else {
return $this->redirectToRoute('front_basket_index');
}
$dateDebut = is_object($firstProductInBasket) ? null : new \DateTime($firstProductInBasket['dateDebut']);
// Si il y a des produits dans le panier qui ne sont pas des cures, on récupère les cures disponibles et valides
$allAvailablesResaCures = [];
if ($basketAsProduct and ODYSSEE_TYPE == 'CURE') {
// On récupère toutes les Cures de tous les patients associés à ce compte
$customers = $this->currentUserConnected->getAuthUserId()->getCustomer();
$orders = [];
foreach ($customers as $customer) {
// Récupération des commandes du client
$order = $api->rechercherResaCure(idOdysseeClient: (int)$customer->getOdysseeReference());
if (!isset($order->status)) {
$orders[] = $api->rechercherResaCure(idOdysseeClient: (int)$customer->getOdysseeReference());
}
}
// On parcours les cures, on ne garde que celles dont la date de début est supérieure à la date du jour
foreach ($orders as $cust) {
foreach ($cust as $cure) {
$dateDebut = new \DateTime($cure->{'Date_Debut_Resa'});
$dateJour = new \DateTime();
if ($dateDebut > $dateJour) {
// On remplace le code de l'indication principale par son nom et l'ID patient de la cure par son nom
$cure->{'Indication_Principale'} = $this->entityManager->getRepository(Cure::class)->findOneBy(
['odysseeReference' => $cure->{'Indication_Principale'}]
)->getTitle();
$cure->{'IdOdysseeClient'} = $api->rechercherClient(
idOdyssee: (int)$cure->{'IdOdysseeClient'}
)[0]->{'Nom'} . ' ' . $api->rechercherClient(
idOdyssee: (int)$cure->{'IdOdysseeClient'}
)[0]->{'Prenom'};
$allAvailablesResaCures[] = $cure;
}
}
}
if (!empty($allAvailablesResaCures) && $carrier_id == 'cure') {
$dateDebut = new \DateTime($allAvailablesResaCures[0]->{'Date_Debut_Resa'});
$this->session->set(
'cureIdForAssociatedProducts',
(int)$allAvailablesResaCures[array_key_first($allAvailablesResaCures)]->{'IdOdysseeResa'}
);
}
}
if (empty($this->session->get('basket'))) {
return $this->redirectToRoute('front_home');
}
// Si on est sur un site de CURE, on désactive les transporteurs
if (ODYSSEE_TYPE == 'CURE') {
$basketAsProductNotDeliverable = true;
} elseif (ODYSSEE_TYPE == 'SPA') {
$dateDebut = $request->get('wantResa') == '1' ? new \DateTime(
str_replace('/', '-', $request->get('date_debut'))
) : null;
$wantResa = $request->get('wantResa');
// if ($dateDebut == null) {
// $basketAsProductNotDeliverable = false;
// }
}
$currentSaisonStart = $this->apiSettings->getCurrentYearStartDate();
$currentSaisonEnd = $this->apiSettings->getCurrentYearEndDate();
$nextSaisonStart = $this->apiSettings->getNextYearStartDate();
$nextSaisonEnd = $this->apiSettings->getNextYearEndDate();
$startYear = $currentSaisonStart->format('Y');
$endYear = $nextSaisonEnd->format('Y');
$datesExcluded = [];
// Parcourir toutes les dates de l'année en cours
for ($year = $startYear; $year <= $endYear; $year++) {
for ($month = 1; $month <= 12; $month++) {
$daysInMonth = cal_days_in_month(CAL_GREGORIAN, $month, $year);
for ($day = 1; $day <= $daysInMonth; $day++) {
// Date du jour testé
$dateActuelle = new DateTime("$year-$month-$day");
// Si la date est en dehors des saisons en cours et à venir
if (($dateActuelle < $currentSaisonStart || $dateActuelle > $currentSaisonEnd) &&
($dateActuelle < $nextSaisonStart || $dateActuelle > $nextSaisonEnd)) {
$datesExcluded[] = $dateActuelle->format('Y-m-d');
}
}
}
}
//Définir le transporteur
$this->session->set('carrier_id', $basketAsProductNotDeliverable ? 0 : $carrier_id);
$step = "";
if (ODYSSEE_TYPE == 'CURE') {
$step = "CURE";
} elseif (ODYSSEE_TYPE == 'SPA') {
$step = "SPA";
} else {
$step = "delivery";
}
return $this->render('@main-app/front/front_basket/delivery.html.twig', [
'subtotal' => $basketService->getSubtotal(),
'odysseeCustomer' => $odysseeCustomer,
'defaultShippingFees' => $basketAsProductNotDeliverable ? 0 : $basketService->getDefaultShippingFees(
$carrier_id,
1
),
'shippingFeesFree' => $basketService->getShippingFeesFree($basketAsProductNotDeliverable ? 0 : $carrier_id),
'carriersList' => $carrierList,
'customer' => $customer,
'discount' => $discount,
'carrier_id' => $carrier_id,
'step' => $step,
'glaciere' => $this->session->get('valueGlaciere'),
'basketAsProduct' => $basketAsProduct,
'basketAsProductNotDeliverable' => $basketAsProductNotDeliverable,
'allAvailablesResaCures' => !isset($allAvailablesResaCures->status) ? $allAvailablesResaCures : [],
'wantResa' => $wantResa ?? 'false',
'dateDebut' => $dateDebut ? $dateDebut->format('d/m/Y') : null,
'datesExcluded' => $datesExcluded,
'startYear' => $startYear,
'endYear' => $endYear
]);
}
// Requête AJAX pour setter en session PHP l'ID de la cure sélectionnée
#[Route(path: '/axCureIdForAssociatedProducts', name: 'front_basket_set_cure_associated')]
public function axCureIdForAssociatedProducts(Request $request, ApiService $api): JsonResponse
{
if ($request->isXmlHttpRequest()) {
$this->session->set('cureIdForAssociatedProducts', (int)$request->get('cureId'));
return new JsonResponse(['status' => 'success']);
}
return new JsonResponse(['status' => 'error']);
}
// Requête AJAX qui va récupérer les soins d'un produit
#[Route(path: '/axGetSoinOnProduct', name: 'front_basket_get_soin_on_product')]
public function axGetSoinOnProduct(Request $request, ApiService $api): JsonResponse
{
if ($request->isXmlHttpRequest()) {
$soinProduct = $api->rechSoinResaSpaParCodeProduit($request->get('reference'));
return new JsonResponse(
[
'status' => true,
'soinProductComposition' => $soinProduct[0]->{'Composition'}
]
);
}
return new JsonResponse(
[
'status' => 'error'
]
);
}
// Requête AJAX qui va récupérer les disponibilité d'un soin avec son ID
#[Route(path: '/axGetSoinAvailability', name: 'front_basket_get_soin_availability')]
public function axGetSoinAvailability(Request $request, ApiService $api): JsonResponse
{
if ($request->isXmlHttpRequest()) {
$basket = $this->session->get('basket');
//On sépare chaque élément de la date dans un tableau
$date = explode('/', $request->get('dateDebut'));
//On vérifie que le tableau de date contient bien 3 éléments
if (count($date) != 3) {
return new JsonResponse(
[
'date' => $date,
'status' => 'error'
]
);
}
// On converti la date récupérée au format dd/mm/YYYY au format YYYY-mm-ddT00:00:00
$dateDebut = (new \DateTime($date[2] . '-' . $date[1] . '-' . $date[0]))->format('Y-m-d') . 'T00:00:00';
// On créer la date de fin en ajoutant 7 jours à la date de début
$dateFin = (new \DateTime($date[2] . '-' . $date[1] . '-' . $date[0]))->modify(
'+' . $this->apiSettings->getNbDaysAvailableSearch() . ' day'
)->format('Y-m-d') . 'T00:00:00';
$disposSoin = $api->dispoSoin((string)$request->get('codeSoin'), $dateDebut, $dateFin);
$error = isset($disposSoin->status);
try {
$disposSoin = $api->dispoSoin((string)$request->get('codeSoin'), $dateDebut, $dateFin);
} catch (Exception $e) {
return new JsonResponse(
[
'status' => true,
'disposSoin' => $disposSoin,
'codeSoin' => $request->get('codeSoin'),
'error' => $e->getMessage()
]
);
}
$disposSoin = $api->dispoSoin((string)$request->get('codeSoin'), $dateDebut, $dateFin);
$error = isset($disposSoin->status);
if (!$error) {
foreach ($basket as $key => $product) {
if (!is_string($product['referenceObject']) && $product['referenceObject']->getId(
) == (int)$request->get('prodId')) {
$basket[$key]['disposSoins'][$request->get('codeSoin')]['day'] = $disposSoin[0]->{'Jour'};
$basket[$key]['disposSoins'][$request->get('codeSoin')]['hour'] = $disposSoin[0]->{'Horaire'};
}
}
}
$this->session->set('basket', $basket);
return new JsonResponse(
[
'status' => true,
'disposSoin' => $disposSoin,
'codeSoin' => $request->get('codeSoin'),
'error' => $error
]
);
}
return new JsonResponse(
[
'status' => 'error'
]
);
}
// Requête AJAX pour setter en session PHP les dispos des soins choisies
#[Route(path: '/axSetSoinDispo', name: 'front_basket_set_soin_dispo')]
public function axSetSoinDispo(Request $request): JsonResponse
{
if ($request->isXmlHttpRequest()) {
$basket = $this->session->get('basket');
$day = $request->get('day');
$hour = $request->get('hour');
$prodId = $request->get('prodId');
foreach ($basket as $key => $product) {
if (!is_string($product['referenceObject']) && $product['referenceObject']->getId() == (int)$prodId) {
$basket[$key]['disposSoins'][$request->get('codeSoin')]['day'] = $day;
$basket[$key]['disposSoins'][$request->get('codeSoin')]['hour'] = $hour;
}
}
$this->session->set('basket', $basket);
return new JsonResponse(
[
'status' => 'success',
'basket' => $this->session->get('basket')
]
);
}
return new JsonResponse(
[
'status' => 'error'
]
);
}
private function giftText($request)
{
if ($request->get('giftText')) {
$this->session->set('giftText', $request->get('giftText'));
}
// elseif($this->session->has('giftText')) {
// $this->session->remove('giftText');
// }
}
/**
* @throws Throwable
*/
#[Route(path: '/paiement/{paymentMode}', name: 'front_basket_payment', defaults: ['paymentMode' => 'bank'])]
public function payment(
BasketService $basketService,
EcoCustomersRepository $customersRepository,
EcoCustomersAddressesRepository $repoAddress,
EcoOrdersRepository $repoOrder,
EcoDiscountRepository $repoDiscount,
ApiService $api,
$paymentMode = 'bank'
): Response {
// Si la connexion à Odyssee est impossible, on redirige vers la page d'accueil
if (!$api->testConnexion()) {
$this->addFlash('danger', 'Une erreur est survenue, veuillez réessayer ultérieurement.');
return $this->redirectToRoute('front_home');
}
//Si l'utilisateur n'est pas connecté
if (!$this->currentUserConnected || $this->currentUserConnected === null) {
$this->session->set('returnToBasket', true);
return $this->redirectToRoute('front_app_login');
}
//Valider les sessions
$this->validateSession();
$patient = $this->getUser()->getCustomer()[0]->getOdysseeReference();
$odysseeCustomer = $api->rechercherClient(idOdyssee: (int)$patient)[0];
$deliveryAddress = $odysseeCustomer->{'Adresse1'} . ' ' . $odysseeCustomer->{'Adresse2'} . ' ' . $odysseeCustomer->{'Adresse3'} . ' ' . $odysseeCustomer->{'CodePostal'} . ' ' . $odysseeCustomer->{'Ville'};
//Vérification des informations obligatoires
// if (!$this->session->has('customer') || $this->session->get('customer') === null || $this->session->get('carrier_id') === null || $this->session->get('basket') === null) {
// return $this->redirectToRoute('front_customer_connection');
// }
// <-- DEBUT --> Récupération remise
$discount = null;
if ($this->session->has('discount_id') && $this->session->get('discount_id') > 0) {
$discount = $repoDiscount->find($this->session->get('discount_id'));
}
// <-- FIN --> Récupération remise
//Enregistrer la commande avant de passer au paiement
//$this->insertOrder($basketService, $deliveryAddress[0]->getId(), $paymentMode, $discount);
$date = new \DateTime();
$dateString = $date->format('Y-m-d');
$this->session->set('order_id', $dateString . '-' . $patient);
return $this->render('@main-app/front/front_basket/payment.html.twig', [
'subtotal' => $subtotal = $basketService->getSubtotal(),
'defaultShippingFees' => $basketService->getDefaultShippingFees(
$this->session->get('carrier_id'),
1
),
// 'order' => $repoOrder->find($this->session->get('order_id')),
'step' => 'payment',
'discount' => $discount,
'currentUser' => $this->currentUserConnected
]);
}
private function insertOrder($basketService, $shipping_id, $paymentMode, $discountCode)
{
if ($shipping_id == null) {
return $this->redirectToRoute('front_app_login');
}
if (!$this->session->has('order_id') || $this->session->get('order_id') === null) {
$this->session->set('order_id', 0);
}
//Récupération de la date de livraison
$now = new \DateTime('', new DateTimeZone('Europe/Paris'));
$now = $now->format('Y-m-d H:i:s');
$company = 0;
if ($this->currentUserConnected && $this->currentUserConnected->getCustAccountType() == 'company') {
$company = $this->currentUserConnected->getId();
} else {
if ($this->currentUserConnected && $this->currentUserConnected->getCustAccountType() == 'employee') {
$company = $this->currentUserConnected->getCompany()->getId();
}
}
$planning = $this->entityManager->getRepository(EcoPlanning::class)->getCurrentDeliveryAndOrder($now, $company);
if (!$planning) {
$planning = $this->entityManager->getRepository(EcoPlanning::class)->getNextDeliveryAndOrder(
$now,
$company
);
}
$params = [
'customer_id' => $this->currentUserConnected->getId(),
'shipping_id' => $shipping_id,
'carrier_id' => $this->session->get('carrier_id'),
'payment_mode' => $paymentMode,
'order_status' => 'failure',
'order_shipping_fees_free' => $basketService->getShippingFeesFree(),
'productsList' => $basketService->getFormatedBasketProducts(),
'order_actual_weight' => $basketService->getBasketWeight(),
'order_loyalty_point_used' => $this->session->has('loyalty_point_used') ? true : false,
'order_gift_text' => $this->session->has('giftText') ? $this->session->get('giftText') : null,
'planning' => $planning,
'glaciere' => $this->session->get('valueGlaciere'),
'discountCode' => $discountCode
];
$order_id = $this->orderService->saveOrder($this->session->get('order_id'), $params);
$this->session->set('order_id', $order_id);
//Liaison avec un code de réduction s'il elle existe
$discount_id = $this->session->has('discount_id') ? $this->session->get('discount_id') : null;
if ($discount_id !== null && $discount_id > 0) {
$discount = new EcoDiscountOrders;
$discount->setDiscountId($discount_id);
$discount->setOrderId($order_id);
$this->entityManager->persist($discount);
$this->entityManager->flush();
}
}
/**
* @throws Throwable
*/
#[Route(path: '/payment_selection', name: 'front_basket_payment_selection')]
public function payment_selection(
Request $request,
BasketService $basketService,
EcoOrdersRepository $repoOrder,
ApiService $api
) {
if ($request->isMethod('POST')) {
switch ($request->get('paiement')) {
case 'cheque' :
$this->addFlash(
'danger',
'Une erreur est survenue avec cette commande, veuillez nous contacter'
);
return $this->redirectToRoute('front_home');
// $order = $repoOrder->find($this->session->get('order_id'));
// $order->setOrderPayment('cheque');
// $this->entityManager->persist($order);
// $this->entityManager->flush();
//
// return $this->redirectToRoute('front_basket_payment_cheque');
break;
case 'bank' :
$carriers = $basketService->getCarriersList($this->currentUserConnected);
$selectedCarrierAmount = 0;
foreach ($carriers as $carrier) {
if ($carrier['detail']->getId() == $this->session->get('carrier_id')) {
$selectedCarrierAmount = (double)$carrier['total'];
}
}
$saveCure = $this->saveApiOrder($selectedCarrierAmount);
if (in_array('error', $saveCure)) {
$this->addFlash('danger', 'Une erreur est survenue, veuillez réessayer ultérieurement.');
return $this->redirectToRoute('front_basket_index');
}
return $this->redirectToRoute('front_payzen_paiement', [
'orderId' => $saveCure[0],
'totalOrder' => $saveCure[1] + $selectedCarrierAmount,
]);
// $order = $repoOrder->find($this->session->get('order_id'));
// $order->setOrderPayment('bank');
// $this->entityManager->persist($order);
// $this->entityManager->flush();
//
// return $this->redirectToRoute('front_basket_payment_paybox');
break;
case 'nopayment' :
$this->addFlash(
'danger',
'Une erreur est survenue avec cette commande, veuillez nous contacter'
);
return $this->redirectToRoute('front_home');
// $order = $repoOrder->find($this->session->get('order_id'));
// $order->setOrderPayment('nopayment');
// $this->entityManager->persist($order);
// $this->entityManager->flush();
//
// $this->validateOrder($order->getId());
//
// return $this->redirectToRoute('front_basket_confirmation');
break;
case 'store' :
$this->addFlash(
'danger',
'Une erreur est survenue avec cette commande, veuillez nous contacter'
);
return $this->redirectToRoute('front_home');
// $order = $repoOrder->find($this->session->get('order_id'));
// $order->setOrderPayment('store');
// $this->entityManager->persist($order);
// $this->entityManager->flush();
//
// $this->validateOrder($order->getId());
// return $this->redirectToRoute('front_basket_confirmation');
break;
}
}
return $this->redirectToRoute('front_basket_index');
}
private function saveApiOrder($selectedCarrierAmount): array
{
$orderRef = null;
$totalOrder = null;
//Créer une référence unique pour la commande à partir de la date et de l'heure si la commande n'est pas nulle et de l'ID Odyssee du patient
foreach ($this->session->get('basket') as $product) {
if (is_string($product['referenceObject'])) {
$orderRef = (new \DateTime(
'',
new DateTimeZone('Europe/Paris')
))->format('Y-m-d-H-i-s') . '-' . $product['productObject']['idOdyssee'];
}
}
// On parcourt tous les produits du panier
foreach ($this->session->get('basket') as $product) {
// Si le produit est une cure
if (is_string($product['referenceObject'])) {
$dateDebut = $product['productObject']['dateDebut']
? (new \DateTime($product['productObject']['dateDebut'], new DateTimeZone('Europe/Paris')))->format(
'Y-m-d'
) . 'T00:00:00'
: (new \DateTime('tomorrow', new DateTimeZone('Europe/Paris')))->format('Y-m-d') . 'T00:00:00';
$dateFin = $product['productObject']['dateFin']
? (new \DateTime($product['productObject']['dateFin'], new DateTimeZone('Europe/Paris')))->format(
'Y-m-d'
) . 'T00:00:00'
: (new \DateTime('tomorrow + 7 days', new DateTimeZone('Europe/Paris')))->format(
'Y-m-d'
) . 'T00:00:00';
try {
// On enregistre la cure dans Odyssee
$returnAddCure = $this->apiService->creerResaCure(
idOdysseeClient: $product['productObject']['idOdyssee'],
idExterneResa: $product['productObject']['idExterne'],
cureP: $product['productObject']['cureP'],
cureS: $product['productObject']['cureS'],
dateDebut: $dateDebut,
dateFin: $dateFin,
nss: $product['productObject']['nss'],
medTherm: $product['productObject']['medTherm'],
medPresc: $product['productObject']['medPresc'],
plageHoraire: $product['productObject']['plageHoraire'],
commentaire: $product['productObject']['commentaire'],
quota: $product['productObject']['quota'],
etab: $product['productObject']['etab'],
pdv: $this->site->getOdysseePdvId()
);
// On enregistre la cure dans la BDD
$newCureOrder = new CureOrder();
$newCureOrder->setIdOdysseeClient($product['productObject']['idOdyssee']);
$newCureOrder->setIdExterne($product['productObject']['idExterne']);
$newCureOrder->setCureP($product['productObject']['cureP']);
$newCureOrder->setCureS($product['productObject']['cureS']);
$newCureOrder->setDateDebut(new \DateTime($dateDebut));
$newCureOrder->setDateFin(new \DateTime($dateFin));
$newCureOrder->setPlageHoraire($product['productObject']['plageHoraire']);
$newCureOrder->setNss($product['productObject']['nss']);
$newCureOrder->setMedTherm($product['productObject']['medTherm']);
$newCureOrder->setMedPresc($product['productObject']['medPresc']);
$newCureOrder->setCommentaire($product['productObject']['commentaire']);
$newCureOrder->setArrhes($product['productObject']['arrhes']);
$newCureOrder->setQuota($product['productObject']['quota']);
$newCureOrder->setEtab($product['productObject']['etab']);
$newCureOrder->setPdv($product['productObject']['pdv']);
$newCureOrder->setCureOrderRef($orderRef);
$newCureOrder->setSavePaymentInOdyssee(0);
// On met à jour la cure dans la BDD suivant le retour de l'API
if (!isset($returnAddCure->status)) { // Si l'API ne retourne pas d'erreurs
$newCureOrder->setIdOdysseeResa($returnAddCure[0]->IdOdysseeResa);
$newCureOrder->setSaveInOdyssee(true);
$newCureOrder->setSaveInOdysseeDate(
new \DateTime(
'',
new DateTimeZone('Europe/Paris')
)
);
} else { // Sinon, on indique l'erreur en BDD pour la traçabilité
$newCureOrder->setSaveInOdyssee(false);
$newCureOrder->setSaveInOdysseeDate(null);
// Si c'est une erreur unique
if (is_string(json_decode($returnAddCure)->errors)) {
$content = "<p><strong style='color:red;'>Erreur :</strong> " . json_decode(
$returnAddCure
)->errors . "</p>";
} else { // Si c'est un tableau d'erreurs
$content = "<p><strong style='color:red;'>Erreurs :</strong></p>";
foreach (json_decode($returnAddCure)->errors as $key => $error) {
$content .= "<br><br><p><strong style='color:red;'>Erreur " . $key . " :</strong> " . $error[0] . "</p>";
}
}
$newCureOrder->setSaveInOdysseeError($content);
}
$this->entityManager->persist($newCureOrder);
} catch (Throwable $apiException) {
// Si l'erreur est une erreur de connexion à l'API, on envoie un mail aux admins
try {
$htmlContent = "<br><br><p><strong style='color:red;'>Erreur :</strong> " . $apiException->getMessage(
) . "</p>";
$this->mailerService->subject = 'Erreur du serveur API - ' . $this->site->getSiteName();
$this->mailerService->sendMail(
$this->recipients,
$htmlContent
);
} catch (Throwable $emailException) {
// Si on a une erreur lors de l'envoi du mail, on écrit dans le fichier de log
$this->mailerService->writeLog(json_encode([
"apiException : " . $apiException->getMessage(),
"eMailException : " . $emailException->getMessage()
]),
'FrontBasketController ligne 801 - Try/Catch <creerResaCure\>');
}
// On retourne une erreur pour afficher un message à l'utilisateur
return ['error'];
}
$totalOrder += $product['productObject']['arrhes'];
} else { // Si le produit n'est pas une cure
if (!$orderRef) {
//Créer une référence unique pour la commande à partir de la date et de l'heure si la commande n'est pas nulle et de l'ID Odyssee du patient
$orderRef = (new \DateTime(
'',
new DateTimeZone('Europe/Paris')
))->format('Y-m-d-H-i-s') . '-' . ($this->session->get('cureIdForAssociatedProducts') ?: 'SPA');
}
// TODO : remplacer la récupération du client par celui inséré en SESSION lors de la commande
if (ODYSSEE_TYPE == 'CURE') {
$customerOdyssee = $this->apiService->rechercherResaCure(
idOdysseeResa: $this->session->get(
'cureIdForAssociatedProducts'
)
)[0]->{'IdOdysseeClient'};
} elseif (ODYSSEE_TYPE == 'SPA') {
$customerOdyssee = $this->session->get('customerIdOdyssee');
}
// On enregistre le produit en BDD
$newCureProductOrder = new CureProductOrder();
$newCureProductOrder->setCodeProduit(
$product['referenceObject']->getTypeOdyssee(
) == 'bkdovalue' ? $product['referenceObject']->getTypeOdyssee(
) : $product['referenceObject']->getRefReference()
);
$newCureProductOrder->setTypeOdyssee($product['referenceObject']->getTypeOdyssee());
$newCureProductOrder->setQteProduit($product['qte']);
$newCureProductOrder->setOrderShippingCost($selectedCarrierAmount);
$newCureProductOrder->setPrixUnitTtc(
$product['referenceObject']->getTypeOdyssee(
) == 'bkdovalue' ? $product['referenceObject']->getRefReferencePrice(
) : $product['referenceObject']->getRefSellingPrice()
);
$newCureProductOrder->setTvaProduit($product['referenceObject']->getRefTva());
$newCureProductOrder->setPrcRemise(0);
$newCureProductOrder->setPdv(null);
$newCureProductOrder->setOrderRef($orderRef);
$newCureProductOrder->setOdysseeId(
ODYSSEE_TYPE == 'CURE' ? $this->session->get('cureIdForAssociatedProducts') : null
);
$newCureProductOrder->setOdysseeClientId((int)$customerOdyssee ?? null);
$newCureProductOrder->setSaveInOdyssee(false);
$newCureProductOrder->setSavePaymentInOdyssee(0);
$newCureProductOrder->setSiteId(CURRENT_SITE_ID);
$this->entityManager->persist($newCureProductOrder);
// Si i ly a des dispos soins, on les enregistre
if (isset($product['disposSoins'])) {
foreach ($product['disposSoins'] as $key => $soin) {
$newCureProductSoinsOrder = new CureProductSoinsOrder();
$newCureProductSoinsOrder->setCureProductOrder($newCureProductOrder);
$newCureProductSoinsOrder->setCodeSoin($key);
$newCureProductSoinsOrder->setDateSoin(new \DateTime($soin['day']));
$newCureProductSoinsOrder->setHeureSoin($soin['hour']);
$this->entityManager->persist($newCureProductSoinsOrder);
$newCureProductOrder->addCureProductSoinsOrder($newCureProductSoinsOrder);
}
}
// Suivant la nature du produit, on ajoute le bon montant au total
if ($product['referenceObject']->getTypeOdyssee() == 'bkdovalue') {
$totalOrder += $product['qte'] * ($product['referenceObject']->getRefReferencePrice(
) - (0 * $product['referenceObject']->getRefReferencePrice() / 100));
} else {
$totalOrder += $product['qte'] * ($product['referenceObject']->getRefSellingPrice(
) - (0 * $product['referenceObject']->getRefSellingPrice() / 100));
}
}
}
$this->entityManager->flush();
// On récupère tous les produits enregistrés pour la commande en cours
$cureProductsOrder = $this->entityManager->getRepository(CureProductOrder::class)->findBy(
[
'orderRef' => $orderRef
]
);
// Si on est pas sur un BON CADEAU, on enregistre les produits dans Odyssee
if ($cureProductsOrder && $cureProductsOrder[0]->getTypeOdyssee(
) != 'bkdo' && $cureProductsOrder[0]->getTypeOdyssee() != 'bkdovalue') {
// Récupération des informations de la cure associée aux produits
if (ODYSSEE_TYPE == 'CURE') {
try {
$cureAssociated = $this->apiService->rechercherResaCure(
idOdysseeResa: $this->session->get(
'cureIdForAssociatedProducts'
)
);
} catch (Throwable $apiException) {
// Si l'erreur est une erreur de connexion à l'API, on envoie un mail aux admins
try {
$htmlContent = "<br><br><p><strong style='color:red;'>Erreur :</strong> " . $apiException->getMessage(
) . "</p>";
$this->mailerService->subject = 'Erreur du serveur API - ' . $this->site->getSiteName();
$this->mailerService->sendMail(
$this->recipients,
$htmlContent
);
} catch (Throwable $emailException) {
// Si on a une erreur lors de l'envoi du mail, on écrit dans le fichier de log
$this->mailerService->writeLog(json_encode([
"apiException : " . $apiException->getMessage(),
"eMailException : " . $emailException->getMessage()
]),
'FrontBasketController ligne 801 - Try/Catch <creerResaCure\>');
}
// On retourne une erreur pour afficher un message à l'utilisateur
return ['error'];
}
}
$produits = [];
$mntRemise = 0;
$mntTotalTtc = 0;
$mntTotalHt = 0;
$mntTotalTva = 0;
// Enregistrement des produits dans Odyssee
foreach ($cureProductsOrder as $cureProduct) {
// Calcul des montants
$ttc = $cureProduct->getQteProduit() * ($cureProduct->getPrixUnitTtc() - ($cureProduct->getPrcRemise(
) * $cureProduct->getPrixUnitTtc() / 100));
$ht = $cureProduct->getQteProduit() * ($cureProduct->getPrixUnitTtc() - ($cureProduct->getPrcRemise(
) * $cureProduct->getPrixUnitTtc() / 100)) / (1 + $cureProduct->getTvaProduit() / 100);
$tva = $cureProduct->getQteProduit() * ($cureProduct->getPrixUnitTtc() - ($cureProduct->getPrcRemise(
) * $cureProduct->getPrixUnitTtc() / 100)) - ($cureProduct->getQteProduit(
) * ($cureProduct->getPrixUnitTtc() - ($cureProduct->getPrcRemise(
) * $cureProduct->getPrixUnitTtc() / 100)) / (1 + $cureProduct->getTvaProduit() / 100));
$soinsPlanifs = [];
foreach ($cureProduct->getCureProductSoinsOrders() as $soin) {
$soinsPlanifs[] = [
'Code_Soin' => $soin->getCodeSoin(),
'Date_Soin' => $soin->getDateSoin()->format('Y-m-d'),
'Heure_Soin' => $soin->getHeureSoin()
];
}
$produits[] = [
'Code_Produit' => $cureProduct->getCodeProduit(),
'Qte_Produit' => $cureProduct->getQteProduit(),
'Prix_Unit_Ttc' => $cureProduct->getPrixUnitTtc(),
'Tva_Produit' => $cureProduct->getTvaProduit(),
'Prc_Remise' => $cureProduct->getPrcRemise(),
'Mnt_Ttc' => $ttc,
'Mnt_Ht' => $ht,
'Mnt_Tva' => $tva,
'Soins_Planifs' => $soinsPlanifs
];
$mntRemise += $cureProduct->getPrcRemise() * $cureProduct->getQteProduit(
) * $cureProduct->getPrixUnitTtc() / 100;
$mntTotalTtc += $ttc;
$mntTotalHt += $ht;
$mntTotalTva += $tva;
}
if ($selectedCarrierAmount > 0) {
$produits[] = [
'Code_Produit' => 'FPT',
'Qte_Produit' => 1,
'Prix_Unit_Ttc' => $selectedCarrierAmount,
'Tva_Produit' => 20,
'Prc_Remise' => 0,
'Mnt_Ttc' => $selectedCarrierAmount,
'Mnt_Ht' => $selectedCarrierAmount,
'Mnt_Tva' => 0,
'Soins_Planifs' => []
];
}
$returnAddProd = '';
try {
if (ODYSSEE_TYPE == 'CURE') { // Si on est sur le site de cure, on ajoute les produits à la cure correspondante
$returnAddProd = $this->apiService->ajoutProduitResaCure(
idOdysseeClient: $cureAssociated[0]->{'IdOdysseeClient'},
idOdysseeResa: $cureProductsOrder[0]->getOdysseeId(),
idExterneResa: $cureAssociated[0]->{'IdExterneResa'},
produits: $produits,
Mnt_Remise: $mntRemise,
Mnt_Regler: 0,
Mnt_Total_Ttc: $mntTotalTtc,
Mnt_Total_Ht: $mntTotalHt,
Mnt_Total_Tva: $mntTotalTva
);
} elseif (ODYSSEE_TYPE == 'SPA') { // Si on est sur le site de spa, on créer la réservation avec vente de produits
$returnAddProd = $this->apiService->creerResaSpa(
idOdysseeClient: $cureProductsOrder[0]->getOdysseeClientId(),
idExterneClient: "",
idOdysseeSpa: 0,
idExterneSpa: $cureProductsOrder[0]->getId() . '-' . $cureProductsOrder[0]->getCodeProduit(),
dateDebut: (new \DateTime(
'now',
new DateTimeZone('Europe/Paris')
))->format('Y-m-d') . 'T00:00:00',
dateFin: (new \DateTime('now', new DateTimeZone('Europe/Paris')))
->modify('+1 year')
->format('Y-m-d') . 'T00:00:00',
produits: $produits,
Mnt_Remise: $mntRemise,
Mnt_Regler: 0,
Mnt_Total_Ttc: $mntTotalTtc,
Mnt_Total_Ht: $mntTotalHt,
Mnt_Total_Tva: $mntTotalTva,
pdv: $this->site->getOdysseePdvId()
);
}
// Ajout du statut sauvegardé dans Odyssée de la cure dans la BDD
foreach ($cureProductsOrder as $cureProduct) {
// Si le statut du paiement est valide et que le retour de l'API est ok
if (!isset($returnAddProd->status)) {
if (ODYSSEE_TYPE == 'SPA') {
$cureProduct->setOdysseeId($returnAddProd->IdOdysseeSpa);
}
$cureProduct->setSaveInOdyssee(true);
$cureProduct->setSaveInOdysseeDate(
new \DateTime(
'',
new DateTimeZone('Europe/Paris')
)
);
} else {
$cureProduct->setSaveInOdysseeError(
is_object($returnAddProd->errors) ? json_encode(
$returnAddProd->errors
) : $returnAddProd->errors
);
return ['error'];
}
$this->entityManager->flush($cureProduct);
}
} catch (\Throwable $apiException) {
// Si l'erreur est une erreur de connexion à l'API, on envoie un mail aux admins
try {
$htmlContent = "<br><br><p><strong style='color:red;'>Erreur :</strong> " . $apiException->getMessage(
) . "</p>";
$this->mailerService->subject = 'Erreur du serveur API - ' . $this->site->getSiteName();
$this->mailerService->sendMail(
$this->recipients,
$htmlContent
);
} catch (Throwable $emailException) {
// Si on a une erreur lors de l'envoi du mail, on écrit dans le fichier de log
$this->mailerService->writeLog(json_encode([
"apiException : " . $apiException->getMessage(),
"eMailException : " . $emailException->getMessage()
]),
'FrontBasketController ligne 801 - Try/Catch <creerResaCure\>');
}
// On retourne une erreur pour afficher un message à l'utilisateur
return ['error'];
}
}
return [$orderRef, $totalOrder];
}
#[Route(path: '/paiement-paybox', name: 'front_basket_payment_paybox')]
public function payment_paybox(
Request $request,
PayboxService $paybox,
EcoOrdersRepository $repoOrders,
EcoCustomersRepository $repoCustomers,
BasketService $basketService,
EcoCustomersAddressesRepository $repoAddress,
EcoOrdersProductsRepository $repoProductsOrder,
EcoDiscountRepository $repoDiscount
) {
//Valider les sessions
$this->validateSession();
$order = $repoOrders->find($this->session->get('order_id'));
$orderProducts = $repoProductsOrder->findBy(["order_id" => $this->session->get('order_id')]);
$customer = $repoCustomers->find($order->getCustomerId());
$deliveryAddress = null;
if ($this->currentUserConnected->getCustAccountType(
) == 'company' && $this->currentUserConnected->getAddressesId() !== null && sizeof(
$this->currentUserConnected->getAddressesId()->getValues()
) > 0) {
$deliveryAddress = $this->currentUserConnected->getAddressesId()->getValues()[0];
} else {
if ($this->currentUserConnected->getCustAccountType(
) == 'employee' && $this->currentUserConnected->getCompany()->getAddressesId() !== null && sizeof(
$this->currentUserConnected->getCompany()->getAddressesId()->getValues()
) > 0) {
$company = $this->currentUserConnected->getCompany();
$deliveryAddress = $company->getAddressesId()->getValues()[0];
}
}
$fp = $basketService->getDefaultShippingFees(
$this->session->get('carrier_id'),
$deliveryAddress->getCountryId()
);
$totalTTC = sprintf('%.2f', $basketService->getSubtotal() + $fp);
if ($this->session->get('valueGlaciere') == 1) {
$totalTTC += 6;
}
// <-- DEBUT --> Récupération remise
if ($this->session->has('discount_id') && $this->session->get('discount_id') > 0) {
$discount = $repoDiscount->find($this->session->get('discount_id'));
if ($discount->getDiscountAmount() != null) {
$totalTTC -= $discount->getDiscountAmount();
} elseif ($discount->getDiscountPercentage() != null) {
$totalTTC = $totalTTC - ($totalTTC * ($discount->getDiscountPercentage() / 100));
}
}
// <-- FIN --> Récupération remise
if ($totalTTC < 0) {
$totalTTC = 0;
}
$paybox->payboxInit([
"cmd" => $order->getOrderReference(),
"email" => $customer->getAuthUserId()->getEmail(),
"total" => $totalTTC * 100,
]);
$paybox->launch_payment();
}
#[Route(path: '/validate-paybox', name: 'front_basket_validate_payment_paybox')]
public function validate_paybox(Request $request, PayboxService $paybox, EcoOrdersRepository $repoOrders)
{
//mail('steeven@otidea.com', 'calesia', print_r($request->query->all(), true));
if ($request->get('ident') && $request->get('ident') != '' && $request->get('auto') && $request->get(
'amount'
) && $request->get('reponse')) {
if ($paybox->validationTransaction($request->get('reponse'))) {
$order = $repoOrders->findOneBy(['order_reference' => $request->get('ident')]);
$this->validateOrder($order->getId(), $request->get('amount') / 100);
}
}
return new Response('', 200);
}
#[Route(path: '/payment_cheque', name: 'front_basket_payment_cheque')]
public function payment_cheque(
Request $request,
SiteCoordonneesRepository $coordonneesRepository,
BasketService $basketService,
EcoOrdersRepository $repoOrder,
EcoCustomersRepository $repoCustomer
) {
//Valider les sessions
$this->validateSession();
$addressBank = $coordonneesRepository->findOneBy(['siteUid' => CURRENT_SITE_ID, 'type' => 'bank-check']);
if ($addressBank == null) {
$addressBank = new SiteCoordonnees();
}
//Valider la commande
if ($request->isMethod('POST')) {
$this->validateOrder($this->session->get('order_id'));
return $this->redirectToRoute('front_basket_confirmation');
}
return $this->render('@main-app/front/front_basket/basket_payment_cheque.html.twig', [
'subtotal' => $subtotal = $basketService->getSubtotal(),
'addressBank' => $addressBank,
'siteName' => SITE_NAME,
'order' => $order = $repoOrder->find($this->session->get('order_id')),
'defaultShippingFees' => $basketService->getDefaultShippingFees(
$this->session->get('carrier_id'),
$order->getLivrCountryId()
),
'customer' => $repoCustomer->find($this->currentUserConnected->getId()),
'step' => 'payment',
]);
}
/**
* Défini les procédures à exécuter quand une commande est payée (pour tous les modes de paiement)
* @param integer $order_id
* @param integer $amount
*/
private function validateOrder($order_id = 0, $amount = 0)
{
if ($order_id > 0) {
//Modification du statut de la commande
$order = $this->entityManager->getRepository(EcoOrders::class)->find($order_id);
if ($order != null && $order != false && $order->getId() > 0 && $order->getOrderStatus() != "valid") {
$order->setOrderStatus('valid');
$order->setOrderPaymentDate(new \DateTime());
$order->setOrderTotalPaid($amount);
$this->entityManager->persist($order);
$this->entityManager->flush();
//Notification confirmation de commande
$this->sendNotification($order);
//Mise à jour des stocks
$this->updateStock($order_id);
}
} else {
return false;
}
}
private function updateStock($order_id)
{
$orderProducts = $this->entityManager->getRepository(EcoOrders::class)->findByOrdersProducts($order_id);
foreach ($orderProducts as $prod) {
$reference = $this->entityManager->getRepository(EcoProductsReferences::class)->find($prod['reference_id']);
//Cas d'un pack, on déduit le stock des articles qui composent le pack
if ($prod['prod_type'] == 'bundle') {
$productsBundle = $this->entityManager->getRepository(EcoProductsBundle::class)->findBy(
['product_id' => $prod['product_id']]
);
foreach ($productsBundle as $prodBundle) {
$refBundle = $this->entityManager->getRepository(EcoProductsReferences::class)->find(
$prodBundle->getReferenceId()
);
$newQte = $refBundle->getRefQuantity() - ($prodBundle->getBundleQte() * $prod['op_qte']);
$refBundle->setRefQuantity($newQte > 0 ? $newQte : 0);
$this->entityManager->persist($refBundle);
}
$this->entityManager->flush();
}
//On déduit le stock
$newQte = $reference->getRefQuantity() - $prod['op_qte'];
$reference->setRefQuantity($newQte > 0 ? $newQte : 0);
//Passage du produit en indispo si stock à 0 et option activée dans les settings Ecommerce
$ecoSettings = $this->entityManager->getRepository(EcoSettings::class)->findOneBy(
['siteId' => CURRENT_SITE_ID]
);
if ($ecoSettings->getUnavailableProductNoStock() && $newQte <= 0) {
$reference->setRefOutOfOrder(true);
}
$this->entityManager->persist($reference);
}
$this->entityManager->flush();
// $orderProducts = $this->entityManager->getRepository(EcoOrdersProducts::class)->findBy(['order_id' => $order_id]);
//
// foreach ($orderProducts as $prod){
//
// $reference = $this->entityManager->getRepository(EcoProductsReferences::class)->find($prod->getReferenceId());
//// $product = $this->entityManager->getRepository(EcoProducts::class)->find($reference->getProductId());
//
// $newQte = $reference->getRefQuantity() - $prod->getOpQte();
// $reference->setRefQuantity($newQte > 0 ? $newQte : 0);
// $this->entityManager->persist($reference);
// }
//
// $this->entityManager->flush();
}
/**
* Envoi un mail de confirmation de commande au client + copie à l'admin
* @param object $order
*/
private function sendNotification($order)
{
$this->mailerService->fromName = SITE_NAME;
$this->mailerService->subject = SITE_NAME . " - Confirmation de votre commande " . $order->getOrderReference();
$customer = $this->entityManager->getRepository(EcoCustomers::class)->find($order->getCustomerId());
$allRecipients[] = [
"nom" => $order->getFactLastname(),
"prenom" => $order->getFactFirstname(),
"email" => $customer->getAuthUserId()->getEmail(),
"type" => 'to'
];
//Remise fidélité
if ($this->currentUserConnected && $this->currentUserConnected != null) {
$this->loyaltySystem->init($this->currentUserConnected->getId());
}
$htmlContent = $this->renderView('layouts/layouts_emails/notification_order_confirmation.html.twig', [
'references' => $this->entityManager->getRepository(
EcoProductsReferences::class
)->findByProductReferencesOrder(
$order->getId(),
$isCanceled = 0
),
'carrier' => $this->entityManager->getRepository(EcoShippingCarriers::class)->find($order->getCarrierId()),
'order' => $order,
'loyaltyDiscount' => $this->loyaltySystem->getTotalDiscount(),
'loyaltyPoints' => $this->loyaltySystem->getTotalPoint(),
'siteName' => SITE_NAME,
]);
$this->mailerService->sendMail($allRecipients, $htmlContent, null, 'admin');
}
#[Route(path: '/confirmation', name: 'front_basket_confirmation')]
public function confirmation(
BasketService $basketService,
EcoOrdersRepository $repoOrder,
EcoDiscountRepository $repoDiscount
): Response {
if (!$this->session->has('basket') || $this->session->get('basket') == null) {
return $this->redirectToRoute('front_home');
}
// $order = $repoOrder->find($this->session->get('order_id'));
$subtotal = $basketService->getSubtotal();
$defaultShippingFees = $basketService->getDefaultShippingFees(
$this->session->get('carrier_id'),
1
);
// <-- DEBUT --> Récupération remise
$discount = null;
if ($this->session->has('discount_id') && $this->session->get('discount_id') > 0) {
$discount = $repoDiscount->find($this->session->get('discount_id'));
}
// <-- FIN --> Récupération remise
$this->session->set('order_valid', 'valid');
//Valider les sessions/*a commenté pour test*/
$this->validateSession();
return $this->render('@main-app/front/front_basket/confirmation.html.twig', [
'subtotal' => $subtotal,
'discount' => $discount,
'user' => $this->currentUserConnected,
'defaultShippingFees' => $defaultShippingFees,
'step' => 'confirmation',
'siteName' => SITE_NAME
]);
}
#[Route(path: '/paiement-refuse', name: 'front_basket_payment_refuse')]
public function payment_refuse(): Response
{
if (!$this->session->has('basket') || $this->session->get('basket') == null) {
return $this->redirectToRoute('front_home');
}
//Valider les sessions /*a commenté pour test*/
$this->validateSession();
$site = $this->entityManager->getRepository(Site::class)->find(CURRENT_SITE_ID);
if ($site == null) {
$site = new Site();
}
return $this->render('@main-app/front/front_basket/payment_refuse.html.twig', [
'step' => 'confirmationRefused',
'site' => $site,
]);
}
#[Route(path: '/paiement-attente', name: 'front_basket_payment_pending')]
public function payment_pending(): Response
{
if (!$this->session->has('basket') || $this->session->get('basket') == null) {
return $this->redirectToRoute('front_home');
}
$site = $this->entityManager->getRepository(Site::class)->find(CURRENT_SITE_ID);
if ($site == null) {
$site = new Site();
}
return $this->render('@main-app/front/front_basket/payment_pending.html.twig', [
'step' => 'confirmationPending',
'site' => $site,
]);
}
#[Route(path: '/paiement-annule', name: 'front_basket_payment_canceled')]
public function payment_canceled(): Response
{
if (!$this->session->has('basket') || $this->session->get('basket') == null) {
return $this->redirectToRoute('front_home');
}
//Valider les sessions/*a commenté pour test*/
$this->validateSession();
$site = $this->entityManager->getRepository(Site::class)->find(CURRENT_SITE_ID);
if ($site == null) {
$site = new Site();
}
return $this->render('@main-app/front/front_basket/payment_canceled.html.twig', [
'step' => 'confirmationCacelled',
'site' => $site,
]);
}
/*
* Permet d'initialiser le template du panneau latéral du panier
* @var string $fromBasket page du panier ou l'internaute se trouve
* @return string le template du panier latéral
*/
private function initBasketPanel($fromBasket = "")
{
return $this->renderView('@main-app/layouts/layouts_front/tpl_basket_panel.html.twig', [
'basket' => $this->session->get('basket'),
'fromBasket' => $fromBasket,
'subtotal' => $this->basketService->getSubtotal(),
'defaultShippingFees' => $this->basketService->getDefaultShippingFees()
]);
}
/*
* Permet d'initialiser le template de la page récap du panier
* @return string le template du contenu du panier
*/
private function initBasketPage()
{
$discount = null;
if ($this->session->has('discount_id') && $this->session->get('discount_id') > 0) {
$discount = $this->repoDiscount->find($this->session->get('discount_id'));
}
//Remise fidélité
if ($this->currentUserConnected) {
$this->loyaltySystem->init($this->currentUserConnected->getId());
}
$now = new \DateTime('', new DateTimeZone('Europe/Paris'));
$now->format('Y-m-d H:i:s');
$basketHasSoin = false;
foreach ($this->session->get('basket') as $item) {
if ($item['referenceObject']->getTypeOdyssee() == "soin") {
$basketHasSoin = true;
}
}
$isCure = false;
if ($this->session->has('basket')) {
foreach ($this->session->get('basket') as $key => $basket) {
if (strpos($key, 'CURE') === 0) {
$isCure = true;
}
}
}
$odysseeCustomers = $this->apiService->rechercherClient(
adrCourriel: $this->currentUserConnected->getAuthUserId()->getEmail()
);
return $this->renderView('@main-app/front/front_basket/tpl_basket_page.html.twig', [
'isCure' => $isCure,
'basket' => $this->session->get('basket'),
'subtotal' => $this->basketService->getSubtotal(),
'defaultShippingFees' => $this->basketService->getDefaultShippingFees(),
'discount' => $discount,
'loyaltyDiscount' => $this->loyaltySystem->getTotalDiscount(),
'loyaltyPoints' => $this->loyaltySystem->getTotalPoint(),
'step' => 'basket',
'basketHasSoin' => $basketHasSoin,
'odysseeCustomers' => $odysseeCustomers,
]);
}
/**
* Permet l'ajout d'un produit au panier
*/
#[Route(path: '/axAddToBasket', name: 'front_axAddToBasket')]
public function axAddToBasket(Request $request): JsonResponse
{
if (!$this->currentUserConnected) {
$url = $this->generateUrl('front_app_login');
return new JsonResponse(
[
'status' => false,
'route' => $url
]
);
}
if ($request->isXmlHttpRequest() && $request->get('reference_id') > 0 && $request->get('qte') > 0) {
$refForAdd = $this->entityManager->getRepository(EcoProductsReferences::class)->find(
$request->get('reference_id')
);
foreach ($this->session->get('basket') as $items) {
// Vérifie si il y a une cure dans le panier, on ne peut pas ajouter de produits
if (is_string($items['referenceObject'])) {
$url = $this->generateUrl('front_shopping_categorie');
$this->addFlash(
'danger',
'Vous ne pouvez pas ajouter de produits lors de la réservation d\'une Cure'
);
return new JsonResponse(
[
'status' => false,
'route' => $url
]
);
}
// Vérifie si il y a un Bon Cadeau dans le panier, on ne peut pas ajouter de produits
if (($items['referenceObject']->getTypeOdyssee() == "bkdo" && $refForAdd->getTypeOdyssee(
) != 'bkdo') || ($items['referenceObject']->getTypeOdyssee(
) == "bkdovalue" && $refForAdd->getTypeOdyssee() != 'bkdovalue')) {
$url = $this->generateUrl('front_shopping_categorie');
$this->addFlash(
'danger',
'Vous ne pouvez pas ajouter de produits lors de l\'achat d\'un Bon Cadeau'
);
return new JsonResponse(
[
'status' => false,
'route' => $url
]
);
}
// Vérifie si il y a un produit dans le panier, on ne peut pas ajouter de Bon Cadeau
if ($items['referenceObject']->getTypeOdyssee() != "bkdo" && $items['referenceObject']->getTypeOdyssee(
) != "bkdovalue" && ($refForAdd->getTypeOdyssee() == 'bkdo' || $refForAdd->getTypeOdyssee(
) == 'bkdovalue')) {
$url = $this->generateUrl('front_shopping_categorie');
$this->addFlash(
'danger',
'Vous ne pouvez pas ajouter de Bon Cadeau lors de l\'achat de produits'
);
return new JsonResponse(
[
'status' => false,
'route' => $url
]
);
}
}
// ajout du produit au panier
$this->basketService->addProduct(
$request->get('reference_id'),
$request->get('qte'),
$request->get('bkdoValueAmount')
);
return new JsonResponse(
[
'status' => true,
'basketPanel' => html_entity_decode($this->initBasketPanel($request->get('fromBasket'))),
// refresh du panneau panier
'totalCountBasket' => $this->baseListener->getProductSumOnBasket()
]
);
}
return new JsonResponse(
[
'status' => false,
'basketPanel' => html_entity_decode($this->initBasketPanel($request->get('fromBasket'))),
]
);
}
/**
* Permet de mettre à jour une quantité pour un produit dans le panier
* en + ou en -
* @param Request $request
*/
#[Route(path: '/axUpdateQteBasket', name: 'front_axUpdateQteBasket')]
public function axUpdateQteBasket(Request $request)
{
if ($request->isXmlHttpRequest() && $request->get('reference_id') > 0) {
$qte = 0;
if ($request->get('qte')) {
$qte = $request->get('qte');
}
$ref_id = $request->get('reference_id');
$direction = $request->get('direction');
$this->basketService->updateProductQte($ref_id, $direction, $qte);
//Mise à jour des remises dans le cas d'une remise fidélité
if ($this->currentUserConnected && $this->session->has('loyalty_point_used') && $this->session->get(
'loyalty_point_used'
) > 0) {
$this->loyaltySystem->init($this->currentUserConnected->getId());
$this->basketService->applyDiscountLoyaltyBasket($this->loyaltySystem->getTotalDiscount());
}
$isCure = false;
foreach ($this->session->get('basket') as $key => $basket) {
if (strpos($key, 'CURE') === 0) {
$isCure = true;
}
}
// refresh du panier dans la page si besoin
$basketPage = "";
if ($request->get('fromBasket') == "panier") {
$basketPage = html_entity_decode($this->initBasketPage());
}
return new JsonResponse([
'isCure' => $isCure,
'status' => true,
'basketPanel' => html_entity_decode($this->initBasketPanel($request->get('fromBasket'))),
// refresh du panneau panier
'basketPage' => $basketPage,
'totalCountBasket' => $this->baseListener->getProductSumOnBasket()
]);
}
return new JsonResponse([
'status' => false,
]);
}
/**
* Permet la suppression d'un produit qui est au panier
* @param Request $request
*/
#[Route(path: '/axRemoveProductBasket', name: 'front_axRemoveProductBasket')]
public function axRemoveProductBasket(Request $request)
{
if ($request->isXmlHttpRequest() && $request->get('reference_id') > 0) {
$ref_id = $request->get('reference_id');
$this->basketService->removeProduct($ref_id);
// refresh du panier dans la page si besoin
$basketPage = "";
if ($request->get('fromBasket') == "panier") {
$basketPage = html_entity_decode($this->initBasketPage());
}
return new JsonResponse([
'status' => true,
'script' => '$("#articlePanier-' . $ref_id . '").remove();',
'basketPanel' => html_entity_decode($this->initBasketPanel()),
// refresh du panneau panier
'basketPage' => $basketPage,
'totalCountBasket' => $this->baseListener->getProductSumOnBasket()
]);
}
return new JsonResponse([
'status' => false,
]);
}
#[Route(path: '/deleteProductBasket/{productId}', name: 'front_deleteProductBasket')]
public function deleteProductBasket($productId): RedirectResponse
{
if ($productId > 0) {
$this->basketService->removeProduct($productId);
}
return $this->redirectToRoute('front_basket_delivery');
}
/**
* Permet de supprimer l'utilisation des points de fidélité sur un panier
* @param Request $request
*/
#[Route(path: '/axRemoveLoyaltyDiscount', name: 'front_axRemoveLoyaltyDiscount')]
public function axRemoveLoyaltyDiscount(Request $request)
{
if ($request->isXmlHttpRequest() && $this->session->has('loyalty_point_used')) {
// $this->session->set('loyalty_point_used', null);
// $this->session->remove('loyalty_point_used');
$this->basketService->removeLoyaltyDiscountBasket();
return new JsonResponse([
'status' => true,
'basketPanel' => html_entity_decode($this->initBasketPanel('panier')),
// refresh du panneau panier
'basketPage' => html_entity_decode($this->initBasketPage()),
'totalCountBasket' => $this->baseListener->getProductSumOnBasket()
]);
}
return new JsonResponse([
'status' => false,
]);
}
/**
* Permet d'ajouter des points de fidélité sur un panier
* @param Request $request
*/
#[Route(path: '/axAddLoyaltyDiscount', name: 'front_axAddLoyaltyDiscount')]
public function axAddLoyaltyDiscount(Request $request)
{
if ($request->isXmlHttpRequest() && $this->currentUserConnected) {
$this->loyaltySystem->init($this->currentUserConnected->getId());
$this->session->set('loyalty_point_used', true);
$this->basketService->applyDiscountLoyaltyBasket($this->loyaltySystem->getTotalDiscount());
return new JsonResponse([
'status' => true,
'basketPanel' => html_entity_decode($this->initBasketPanel('panier')),
// refresh du panneau panier
'basketPage' => html_entity_decode($this->initBasketPage()),
'totalCountBasket' => $this->baseListener->getProductSumOnBasket()
]);
}
return new JsonResponse([
'status' => false,
]);
}
/**
* Permet de supprimer une remise sur un panier
* @param Request $request
*/
#[Route(path: '/axRemoveDiscount', name: 'front_axRemoveDiscount')]
public function axRemoveDiscount(Request $request)
{
if ($request->isXmlHttpRequest()) {
$this->basketService->removeDiscountBasket();
return new JsonResponse([
'status' => true,
'basketPanel' => html_entity_decode($this->initBasketPanel('panier')),
// refresh du panneau panier
'basketPage' => html_entity_decode($this->initBasketPage()),
'totalCountBasket' => $this->baseListener->getProductSumOnBasket()
]);
}
return new JsonResponse([
'status' => false,
]);
}
/**
* Permet d'ajouter une remise sur un panier
* @param Request $request
*/
#[Route(path: '/axAddDiscount', name: 'front_axAddDiscount')]
public function axAddDiscount(Request $request)
{
if ($request->isXmlHttpRequest() && $request->get('discount_code')) {
$popup = "";
$articles = $this->basketService->getFormatedBasketProducts();
$this->discountService->initService(
$articles,
$this->currentUserConnected ? $this->currentUserConnected : null
);
$discount = $this->discountService->discountValidation($request->get('discount_code'));
if ($discount['status']) {
$this->session->set('discount_id', $this->discountService->discount_id);
//Mise en commentaire du DiscountService actuel => non fonctionnel
//$this->basketService->applyDiscountBasket($request->get('discount_code'));
} else {
$popup = $this->renderView('layouts/layouts_front/tpl_popup.html.twig', [
'popupTitle' => "Problème avec votre remise",
'popupMessage' => isset($discount['message']) && trim(
$discount['message']
) != "" ? $discount['message'] : "Code promo invalide",
'popupBtn2' => null,
]);
}
return new JsonResponse([
'popup' => $popup,
'status' => true,
'basketPanel' => html_entity_decode($this->initBasketPanel('panier')),
// refresh du panneau panier
'basketPage' => html_entity_decode($this->initBasketPage()),
'totalCountBasket' => $this->baseListener->getProductSumOnBasket()
]);
}
return new JsonResponse([
'status' => false,
]);
}
private function displayPopup()
{
if ($this->session->has('displayPopup')) {
//Erreur de connexion
if ($this->session->get('displayPopup') == 'delivery-account-error') {
$this->otideaUtils->createPopup([
"title" => 'Adresse de livraison indisponible',
"message" => "Aucune adresse de livraison n'est défini dans votre espace client.",
"btn2" => null
]
);
}
//Acceptation des CGV
if ($this->session->get('displayPopup') == 'cgv-error') {
$this->otideaUtils->createPopup([
"title" => 'CGV',
"message" => "Vous devez accepter les conditions générales de vente pour valider votre commande.",
"btn2" => null
]
);
}
$this->session->set('displayPopup', null);
}
}
}