src/Controller/BillingController.php line 156

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\Address;
  4. use App\Entity\Billing;
  5. use App\Entity\BillingItem;
  6. use App\Entity\Client;
  7. use App\Entity\Company;
  8. use App\Entity\Intervenant;
  9. use App\Entity\Parameter;
  10. use App\Entity\Product;
  11. use App\Entity\RDV;
  12. use App\Entity\RDVBilling;
  13. use App\Entity\RDVProduct;
  14. use App\Entity\Reglement;
  15. use App\Entity\Salon;
  16. use App\Entity\Session;
  17. use App\Entity\Site;
  18. use App\Entity\User;
  19. use App\Form\Billing\ContencieuxType;
  20. use App\Form\Billing\EasyCollect;
  21. use App\Form\Billing\LotType;
  22. use App\Form\Billing\RelanceType;
  23. use App\Form\Billing\SendType;
  24. use App\Form\Billing\ValidateType;
  25. use App\Form\BillingType;
  26. use App\Form\CompanyType;
  27. use App\Form\Billing\GenerateType;
  28. use App\Form\RDVType;
  29. use App\Form\ReplanningType;
  30. use App\Manager\BillingItemManager;
  31. use App\Manager\BillingManager;
  32. use App\Manager\RDVBillingManager;
  33. use App\Manager\ReglementManager;
  34. use App\Repository\BillingItemsRepository;
  35. use App\Repository\BillingRepository;
  36. use App\Repository\ClientRepository;
  37. use App\Repository\CompanyRepository;
  38. use App\Repository\ProductRepository;
  39. use App\Repository\RDVProductRepository;
  40. use App\Repository\RDVRepository;
  41. use App\Repository\SiteRepository;
  42. use App\Service\FileUploader;
  43. use App\Service\MailService;
  44. use App\Service\PaytweakService;
  45. use App\Service\SepaService;
  46. use App\Traits\MailServiceTrait;
  47. use App\Traits\ManagerTrait;
  48. use App\Traits\PdfServiceTrait;
  49. use Doctrine\Common\Collections\ArrayCollection;
  50. use Doctrine\ORM\EntityManagerInterface;
  51. use Doctrine\Persistence\ManagerRegistry;
  52. use Knp\Bundle\SnappyBundle\Snappy\Response\PdfResponse;
  53. use Knp\Snappy\Pdf;
  54. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  55. use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
  56. use Symfony\Component\HttpFoundation\BinaryFileResponse;
  57. use Symfony\Component\HttpFoundation\JsonResponse;
  58. use Symfony\Component\HttpFoundation\RedirectResponse;
  59. use Symfony\Component\HttpFoundation\Request;
  60. use Symfony\Component\HttpFoundation\Response;
  61. use Symfony\Component\HttpFoundation\StreamedResponse;
  62. use Symfony\Component\Routing\Annotation\Route;
  63. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
  64. use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
  65. use Symfony\Component\Serializer\Serializer;
  66. use Symfony\Component\Serializer\SerializerInterface;
  67. use Digitick\Sepa\TransferFile\Factory\TransferFileFacadeFactory;
  68. use Digitick\Sepa\PaymentInformation;
  69. /**
  70.  * @Route("/facturation")
  71.  */
  72. class BillingController extends AbstractController
  73. {
  74.     private $billingItemManager;
  75.     /** @var BillingManager $billingManager */
  76.     private $billingManager;
  77.     use ManagerTrait;
  78.     use MailServiceTrait;
  79.     use PdfServiceTrait;
  80.     /**
  81.      * BillingController constructor.
  82.      * @param BillingItemManager $billingItemManager
  83.      */
  84.     public function __construct(BillingManager $billingManagerBillingItemManager $billingItemManager)
  85.     {
  86.         $this->billingItemManager $billingItemManager;
  87.         $this->billingManager $billingManager;
  88.     }
  89.     /**
  90.      * @Route("/testSepa", methods={"GET","POST"})
  91.      */
  92.     public function testSepa(
  93.         Request $request,
  94.         BillingRepository $billingRepository,
  95.         SepaService $sepaService,
  96.         CompanyRepository $companyRepository
  97.     ): Response
  98.     {
  99.         $entityManager $this->getDoctrine()->getManager();
  100.         $billings $billingRepository->findBy([],null,20);
  101.         $company $companyRepository->find(1);
  102.         $directDebit $sepaService->generate($company);
  103.         foreach($billings as $billing){
  104.             $directDebit $sepaService->addTransaction($directDebit$billing);
  105.         }
  106.         //dd(count($billings));
  107.         return new Response($directDebit->asXML(), Response::HTTP_OK, [
  108.             'Content-Type' => 'application/octect-stream',
  109.             'Content-Transfer-Encoding' => 'Binary',
  110.             'Content-disposition' => 'attachment;  filename="sepa.xml"'
  111.         ]);
  112.     }
  113.     /**
  114.      * @Route("/billing/rendrecontencieux", name="app_billing_rendrecontencieux", methods={"POST"})
  115.      */
  116.     public function rendreContencieux(Request $requestBillingRepository $billingRepositoryEntityManagerInterface  $entityManager): JsonResponse
  117.     {
  118.         // Get the 'ids' from the AJAX request
  119.         $selectedIds $request->request->get('ids', []);
  120.         if (!empty($selectedIds)) {
  121.              foreach ($selectedIds as $id) {
  122.                  $billing $billingRepository->find($id);
  123.                  if ($billing) {
  124.                      $billing->setStatus('contentieux');
  125.                      $entityManager->persist($billing);
  126.                  }
  127.              }
  128.              $entityManager->flush();
  129.             // Return a JSON response indicating success
  130.             return new JsonResponse(['message' => 'Factures marquées comme contentieuses avec succès.'], 200);
  131.         } else {
  132.             // Return a JSON response indicating an error
  133.             return new JsonResponse(['message' => 'Aucune facture sélectionnée.'], 400);
  134.         }
  135.     }
  136.     /**
  137.      * @Route("/liste", methods={"GET","POST"})
  138.      * @Template()
  139.      * @return array|RedirectResponse
  140.      */
  141.     public function index(
  142.         Request $request,
  143.         CompanyRepository $companyRepository,
  144.         SiteRepository $siteRepository,
  145.         BillingRepository $billingRepository,
  146.         MailService $mailService,
  147.         PaytweakService $paytweakService,
  148.         SepaService $sepaService,
  149.         Pdf $knpSnappyPdf,
  150.         ReglementManager $reglementManager,
  151.         ManagerRegistry  $em,
  152.         ParameterBagInterface $parameterBag
  153.     )
  154.     {
  155.         $sites $siteRepository->findAll();
  156.         $compagnies $companyRepository->findAll();
  157.         $form $this->createForm(GenerateType::class);
  158.         $validateForm $this->createForm(ValidateType::class);
  159.         $sendForm $this->createForm(SendType::class);
  160.         $relanceForm $this->createForm(RelanceType::class);
  161.         $lotForm $this->createForm(LotType::class);
  162.         $easyCollect $this->createForm(EasyCollect::class);
  163.         $billingsSEPA = [];
  164.         $company null;
  165.         $filterForm $this->createForm(\App\Form\Billing\FilterType::class, null, ['company' => $companyRepository->find(2)]);
  166.         $form->handleRequest($request);
  167.         $filterForm->handleRequest($request);
  168.         $sendForm->handleRequest($request);
  169.         $validateForm->handleRequest($request);
  170.         $relanceForm->handleRequest($request);
  171.         $easyCollect->handleRequest($request);
  172.         $lotForm->handleRequest($request);
  173.         // FILTER FORM
  174.         if ($filterForm->isSubmitted() && $filterForm->isValid()) {
  175.             $site $filterForm['site']->getData();
  176.             $statusSite $filterForm['statusSite']->getData();
  177.             $company $filterForm['company']->getData();
  178.             $numFacture $filterForm['numFacture']->getData();
  179.             $client $filterForm['client']->getData();
  180.             $dateDebut $filterForm['dateDebut']->getData();
  181.             $dateFin $filterForm['dateFin']->getData();
  182.             $status $filterForm['status']->getData();
  183.             $billings $billingRepository->filter($site$client$dateDebut,$dateFin$status$company$numFacturefalsenull$statusSite);
  184.             $billingsSEPA $billingRepository->findBy(['company' => $company]);
  185.             $billingsEncaissement $billingRepository->searchForEncaissement($site$client$dateDebut,$dateFin$company$numFacture);
  186.         }
  187.         else {
  188.             $billings $billingRepository->findBy([],['id' => 'DESC'],200);
  189.             $billingsEncaissement $billingRepository->searchForEncaissement();
  190.         }
  191.         // VALIDATE
  192.         if ($validateForm->isSubmitted() ) {
  193.             $site $validateForm['site']->getData();
  194.             $company $validateForm['company']->getData();
  195.             $start $validateForm['start']->getData();
  196.             $end $validateForm['end']->getData();
  197.             $dateBillingStr $validateForm['dateBilling']->getData();
  198.             $dateBilling null;
  199.             if($dateBillingStr){
  200.                 $dateBilling date_create_from_format('Y-m-d'$dateBillingStr);
  201.             }
  202.             $billings $billingRepository->searchForValidate($site$company$start$end);
  203.             /** @var Billing $billing */
  204.             $i 0;
  205.             $lastCode null;
  206.             foreach($billings as $billing) {
  207.                 if($i === 0){
  208.                     $code $this->billingManager->getCodeBilling($company$billing$dateBilling);
  209.                 }
  210.                 else {
  211.                     $code $this->billingManager->getCodeBillingByLastCode($company$billing$lastCode$dateBilling);
  212.                 }
  213.                 $billing->setCode($code);
  214.                 $billing->setStatus(Billing::STATUS_VALIDE);
  215.                 if($billing->getHt() <= || $billing->getSolde() < 0){
  216.                     $billing->setStatus(Billing::STATUS_REGLEE);
  217.                 }
  218.                 $em->getManager()->persist($billing);
  219.                 $lastCode $code;
  220.                 $i++;
  221.             }
  222.             $em->getManager()->flush();
  223.             return $this->redirectToRoute('app_billing_index');
  224.         }
  225.         // HANDLE encaissement
  226.         if($request->isMethod(Request::METHOD_POST) && $request->request->get('payment-method')) {
  227.             $paymentMethod $request->request->get('payment-method');
  228.             $reference $request->request->get('reference');
  229.             $companyKey $request->request->get('company');
  230.             $date $request->request->get('date');
  231.             $encaissementDate $request->request->get('date');
  232.             $client $request->request->get('client');
  233.             $encaissements $request->request->get('encaissement');
  234.             if($encaissementDate) {
  235.                 $encaissementDate date_create_from_format('Y-m-d'$encaissementDate);
  236.             }
  237.             else {
  238.                 $encaissementDate = new \DateTime();
  239.             }
  240.             if(!$date) {
  241.                 $date = new \DateTime('now');
  242.             }
  243.             else {
  244.                 $date date_create_from_format('Y-m-d'$date);
  245.             }
  246.             $company null;
  247.             if($companyKey) {
  248.                 $company $companyRepository->find($companyKey);
  249.             }
  250.             // SEPA
  251.             if(( $paymentMethod === Reglement::MODE_SEPA  && $company)) {
  252.                 $directDebit $sepaService->generate($company);
  253.                 if(!$encaissements){
  254.                     $this->addFlash('error','Pas d\'encaissements selectionés');
  255.                 }
  256.                 if($encaissements){
  257.                     // generare onereglement per billing
  258.                     foreach($encaissements as $key => $solde) {
  259.                         if(!$solde || $solde == 0) {
  260.                             continue;
  261.                         }
  262.                         $billing $billingRepository->findOneBy(['id'=> $key]);
  263.                         $clientBilling $billing->getClient();
  264.                         $oldSolde $billing->getSolde();
  265.                         $newSolde $oldSolde $solde;
  266.                         $billing->setSolde(number_format($newSolde2));
  267.                         if($newSolde <= 0){
  268.                             $billing->setStatus(Billing::STATUS_REGLEE);
  269.                         }
  270.                         $reglementManager->create($date$billing$billing->getTtc(),$reference$clientBilling$paymentMethod);
  271.                         $em->getManager()->persist($billing);
  272.                         $directDebit $sepaService->addTransaction($directDebit$billing);
  273.                     }
  274.                     $em->getManager()->flush();
  275.                     try {
  276.                         $xml $directDebit->asXML();
  277.                         return new Response($xmlResponse::HTTP_OK, [
  278.                             'Content-Type' => 'application/octect-stream',
  279.                             'Content-Transfer-Encoding' => 'Binary',
  280.                             'Content-disposition' => 'attachment;  filename="sepa.xml"'
  281.                         ]);
  282.                     } catch (\Exception $exception){
  283.                         $this->addFlash('error''Manquement des informations bancaires, ICS, IBAN...');
  284.                     }
  285.                 }
  286.             }
  287.             // OTHERS PAYMENT METHODS
  288.             if($company) {
  289.                 $billings = [];
  290.                 $sumSolde 0;
  291.                 // generare one reglement per billing
  292.                 foreach($encaissements as $key => $encaissement) {
  293.                     //if it's checked
  294.                     if(!isset($encaissement['value'])){
  295.                         continue;
  296.                     }
  297.                     $solde $encaissement['solde'];
  298.                     if(!$solde || $solde == 0) {
  299.                         continue;
  300.                     }
  301.                     $billing $billingRepository->findOneBy(['id'=> $key]);
  302.                     $oldSolde $billing->getSolde();
  303.                     $newSolde $oldSolde $solde;
  304.                     $billing->setSolde($newSolde);
  305.                     if($newSolde <= 0){
  306.                         $billing->setStatus(Billing::STATUS_REGLEE);
  307.                     }
  308.                     $clientBilling $billing->getClient();
  309.                     $em->getManager()->persist($billing);
  310.                     $isDuplicate false;
  311.                     foreach ($billings as $existingBilling) {
  312.                         if ($existingBilling->getId() === $billing->getId()) {
  313.                             $isDuplicate true;
  314.                             break;
  315.                         }
  316.                     }
  317.                     if (!$isDuplicate) {
  318.                         $billings[] = $billing;
  319.                     }
  320.                     $sumSolde+= $solde;
  321.                 }
  322.                 $reglementManager->createByBillings($encaissementDate$billings$sumSolde$reference$billings[0]->getClient(), $paymentMethod $company);
  323.             }
  324.             $em->getManager()->flush();
  325.         }
  326.         // facture
  327.         if ($form->isSubmitted() && $form->isValid()) {
  328.             $this->generateBilling($form->getData());
  329.             return $this->redirectToRoute('app_billing_index');
  330.         }
  331.         /***********
  332.          * SEND FORM
  333.          ************/
  334.         if($sendForm->isSubmitted() && $sendForm->isValid()){
  335.             $pdfBillings = [];
  336.             $modeEnvoi $sendForm->getData()['modeEnvoi'];
  337.             $start $sendForm->getData()['start'];
  338.             $end $sendForm->getData()['end'];
  339.             $company $sendForm->getData()['company'];
  340.             $site $sendForm->getData()['site'];
  341. //            $start = \DateTime::createFromFormat('Y-m-d',$start)->format('Y-m-d');
  342. //            $end = \DateTime::createFromFormat('d-m-Y', $end)->format('Y-m-d');
  343.             $billings $billingRepository->searchForSend($site$company$start$end);
  344.             //dd($billings);
  345.             /** @var Billing $billing */
  346.             foreach($billings as $billing) {
  347.                 /** @var Client $client */
  348.                 $client $billing->getClient();
  349.                 $payMode $client->getBillingInfos()->getPayMode();
  350.                 $sendMode $client->getBillingInfos()->getSendMode();
  351.                 // mail + SEPA
  352.                 if($modeEnvoi === 'mail' && $sendMode === Client\BillingInfos::SEND_MODE_EMAIL &&
  353.                     ($payMode == Client\BillingInfos::PAY_MODE_SEPA) ) {
  354.                     if($billing->getClient()->getBillingInfos()->getEmail()){
  355.                         $html $this->renderView('billing/pdf.html.twig',[
  356.                             'billings' => [$billing],
  357.                             'company'  => $billing->getCompany()
  358.                         ]);
  359.                         $knpSnappyPdf->setOption('enable-local-file-access'true);
  360.                         $pdf$knpSnappyPdf->getOutputFromHtml($html, ['encoding' => 'utf-8']);
  361.                             if($billing->getClient()->getBillingInfos()->getEmail()){
  362.                                 try {
  363.                                     $mailService->sent(new \Symfony\Component\Mime\Address'comptabilite@silverbeaute.com''Comptabilité Silver Beauté'), $billing->getClient()->getBillingInfos()->getEmail(), $company,$pdf$billing );
  364.                                     $billing->setStatus(Billing::STATUS_SENT);
  365.                                     $billing->setSendingDate(new \DateTime());
  366.                                     $em->getManager()->persist($billing);
  367.                                 }
  368.                                 catch (\Exception $exception){
  369.                                 }
  370.                             }
  371.                     }
  372.                 }
  373.                 elseif($modeEnvoi === 'courrier' && $sendMode === Client\BillingInfos::SEND_MODE_COURRIER ){
  374.                     $pdfBillings[] = $billing;
  375.                     $billing->setStatus(Billing::STATUS_SENT);
  376.                     $billing->setSendingDate(new \DateTime());
  377.                     $em->getManager()->persist($billing);
  378.                 }
  379.                 elseif (
  380.                     $modeEnvoi === 'mail'  &&
  381.                     $billing->getSolde() > && (
  382.                         (
  383.                             $sendMode === Client\BillingInfos::SEND_MODE_EMAIL &&
  384.                             ($payMode == Client\BillingInfos::PAY_MODE_CB
  385.                                 || $payMode == Client\BillingInfos::PAY_MODE_CHEQUES
  386.                                 || $payMode == Client\BillingInfos::PAY_MODE_VIREMENT)
  387.                         )
  388.                         ||
  389.                         ($sendMode === Client\BillingInfos::SEND_MODE_COURRIER && $payMode == Client\BillingInfos::PAY_MODE_CB  )
  390.                         || ( $sendMode === Client\BillingInfos::SEND_MODE_EMAIL && $payMode === null)
  391.                     )
  392.                 )
  393.                 {
  394.                     $invoice $paytweakService->createInvoiceFromClient($client$billing);
  395.                     $call  $paytweakService->createBilling($invoice$company);
  396.                     if($call['code'] == 'OK') {
  397.                         $billing->setStatus(Billing::STATUS_SENT);
  398.                         if(isset($call['link_id'] )){
  399.                             $billing->setLinkPaytweak($call['link_id']);
  400.                         }
  401.                         $billing->setSendingDate(new \DateTime());
  402.                         $em->getManager()->persist($billing);
  403.                     }
  404.                     else {
  405.                         $mailService->sentErrorPaytweak($billing$call['code'], $call['message']);
  406.                     }
  407.                 }
  408.             }
  409.             $em->getManager()->flush();
  410.             if(count($pdfBillings) > 0){
  411.                 $html $this->renderView('billing/pdf.html.twig',[
  412.                     'billings' => $pdfBillings,
  413.                     'company'  => $billing->getCompany()
  414.                 ]);
  415.                 $knpSnappyPdf->setOption('enable-local-file-access'true);
  416.                 return new PdfResponse(
  417.                     $knpSnappyPdf->getOutputFromHtml($html, ['encoding' => 'utf-8']),
  418.                     'file.pdf'
  419.                 );
  420.             }
  421.             $em->getManager()->flush();
  422.         }
  423.         /***********
  424.          * SEND FORM
  425.          ************/
  426.         if($easyCollect->isSubmitted() && $easyCollect->isValid()){
  427.             $modeEnvoi $easyCollect->getData()['modeEnvoi'];
  428.             $start $easyCollect->getData()['start'];
  429.             $end $easyCollect->getData()['end'];
  430.             $company $easyCollect->getData()['company'];
  431.             $site $easyCollect->getData()['site'];
  432. //            $start = \DateTime::createFromFormat('Y-m-d',$start)->format('Y-m-d');
  433. //            $end = \DateTime::createFromFormat('d-m-Y', $end)->format('Y-m-d');
  434.             $billings $billingRepository->searchForSend($site$company$start$end);
  435.             //dd($billings);
  436.             /** @var Billing $billing */
  437.             foreach($billings as $billing) {
  438.                 /** @var Client $client */
  439.                 $client $billing->getClient();
  440.                 $payMode $client->getBillingInfos()->getPayMode();
  441.                 $sendMode $client->getBillingInfos()->getSendMode();
  442.                 $hasSigned = !!$client->isHasSignedEasyCollect();
  443.                 if (
  444.                     $modeEnvoi === 'mail'  &&
  445.                     $billing->getSolde() > && $sendMode === Client\BillingInfos::SEND_MODE_EMAIL
  446.                     && !$hasSigned
  447.                 )
  448.                 {
  449.                     $amount $billing->getSolde();
  450.                     // PDF
  451.                     $invoice $paytweakService->createInvoiceFromClient($client$billing);
  452.                     //$call  = $paytweakService->createBilling($invoice, $company);
  453.                     //if($call['code'] == 'OK') {
  454.                     if(!$client->isHasSignedEasyCollect()) {
  455.                         $paytweakService->createLinkScenario($billing->getCompany(),null'BhaXARK'$amount,
  456.                             $client->getBillingInfos() ? $client->getBillingInfos()->getEmail() : $client->getEmail(),
  457.                             $client->getFirstname(),
  458.                             $client->getLastname(),
  459.                             $client->getGender(),
  460.                             $billing->getCode(),
  461.                             null,
  462.                             'B7EV3PN'
  463.                         );
  464.                         $billing->setStatus(Billing::STATUS_SENT);
  465.                         $billing->setSendingDate(new \DateTime());
  466.                         $em->getManager()->persist($billing);
  467.                     }
  468.                     else {
  469.                         // email
  470.                         // TODO: rappel endpoint email
  471.                         $paytweakService->createLinkScenario($billing->getCompany(),null'BhaXARK'$amount,
  472.                             $client->getBillingInfos() ? $client->getBillingInfos()->getEmail() : $client->getEmail(),
  473.                             $client->getFirstname(),
  474.                             $client->getLastname(),
  475.                             $client->getGender(),
  476.                             $billing->getCode(),
  477.                             $client->getBillingInfos() ? $client->getBillingInfos()->getRum() : null,
  478.                             'HURNEAN'
  479.                         );
  480.                         $billing->setStatus(Billing::STATUS_SENT);
  481.                         $billing->setSendingDate(new \DateTime());
  482.                         $em->getManager()->persist($billing);
  483.                     }
  484.                 }
  485.             }
  486.             $em->getManager()->flush();
  487.         }
  488.         /***********
  489.          * RELANCE FORM
  490.          ************/
  491.         if($relanceForm->isSubmitted() && $relanceForm->isValid()){
  492.             $start $relanceForm->getData()['start'];
  493.             $end $relanceForm->getData()['end'];
  494.             $company $relanceForm->getData()['company'];
  495.             $site $relanceForm->getData()['site'];
  496.             $modeEnvoi $relanceForm->getData()['modeEnvoi'];
  497.             $pdfBillings = [];
  498.             $billings $billingRepository->searchForRelance($site$company$start$end);
  499.             foreach($billings as $billing) {
  500.                 /** @var Client $client */
  501.                 $client $billing->getClient();
  502.                 $payMode $client->getBillingInfos()->getPayMode();
  503.                 $sendMode $client->getBillingInfos()->getSendMode();
  504.                 if (
  505.                     $modeEnvoi === 'mail'  &&
  506.                     $billing->getSolde() > && (
  507.                         (
  508.                             $sendMode === Client\BillingInfos::SEND_MODE_EMAIL &&
  509.                             ($payMode == Client\BillingInfos::PAY_MODE_CB
  510.                                 || $payMode == Client\BillingInfos::PAY_MODE_CHEQUES
  511.                                 || $payMode == Client\BillingInfos::PAY_MODE_VIREMENT)
  512.                         )
  513.                         ||
  514.                         ($sendMode === Client\BillingInfos::SEND_MODE_COURRIER &&
  515.                             ($payMode == Client\BillingInfos::PAY_MODE_CB
  516.                                 || $payMode == Client\BillingInfos::PAY_MODE_CHEQUES
  517.                                 || $payMode == null
  518.                                 || $payMode == Client\BillingInfos::PAY_MODE_VIREMENT)  )
  519.                         || ( $sendMode === Client\BillingInfos::SEND_MODE_EMAIL && $payMode === null)
  520.                     )
  521.                 )
  522.                 {
  523.                     $email $billing->getClient()->getBillingInfos() ? $billing->getClient()->getBillingInfos()->getEmail(): null;
  524.                     if($email){
  525.                         $senderAdress = new \Symfony\Component\Mime\Address'comptabilite@silverbeaute.com''Comptabilité Silver Beauté');
  526.                         $html $this->renderView('billing/pdf.html.twig',[
  527.                             'billings' => [$billing],
  528.                             'company'  => $billing->getCompany()
  529.                         ]);
  530.                         $this->pdfService->setTimeout(120);
  531.                         $this->pdfService->setOption('enable-local-file-access'true);
  532.                         $pdf $this->pdfService->getOutputFromHtml($html);
  533.                         //$call  = $paytweakService->reSend($company, $billing->getCode(), $email);
  534.                         $res  $paytweakService->getLink($company$billing->getCode());
  535.                         if($res['code'] === PaytweakService::CODE_OK) {
  536.                             $link reset($res);
  537.                             if($link["paid"] == "1"){
  538.                                 continue;
  539.                             }
  540.                             try {
  541.                                 $this->mailService->sentRelance($senderAdress,$email$company$pdf$billing$link["link_url"]);
  542.                             }
  543.                             catch (\Exception $exception){
  544.                             }
  545.                         }
  546.                         elseif($res['code'] === PaytweakService::CODE_NOT_FOUND){
  547.                             $invoice $paytweakService->createInvoiceFromClient($client$billing);
  548.                             $call  $paytweakService->createBilling($invoice$company);
  549.                             if($call['code'] == 'OK') {
  550.                                 $billing->setStatus(Billing::STATUS_SENT);
  551.                                 $billing->setSendingDate(new \DateTime());
  552.                                 $em->getManager()->persist($billing);
  553.                             }
  554.                             else {
  555.                                 $mailService->sentErrorPaytweak($billing$call['code'], $call['message']);
  556.                             }
  557.                         }
  558.                         else {
  559.                             //$mailService->sentErrorPaytweak($billing, $call['code'], $call['message']);
  560.                         }
  561.                     }
  562.                 }
  563.                 elseif($modeEnvoi === 'courrier' && $sendMode === Client\BillingInfos::SEND_MODE_COURRIER ){
  564.                     $pdfBillings[] = $billing;
  565.                     $billing->setStatus(Billing::STATUS_SENT);
  566.                     $billing->setSendingDate(new \DateTime());
  567.                     $em->getManager()->persist($billing);
  568.                 }
  569.             }
  570.             $em->getManager()->flush();
  571.             if(count($pdfBillings) > 0){
  572.                 $html $this->renderView('billing/pdf.html.twig',[
  573.                     'billings' => $pdfBillings,
  574.                     'company'  => $billing->getCompany()
  575.                 ]);
  576.                 $knpSnappyPdf->setOption('enable-local-file-access'true);
  577.                 return new PdfResponse(
  578.                     $knpSnappyPdf->getOutputFromHtml($html, ['encoding' => 'utf-8']),
  579.                     'file.pdf'
  580.                 );
  581.             }
  582.         }
  583.         /***********
  584.          * LOT FORM
  585.          ************/
  586.         if($lotForm->isSubmitted() && $lotForm->isValid()) {
  587.             $start $lotForm->getData()['start'];
  588.             $company $lotForm->getData()['company'];
  589.             $end $lotForm->getData()['end'];
  590.             $site $lotForm->getData()['site'];
  591.             $modeEnvoi $lotForm->getData()['modeEnvoi'];
  592.             $status $lotForm->getData()['status'];
  593.             $clientFilter $lotForm->getData()['client'];
  594.             $pdfBillings = [];
  595.             $billings $billingRepository->searchForLot($site$company$start$end$status$modeEnvoi$clientFilter);
  596.             foreach($billings as $billing) {
  597.                 /** @var Client $client */
  598.                 $client $billing->getClient();
  599.                 $pdfBillings[] = $billing;
  600.             }
  601.             $em->getManager()->flush();
  602.             if(count($pdfBillings) > 0){
  603.                 $html $this->renderView('billing/pdf.html.twig',[
  604.                     'billings' => $pdfBillings,
  605.                     'company'  => $billing->getCompany()
  606.                 ]);
  607.                 $knpSnappyPdf->setOption('enable-local-file-access'true);
  608.                 return new PdfResponse(
  609.                     $knpSnappyPdf->getOutputFromHtml($html, ['encoding' => 'utf-8']),
  610.                     'file.pdf'
  611.                 );
  612.             }
  613.         }
  614.         return [
  615.             'billings' => $billings,
  616.             'billingsEncaissement' => $billingsEncaissement,
  617.             'billingsSEPA' => $billingsSEPA,
  618.             'compagnies' => $compagnies,
  619.             'company' => $company,
  620.             'sites' => $sites,
  621.             'generateForm' => $form->createView(),
  622.             'formFilter' => $filterForm->createView(),
  623.             'validateForm' => $validateForm->createView(),
  624.             'easycollect' => $easyCollect->createView(),
  625.             'sendForm' => $sendForm->createView(),
  626.             'lotForm' => $lotForm->createView(),
  627.             'relanceForm' => $relanceForm->createView()
  628.         ];
  629.     }
  630.     /**
  631.      * @Route("/new/rdv/{id}", name="billing_new_rdv", methods={"GET","POST"})
  632.      */
  633.     public function new(
  634.         RDV $RDV,
  635.         Request $request,
  636.         BillingRepository $billingRepository,
  637.         BillingItemManager $billingItemManager,
  638.         RDVBillingManager $RDVBillingManager,
  639.         CsrfTokenManagerInterface  $csrfTokenManager,
  640.         PaytweakService  $paytweakService,
  641.         MailService  $mailService
  642.     ): Response
  643.     {
  644.         if($RDV->getStatus() === RDV::STATUS_FACTURER){
  645.             return $this->redirectToRoute('app_planning_coiffeurliste');
  646.         }
  647.         $entityManager $this->getDoctrine()->getManager();
  648.         /** @var Parameter $setting */
  649.         $setting $this->getDoctrine()->getRepository(Parameter::class)->find(1);
  650.         $tva $setting->getTva();
  651.         $billing = new Billing();
  652.         $billing->setDateBilling(new \DateTime());
  653.         $total 0;
  654.         $total_ht 0;
  655.         /** @var RDVProduct $rdvProduct */
  656.         foreach($RDV->getRdvProducts() as $rdvProduct){
  657.             $product $rdvProduct->getProduct();
  658.             $billingItem $billingItemManager->create($product$billing1$tva);
  659.             // date du jour du rdv pour facturer immadialite
  660.             $billingItem->setDateRDV($RDV->getStart());
  661.             $gridPrice null;
  662.             $salon =  $RDV->getSalon();
  663.             if($salon) {
  664.                 $gridPrice $RDV->getSalon()->getGridPrice();
  665.             }
  666.             $price null;
  667.             if($gridPrice) {
  668.                 switch ($gridPrice->getId()) {
  669.                     case 1:
  670.                         $price $product->getPriceHtA();
  671.                         break;
  672.                     case 2:
  673.                         $price $product->getPriceHtB();
  674.                         break;
  675.                     case 3:
  676.                         $price $product->getPriceHtC();
  677.                         break;
  678.                     case 4:
  679.                         $price $product->getPriceHtD();
  680.                         break;
  681.                 }
  682.             }
  683.             else {
  684.                 $price $product->getPriceHtA();
  685.             }
  686.             // protect
  687.             $remise $RDV->getClient()->getBillingInfos()->getDiscount();
  688.             if($product->getRemiseGenerale() > $remise ){
  689.                 $remise $product->getRemiseGenerale();
  690.             }
  691.             if($remise){
  692.                 $billingItem->setDiscount(floatval($remise));
  693.             }
  694.             $remisePurcent $remise ? ($remise 100) : 0;
  695.             $billingItem->setPrice($price);
  696.             if($remisePurcent != 0){
  697.                 $price $price $remisePurcent;
  698.             }
  699.             $calcultHt number_format((float)$price2);
  700.             if($tva <= 0) {
  701.                 $tva 20;
  702.             }
  703.             $ttc number_format($price * ($tva 100),2);
  704.             $billingItem->setRefProduct($product->getReference());
  705.             $billingItem->setTtc($ttc);
  706.             $billing->getBillingItems()->add($billingItem);
  707.             $total += $ttc;
  708.             $total_ht += $calcultHt;
  709.         }
  710.         $billing->setHt(number_format((float)$total_ht2"."""));
  711.         $billing->setTtc(number_format((float)$total2"."""));
  712.         $billing->setSolde(number_format($billing->getTtc(),2"."""));
  713.         $form $this->createForm(BillingType::class, $billing);
  714.         $form->handleRequest($request);
  715.         if($form->isSubmitted() && !$form->isValid()) {
  716.             $submittedToken $request->request->get('token');
  717.             if (!$this->isCsrfTokenValid('token_id'$submittedToken)) {
  718.                 return $this->redirectToRoute('app_planning_coiffeurliste');
  719.             }
  720.         }
  721.         if ($form->isSubmitted() && $form->isValid()) {
  722.             // FLAGGER ICI le loading comme ca pas de doublon
  723.             $billingsRDV $RDV->getRDVBillings();
  724.             $count 0;
  725.             if($billingsRDV->count() > 0){
  726.                 foreach ($billingsRDV as $itemBilling) {
  727.                     if ($itemBilling->getBilling() && $itemBilling->getBilling()->getStatus() !== Billing::STATUS_SOLDE_AVOIR && $itemBilling->getBilling()->getStatus() !== Billing::STATUS_SOLDE) {
  728.                         $count++;
  729.                     }
  730.                 }
  731.                 if($count 0){
  732.                     $this->addFlash('error''RDV déjà facturé');
  733.                     return $this->redirectToRoute('app_planning_coiffeurliste');
  734.                 }
  735.             }
  736.             $csrfTokenManager->refreshToken("form_intention");
  737.             $company null;
  738.             $date $form['dateBilling']->getData();
  739.             $billing->setDateBilling($date);
  740.             $total 0;
  741.             $totalHt 0;
  742.             $calcultHt 0;
  743.             /** @var BillingItem $billingItem */
  744.             foreach($form['billingItems']->getData() as $billingItem) {
  745.                 $date $billingItem->getDateRDV();
  746.                 $billingItem->setDateRDV($date);
  747.                 $billingItem->setQuantity($billingItem->getQuantity());
  748.                 $billingItem->setRefProduct($billingItem->getRefProduct());
  749.                 $billingItem->setTtc($billingItem->getTtc());
  750.                 $remise $billingItem->getDiscount() ?: 0;
  751.                 $price $billingItem->getPrice();
  752.                 if($remise && $remise != 0){
  753.                     $calcul = (floatval($price) * $billingItem->getQuantity() * ($remise 100 )) * ($billingItem->getTva() / 100);
  754.                     $calcultHt = (floatval($price)* $billingItem->getQuantity() * ( $remise 100 ));
  755.                 }
  756.                 else {
  757.                     $calcul floatval($price)* $billingItem->getQuantity()  * ($billingItem->getTva()  / 100);
  758.                     $calcultHt floatval($price) * $billingItem->getQuantity();
  759.                 }
  760.                 $total += $calcul;
  761.                 $totalHt += $calcultHt;
  762.                 $billingItem->setDateRDV($date);
  763.                 $entityManager->persist($billingItem);
  764.             }
  765.             $billing->setClient($RDV->getClient());
  766.             //retrive company
  767.             if($RDV->getClient()) {
  768.                 $billingInfos $RDV->getClient()->getBillingInfos();
  769.                 if ($billingInfos) {
  770.                     $company $billingInfos->getCompany();
  771.                     $billing->setCompany($company);
  772.                 }
  773.             }
  774.             $code $this->billingManager->getCodeBilling($company$billing);
  775.             $billing->setCode($code);
  776.             $billing->setTtc(number_format((float) $total2,"."""));
  777.             $billing->setHt(number_format($totalHt2,"."""));
  778.             $billing->setStatus(Billing::STATUS_VALIDE);
  779.             if($billing->getHt() <= || $billing->getSolde() < 0){
  780.                 $billing->setStatus(Billing::STATUS_REGLEE);
  781.             }
  782.             $billing->setCreator($this->getUser());
  783.             $billing->setModeFacturation(Billing::MODE_FRDV);
  784.             //$this->persistBillingItems($RDV, $billing);
  785.             $rdvBilling $RDVBillingManager->create($billing$RDV);
  786.             $billing->addRDVBilling($rdvBilling);
  787.             $RDV->addRDVBilling($rdvBilling);
  788.             $RDV->setStatus(RDV::STATUS_FACTURER);
  789.             $entityManager->persist($RDV);
  790.             $entityManager->persist($billing);
  791.             $entityManager->flush();
  792.             // TODO fix product list in invoice
  793.              $invoice $paytweakService->createInvoiceFromClient($RDV->getClient(), $billing);
  794.              $call  $paytweakService->createBilling($invoice$company);
  795.              if($call['code'] == 'OK') {
  796.                  $billing->setStatus(Billing::STATUS_SENT);
  797.                  if(isset($call['link_id'] )){
  798.                      $billing->setLinkPaytweak($call['link_id']);
  799.                  }
  800.                  $billing->setSendingDate(new \DateTime());
  801.                  $entityManager->persist($billing);
  802.              }
  803.              else {
  804.                  $mailService->sentErrorPaytweak($billing$call['code'], $call['message']);
  805.              }
  806.              $entityManager->flush();
  807.             return $this->redirectToRoute('app_planning_coiffeurliste');
  808.         }
  809.         return $this->render('billing/new_rdv.html.twig', [
  810.             'billing' => $billing,
  811.             'rdv' => $RDV,
  812.             'tva' => $tva,
  813.             'form' => $form->createView(),
  814.         ]);
  815.     }
  816.     /**
  817.      * @Route("/edit/{id}", name="billing_edit", methods={"GET","POST"})
  818.      */
  819.     public function edit(Request $requestBilling $billingPdf $knpSnappyPdf): Response
  820.     {
  821.         $entityManager $this->getDoctrine()->getManager();
  822. //        if($billing->getDateBilling()){
  823. //            $billing->setDateBilling($billing->getDateBilling()->format('d/m/Y'));
  824. //        }
  825.         //dd($billing->getDateBilling());
  826.         /** @var BillingItem $billingItem */
  827.         foreach($billing->getBillingItems() as $billingItem) {
  828.             if($billingItem->getDateRDV()){
  829.                 $billingItem->setDateRDV($billingItem->getDateRDV());
  830.             }
  831.         }
  832.         $form $this->createForm(BillingType::class, $billing);
  833.         $contencieux $this->createForm(ContencieuxType::class, $billing);
  834.         $client $billing->getClient();
  835.         /** @var Parameter $setting */
  836.         $setting $this->getDoctrine()->getRepository(Parameter::class)->find(1);
  837.         $tva $setting->getTva();
  838.         // SET FIELD ICI A FAIRE
  839.         $pdf $request->request->get('pdf');
  840.         if($pdf){
  841.             $html $this->renderView('billing/pdf.html.twig',[
  842.                 'billings' => [$billing],
  843.                 'company'  => $billing->getCompany()
  844.             ]);
  845.             $knpSnappyPdf->setOption('enable-local-file-access'true);
  846.             return new PdfResponse(
  847.                 $knpSnappyPdf->getOutputFromHtml($html, ['encoding' => 'utf-8']),
  848.                 'file.pdf'
  849.             );
  850.         }
  851.         $form->handleRequest($request);
  852.         //dump($form->getErrors());die;
  853.         if ($form->isSubmitted() && $form->isValid()) {
  854.             $total 0;
  855.             $totalHt 0;
  856.             $calcultHt 0;
  857.             $date $form['dateBilling']->getData();
  858.             $billing->setDateBilling($date);
  859.             foreach($form['billingItems']->getData() as $billingItem) {
  860.                 $date $billingItem->getDateRDV();
  861.                 $price $billingItem->getPrice();
  862.                 $remise $billingItem->getDiscount() ?: 0;
  863.                 if($remise && $remise != 0){
  864.                     $calculationTtc = ($price $billingItem->getQuantity() * ($remise 100)) * ($tva 100);
  865.                     $calcul = (floatval($price) * $billingItem->getQuantity() * ($remise 100 )) * ($billingItem->getTva() / 100);
  866.                     $calcultHt = (floatval($price)* $billingItem->getQuantity() * ( $remise 100 ));
  867.                 }
  868.                 else {
  869.                     $calculationTtc $price $billingItem->getQuantity() * ($tva 100);
  870.                     $calcul floatval($price)* $billingItem->getQuantity()  * ($billingItem->getTva()  / 100);
  871.                     $calcultHt floatval($price) * $billingItem->getQuantity();
  872.                 }
  873.                 $billingItem->setQuantity($billingItem->getQuantity());
  874.                 $calculationTtc number_format((float) $calculationTtc2,".""");
  875.                 $billingItem->setTtc($calculationTtc);
  876.                 $total += $calcul;
  877.                 $totalHt += $calcultHt;
  878.                 $billingItem->setDateRDV($date);
  879.                 $entityManager->persist($billingItem);
  880.             }
  881.             $billing->setTtc(number_format($total2,"."""));
  882.             $billing->setHt(number_format($totalHt2,"."""));
  883.             //$billing->setSolde(number_format($billing->getTtc(), 2));s
  884.             if($billing->getHt() <= || $billing->getSolde() < 0){
  885.                 $billing->setStatus(Billing::STATUS_REGLEE);
  886.             }
  887.             $billing->setCreator($this->getUser());
  888.             $billing->setMaj($this->getUser());
  889.             $entityManager->persist($billing);
  890.             $entityManager->flush();
  891.             return $this->redirectToRoute('app_billing_index');
  892.         }
  893.         $contencieux->handleRequest($request);
  894.         if ($contencieux->isSubmitted() && $contencieux->isValid()) {
  895.             $billing->setStatus(Billing::STATUS_CONTENTIEUX);
  896.             $entityManager->persist($billing);
  897.             $entityManager->flush();
  898.         }
  899.         return $this->render('billing/edit.html.twig', [
  900.             'billing' => $billing,
  901.             'client' => $client,
  902.             'tva' => $tva,
  903.             'form' => $form->createView(),
  904.             'contencieuxForm' => $contencieux->createView(),
  905.         ]);
  906.     }
  907.     /**
  908.      * @Route("/cancel/{id}/{date}", name="billing_cancel", methods={"GET","POST"})
  909.      */
  910.     public function cancel(Request $requestBilling $billingBillingRepository $billingRepositoryBillingItemManager $billingItemManager$date): Response
  911.     {
  912.         $em $this->getDoctrine()->getManager();
  913.         if($billing->getStatus() === Billing::STATUS_EN_COURS){
  914.             foreach ($billing->getRDVBillings() as $RDVBilling){
  915.                 $rdv $RDVBilling->getRDV();
  916.                 if($rdv && $rdv->getId()){
  917.                     $rdv->setStatus(RDV::STATUS_VALIDATED);
  918.                     $em->persist($rdv);
  919.                 }
  920.                 $em->remove($RDVBilling);
  921.             }
  922.             $em->remove($billing);
  923.             $em->flush();
  924.             return $this->redirectToRoute('app_billing_index');
  925.         }
  926.         $dateObject = new \DateTime($date);
  927.         $this->billingManager->createAvoir($billing$this->getUser(), $dateObject);
  928.         $em->flush();
  929.         return $this->redirectToRoute('app_billing_index');
  930.     }
  931.     /**
  932.      * @Route("/import-ajax", name="billing_importajax")
  933.      */
  934.     public function importajax(Request $requestFileUploader $fileUploader){
  935.         $path $this->getParameter('updatebilling_import_directory');
  936.         $file $request->files->get('file');
  937.         if($file) {
  938.             try {
  939.                 $resp $fileUploader->upload($request->files->get('file'), $path);
  940.                 return new JsonResponse(['filename' => $resp ]);
  941.             }catch (\Exception $e) {
  942.             }
  943.         }
  944.         return new JsonResponse(['error' => '' ]);
  945.     }
  946.     /**
  947.      * @Route("/importCSV", name="import_csv", methods={"GET","POST"})
  948.      */
  949.     public function importCSV(Request $requestBillingRepository $billingRepositoryEntityManagerInterface  $entityManager){
  950.         $path $this->getParameter('updatebilling_import_directory');
  951.         if($request->isMethod(Request::METHOD_POST)) {
  952.             $files $request->request->get('files');
  953.             $path_file $path '/' $files[0];
  954.             if(file_exists($path_file)) {
  955.                 try {
  956.                     /**  Identify the type of $inputFileName  **/
  957.                     $inputFileType \PhpOffice\PhpSpreadsheet\IOFactory::identify($path_file);
  958.                     /**  Create a new Reader of the type defined in $inputFileType  **/
  959.                     $reader \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType);
  960.                     /**  Advise the Reader that we only want to load cell data  **/
  961.                     $reader->setReadDataOnly(true);
  962.                     $spreadsheet $reader->load($path_file);
  963.                     $worksheet =  $spreadsheet->getActiveSheet();
  964.                     //$lines = $spreadsheet->getActiveSheet()->toArray();
  965.                     foreach ($worksheet->getRowIterator() as $key => $row) {
  966.                         $cellIterator $row->getCellIterator();
  967.                         $cellIterator->setIterateOnlyExistingCells(FALSE); // This loops through all cells,
  968.                         $billingfound null;
  969.                         foreach ($cellIterator as $key2 => $cell) {
  970.                             $value $cell->getValue();
  971.                             switch ($key2) {
  972.                                 case 'A':
  973.                                 {
  974.                                     $billingfound =  $billingRepository->findOneBy(['id' => (int) $value]);
  975.                                     break;
  976.                                 }
  977.                                 case 'B':
  978.                                 {
  979.                                     if($billingfound) {
  980.                                         $billingfound->setCode($value);
  981.                                         $entityManager->persist($billingfound);
  982.                                     }
  983.                                     break;
  984.                                 }
  985.                                 default:
  986.                                     break;
  987.                             }
  988.                         }
  989.                     }
  990.                 }
  991.                 catch (\Exception $exception) {
  992.                     dump($exception);die;
  993.                 }
  994.                 $entityManager->flush();
  995.             }
  996.             $this->addFlash('success''Fichier importé');
  997.         }
  998.         return $this->render('billing/import.html.twig', [
  999.         ]);
  1000.     }
  1001.     /**
  1002.      * @Route("/downloadExcel")
  1003.      */
  1004.     public function downloadExcel(Request $requestBillingRepository $repository) {
  1005.         $date_debut $request->request->get('date_debut') ?? null;
  1006.         $date_fin $request->request->get('date_fin') ?? null;
  1007.         $entities =  new ArrayCollection($repository->filter(null,null $date_debut,$date_fin));
  1008.         $response = new StreamedResponse();
  1009.         $columns $this->getColumnsForEntity(Billing::class);
  1010.         $billingItemColumns $this->getColumnsForEntity(BillingItem::class);
  1011.         $response->setCallback(function () use ($entities$columns$billingItemColumns) {
  1012.             $handle fopen('php://output''w+');
  1013.             // Add header
  1014.             fputcsv($handlearray_keys($columns));
  1015.             /** @var Billing $entity */
  1016.             while ($entity $entities->current()) {
  1017.                 $values = [];
  1018.                 foreach ($columns as $column => $callback) {
  1019.                     $value $callback;
  1020.                     if (is_callable($callback)) {
  1021.                         $value $callback($entity);
  1022.                     }
  1023.                     $values[] = $value;
  1024.                 }
  1025.                 fputcsv($handle$values);
  1026. //                fputcsv($handle, array_keys($billingItemColumns));
  1027. //                $values = [];
  1028. //                foreach ($entity->getBillingItems() as $billingItem) {
  1029. //                    foreach ($billingItemColumns as $column => $callback) {
  1030. //                        $value = $callback;
  1031. //                        if (is_callable($callback)) {
  1032. //                            $value = $callback($billingItem);
  1033. //                        }
  1034. //                        $values[] = $value;
  1035. //                    }
  1036. //                }
  1037. //
  1038. //                fputcsv($handle, $values);
  1039.                 $entities->next();
  1040.             }
  1041.             fclose($handle);
  1042.         });
  1043.         $filename 'billing.csv';
  1044.         $response->headers->set('Content-Type''text/csv; charset=utf-8');
  1045.         $response->headers->set('Content-Disposition''attachment; filename="' $filename '"');
  1046.         return $response;
  1047.     }
  1048.     /**
  1049.      * @Route("/downloadItemsExcel")
  1050.      */
  1051.     public function downloadItemsExcel(BillingItemsRepository $repository) {
  1052.         $entities =  new ArrayCollection($repository->findAll());
  1053.         $response = new StreamedResponse();
  1054.         $columns $this->getColumnsForEntity(BillingItem::class);
  1055.         $response->setCallback(function () use ($entities$columns) {
  1056.             $handle fopen('php://output''w+');
  1057.             // Add header
  1058.             fputcsv($handlearray_keys($columns));
  1059.             while ($entity $entities->current()) {
  1060.                 $values = [];
  1061.                 foreach ($columns as $column => $callback) {
  1062.                     $value $callback;
  1063.                     if (is_callable($callback)) {
  1064.                         $value $callback($entity);
  1065.                     }
  1066.                     $values[] = $value;
  1067.                 }
  1068.                 fputcsv($handle$values);
  1069.                 $entities->next();
  1070.             }
  1071.             fclose($handle);
  1072.         });
  1073.         $filename 'billing_items.csv';
  1074.         $response->headers->set('Content-Type''text/csv; charset=utf-8');
  1075.         $response->headers->set('Content-Disposition''attachment; filename="' $filename '"');
  1076.         return $response;
  1077.     }
  1078.     /**
  1079.      * @param RDV $RDV
  1080.      * @param Billing $billing
  1081.      */
  1082.     private function persistBillingItems(RDV $RDVBilling $billing)
  1083.     {
  1084.         $em $this->getDoctrine()->getManager();
  1085.         /** @var RR $rdvProduct */
  1086.         foreach ($RDV->getRdvProducts() as $rdvProduct) {
  1087.             $product $rdvProduct->getProduct();
  1088.             // Fetch products to add billings..
  1089.             $billingItem = new BillingItem();
  1090.             $billingItem->setBilling($billing);
  1091.             $billingItem->setRefProduct($product->getReference());
  1092.             $billingItem->setLibelleProduct($product->getName());
  1093.             $billingItem->setProduct($product);
  1094.             $em->persist($billingItem);
  1095.         }
  1096.     }
  1097.     /**
  1098.      * @param array $data
  1099.      * @throws \Exception
  1100.      */
  1101.     private function generateBilling(array $data)
  1102.     {
  1103.         $em $this->managerRegistry;
  1104.         /** @var RDVRepository $repository */
  1105.         $repository $em->getRepository(RDV::class);
  1106.         /** @var ClientRepository $clientRepository */
  1107.         $clientRepository $em->getRepository(Client::class);
  1108.         /** @var SiteRepository $siteRepository */
  1109.         $siteRepository $em->getRepository(Site::class);
  1110.         /** @var ProductRepository $productRepository */
  1111.         $productRepository $em->getRepository(Product::class);
  1112.         /** @var BillingRepository $billingRepository */
  1113.         $billingRepository $em->getRepository(Billing::class);
  1114.         $typeBilling $data['typeBilling'];
  1115.         $start $data['start'];
  1116.         $end $data['end'];
  1117.         $company $data['company'];
  1118.         $site =  $data['site'];
  1119.         /** @var Parameter $setting */
  1120.         $setting $this->managerRegistry->getRepository(Parameter::class)->find(1);
  1121.         $tva $setting->getTva();
  1122.         $billing_added 0;
  1123.         //dump($company);die;
  1124.         $rdvs $repository->findForBilling($start$endRDV::STATUS_VALIDATED$company$site);
  1125.         //$company = $companyRepository->find
  1126.         $merge_rdv = [];
  1127.         /** @var RDV $rdv */
  1128.         foreach ($rdvs as $rdv) {
  1129.             if ($typeBilling === 'client') {
  1130.                 $client_id $rdv['client_id'];
  1131.                 $merge_rdv[$client_id][] = $rdv;
  1132.             } else {
  1133.                 $site_id $rdv['site_id'];
  1134.                 $merge_rdv[$site_id][] = $rdv;
  1135.             }
  1136.         }
  1137.         // Merge contiient tout les rdvs trié soit pppar client_id soit par site_id
  1138.         //dump($merge_rdv);die;
  1139.         // pour  chaque site ou client
  1140.         foreach ($merge_rdv as $key => $rdvs) {
  1141.             $billing = new Billing();
  1142.             $billing->setCreator($this->getUser());
  1143.             $client null;
  1144.             if ($typeBilling === 'client') {
  1145.                 $client $clientRepository->find($key);
  1146.                 $billing->setClient($client);
  1147.             } elseif ($typeBilling === 'site') {
  1148.                 $site $siteRepository->find($key);
  1149.                 $billing->setSite($site);
  1150.             }
  1151.             if($company) {
  1152.                 $billing->setCompany($company);
  1153.             }
  1154.             $total 0;
  1155.             $totalHt 0;
  1156.             foreach ($rdvs as $rdv) {
  1157.                 $rdv_id $rdv['id'];
  1158.                 // get the rdv
  1159.                 $rdvObj $repository->findOneBy(['id' => $rdv_id]);
  1160.                 $dateRdv $rdvObj->getEnd();
  1161.                 // if we bill from site take client from rdv because it will be null
  1162.                 if(!$client){
  1163.                     $client $rdvObj->getClient();
  1164.                 }
  1165.                 // GET PRODUCT OF RDV
  1166.                 $rdvProducts $rdvObj->getRdvProducts();
  1167.                 $products = [];
  1168.                 /** @var RDVProduct $rdvProduct */
  1169.                 foreach ($rdvProducts as $rdvProduct) {
  1170.                     $product $rdvProduct->getProduct();
  1171.                     if(array_key_exists($product->getId(),$products)) {
  1172.                         $products[$product->getId()] = $products[$product->getId()]++;
  1173.                     }
  1174.                     else {
  1175.                         $products[$product->getId()] = 1;
  1176.                     }
  1177.                 }
  1178.                 foreach ($products as $key => $productQuantity) {
  1179.                     $product $productRepository->find($key);
  1180.                     // Fetch products to add billings..
  1181.                     $billingItem $this->billingItemManager->create($product$billing$productQuantity$tva$rdvObj);
  1182.                     //date fin de RDV
  1183.                     //$castedDate = new \DateTime($end);
  1184.                     $billingItem->setDateRDV($dateRdv);
  1185.                     $em->getManager()->persist($billingItem);
  1186.                     $gridPrice null;
  1187.                     $salon =  $rdvObj->getSalon();
  1188.                     if($salon) {
  1189.                         $gridPrice $rdvObj->getSalon()->getGridPrice();
  1190.                     }
  1191.                     $price null;
  1192.                     if($gridPrice) {
  1193.                         switch ($gridPrice->getId()) {
  1194.                             case 1:
  1195.                                 $price $product->getPriceHtA();
  1196.                                 break;
  1197.                             case 2:
  1198.                                 $price $product->getPriceHtB();
  1199.                                 break;
  1200.                             case 3:
  1201.                                 $price $product->getPriceHtC();
  1202.                                 break;
  1203.                             case 4:
  1204.                                 $price $product->getPriceHtD();
  1205.                                 break;
  1206.                         }
  1207.                     }
  1208.                     else {
  1209.                         $price $product->getPriceHtA();
  1210.                     }
  1211.                     /**
  1212.                      *
  1213.                      */
  1214.                     // protect
  1215.                     $remiseClient $client->getBillingInfos()->getDiscount() ?: 0;
  1216.                     $remise $remiseClient;
  1217.                     if($product->getRemiseGenerale() && $product->getRemiseGenerale() > $remiseClient ){
  1218.                         $remise $product->getRemiseGenerale() ?: 0;
  1219.                     }
  1220.                     if($tva <= 0) {
  1221.                         $tva 20;
  1222.                     }
  1223.                     if($remise && $remise != 0){
  1224.                         $calcul = (floatval($price) * ($remise 100 )) * ($tva 100) * $billingItem->getQuantity();
  1225.                         $calcultHt = (floatval($price) * ( $remise 100 ) ) * $billingItem->getQuantity() ;
  1226.                     }
  1227.                     else {
  1228.                         $calcul floatval($price)  * ($tva 100)  * $billingItem->getQuantity();
  1229.                         $calcultHt floatval($price)  * $billingItem->getQuantity();
  1230.                     }
  1231.                     $ttc number_format($calcul2".""");
  1232.                     if($remise){
  1233.                         $billingItem->setDiscount(floatval($remise));
  1234.                     }
  1235.                     $billingItem->setPrice(floatval($price));
  1236.                     $billingItem->setTtc($ttc);
  1237.                     // ADD ITEM
  1238.                     $billing->addBillingItem($billingItem);
  1239.                     $total += $billingItem->getTtc();
  1240.                     $totalHt += $calcultHt;
  1241.                 }
  1242.                 //UPDATE RDV
  1243.                 $rdvObj->setStatus(RDV::STATUS_FACTURER);
  1244.                 // LINK TO BILLING / RDV
  1245.                 $rdvBilling = new RDVBilling();
  1246.                 $rdvBilling->setBilling($billing);
  1247.                 $rdvBilling->setRDV($rdvObj);
  1248.                 $em->getManager()->persist($rdvBilling);
  1249.                 $billing->addRDVBilling($rdvBilling);
  1250.                 $rdvObj->addRDVBilling($rdvBilling);
  1251.                 $em->getManager()->persist($rdvObj);
  1252.             }
  1253.             // facture need to be in brouillon
  1254.             //$code = $this->billingManager->getCodeBilling($company);
  1255.             //$billing->setCode($code);
  1256.             $billing->setModeFacturation(Billing::MODE_FFDP);
  1257.             // set billing to total of all RDV
  1258.             $billing->setTtc(number_format((float)$total2"."""));
  1259.             $billing->setHt($totalHt);
  1260.             $ttc str_replace(array("."","), array(",""."), $billing->getTtc());
  1261.             $billing->setSolde(number_format((float)$ttc2"."""));
  1262.             // UPDTAE  BILLING
  1263.             $billing->setStatus(Billing::STATUS_EN_COURS);
  1264. //            if($billing->getHt() <= 0 || $billing->getSolde() < 0){
  1265. //                $billing->setStatus(Billing::STATUS_REGLEE);
  1266. //            }
  1267.             $billing->setCreator($this->getUser());
  1268.             $billing->setMaj($this->getUser());
  1269.             // set end of period to billing date
  1270.             $date date_create_from_format('Y-m-d'$end);
  1271.             $billing->setDateBilling($date);
  1272.             $em->getManager()->persist($billing);
  1273.             $billing_added++;
  1274.         }
  1275.         $em->getManager()->flush();
  1276.     }
  1277.     /**
  1278.      * @param $class
  1279.      * @return mixed
  1280.      */
  1281.     private function getColumnsForEntity($class)
  1282.     {
  1283.         $columns[Billing::class] = [
  1284.             'Id' => function (Billing $billing) {
  1285.                 return (string) $billing->getId();
  1286.             },
  1287.             'Date' => function (Billing $billing) {
  1288.                 return $billing->getDateBilling() ? $billing->getDateBilling()->format('d-m-Y H:i:s') : '';
  1289.             },
  1290.             'Mode de facturation' => function (Billing $billing) {
  1291.                 return $billing->getModeFacturation();
  1292.             },
  1293.             'Code' => function (Billing $billing) {
  1294.                 return $billing->getCode();
  1295.             },
  1296.             'Comment' => function (Billing $billing) {
  1297.                 return $billing->getComment();
  1298.             },
  1299.             'Ttc' => function (Billing $billing) {
  1300.                 return (string) $billing->getTtc();
  1301.             },
  1302.             'Solde' => function (Billing $billing) {
  1303.                 return (string) $billing->getSolde();
  1304.             },
  1305.             'Status' => function (Billing $billing) {
  1306.                 return $billing->getStatus();
  1307.             },
  1308.             'Accompte' => function (Billing $billing) {
  1309.                 return $billing->getAccompte();
  1310.             },
  1311.             'Type' => function (Billing $billing) {
  1312.                 return $billing->getType();
  1313.             },
  1314.             'Site' => function (Billing $billing) {
  1315.                 return $billing->getClient() && $billing->getClient()->getSite() ? $billing->getClient()->getSite()->getName() : "";
  1316.             },
  1317.             'Status Site' => function (Billing $billing) {
  1318.                 return $billing->getClient() && $billing->getClient()->getSite() ? $billing->getClient()->getSite()->getStatus() : "";
  1319.             },
  1320.             'ID client' => function (Billing $billing) {
  1321.                 return $billing->getClient() ? $billing->getClient()->getId(): "";
  1322.             },
  1323.             'Civilité' => function (Billing $billing) {
  1324.                 return $billing->getClient() ? $billing->getClient()->getCivilite(): "";
  1325.             },
  1326.             'Client' => function (Billing $billing) {
  1327.                 return (string) $billing->getClient();
  1328.             },
  1329.             'Tel facturation' => function (Billing $billing) {
  1330.                 return $billing->getClient() && $billing->getClient()->getBillingInfos() ? $billing->getClient()->getBillingInfos()->getPhone(): "";
  1331.             },
  1332.             'Adresse email facturation' => function (Billing $billing) {
  1333.                 return (string) $billing->getClient() && $billing->getClient()->getBillingInfos() ? $billing->getClient()->getBillingInfos()->getEmail() : "";
  1334.             },
  1335.             'Adresse  facturation' => function (Billing $billing) {
  1336.                 return (string) $billing->getClient() ? $billing->getClient()->getAddressFacturation(): "";
  1337.             },
  1338.             'Adresse complément facturation' => function (Billing $billing) {
  1339.                 return (string) $billing->getClient() ? $billing->getClient()->getComplementAdresseFacturation(): "";
  1340.             },
  1341.             'Ville  facturation' => function (Billing $billing) {
  1342.                 return (string) $billing->getClient() ? $billing->getClient()->getVilleFacturation(): "";
  1343.                 },
  1344.             'Code postal facturation' => function (Billing $billing) {
  1345.                 return (string) $billing->getClient() ? $billing->getClient()->getCodePostalFacturation(): "";
  1346.             },
  1347.             'Mode envoi facturation' => function (Billing $billing) {
  1348.                 return $billing->getClient() && $billing->getClient()->getBillingInfos() ? $billing->getClient()->getBillingInfos()->getSendMode() : "";
  1349.             },
  1350.         ];
  1351.         $columns[BillingItem::class] = [
  1352.             'Id' => function (BillingItem $billing) {
  1353.                 return $billing->getId();
  1354.             },
  1355.             'ReferenceFacture' => function (BillingItem $billing) {
  1356.                 return $billing->getBilling()->getCode();
  1357.             },
  1358.             'Date' => function (BillingItem $billing) {
  1359.                 return $billing->getDateRDV() ? $billing->getDateRDV()->format('d-m-Y H:i:s') : '';
  1360.             },
  1361.             'Réf product' => function (BillingItem $billing) {
  1362.                 return $billing->getRefProduct();
  1363.             },
  1364.             'Price' => function (BillingItem $billing) {
  1365.                 return (string) $billing->getPrice();
  1366.             },
  1367.             'Discount' => function (BillingItem $billing) {
  1368.                 return (string) $billing->getDiscount();
  1369.             },
  1370.             'Ttc' => function (BillingItem $billing) {
  1371.                 return (string) $billing->getTtc();
  1372.             },
  1373.             'Quantity' => function (BillingItem $billing) {
  1374.                 return (string) $billing->getQuantity();
  1375.             },
  1376.             'Libelle Produit' => function (BillingItem $billing) {
  1377.                 return $billing->getLibelleProduct();
  1378.             },
  1379.         ];
  1380.         if (array_key_exists($class$columns)) {
  1381.             return $columns[$class];
  1382.         }
  1383.         throw new \InvalidArgumentException(sprintf(
  1384.             'No columns set for "%s" entity',
  1385.             $class
  1386.         ));
  1387.     }
  1388. }