<?php
namespace App\Controller;
use App\Entity\Billing;
use App\Entity\Client;
use App\Entity\Company;
use App\Entity\Contract;
use App\Entity\Intervenant;
use App\Entity\LogCancel;
use App\Entity\LogPlanning;
use App\Entity\LogRDV;
use App\Entity\Product;
use App\Entity\RDV;
use App\Entity\RDVProduct;
use App\Entity\Salon;
use App\Entity\Session;
use App\Entity\SessionSalon;
use App\Entity\Site;
use App\Entity\User;
use App\Form\AddSessionSalonType;
use App\Form\CompanyType;
use App\Form\FilterType;
use App\Form\RDVType;
use App\Form\ReplanningIntervenantType;
use App\Form\ReplanningType;
use App\Form\SessionSalonType;
use App\Manager\ReglementManager;
use App\Message\SendingPlanning;
use App\Repository\BillingRepository;
use App\Repository\ClientRepository;
use App\Repository\IntervenantRepository;
use App\Repository\ProductRepository;
use App\Repository\RDVProductRepository;
use App\Repository\RDVRepository;
use App\Repository\SalonRepository;
use App\Repository\SessionSalonRepository;
use App\Service\MailService;
use App\Service\PaytweakService;
use App\Traits\BillingManagerTrait;
use App\Traits\MailServiceTrait;
use App\Traits\ManagerTrait;
use App\Traits\RDVManagerTrait;
use DateTime;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\EntityManagerInterface;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
use Symfony\Component\HttpFoundation\StreamedResponse;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Routing\Annotation\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Csrf\CsrfTokenManager;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\SerializerInterface;
/**
* @Route("/planning")
*/
class PlanningController extends AbstractController
{
use RDVManagerTrait;
use ManagerTrait;
use BillingManagerTrait;
use MailServiceTrait;
/**
* @Route("/site", methods={"GET"})
* @Template()
*/
public function site(SerializerInterface $serializer): array
{
$em = $this->managerRegistry;
$sessions = $em->getRepository(RDV::class)->findForPlanning();
$sites = $em->getRepository(Site::class)->findAll();
$intervenants = $em->getRepository(Intervenant::class)->findAll();
$companies = $em->getRepository(Company::class)->findAll();
$rdv = new RDV();
$form = $this->createForm(RDVType::class, $rdv);
$sessions = $serializer->serialize($sessions, 'json', [
'groups' => 'rdv',
'circular_reference_handler' => function ($object) {
return $object->getId();
}
]);
//dump($sessions);die;
return [
'sites' => $sites,
'intervenants' => $intervenants,
'sessions' => $sessions,
'companies' => $companies,
'form' => $form->createView()
];
}
/**
* TODO: not in use
* @Route("/intervenant", methods={"GET"})
* @Template()
*/
public function intervenant(SerializerInterface $serializer): array
{
$em = $this->managerRegistry;
$sessions = $em->getRepository(RDV::class)->findAll();
$rdv = new RDV();
$form = $this->createForm(RDVType::class, $rdv);
$sessions = $serializer->serialize($sessions, 'json', [
'groups' => 'rdv',
'circular_reference_handler' => function ($object) {
return $object->getId();
}
]); //dump($sessions);die;
return [
'sessions' => $sessions,
'form' => $form->createView()
];
}
/**
* @Route("/envoiPlanning")
*/
public function envoiPlanning(MessageBusInterface $messageBus): RedirectResponse
{
$this->addFlash('success', 'Envoi pris en compte. ');
$messageBus->dispatch(new SendingPlanning());
return $this->redirectToRoute('app_planning_pilotage');
}
/**
* @Route("/liste", methods={"GET","POST"})
* @Template()
*/
public function liste(
Request $request,
RDVRepository $RDVRepository,
SessionSalonRepository $sessionSalonRepository,
ProductRepository $productRepository,
ClientRepository $clientRepository,
BillingRepository $billingRepository
): array {
$em = $this->managerRegistry;
// date ajdh
//$sessions = $repository->findFromToday();
$sites = $em->getRepository(Site::class)->findAll();
$rdv = new RDV();
$status = $request->query->get('status');
$client = $request->query->get('client');
$clientId = $request->query->get('client_id');
$clientFind = null;
if ($clientId) {
$clientFind = $clientRepository->find($clientId);
$rdv->setClient($clientFind);
$salon = $clientFind->getSite()->getSalons();
$first = $salon->first();
if ($first) {
$rdv->setSalon($first);
}
}
$formFilter = $this->createForm(FilterType::class, null, ['status' => $status, 'client' => $clientFind]);
$form = $this->createForm(RDVType::class, $rdv, ['withCustomPicker' => true]);
$formReplanning = $this->createForm(ReplanningType::class, null);
$formReplanning2 = $this->createForm(ReplanningIntervenantType::class, null);
$formReplanning->handleRequest($request);
$formReplanning2->handleRequest($request);
$formFilter->handleRequest($request);
$sessions = $RDVRepository->findByFilter(null, null, $client, null, null, $status, $clientId);
$sessionsResult =[];
/** @var RDV $session */
foreach ($sessions as $session) {
$client = $session->getClient();
if($client){
$billings = $client->getBillings();
/** @var Billing $billing */
$lastBilling = [];
$billings = $billingRepository->searchUnpaid($client);
$session->paid = null;
$currentDate = new \DateTime();
if (count($billings) > 0) {
$myLastElement = end($billings);
$diff = $currentDate->diff($myLastElement['dateBilling'])->format("%r%a");
$session->paid = abs($diff);
}
}
// $products = $productRepository->getProductsArrayByRDV($session['id']);
// $session['products'] = $products;
//
// $session['label'] = RDV::getRDVLabel($session['status']);
// $sessionRdv = $RDVRepository->find($session['id']);
// $session['ttc'] = $sessionRdv->ttc();
$sessionsResult[] = $session;
}
// replannification
if ($formReplanning->isSubmitted() && $formReplanning->isValid()) {
$this->RDVManager->replannification($formReplanning);
$em->getManager()->flush();
}
if ($formReplanning2->isSubmitted() && $formReplanning2->isValid()) {
$this->RDVManager->replannificationIntervenant($formReplanning2);
$em->getManager()->flush();
}
if ($formFilter->isSubmitted() && $formFilter->isValid()) {
$intervenant = $formFilter->getData()['intervenant'];
$site = $formFilter->getData()['site'];
$client = $formFilter->getData()['client'];
$start = $formFilter->getData()['start'];
$status = $formFilter->getData()['status'];
$end = $formFilter->getData()['end'];
$salon = $formFilter->getData()['salon'];
$request->getSession()->set('intervenant', $intervenant);
$request->getSession()->set('site', $site);
$request->getSession()->set('client', $client);
$request->getSession()->set('start', $start);
$request->getSession()->set('end', $end);
$request->getSession()->set('salon', $salon);
$sessions = $RDVRepository->findByFilter($intervenant, $site, $client, $start, $end, $status, $clientId, null, $salon);
foreach ($sessions as $session) {
$client = $session->getClient();
$session->paid = null;
if($client){
$billings = $client->getBillings();
/** @var Billing $billing */
$lastBilling = [];
$billings = $billingRepository->searchUnpaid($client);
$currentDate = new \DateTime();
if (count($billings) > 0) {
$myLastElement = end($billings);
$diff = $currentDate->diff($myLastElement['dateBilling'])->format("%r%a");
$session->paid = abs($diff);
}
}
$sessionsResult[] = $session;
}
$sessionsResult = $sessions;
}
return [
'sessions' => $sessionsResult,
'form' => $form->createView(),
'formReplanning' => $formReplanning->createView(),
'formReplanning2' => $formReplanning2->createView(),
'formFilter' => $formFilter->createView(),
'sites' => $sites,
'intervenant' => $request->getSession()->get('intervenant'),
];
}
/**
* @Route("/listeBO", methods={"GET","POST"}, name="app_planning_liste_bo")
* @Template()
*/
public function listeBO(
Request $request,
SerializerInterface $serializer,
SessionSalonRepository $sessionSalonRepository,
SalonRepository $salonRepository,
IntervenantRepository $intervenantRepository,
RDVRepository $RDVRepository
): Response {
$salonQuery = $request->query->get('salon');
$intervenantQuery = $request->query->get('intervenant');
$dateDebut = $request->query->get('date_debut');
$dateFin = $request->query->get('date_fin');
$user = $this->getUser();
$sessions = $sessionSalonRepository->findAllMax($salonQuery, $intervenantQuery, $dateDebut, $dateFin, $user);
/** @var SessionSalon $session */
foreach ($sessions as $session) {
$rdvs = $RDVRepository->countRDVsBySalonAndDate($session->getSalon(), $session->getStart());
$totalCa = 0;
/** @var RDV $rdv */
$i = 0;
foreach ($rdvs as $rdv){
/** @var RDVProduct $rdvProduct */
foreach ($rdv->getRdvProducts() as $rdvProduct) {
$grid = $rdv->getSalon() && $rdv->getSalon()->getGridPrice() ? $rdv->getSalon()->getGridPrice()->getId() : 1;
switch ($grid) {
case 1:
$price = $rdvProduct->getProduct()->getPriceHtA();
break;
case 2:
$price = $rdvProduct->getProduct()->getPriceHtB();
break;
case 3:
$price = $rdvProduct->getProduct()->getPriceHtC();
break;
case 4:
$price = $rdvProduct->getProduct()->getPriceHtD();
break;
}
$totalCa += $price;
}
$i++;
}
$session->startRDV = $session->getStart();
// Assuming $session->getRdvs() returns a collection of rdvs
$session->rdvCount = $i;
$session->rdvCA = number_format(round($totalCa, 2), 2, '.', '');
}
$salons = $salonRepository->findAll();
$intervenants = $intervenantRepository->findAll();
return $this->render('planning/liste_bo.html.twig', [
'dateDebut' => $dateDebut,
'dateFin' => $dateFin,
'sessions' => $sessions,
'salons' => $salons,
'intervenants' => $intervenants
]);
}
/**
* @Route("/coiffeurListe", methods={"GET","POST"})
* @Template()
* @param Request $request
* @param RDVRepository $repository
* @return array
*/
public function coiffeurListe(
Request $request,
RDVRepository $repository,
SessionSalonRepository $sessionSalonRepository,
RDVRepository $RDVRepository,
ClientRepository $clientRepository,
ProductRepository $productRepository,
BillingRepository $billingRepository,
PaytweakService $paytweakService
): array {
$em = $this->managerRegistry;
// date ajdh
//$sessions = $repository->findFromToday();
$sites = $em->getRepository(Site::class)->findAll();
$rdv = new RDV();
$status = $request->query->get('status');
$client = $request->query->get('client');
$clientId = $request->query->get('client_id');
$formFilter = $this->createForm(FilterType::class, null, ['status' => $status, 'client' => $client]);
$form = $this->createForm(
RDVType::class,
$rdv,
['withCustomPicker' => true]
);
$formReplanning = $this->createForm(ReplanningType::class, null);
$formReplanning->handleRequest($request);
$formReplanning2 = $this->createForm(ReplanningType::class, null);
$formReplanning2->handleRequest($request);
$formFilter->handleRequest($request);
$sessions = $repository->findByFilterCoiffeuse(null, null, $client, null, null, $status, $clientId, $this->getUser());
$sessionsResult = [];
/** @var Session $session */
foreach ($sessions as $session) {
$session['client'] = null;
if (isset($session['client_id'])) {
$client = $clientRepository->find($session['client_id']);
$session['client'] = $client;
}
if ($client == null)
continue;
$billings = $client->getBillings();
/** @var Billing $billing */
$lastBilling = [];
$billings = $billingRepository->searchUnpaid($client);
$session['paid'] = null;
$currentDate = new \DateTime();
if (count($billings) > 0) {
$myLastElement = end($billings);
$diff = $currentDate->diff($myLastElement['dateBilling'])->format("%r%a");
$session['paid'] = abs($diff);
}
$products = $productRepository->getProductsArrayByRDV($session['id']);
$session['products'] = $products;
$session['label'] = RDV::getRDVLabel($session['status']);
$sessionRdv = $RDVRepository->find($session['id']);
$rdvBillings = $sessionRdv->getRDVBillings();
$billingCodes = [];
foreach ($rdvBillings as $rdvBilling) {
// Assuming the billing object has a getCode() method
$billingCodes[] = $rdvBilling->getBilling()->getCode();
}
$session['ttc'] = $sessionRdv->ttc();
$session['qrimage']= null;
$link = ($rdvBillings && isset($rdvBillings[0]) && $rdvBillings[0]->getBilling()) ? $rdvBillings[0]->getBilling()->getLinkPaytweak() : null;
if($link){
// try {
// $res = $paytweakService->getLink($rdvBillings[0]->getBilling()->getCompany(), $rdvBillings[0]->getBilling()->getCode());
// if ($res['code'] === PaytweakService::CODE_OK) {
// $item = reset($res);
// if (isset($link['qrcode'])){
// $session['qrimage'] = $item['qrcode'];
// }
// }
//
//
// }
// catch (\Exception $exception){
//
// }
$prefix = "https://paytweak.link/";
if($rdvBillings[0]->getBilling()->getCompany()->getId() === 2){
$prefix = "https://silver-beaute.link/";
}
$link = $prefix . $rdvBillings[0]->getBilling()->getLinkPaytweak();
}
$session['qrlink'] = $link;
$session['codeBilling'] = implode(",",$billingCodes);
$sessionsResult[] = $session;
}
// replannification
if ($formReplanning->isSubmitted() && $formReplanning->isValid()) {
$this->RDVManager->replannification($formReplanning);
$em->getManager()->flush();
}
// replannificcation interrvenant
if ($formReplanning2->isSubmitted() && $formReplanning2->isValid()) {
$this->RDVManager->replannification($formReplanning2);
$em->getManager()->flush();
}
if ($formFilter->isSubmitted() && $formFilter->isValid()) {
$intervenant = $formFilter->getData()['intervenant'];
$site = $formFilter->getData()['site'];
$client = $formFilter->getData()['client'];
$start = $formFilter->getData()['start'];
$status = $formFilter->getData()['status'];
$salon = $formFilter->getData()['salon'];
$end = $formFilter->getData()['end'];
$request->getSession()->set('intervenant', $intervenant);
$request->getSession()->set('site', $site);
$request->getSession()->set('client', $client);
$request->getSession()->set('start', $start);
$request->getSession()->set('end', $end);
$sessions = $repository->findByFilterCoiffeuse($intervenant, $site, $client, $start, $end, $status, null, null, $salon);
$sessionsResult = [];
foreach ($sessions as $session) {
$client = null;
if ($session['client_id']) {
$client = $clientRepository->find($session['client_id']);
}
$products = $productRepository->getProductsArrayByRDV($session['id']);
$session['products'] = $products;
$session['client'] = $client;
$session['label'] = RDV::getRDVLabel($session['status']);
$billings = [];
if ($client) {
$billings = $billingRepository->searchUnpaid($client);
}
$session['paid'] = null;
$currentDate = new \DateTime();
if (count($billings) > 0) {
$myLastElement = end($billings);
$diff = $currentDate->diff($myLastElement['dateBilling'])->format("%r%a");
$session['paid'] = abs($diff);
}
$sessionRdv = $RDVRepository->find($session['id']);
$rdvBillings = $sessionRdv->getRDVBillings();
$billingCodes = [];
foreach ($rdvBillings as $rdvBilling) {
// Assuming the billing object has a getCode() method
$billingCodes[] = $rdvBilling->getBilling()->getCode();
}
$session['codeBilling'] = implode(",",$billingCodes);
$link = ($rdvBillings && isset($rdvBillings[0]) && $rdvBillings[0]->getBilling()) ? $rdvBillings[0]->getBilling()->getLinkPaytweak() : null;
if($link){
// try {
// $res = $paytweakService->getLink($rdvBillings[0]->getBilling()->getCompany(), $rdvBillings[0]->getBilling()->getCode());
// if ($res['code'] === PaytweakService::CODE_OK) {
// $item = reset($res);
// if (isset($link['qrcode'])){
// $session['qrimage'] = $item['qrcode'];
// }
// }
//
//
// }
// catch (\Exception $exception){
//
// }
$prefix = "https://paytweak.link/";
if($rdvBillings[0]->getBilling()->getCompany()->getId() === 2){
$prefix = "https://silver-beaute.link/";
}
$link = $prefix . $rdvBillings[0]->getBilling()->getLinkPaytweak();
}
$session['qrlink'] = $link;
$session['ttc'] = $sessionRdv->ttc();
$sessionsResult[] = $session;
}
}
return [
'sessions' => $sessionsResult,
'form' => $form->createView(),
'formReplanning' => $formReplanning->createView(),
'formReplanning2' => $formReplanning2->createView(),
'formFilter' => $formFilter->createView(),
'sites' => $sites,
'intervenant' => $request->getSession()->get('intervenant'),
];
}
/**
* @Route("/new", methods={"GET","POST"})
*/
public function new(Request $request): Response
{
$company = new Company();
$form = $this->createForm(CompanyType::class, $company);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($company);
$entityManager->flush();
return $this->redirectToRoute('company_index');
}
return $this->render('company/new.html.twig', [
'company' => $company,
'form' => $form->createView(),
]);
}
/**
* @Route("/newJOS", methods={"GET","POST"})
*/
public function newJOS(Request $request): Response
{
$em = $this->getDoctrine()->getManager();
$sessionSalon = new SessionSalon();
$form = $this->createForm(AddSessionSalonType::class, $sessionSalon, []);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em->persist($sessionSalon);
$em->flush();
return $this->redirectToRoute('app_planning_pilotage');
}
return $this->render('planning/newJOS.html.twig', [
'session' => $sessionSalon,
'form' => $form->createView()
]);
}
/**
* @Route("/pilotage-expoitation", methods={"GET","POST"})
*/
public function pilotage(
Request $request,
SerializerInterface $serializer,
SessionSalonRepository $sessionSalonRepository,
SalonRepository $salonRepository,
IntervenantRepository $intervenantRepository
): Response {
$salonQuery = $request->query->get('salon');
$intervenantQuery = $request->query->get('intervenant');
$dateDebut = $request->query->get('date_debut');
$dateFin = $request->query->get('date_fin');
$user = $this->getUser();
$sessions = $sessionSalonRepository->findAllMax($salonQuery, $intervenantQuery, $dateDebut, $dateFin, $user);
$salons = $salonRepository->findAll();
$intervenants = $intervenantRepository->findAll();
// $sessions = $serializer->serialize($sessions, 'json', [
// 'groups' => 'rdv',
// 'circular_reference_handler' => function ($object) {
// return $object->getId();
// }
// ]);
return $this->render('planning/pilotage.html.twig', [
'dateDebut' => $dateDebut,
'dateFin' => $dateFin,
'sessions' => $sessions,
'salons' => $salons,
'intervenants' => $intervenants
]);
}
/**
* @Route("/calendrier-expoitation", methods={"GET","POST"})
*/
public function calendrier(
Request $request,
RDVRepository $rdvRepository,
SessionSalonRepository $sessionSalonRepository,
SalonRepository $salonRepository,
IntervenantRepository $intervenantRepository
): Response {
$salonQuery = $request->query->get('salon');
$intervenantQuery = $request->query->get('intervenant');
$dateDebut = $request->query->get('date_debut');
$dateFin = $request->query->get('date_fin');
$metier = $request->query->get('metier');
$status = $request->query->get('status');
$zoneGeographique = $request->query->get('zoneGeographique');
$user = $this->getUser();
$sessions = $sessionSalonRepository->findCalendar($salonQuery, $intervenantQuery, $dateDebut, $dateFin, $user, $zoneGeographique, $metier, $status);
$intervenantsFilter = $intervenantRepository->findAll();
$intervenants = [];
$ressources = [];
$events = [];
$ca = [];
$rdvsNumber = [];
$sessionsIds = [];
$joursReposColor = '#794cf6';
$jourReposDays = [];
$key = 1;
usort($sessions, function($a, $b) {
// Prioritize "IDF" by moving it to the front.
if ($a['zoneGeographique'] === 'IDF' && $b['zoneGeographique'] !== 'IDF') {
return -1;
} elseif ($a['zoneGeographique'] !== 'IDF' && $b['zoneGeographique'] === 'IDF') {
return 1;
}
// Prioritize "Coiffeur" by moving it to the front.
if ($a['metier'] === Intervenant::METIER_COIFFEUR && $b['metier'] !== Intervenant::METIER_COIFFEUR) {
return -1;
} elseif ($a['metier'] !== Intervenant::METIER_COIFFEUR && $b['metier'] === Intervenant::METIER_COIFFEUR) {
return 1;
}
// For other values, use standard string comparison for 'zoneGeographique'.
$zoneComparison = strcmp($a['zoneGeographique'], $b['zoneGeographique']);
if ($zoneComparison !== 0) {
return $zoneComparison;
}
// For other values, use standard string comparison for 'metier'.
$metierComparison = strcmp($a['metier'], $b['metier']);
if ($metierComparison !== 0) {
return $metierComparison;
}
// For other values, use standard string comparison for 'intervenant_last_name'.
return strcmp($a['intervenant_last_name'], $b['intervenant_last_name']);
});
foreach ($sessions as &$session) {
// dd($session);
// // get chiffre d'affaire et totale des rdvs par salon
// if (!in_array($session['salon_id'], $sessionsIds)) {
// $rdvs = $rdvRepository->findBy(['salon' => $session['salon_id'], 'intervenant' => $session['intervenant_id']]);
// $rdvsNumber[$session['salon_id']] = count($rdvs);
// $totalHt = $this->calculateTotalHtForRDVs($rdvs);
// $sessionsIds[] = $session['salon_id'];
// $ca[$session['salon_id']] = number_format($totalHt, 2);
// }
$name = htmlspecialchars($session['salon_name'], ENT_QUOTES, 'UTF-8');
$intervenants[]=[
'id' => $session['intervenant_id'],
'firstname' => $session['intervenant_first_name'],
'lastname' => $session['intervenant_last_name'],
];
$hourEnd = $session['end'] ? $session['end']->format('H:i') : '';
$title = ($session['observation'] ? "❶ " : "") . ($session['actionArealiser'] ? "🚩 " : "") . $name . " - Horaire: {$session['start']->format('H:i')} " . $hourEnd;
$eventColor = $this->getColorForSessionStatus($session['status']);
$events[] = [
'start' => $session['start']->format('Y-m-d\TH:i'),
'end' => $session['end'] ? $session['end']->format('Y-m-d\TH:i') : $session['start']->format('Y-m-d\T23:59'),
'title' => $title,
//'allDay' => true,
'color' => $eventColor,
'resource' => $session['intervenant_id'],
'event_id' => $session['session_id']
];
if (isset($session['absence_start']) && isset($session['absence_end'])) {
$heureDebut = $session['absence_start_time'] ?? '00:00';
$heureFin = $session['absence_end_time'] ?? '23:59';
$absenceStart = $this->createDateTimeObject($session['absence_start'], $heureDebut);
$absenceEnd = $this->createDateTimeObject($session['absence_end'], $heureFin);
$dateRange = $absenceStart->format('d-m-Y H:i') . ' - ' . $absenceEnd->format('d-m-Y H:i');
$absenceEvent = [
'start' => $absenceStart->format('Y-m-d\TH:i'),
'end' => $absenceEnd->format('Y-m-d\TH:i'),
'title' => 'Absence: ' . $session['motif'] . ' ' . $session['absence_comment'] .' -- Date : ' . $dateRange,
'resource' => $session['intervenant_id'],
'event_id' => 'absence_' . $session['session_id'],
'color' => '#ff9c04',
];
$events[] = $absenceEvent;
}
//intervenant_id
$ressources[$session['intervenant_id']] = [
'id' => $session['intervenant_id'],
'name' => $session["intervenant_last_name"] . " " . $session["intervenant_first_name"],
'color' => '#34c8e0'
];
$key++;
}
$holidays = $this->getHolidays();
$holidayColor = '#ff0000';
$exist = [];
foreach ($sessions as $sessionRepo) {
$endDate = (new DateTime("now"))->modify("+1 years");
$startDate = (new DateTime("now"))->modify("-5 months");
if ((!in_array($sessionRepo['intervenant_id'], $exist)) ){
foreach ($holidays as $holiday) {
$events[] = [
'start' => $holiday->format('Y-m-d\T00:00'),
'end' => $holiday->format('Y-m-d\T23:59'),
'title' => 'Holiday',
'color' => $holidayColor,
'resource' => $sessionRepo['intervenant_id'],
'event_id' => 'holiday_' . $holiday->format('Ymd'),
];
}
if ( $sessionRepo['joursRepos'] !== null ) {
while ($startDate <= $endDate) {
$joursrepos = $sessionRepo['joursRepos'];
asort($joursrepos);
foreach ($joursrepos as $key => $reposDay) {
if ($startDate->format('w') == $reposDay) {
$events[] = [
'start' => $startDate->format('Y-m-d\T00:00'),
'end' => $startDate->format('Y-m-d\T23:59'),
'title' => 'Repos',
'color' => $joursReposColor,
'resource' => $sessionRepo['intervenant_id'],
'event_id' => 'repos_' . rand(1000, 10000) . '_' . $sessionRepo['session_id']
];
}
}
$startDate->modify('+1 days');
}
}
$exist[] = $sessionRepo['intervenant_id'];
}
}
$salons = $salonRepository->findAll();
return $this->render('planning/calendar.html.twig', [
'intervenantsFilter' => $intervenantsFilter,
'dateDebut' => $dateDebut,
'dateFin' => $dateFin,
'sessions' => $events,
'ressources' => array_values($ressources),
'salons' => $salons,
'intervenants' => json_encode($intervenants)
]);
}
public function createDateTimeObject($absenceDate, $heure)
{
$heure = strlen($heure) !== 2 ? $heure : $heure . ':00';
return \DateTime::createFromFormat('d-m-Y H:i', $absenceDate . ' ' . $heure);
}
public function getColorForSessionStatus($status) {
switch ($status) {
case 'modifier':
return 'rgb(255, 245, 97)';
case 'event':
return '#FF5733';
case 'indisponible':
return '#707070';
default:
return 'rgb(52, 200, 224)';
}
}
public function calculateTotalHtForRDVs($rdvs) {
$totalHt = 0;
foreach ($rdvs as $rdv) {
$rdvProductsArray = iterator_to_array($rdv->getRdvProducts());
foreach ($rdv->getRDVBillings() as $RDVBilling) {
$billing = $RDVBilling->getBilling();
$rdv = $RDVBilling->getRDV();
if ($billing->getStatus() === Billing::STATUS_SENT || $billing->getStatus() === Billing::STATUS_REGLEE) {
$products = array_map(function ($rdvProduct) {
return $rdvProduct->getProduct()->getId();
}, $rdvProductsArray);
foreach ($billing->getBillingItems() as $item) {
if (in_array($item->getProduct()->getId(), $products)) {
$ht = $item->getPrice() * $item->getQuantity();
if ($item->getDiscount()) {
$totalHt += $ht - ($ht * $item->getDiscount() / 100);
} else {
$totalHt += $ht;
}
}
}
}
}
}
return $totalHt;
}
/**
* Get holidays for the current year and the next year.
*
* @param null $year
* @return array
* @throws \Exception
*/
public function getHolidays($year = null)
{
// If $year is not specified, use the current year
if ($year === null) {
$currentYear = intval(date('Y'));
} else {
$currentYear = intval($year);
}
// Calculate the next year
$nextYear = $currentYear + 1;
$dateTimeHoliday = array();
$easterDate = easter_date($currentYear);
$easterDay = date('j', $easterDate);
$easterMonth = date('n', $easterDate);
$easterYear = date('Y', $easterDate);
$holidays = array(
// Fixed holidays
gmmktime(0, 0, 0, 1, 1, $currentYear), // New Year's Day
gmmktime(0, 0, 0, 5, 1, $currentYear), // Labor Day
gmmktime(0, 0, 0, 5, 8, $currentYear), // Victory in Europe Day
gmmktime(0, 0, 0, 7, 14, $currentYear), // Bastille Day
gmmktime(0, 0, 0, 8, 15, $currentYear), // Assumption Day
gmmktime(0, 0, 0, 11, 1, $currentYear), // All Saints' Day
gmmktime(0, 0, 0, 11, 11, $currentYear), // Armistice Day
gmmktime(0, 0, 0, 12, 25, $currentYear), // Christmas Day
// Holidays dependent on Easter
gmmktime(0, 0, 0, $easterMonth, $easterDay + 1, $currentYear), // Easter Monday
gmmktime(0, 0, 0, $easterMonth, $easterDay + 39, $currentYear), // Ascension
gmmktime(0, 0, 0, $easterMonth, $easterDay + 50, $currentYear), // Pentecost
);
$easterDateNextYear = easter_date($nextYear);
$easterDayNextYear = date('j', $easterDateNextYear);
$easterMonthNextYear = date('n', $easterDateNextYear);
$holidaysNextYear = array(
// Fixed holidays
gmmktime(0, 0, 0, 1, 1, $nextYear), // New Year's Day
gmmktime(0, 0, 0, 5, 1, $nextYear), // Labor Day
gmmktime(0, 0, 0, 5, 8, $nextYear), // Victory in Europe Day
gmmktime(0, 0, 0, 7, 14, $nextYear), // Bastille Day
gmmktime(0, 0, 0, 8, 15, $nextYear), // Assumption Day
gmmktime(0, 0, 0, 11, 1, $nextYear), // All Saints' Day
gmmktime(0, 0, 0, 11, 11, $nextYear), // Armistice Day
gmmktime(0, 0, 0, 12, 25, $nextYear), // Christmas Day
// Holidays dependent on Easter
gmmktime(0, 0, 0, $easterMonthNextYear, $easterDayNextYear + 1, $nextYear), // Easter Monday
gmmktime(0, 0, 0, $easterMonthNextYear, $easterDayNextYear + 39, $nextYear), // Ascension
gmmktime(0, 0, 0, $easterMonthNextYear, $easterDayNextYear + 50, $nextYear), // Pentecost
);
$holidays = array_merge($holidays, $holidaysNextYear);
// Add holidays for the next year
// foreach ($holidays as $holiday) {
// $holidayNextYear = $holiday + 31536000; // Add one year in seconds
// $holidays[] = $holidayNextYear;
// }
// Sort the holidays
sort($holidays);
foreach ($holidays as $value) {
$dateTimeHoliday[] = new \DateTime('@' . $value, new \DateTimeZone('Europe/Paris'));
}
return $dateTimeHoliday;
}
/**
* @Route("/send_email", name="send_email", methods={"POST"})
*/
public function sendEmail(MailService $mailService, Request $request, IntervenantRepository $intervenantRepository)
{
$id = $request->request->all()['id'];
$intervenant = $intervenantRepository->find($id);
$email = $intervenant->getEmail();
if (!$email) {
$email = $intervenant->getEmailPro();
if (!$email) {
$user = $intervenant->getUser();
if (!$user) {
return new JsonResponse('Utilisateur non trouvé', 400);
}
$email = $user->getEmail();
}
}
$mailService->sendToIntervenant(
$email,
[
'intervenant' => $intervenant
]
);
return new JsonResponse('ok', 200);
}
/**
* @Route("/generateForm", methods={"GET","POST"})
*/
public function generateForm(
Request $request,
SessionSalonRepository $sessionSalonRepository,
FormFactoryInterface $formFactory,
UrlGeneratorInterface $urlGenerator
): Response {
$sessionSalonQuery = $request->request->get('sessionSalon');
$sessionSalon = $sessionSalonRepository->find($sessionSalonQuery);
$actionUrl = $urlGenerator->generate('planning_handle_form'); // Replace with your actual route name
$form = $formFactory->create(AddSessionSalonType::class, $sessionSalon, [
'action' => $actionUrl,
]);
$form->add('sessionSalon', HiddenType::class, [
'data' => $sessionSalon->getId(),
'mapped' => false
]);
// Render the form view separately
$formView = $this->renderView('planning/SessionSalon/_form.html.twig', [
'form' => $form->createView(),
]);
return new JsonResponse(['view' => $formView]);
}
/**
* @Route("/handleForm", methods={"GET","POST"}, name="planning_handle_form")
*/
public function handleForm(
Request $request,
EntityManagerInterface $entityManager,
RDVRepository $RDVRepository,
SessionSalonRepository $sessionSalonRepository,
IntervenantRepository $intervenantRepository
): Response {
$sessionSalonId = $request->request->get('add_session_salon')['sessionSalon'];
// Retrieve the sessionSalon entity from the repository
/** @var SessionSalon $sessionSalon */
$sessionSalon = $sessionSalonRepository->find($sessionSalonId);
$dateSession = $sessionSalon->getStart();
$oldIntervenant = $sessionSalon->getIntervenant(); // JOS INTERVENANT
$form = $this->createForm(AddSessionSalonType::class,$sessionSalon);
$form->handleRequest($request);
if ($form->isSubmitted()) {
if ($sessionSalon) {
$day = $request->request->get('add_session_salon')['start']['date']['day'];
$month = $request->request->get('add_session_salon')['start']['date']['month'];
$year = $request->request->get('add_session_salon')['start']['date']['year'];
$hour = $request->request->get('add_session_salon')['start']['time']['hour'];
$minute = $request->request->get('add_session_salon')['start']['time']['minute'];
$dayEnd = $request->request->get('add_session_salon')['end']['date']['day'];
$monthEnd = $request->request->get('add_session_salon')['end']['date']['month'];
$yearEnd = $request->request->get('add_session_salon')['end']['date']['year'];
$hourEnd = $request->request->get('add_session_salon')['end']['time']['hour'];
$minuteEnd = $request->request->get('add_session_salon')['end']['time']['minute'];
$timestamp = strtotime("$year-$month-$day $hour:$minute");
$timestampEnd = strtotime("$yearEnd-$monthEnd-$dayEnd $hourEnd:$minuteEnd");
$dateTime = \DateTime::createFromFormat('U', $timestamp);
$intervenantId = $request->request->get('add_session_salon')['intervenant']; // INTERVENANT CHOOSE
$intervenant = $intervenantRepository->find($intervenantId);
$rdvs = $RDVRepository->replanifierDate($oldIntervenant, $sessionSalon->getSalon(), $dateSession);
$logplanning = new LogPlanning();
$logplanning->setIntervenantOld($oldIntervenant);
$logplanning->setNewIntervenant($intervenant);
$logplanning->setSessionSalon($sessionSalon);
$entityManager->persist($logplanning);
$entityManager->flush();
/** @var RDV $rdv */
foreach ($rdvs as $rdv) {
$dateTimeStart = \DateTime::createFromFormat('U', $timestamp);
$dateTimeEnd = \DateTime::createFromFormat('U', $timestampEnd);
$dateTimeStart->setTime(
$rdv->getStart()->format('H'), // Hours
$rdv->getStart()->format('i'), // Minutes
$rdv->getStart()->format('s') // Seconds
);
$dateTimeEnd->setTime(
$rdv->getEnd()->format('H'), // Hours
$rdv->getEnd()->format('i'), // Minutes
$rdv->getEnd()->format('s') // Seconds
);
$rdv->setStart($dateTimeStart);
$rdv->setEnd($dateTimeEnd);
$rdv->setIntervenant($intervenant);
$entityManager->persist($rdv);
}
// // replanification
// take all rdv from the JOS intervenant of today and set up to the new intervenant/
// $rdvs = $RDVRepository->replanifierIntervenant($oldIntervenant, $dateTime);
// /** @var RDV $rdv */
// foreach ($rdvs as $rdv) {
// $rdv->setIntervenant($intervenant);
// $entityManager->persist($rdv);
// }
if ($intervenant) {
$sessionSalon->setIntervenant($intervenant);
}
}
$entityManager->persist($sessionSalon);
$entityManager->flush();
}
return $this->redirectToRoute('app_planning_calendrier');
}
/**
* @Route("/dragdrop", methods={"GET","POST"})
*/
public function dragdrop(Request $request,
SessionSalonRepository $sessionSalonRepository,
EntityManagerInterface $entityManager,
RDVRepository $RDVRepository,
IntervenantRepository $intervenantRepository
) {
$event = $request->request->get('event');
$resource = $request->request->get('resource');
$start = $request->request->get('start');
if (strlen($start) === 13) {
$start = $start / 1000; // Convert milliseconds to seconds
}
/** @var SessionSalon $sessionSalon */
$sessionSalon = $sessionSalonRepository->find($event);
$updated = false;
if($sessionSalon){
$updated = true;
$intervenant = $intervenantRepository->find($resource);
// prends les rdv de l'ancienne intervenannte sur l'ancienne date et on les passe à la nouvelle date
$rdvs = $RDVRepository->replanifierDate($sessionSalon->getIntervenant(), $sessionSalon->getSalon(), $sessionSalon->getStart());
/** @var RDV $rdv */
foreach ($rdvs as $rdv){
$dateTimeStart = \DateTime::createFromFormat('U', $start);
$dateTimeEnd = \DateTime::createFromFormat('U', $start);
$dateTimeStart->setTime(
$rdv->getStart()->format('H'), // Hours
$rdv->getStart()->format('i'), // Minutes
$rdv->getStart()->format('s') // Seconds
);
$dateTimeEnd->setTime(
$rdv->getEnd()->format('H'), // Hours
$rdv->getEnd()->format('i'), // Minutes
$rdv->getEnd()->format('s') // Seconds
);
$rdv->setStart($dateTimeStart);
$rdv->setEnd($dateTimeEnd);
$rdv->setIntervenant($intervenant);
$entityManager->persist($rdv);
}
// replanification
// $rdvs = $RDVRepository->replanifierIntervenant($sessionSalon->getIntervenant(), $dateTime);
// /** @var RDV $rdv */
// foreach ($rdvs as $rdv){
// $entityManager->persist($rdv);
// }
if($intervenant){
$sessionSalon->setIntervenant($intervenant);
}
$dateTime = \DateTime::createFromFormat('U', $start);
$dateTime->setTime(10, 00, 00);
$endTime = \DateTime::createFromFormat('U', $start);
$endTime->setTime(18, 00, 00);
$sessionSalon->setStart($dateTime);
$sessionSalon->setEnd($endTime);
$entityManager->persist($sessionSalon);
$entityManager->flush();
}
return new JsonResponse(['status' => $updated]);
}
/**
* @Route("/export-calendrier", methods={"GET","POST"})
*/
public function exportCalendrier(Request $request, SessionSalonRepository $sessionSalonRepository){
$salonQuery = $request->query->get('salon');
$intervenantQuery = $request->query->get('intervenant');
$dateDebut = $request->query->get('date_debut');
$dateFin = $request->query->get('date_fin');
$user = $this->getUser();
$sessions = $sessionSalonRepository->findAllMax($salonQuery, $intervenantQuery, $dateDebut, $dateFin, $user);
// Create a new PhpSpreadsheet spreadsheet
$spreadsheet = new Spreadsheet();
// Create a new worksheet
$worksheet = $spreadsheet->getActiveSheet();
// Add headers to the worksheet (customize this part as needed)
$worksheet->setCellValue('A1', 'Session Start');
$worksheet->setCellValue('B1', 'Session End');
$worksheet->setCellValue('C1', 'Session Title');
$worksheet->setCellValue('D1', 'Intervenant Name');
$row = 2; // Start from row 2
// Add data to the worksheet
/** @var SessionSalon $session */
foreach ($sessions as $session) {
$worksheet->setCellValue('A' . $row, $session->getStart()->format('Y-m-d\TH:i'));
$worksheet->setCellValue('B' . $row, $session->getEnd() ? $session->getEnd()->format('Y-m-d\TH:i') : $session->getStart()->format('Y-m-d\T23:59'));
$worksheet->setCellValue('C' . $row, htmlspecialchars($session->getSalon()->getName(), ENT_QUOTES, 'UTF-8'));
$worksheet->setCellValue('D' . $row, $session->getIntervenant()->getLastname() . " " . $session->getIntervenant()->getFirstname());
$row++;
}
// Create a response for the Excel file
// Create a temporary file to store the Excel data
$filePath = $this->getParameter('kernel.project_dir') . '/public/exported_excel.xlsx';
$writer = new Xlsx($spreadsheet);
$writer->save($filePath);
// Create a BinaryFileResponse for the temporary file
$response = new Response();
$response->headers->set('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
$response->headers->set('Content-Disposition', 'attachment;filename="exported_excel.xlsx"');
// Read the file and set its content
$response->setContent(file_get_contents($filePath));
return $response;
}
/**
* @Route("/{id}/delete", name="planning_delete", methods={"DELETE"})
*/
public function deletePlanning(Request $request, SessionSalon $sessionSalon): Response
{
if ($this->isCsrfTokenValid('delete' . $sessionSalon->getId(), $request->request->get('_token'))) {
$entityManager = $this->getDoctrine()->getManager();
$entityManager->remove($sessionSalon);
$entityManager->flush();
}
return $this->redirectToRoute('app_planning_pilotage');
}
/**
* @Route("/{id}/sessionSalon", methods={"GET","POST"})
*/
public function sessionSalon(Request $request,int $id, SessionSalon $sessionSalon, EntityManagerInterface $em,
RDVRepository $RDVRepository, IntervenantRepository $intervenantRepository,
SessionSalonRepository $sessionSalonRepository): Response
{
$form = $this->createForm(SessionSalonType::class, $sessionSalon, [
'salon' => $sessionSalon->getSalon()
]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$oldInfo = $sessionSalonRepository->getOldInInfos($id);
// Make a copy of the old intervenant
$oldIntervenant = $intervenantRepository->find($oldInfo["id"]);
$rdvs = $RDVRepository->replanifierDate($oldIntervenant, $sessionSalon->getSalon(), $oldInfo["start"]);
// Retrieve the new intervenant entity
$intervenantRequest = $request->request->get('session_salon')["intervenant"];
$intervenant = $intervenantRepository->find($intervenantRequest);
// Retrieve the start date information
$dateStart = $request->request->get('session_salon')["start"];
$year = $dateStart["date"]["year"];
$month = $dateStart["date"]["month"];
$day = $dateStart["date"]["day"];
foreach ($rdvs as $rdv){
$start = $rdv->getStart();
$end = $rdv->getEnd();
// Create new start and end DateTime objects
$newStart = new DateTime("$year-$month-$day " . $start->format('H:i:s'));
$newEnd = new DateTime("$year-$month-$day " . $end->format('H:i:s'));
// Update RDV properties
$rdv->setStart($newStart);
$rdv->setEnd($newEnd);
$rdv->setIntervenant($intervenant);
$em->persist($rdv);
}
$em->persist($sessionSalon);
$em->flush();
}
return $this->render('planning/session_salon.html.twig', [
'session' => $sessionSalon,
'form' => $form->createView()
]);
}
/**
* @Route("/fusion", methods={"GET","POST"})
*/
public function fusion(Request $request, RDVRepository $RDVRepository, EntityManagerInterface $entityManager)
{
// do handle consumer
// //TODO : filter by auto author
// $rdvs = $RDVRepository->findForFusion();
//
// foreach ($rdvs as $rdv) {
//
// if(!$rdv->getClient()){
// continue;
// }
//
// foreach ($rdvs as $key => $rdv2) {
//
// if(!$rdv2->getClient()){
// continue;
// }
//
// if ($rdv->getId() != $rdv2->getId() &&
// $rdv->getClient()->getId() == $rdv2->getClient()->getId() &&
// $rdv->getStart() == $rdv2->getStart() &&
// $rdv->getSalon()->getId() == $rdv2->getSalon()->getId()
//
// ) {
//
// $gridA = $rdv->getSalon()->getGridPrice()->getId();
// $gridB = $rdv2->getSalon()->getGridPrice()->getId();
// $total1 = 0;
// $total2 = 0;
// foreach ($rdv->getRdvProducts() as $rdvProduct) {
// $total1 += $rdvProduct->getProduct()->getPriceSellTTCByGrid($gridA);
// }
//
// foreach ($rdv2->getRdvProducts() as $rdvProduct) {
// $total2 += $rdvProduct->getProduct()->getPriceSellTTCByGrid($gridB);
// }
//
// if ($total1 >= $total2) {
// // delete 2
// $entityManager->remove($rdv2);
// } else {
// $entityManager->remove($rdv);
// }
// $entityManager->flush();
//
// }
//
//
// }
// }
return $this->redirectToRoute('app_planning_site');
}
/**
* @Route("/downloadExcel")
*/
public function downloadExcel(Request $request, RDVRepository $repository)
{
$date_debut = $request->request->get('date_debut') ?? null;
$date_fin = $request->request->get('date_fin') ?? null;
$entities = new ArrayCollection($repository->findForExport($date_debut, $date_fin));
$response = new StreamedResponse();
$columns = $this->getColumnsForEntity(RDV::class);
$response->setCallback(function () use ($entities, $columns) {
$handle = fopen('php://output', 'w+');
// Add header
fputcsv($handle, array_keys($columns));
while ($entity = $entities->current()) {
$values = [];
foreach ($columns as $column => $callback) {
$value = $callback;
if (is_callable($callback)) {
$value = $callback($entity);
}
$values[] = $value;
}
fputcsv($handle, $values);
$entities->next();
}
fclose($handle);
});
$filename = 'rdv_export.csv';
$response->headers->set('Content-Type', 'text/csv; charset=utf-8');
$response->headers->set('Content-Disposition', 'attachment; filename="' . $filename . '"');
return $response;
}
/**
* @Route("/addRdv", methods={"POST"}, condition="request.isXmlHttpRequest()")
*/
public function addRdvAjax(
Request $request,
SerializerInterface $serializer,
ProductRepository $productRepository,
SalonRepository $salonRepository,
SessionSalonRepository $sessionSalonRepository
) {
$rdv = new RDV();
$em = $this->getDoctrine()->getManager();
$form = $this->createForm(RDVType::class, $rdv, [
'action' => $this->generateUrl($request->get('_route'))
])->handleRequest($request);
if ($form->isSubmitted()) {
$products = $form->get('products')->getViewData();
foreach ($products as $product) {
$obj = $productRepository->find($product);
$rdvProduct = new RDVProduct();
$rdvProduct->setRdv($rdv);
$rdvProduct->setProduct($obj);
$em->persist($rdvProduct);
}
$params = $request->request->get('rdv');
$salon = $salonRepository->find((int)$params['salon']);
$start = new \DateTime($params['start']);
$end = clone $start;
$sessionLength = $salon->getSite()->getType() === Site::TYPE_EHPAD ? '+15 minutes' : '+30 minutes';
$end->modify($sessionLength);
$rdv->setStart($start);
$rdv->setEnd($end);
$sessionSalon = $sessionSalonRepository->findSessionBySalonAndDate($salon, $start);
$rdv->setIntervenant($sessionSalon[0]->getIntervenant());
$rdv->setAuthor($this->getUser());
$this->getDoctrine()->getManager()->persist($rdv);
$this->getDoctrine()->getManager()->flush();
$rdv_json = $serializer->serialize($rdv, 'json', [
'groups' => 'rdv',
'circular_reference_handler' => function ($object) {
return $object->getId();
}
]);
return new JsonResponse($rdv_json, Response::HTTP_OK, [], true);
}
return new JsonResponse(null, Response::HTTP_BAD_REQUEST);
}
/**
* @Route("/getPlannings", methods={"GET"}, condition="request.isXmlHttpRequest()")
*/
public function ajaxFilter(Request $request, RDVRepository $repository, SerializerInterface $serializer)
{
$company = $request->get('company');
$intervenant = $request->get('intervenant');
$site = $request->get('site');
$result = null;
if ($site) {
$result = $repository->findBySite($site);
}
if ($company) {
$result = $repository->findByCompany($company);
}
if ($intervenant) {
$result = $repository->findBy(['intervenant' => $intervenant]);
}
if (!$site && !$company && !$intervenant) {
$result = $repository->findAll();
}
$result = $serializer->serialize($result, 'json', [
'groups' => 'rdv',
'circular_reference_handler' => function ($object) {
return $object->getId();
}
]);
return new JsonResponse($result, Response::HTTP_OK, [], true);
}
/**
* @Route("/getSalons/{id}", methods={"GET"}, condition="request.isXmlHttpRequest()")
*/
public function ajaxGetSalons(Client $client, SerializerInterface $serializer)
{
// dump('d'. $client->getSite()->getId());die;
$salons = $client->getSite()->getSalons();
$result = $serializer->serialize($salons, 'json', [
'groups' => 'rdv',
'circular_reference_handler' => function ($object) {
return $object->getId();
}
]);
return new JsonResponse($result, Response::HTTP_OK, [], true);
}
/**
* @Route("/getIntervenants/{id}/{date}", methods={"GET"}, condition="request.isXmlHttpRequest()")
*/
public function ajaxGetIntervenants(
Salon $salon,
SerializerInterface $serializer,
SessionSalonRepository $sessionSalonRepository,
$date
) {
// dump('d'. $client->getSite()->getId());die;
// $intervenants = $salon->getIntervenantSalons()->filter(function ($e){
// return $e->getIntervenant()->getStatus() == 1;
// });
$date = date_create_from_format('Y-m-d H:i', $date);
$intervenants = [];
$sessionsSalons = $sessionSalonRepository->findBy(['salon' => $salon]);
/** @var SessionSalon $sessionSalon */
foreach ($sessionsSalons as $sessionSalon) {
$dateSalon = $sessionSalon->getStart();
if ($sessionSalon->getIntervenant() && $sessionSalon->getIntervenant()->getStatus() == 1 && $dateSalon->format('Y-m-d') == $date->format('Y-m-d')) {
$intervenants[$sessionSalon->getIntervenant()->getId()] = $sessionSalon->getIntervenant();
}
}
$result = $serializer->serialize(array_values($intervenants), 'json', [
'groups' => 'rdv',
'circular_reference_handler' => function ($object) {
return $object->getId();
}
]);
return new JsonResponse($result, Response::HTTP_OK, [], true);
}
/**
* @Route("/getProducts/{id}", methods={"GET"}, condition="request.isXmlHttpRequest()")
*/
public function ajaxGetProducts(Salon $salon, SerializerInterface $serializer, ProductRepository $productRepository)
{
$tag = $salon->getService();
$products = $productRepository->findBy([
'type' => strtolower($tag),
'indisponibleVente' => 0
]);
$result = $serializer->serialize($products, 'json', [
'groups' => 'planning',
'circular_reference_handler' => function ($object) {
return $object->getId();
}
]);
return new JsonResponse($result, Response::HTTP_OK, [], true);
}
/**
* @Route("/{id}", methods={"GET"})
*/
public function show(RDV $company): Response
{
return $this->render('company/show.html.twig', [
'company' => $company,
]);
}
/**
* @Route("/{id}/edit", methods={"GET","POST"})
*/
public function edit(
Request $request,
RDV $rdv,
ProductRepository $productRepository,
RDVProductRepository $RDVProductRepository,
SessionSalonRepository $sessionSalonRepository,
RDVRepository $RDVRepository,
PaytweakService $paytweakService,
LoggerInterface $logger,
ReglementManager $reglementManager,
ClientRepository $clientRepository,
CsrfTokenManagerInterface $csrfTokenManager
): Response {
// if (!$rdv->getClient()) {
// return $this->redirectToRoute('app_planning_liste');
// }
$now = new \DateTime();
$em = $this->getDoctrine()->getManager();
/** @var User $user */
$user = $this->getUser();
$canBill = true;
$canvalidate = true;
$total = 0;
if ($user->hasRole('ROLE_COIFFEUR')) {
if (!$rdv->getIntervenant() || !$rdv->getIntervenant()->getUser() || ($rdv->getIntervenant()->getUser() && $rdv->getIntervenant()->getUser() != $user)) {
$canBill = false;
}
$interval = $now->diff($rdv->getStart());
if ($interval->days > 1 && $rdv->getStart() > $now) {
$canBill = false;
}
}
// on désactiver l'option facturer
if ($user->hasRole('ROLE_COIFFEUR')) {
$canvalidate = false;
}
// on désativer le fait de changer de stratus
$canChangeStatus = true;
if ($user->hasRole('ROLE_COIFFEUR') && $rdv->getStatus() === RDV::STATUS_FACTURER) {
$canChangeStatus = false;
}
$disabled = false;
if ($rdv->getValidated()) {
$dif = time() - $rdv->getValidated()->getTimestamp();
// $user->hasRole(User::ROLE_COIFFEUR) &&
if ($rdv->getStatus() == RDV::STATUS_VALIDATED && $dif > 86400) {
$disabled = true;
}
}
if ($user->hasRole(User::ROLE_COIFFEUR && $rdv->getStatus() === RDV::STATUS_ANNULER)) {
$disabled = true;
}
if ($user->hasRole(User::ROLE_ADMIN) || $user->hasRole(User::ROLE_BO) || $user->hasRole(User::ROLE_ADMINISTRATIVE)) {
$disabled = false;
}
if ($rdv->isPlatform()) {
$createdFrom = 'Plateforme';
} else {
$createdFrom = $rdv->getAuthor() ?: 'auto';
}
$oldStatus = $rdv->getStatus();
$now = new \DateTime();
$form = $this->createForm(
RDVType::class,
$rdv,
[
'edition' => true,
'disabled' => $disabled,
'salon' => $rdv->getSalon(),
'hideFacture' => $user->hasRole(User::ROLE_COIFFEUR),
'canValidate' => $user->hasRole(User::ROLE_ADMIN)
|| $user->hasRole(User::ROLE_BO)
|| $user->hasRole(User::ROLE_ADMINISTRATIVE),
'createdFrom' => $createdFrom,
'csrf_protection' => true,
'csrf_field_name' => '_token',
// important part; unique key
'csrf_token_id' => 'form_intention',
'canChangeStatus' => $canChangeStatus
]
);
if($rdv->getClient()){
if ($rdv->getClient()->getConsignesClient()){
$form->get('consignesClient')->setData($rdv->getClient()->getConsignesClient());
}
if ($rdv->getClient()->getRoomNumber()){
$form->get('roomNumber')->setData($rdv->getClient()->getRoomNumber());
}
}
$form->handleRequest($request);
if (!$form->isSubmitted()) {
$total = 0;
$products = $productRepository->getProductsByRDV($rdv);
foreach ($products as $product) {
$grid = $rdv->getSalon() && $rdv->getSalon()->getGridPrice() ? $rdv->getSalon()->getGridPrice()->getId() : 1;
$productObj = $productRepository->find($product);
$total += $productObj->getPriceSellTTCByGrid($grid);
}
$form->get(
'products'
)->setData($products);
}
else if ($form->isSubmitted() && $form->isValid()) {
$roomNumber = $form->get('roomNumber')->getData();
$comment = $form->get('consignesClient')->getData();
$client= $rdv->getClient();
if($client) {
$client->setConsignesClient($comment);
$client->setRoomNumber($roomNumber);
$em->persist($client);
}
$products = $form->get('products')->getViewData();
$csrfTokenManager->refreshToken('form_intention');
// START: Si on change la date d’un RDV créé par une récurrence de contrat, les RDV de la même récurrence => décalage des autres RDV
$uow = $em->getUnitOfWork();
/** @var RDV $oldRDV */
$oldRDV = $uow->getOriginalEntityData($rdv);
if ($oldRDV['start'] != $rdv->getStart() && $rdv->getContract()) {
$diff = $oldRDV['start']->diff($rdv->getStart());
$diff2 = $oldRDV['start']->diff($rdv->getStart());
$rdvs = [];
if ($rdv->getContract()) {
$rdvs = $RDVRepository->findForReplanificationByContract([$rdv->getContract()], $rdv->getStart(), $rdv->getSalon());
}
/** @var RDV $item */
foreach ($rdvs as $item) {
if ($item->getId() === $rdv->getId()) {
continue;
}
$date = clone $item->getStart();
$endDate = clone $item->getEnd();
$date->add($diff);
$endDate->add($diff2);
$item->setStart($date);
$item->setEnd($endDate);
$em->persist($item);
$em->flush();
}
$em->flush();
}
// END
$productRdv = $RDVProductRepository->findBy([
'rdv' => $rdv
]);
/*
* On duplique le RDV à la prochaine date d’ouverture du salon,
* Seule la date et le statut sont différents du RDV d’origine. Le statut = « Replanifié »
* Le RDV d’origine est lui conservé en statut annulé
*/
if (
$oldStatus != RDV::STATUS_ANNULER
&& $rdv->getStatus() === RDV::STATUS_ANNULER
&& $rdv->getCancelReason()->getLabel() != 'Décès'
&& $rdv->getCancelReason()->getLabel() != 'Client parti du site'
&& $rdv->getCancelReason()->getLabel() != 'RDV supprimé'
) {
$sessionSalons = null;
$salon = $rdv->getSalon();
$dateStart = clone $rdv->getStart();
//$dateStart->setTime(0, 0, 0, 0);
$dateStart->modify('+1 day');
$dateStart->setTime(
$rdv->getStart()->format('H'), // Hours
$rdv->getStart()->format('i'), // Minutes
$rdv->getStart()->format('s') // Seconds
);
if ($salon) {
$sessionSalons = $sessionSalonRepository->findFirstBySalon($salon, $dateStart);
}
//1 . create new RDV to next "JOS"
if ($sessionSalons) {
/** @var \DateTime $josStart */
// keep the rdv hour
$josStart = $sessionSalons->getStart();
/** @var \DateTime $josEnd */
$josEnd = $sessionSalons->getEnd();
$josStart->setTime(
$rdv->getStart()->format('H'), // Hours
$rdv->getStart()->format('i'), // Minutes
$rdv->getStart()->format('s') // Seconds
);
$josEnd->setTime(
$rdv->getEnd()->format('H'), // Hours
$rdv->getEnd()->format('i'), // Minutes
$rdv->getEnd()->format('s') // Seconds
);
// CREATE NEW RDV because we cancel the previous one
$rdv2 = new RDV();
$rdv2->setStatus(RDV::STATUS_REPLANIFIER);
$rdv2->setStart($josStart);
$rdv2->setEnd($josStart);
$rdv2->setAuthor($rdv->getAuthor());
$rdv2->setPriorite($rdv->getPriorite());
$rdv2->setRdvProducts($rdv->getRdvProducts());
if($rdv->getRecurrenceRdvs()) {
$rdv2->setRecurrenceRdvs($rdv->getRecurrenceRdvs());
}
foreach ($rdv->getRdvProducts() as $rdvProductOld) {
$rdvProduct = new RDVProduct();
$rdvProduct->setRdv($rdv2);
$rdvProduct->setProduct($rdvProductOld->getProduct());
$em->persist($rdvProduct);
}
$rdv2->setBillings($rdv->getBillings());
$logRDV = new LogCancel();
$rdv2->setSalon($rdv->getSalon());
$rdv2->setRDVBillings($rdv->getRDVBillings()); // to fix ??
$logRDV->setIntervenantOld($rdv->getIntervenant());
if ($sessionSalons->getIntervenant()) {
$rdv2->setIntervenant($sessionSalons->getIntervenant());
$logRDV->setNewIntervenant($sessionSalons->getIntervenant());
} else {
$rdv2->setIntervenant($rdv->getIntervenant());
$logRDV->setNewIntervenant($rdv->getIntervenant());
}
$logRDV->setSessionSalon($sessionSalons);
$em->persist($logRDV);
if ($rdv->getContract()) {
$rdv2->setContract($rdv->getContract());
}
$rdv2->setComment($rdv->getComment());
$rdv2->setClient($rdv->getClient());
$rdv2->setValidated($rdv->getValidated());
$rdv2->setCommentForfait($rdv->getCommentForfait());
$em->persist($rdv2);
///// END CREATE NEW RDV
}
// 2. get all contracts of the clients
// $clientContrats = [];
// foreach ($rdv->getClient()->getContract() as $contract) {
// $clientContrats[] = $contract->getId();
// }
//
// // 3. get theirs RDV, we exclude the new RDV with the status
// $rdvs = $RDVRepository->findForReplanificationByContract($clientContrats, $rdv->getStart(), $rdv->getSalon());
//
// /** @var RDV $item */
// foreach ($rdvs as $item) {
// // do not report current RDV
// if ($item->getId() === $rdv->getId()) {
// continue;
// }
// $dateStart = clone $item->getStart();
// $dateStart->setTime(0, 0, 0, 0);
// $dateStart->modify('+1 day');
// // find next jos
// $sessionSalons = $sessionSalonRepository->findFirstBySalon($item->getSalon(), $dateStart);
// if ($sessionSalons) {
// $item->setStart($sessionSalons->getStart());
// $item->setEnd($sessionSalons->getStart());
// $em->persist($item);
// }
// }
$rdvs = $RDVRepository->findForReplanificationNewRecurence($rdv->getClient(), $rdv->getStart(), $rdv->getSalon());
/** @var RDV $item */
foreach ($rdvs as $item) {
// do not report current RDV
if ($item->getId() === $rdv->getId()) {
continue;
}
$dateStart = clone $item->getStart();
//$dateStart->setTime(0, 0, 0, 0);
$dateStart->modify('+1 day');
$dateStart->setTime(
$item->getStart()->format('H'), // Hours
$item->getStart()->format('i'), // Minutes
$item->getStart()->format('s') // Seconds
);
// find next jos
$sessionSalons = $sessionSalonRepository->findFirstBySalon($item->getSalon(), $dateStart);
if ($sessionSalons) {
$startSessionSalon = $sessionSalons->getStart();
$startSessionSalon->setTime(
$item->getStart()->format('H'), // Hours
$item->getStart()->format('i'), // Minutes
$item->getStart()->format('s') // Seconds
);
$item->setStart($startSessionSalon);
$item->setEnd($startSessionSalon);
$em->persist($item);
}
}
$em->flush();
}
if (
$rdv->getStatus() === RDV::STATUS_ANNULER
&& ($rdv->getCancelReason()->getLabel() == 'Décès'
|| $rdv->getCancelReason()->getLabel() == 'Client parti du site')
) {
$rdvsTodelete = $this->RDVManager->findFromTodayByStatusPlan($client);
// supprimer la recurrence TODO:
$recurrence = $rdv->getRecurrence();
foreach ($rdvsTodelete as $rdvDelete) {
if($rdvDelete->getId() === $rdv->getId()){
continue;
}
$em->remove($rdvDelete);
}
if($client->getSolde() <= 0){
$client->setStatusProspect(Client::STATUS_INACTIF);
}
else {
if($rdv->getCancelReason()->getLabel() == 'Client parti du site'){
$client->setStatusProspect(Client::STATUS_PARTI);
}
if($rdv->getCancelReason()->getLabel() == 'Décès'){
$client->setStatusProspect(Client::STATUS_DECES);
}
}
$em->flush();
}
foreach ($productRdv as $product) {
$em->remove($product);
}
$em->flush();
$total = 0;
foreach ($products as $product) {
$grid = $rdv->getSalon() && $rdv->getSalon()->getGridPrice() ? $rdv->getSalon()->getGridPrice()->getId() : 1;
$productObj = $productRepository->find($product);
$total += $productObj->getPriceSellTTCByGrid($grid);
// if rdvproduct already exists
$rdvProduct = $RDVProductRepository->findOneBy([
'product' => $product,
'rdv' => $rdv
]);
//
if (!$rdvProduct) {
$rdvProduct = new RDVProduct();
$rdvProduct->setRdv($rdv);
$rdvProduct->setProduct($productObj);
$rdv->addRdvProduct($rdvProduct);
$em->persist($rdvProduct);
$em->persist($rdv);
}
}
if ($oldStatus != RDV::STATUS_VALIDATED && $rdv->getStatus() === RDV::STATUS_VALIDATED) {
$rdv->setValidated(new \DateTime());
if($rdv->isPlatform()){
$clientExist = $clientRepository->findOneBy([
'lastname' => $rdv->getClient()->getLastname(),
'firstname' => $rdv->getClient()->getFirstname(),
'civilite' => $rdv->getClient()->getCivilite(),
'site' => $rdv->getSalon()->getSite(),
]);
$paymentLink = $rdv->getPaymentLink();
if($clientExist){
/** @var RDV $lastRDV */
$lastRDV = $this->RDVManager->getRepository()->findOneByClientAndToken($clientExist);
if($lastRDV){
$paymentLink = $lastRDV->getPaymentLink();
//$path = parse_url($paymentLink, PHP_URL_PATH);
//$orderIdPaytweak = basename($path);
}
}
$billing = $this->billingManager->createFromRDV($rdv, $this->getUser());
$response = $paytweakService->triggerPayment($paymentLink, $billing->getTtc(), $billing->getCode());
if ($response['code'] !== 'OK') {
$this->mailService->sentErrorPaytweakResa($rdv, $response['code'], $response['message']);
$logger->error('An error occurred for RDV ID ' . $rdv->getId() . ': ' . $response['message']);
}
}
}
// set the form product agains
$em->flush();
}
return $this->render('planning/edit.html.twig', [
'rdv' => $rdv,
'canvalidate' => $canvalidate,
'canBill' => $canBill,
'total' => $total,
'rdvProducts' => $rdv->getRdvProducts(),
'form' => $form->createView(),
'minuteIncrement' => $rdv->getSalon() && $rdv->getSalon()->getSite() ? ($rdv->getSalon()->getSite()->getType() === Site::TYPE_EHPAD ? 15 : 30) : 15,
]);
}
/**
* @Route("/{id}", methods={"DELETE"})
*/
public function delete(Request $request, RDV $RDV): Response
{
if ($this->isCsrfTokenValid('delete' . $RDV->getId(), $request->request->get('_token'))) {
$entityManager = $this->getDoctrine()->getManager();
$entityManager->remove($RDV);
$entityManager->flush();
}
return $this->redirectToRoute('app_planning_liste');
}
/**
* @param $class
* @return \Closure[]|mixed
*/
private function getColumnsForEntity($class)
{
$columns[RDV::class] = [
'Id' => function (RDV $RDV) {
return $RDV->getId();
},
'Client' => function (RDV $RDV) {
return (string)$RDV->getClient();
},
'Début' => function (RDV $RDV) {
return $RDV->getStart() ? $RDV->getStart()->format('d-m-Y H:i:s') ? $RDV->getStart()->format('d-m-Y H:i:s') : '' : '';
},
'Fin' => function (RDV $RDV) {
return $RDV->getEnd() ? $RDV->getEnd()->format('d-m-Y H:i:s') ? $RDV->getEnd()->format('d-m-Y H:i:s') : '' : '';
},
'Intervenant' => function (RDV $RDV) {
return (string)$RDV->getIntervenant();
},
'Salon' => function (RDV $RDV) {
return $RDV->getSalon() ? $RDV->getSalon()->getName() : '';
},
'Status' => function (RDV $RDV) {
return $RDV->getStatus();
},
'Raison annulation' => function (RDV $RDV) {
return $RDV->getCancelReason();
},
'Commentaires' => function (RDV $RDV) {
return $RDV->getComment();
},
'Prise de RDV' => function (RDV $RDV) {
if ($RDV->isPlatform()) {
$createdFrom = 'Plateforme';
} else {
$createdFrom = $RDV->getAuthor() ? $RDV->getAuthor() : 'auto';
}
return $createdFrom;
},
'Priorite' => function (RDV $RDV) {
return $RDV->getPriorite();
},
'Récurrence' => function (RDV $RDV) {
return $RDV->getRecurrence();
},
'Email de facturation' => function (RDV $RDV) {
$billingEmail = "";
$client = $RDV->getClient();
if ($client && $client->getBillingInfos()) {
$billingEmail = $client->getBillingInfos()->getEmail();
}
return $billingEmail;
},
'Montant TTC' => function (RDV $RDV) {
return $RDV->ttc();
},
'Products' => function (RDV $RDV) {
$products =[];
$productsRDV = $RDV->getRdvProducts();
foreach($productsRDV as $productRdv)
{$products []= $productRdv->getProduct()->getName(); }
return implode(",", $products);
},
'Factures' => function (RDV $RDV) {
$billingCodes = [];
if($RDV->getBillings() && $RDV->getRDVBillings()->count() > 0){
foreach ($RDV->getRDVBillings() as $billing) {
$billingCodes[] = $billing->getBilling()->getCode();
}
}
return implode(",", $billingCodes);
},
];
if (array_key_exists($class, $columns)) {
return $columns[$class];
}
throw new \InvalidArgumentException(sprintf(
'No columns set for "%s" entity',
$class
));
}
/**
* @Route("/rdv/auto-save", name="rdv_auto_save", methods={"POST"})
*/
public function autoSave(Request $request, EntityManagerInterface $em, RdvRepository $rdvRepository): JsonResponse
{
$data = json_decode($request->getContent(), true);
$field = $data['field'];
$value = $data['value'];
$rdvId = $data['rdvId'];
$rdv = $rdvRepository->find($rdvId);
if (!$rdv) {
return new JsonResponse(['success' => false, 'message' => 'RDV not found'], 404);
}
// Update the appropriate field
if ($field === 'chequeReception') {
$rdv->setChequeReception($value);
} elseif ($field === 'infoCheque') {
$rdv->setInfoCheque($value);
} else {
return new JsonResponse(['success' => false, 'message' => 'Invalid field'], 400);
}
$em->persist($rdv);
$em->flush();
return new JsonResponse(['success' => true]);
}
}