src/Controller/LotController.php line 58

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\Lot;
  4. use App\Form\ImportType;
  5. use App\Form\LotBulkAuction;
  6. use App\Form\LotBulkChangeStatus;
  7. use App\Form\LotBulkDelete;
  8. use App\Form\LotBulkImageDelete;
  9. use App\Form\LotBulkReportSale;
  10. use App\Form\LotBulkReportSold;
  11. use App\Form\LotBulkReturn;
  12. use App\Form\LotType;
  13. use App\Repository\AuctionRepository;
  14. use App\Repository\CategoryRepository;
  15. use App\Repository\ChangeLogRepository;
  16. use App\Repository\ClientRepository;
  17. use App\Repository\CountryRepository;
  18. use App\Repository\DealerRepository;
  19. use App\Repository\InvoiceRepository;
  20. use App\Repository\LotRepository;
  21. use App\Service\ImportService;
  22. use App\Service\ExportService;
  23. use Doctrine\Persistence\ManagerRegistry;
  24. use PhpOffice\PhpSpreadsheet\Exception;
  25. use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
  26. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  27. use Symfony\Component\HttpFoundation\JsonResponse;
  28. use Symfony\Component\HttpFoundation\Request;
  29. use Symfony\Component\HttpFoundation\Response;
  30. use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
  31. use Symfony\Component\Routing\Annotation\Route;
  32. use Symfony\Component\Validator\Constraints;
  33. use Symfony\Component\Validator\Validator\ValidatorInterface;
  34. /**
  35.  * @Route("/")
  36.  */
  37. class LotController extends AbstractController
  38. {
  39.     use SortByIdsTrait;
  40.     /**
  41.      * @Route("/", name="lot_index", methods={"GET"})
  42.      *
  43.      * @param Request $request
  44.      * @param LotRepository $lotRepository
  45.      * @param AuctionRepository $auctionRepository
  46.      * @param CountryRepository $countryRepository
  47.      * @param CategoryRepository $categoryRepository
  48.      * @param DealerRepository $dealerRepository
  49.      * @param ClientRepository $clientRepository
  50.      * @param InvoiceRepository $invoiceRepository
  51.      *
  52.      * @return Response
  53.      */
  54.     public function index(
  55.         Request $request,
  56.         LotRepository $lotRepository,
  57.         AuctionRepository $auctionRepository,
  58.         CountryRepository $countryRepository,
  59.         CategoryRepository $categoryRepository,
  60.         DealerRepository $dealerRepository,
  61.         ClientRepository $clientRepository,
  62.         InvoiceRepository $invoiceRepository
  63.     ): Response {
  64.         $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
  65.         $perPage 100;
  66.         $filters = [];
  67.         $sort $request->query->get('sort');
  68.         $sortOrder $request->query->get('sortOrder');
  69.         $term $request->query->get('term');
  70.         $page $request->query->get('page'1);
  71.         $ids $request->query->get('ids'false);
  72.         $filters['auction'] = $request->query->get('auction');
  73.         $filters['country'] = $request->query->get('country');
  74.         $filters['category'] = $request->query->get('category');
  75.         $filters['category2'] = $request->query->get('category2');
  76.         $filters['nominal'] = $request->query->get('nominal');
  77.         $filters['year'] = $request->query->get('year');
  78.         $filters['dealer'] = $request->query->get('dealer');
  79.         $filters['customer'] = $request->query->get('customer');
  80.         $filters['status'] = $request->query->get('status');
  81.         $filters['invoice'] = $request->query->get('invoice');
  82.         $filters['checked'] = $request->query->get('checked');
  83.         $filters['statusPhoto'] = $request->query->get('statusPhoto');
  84.         if ($ids) {
  85.             $perPage null;
  86.             $page null;
  87.             $sort null;
  88.             $sortOrder null;
  89.         }
  90.         $lotsIds $lotRepository->getAll($term$sort$sortOrder$filtersnull);
  91.         $availableIds array_column(
  92.             array_slice($lotsIds, ($page 1) * $perPage$perPage),
  93.             'id'
  94.         );
  95.         $lots $lotRepository->getAllByIds($availableIds);
  96.         $lots $this->sortByIds($lots$availableIds);
  97.         if ($ids) {
  98.             $return = [];
  99.             foreach ($lots as $lot) {
  100.                 $return[] = $lot->getId();
  101.             }
  102.             return new JsonResponse($return);
  103.         }
  104.         $lotsCount $lotRepository->getCount($term$filters);
  105.         $pages ceil($lotsCount $perPage);
  106.         $auctions $auctionRepository->getAll();
  107.         $countries $countryRepository->findBy([], ['name' => 'ASC']);
  108.         $categories $categoryRepository->findBy([], ['name' => 'ASC']);
  109.         $dealers $dealerRepository->getAll();
  110.         $customers $clientRepository->getAll();
  111.         $statuses Lot::getStatuses();
  112.         $invoices $invoiceRepository->findAll();
  113.         return $this->render('lot/index.html.twig', [
  114.             'lots' => $lots,
  115.             'sort' => $sort,
  116.             'sortOrder' => $sortOrder,
  117.             'page' => $page,
  118.             'filters' => $filters,
  119.             'pages' => $pages,
  120.             'total' => $lotsCount,
  121.             'term' => $term,
  122.             'auctions' => $auctions,
  123.             'countries' => $countries,
  124.             'categories' => $categories,
  125.             'dealers' => $dealers,
  126.             'customers' => $customers,
  127.             'statuses' => $statuses,
  128.             'invoices' => $invoices,
  129.         ]);
  130.     }
  131.     /**
  132.      * @Route("/lot/new", name="lot_new", methods={"GET","POST"})
  133.      *
  134.      * @param Request $request
  135.      * @param ManagerRegistry $doctrine
  136.      *
  137.      * @return Response
  138.      */
  139.     public function new(Request $requestManagerRegistry $doctrine): Response
  140.     {
  141.         if (!$this->isGranted('ROLE_WAREHOUSE') && !$this->isGranted('ROLE_EDITOR')) {
  142.             throw $this->createAccessDeniedException();
  143.         }
  144.         $lot = new Lot();
  145.         $form $this->createForm(LotType::class, $lot);
  146.         $form->handleRequest($request);
  147.         if ($form->isSubmitted() && $form->isValid()) {
  148.             $entityManager $doctrine->getManager();
  149.             $entityManager->persist($lot);
  150.             $entityManager->flush();
  151.             return $this->redirectToRoute('lot_index');
  152.         }
  153.         return $this->render('lot/new.html.twig', [
  154.             'lot' => $lot,
  155.             'form' => $form->createView(),
  156.             'image' => null,
  157.             'imageA' => null,
  158.             'imageB' => null,
  159.             'missing' => [],
  160.             'changes' => [],
  161.         ]);
  162.     }
  163.     /**
  164.      * @Route("/lot/import", name="lot_import", methods={"GET", "POST"})
  165.      *
  166.      * @IsGranted("ROLE_WAREHOUSE")
  167.      *
  168.      * @param Request $request
  169.      * @param ImportService $importService
  170.      *
  171.      * @return Response
  172.      */
  173.     public function import(Request $requestImportService $importService): Response
  174.     {
  175.         $form $this->createForm(ImportType::class);
  176.         $form->handleRequest($request);
  177.         if ($form->isSubmitted() && $form->isValid()) {
  178.             $file $form->get('file')->getData();
  179.             $importErrors $importService->importLot($file->getRealPath());
  180.             if (!$importErrors) {
  181.                 $this->addFlash('success''Lots imported successfully!');
  182.                 return $this->redirectToRoute('lot_index');
  183.             }
  184.             if (!empty($importErrors['exists'])) {
  185.                 $this->addFlash('danger', [
  186.                     'message' => 'Lot already exists (' count($importErrors['exists']) . ')',
  187.                     'messages' => $importErrors['exists'],
  188.                 ]);
  189.             }
  190.             if (!empty($importErrors['auction'])) {
  191.                 $this->addFlash('danger', [
  192.                     'message' => 'Auction hasn\'t been found (' count($importErrors['auction']) . ')',
  193.                     'messages' => $importErrors['auction'],
  194.                 ]);
  195.             }
  196.             if (!empty($importErrors['dealer'])) {
  197.                 $this->addFlash('danger', [
  198.                     'message' => 'Dealer does not exist (' count($importErrors['dealer']) . ')',
  199.                     'messages' => $importErrors['dealer'],
  200.                 ]);
  201.             }
  202.             if (!empty($importErrors['incorrect'])) {
  203.                 $this->addFlash('warning', [
  204.                     'message' => 'Incorrect data (' count($importErrors['incorrect']) . ')',
  205.                     'messages' => $importErrors['incorrect'],
  206.                 ]);
  207.             }
  208.             return $this->redirectToRoute('lot_import');
  209.         }
  210.         return $this->render('lot/import.html.twig', [
  211.             'form' => $form->createView(),
  212.         ]);
  213.     }
  214.     /**
  215.      * @Route("/lot/import-result", name="lot_result_import", methods={"GET", "POST"})
  216.      *
  217.      * @IsGranted("ROLE_WAREHOUSE")
  218.      *
  219.      * @param Request $request
  220.      * @param ImportService $importService
  221.      *
  222.      * @return Response
  223.      */
  224.     public function importResult(Request $requestImportService $importService): Response
  225.     {
  226.         $form $this->createForm(ImportType::class);
  227.         $form->handleRequest($request);
  228.         if ($form->isSubmitted() && $form->isValid()) {
  229.             $file $form->get('file')->getData();
  230.             $importErrors $importService->importAuctionResults($file->getRealPath());
  231.             if (!$importErrors) {
  232.                 $this->addFlash('success''Auction results imported successfully!');
  233.                 return $this->redirectToRoute('lot_index');
  234.             }
  235.             foreach ($importErrors as $importError) {
  236.                 $this->addFlash('danger'$importError);
  237.             }
  238.             return $this->redirectToRoute('lot_result_import');
  239.         }
  240.         return $this->render('lot/import.html.twig', [
  241.             'form' => $form->createView(),
  242.         ]);
  243.     }
  244.     /**
  245.      * @Route("/lot/batch", name="lot_batch", methods={"POST"})
  246.      *
  247.      * @IsGranted("ROLE_MANAGER")
  248.      *
  249.      * @param Request $request
  250.      * @param ExportService $exportService
  251.      *
  252.      * @return Response
  253.      */
  254.     public function batch(Request $requestExportService $exportService): Response
  255.     {
  256.         $method $request->get('method');
  257.         $lots $request->get('elements');
  258.         if (!$lots) {
  259.             $this->addFlash('danger''No Lots selected for export');
  260.             return $this->redirectToRoute('lot_index');
  261.         }
  262.         if ($method === 'export-lots') {
  263.             try {
  264.                 return $exportService->exportLots($lots);
  265.             } catch (Exception $e) {
  266.                 $this->addFlash('danger''Error while trying to export lots');
  267.                 return $this->redirectToRoute('lot_index');
  268.             }
  269.         }
  270.         if ($method === 'export-images') {
  271.             return $exportService->exportImages($lots);
  272.         }
  273.         $this->addFlash('danger''Unknown batch method');
  274.         return $this->redirectToRoute('lot_index');
  275.     }
  276.     /**
  277.      * @Route("/lot/bulk/move-to-auction", name="lot_bulk_auction", methods={"GET", "POST"})
  278.      *
  279.      * @IsGranted("ROLE_MANAGER")
  280.      *
  281.      * @param Request $request
  282.      * @param ExportService $exportService
  283.      * @param LotRepository $repository
  284.      * @param ManagerRegistry $doctrine
  285.      *
  286.      * @return Response
  287.      */
  288.     public function lotAuction(
  289.         Request $request,
  290.         ExportService $exportService,
  291.         LotRepository $repository,
  292.         ManagerRegistry $doctrine
  293.     ): Response {
  294.         $lots $request->get('elements', []);
  295.         $form $this->createForm(LotBulkAuction::class, null, [
  296.             'lots' => $lots,
  297.             'action' => $this->generateUrl('lot_bulk_auction'),
  298.         ]);
  299.         $form->handleRequest($request);
  300.         if ($form->isSubmitted() && $form->isValid()) {
  301.             $format $form->get('format')->getData();
  302.             $lotIds explode(','$form->get('lots')->getData());
  303.             $validationData $this->validateLots($lotIds$repositoryfalsetruetrue);
  304.             if (!empty($validationData['error'])) {
  305.                 foreach ($validationData['error'] as $error) {
  306.                     $this->addFlash('danger'$error);
  307.                 }
  308.                 return $this->redirectToRoute('lot_index');
  309.             }
  310.             $auction $form->get('auction')->getData();
  311.             if (!$auction) {
  312.                 $this->addFlash('danger''Auction not found');
  313.                 return $this->redirectToRoute('lot_index');
  314.             }
  315.             $lots $repository->findBy([
  316.                 'id' => $lotIds,
  317.             ]);
  318.             try {
  319.                 $response $exportService->moveLots($lots$auction$format);
  320.             } catch (Exception $e) {
  321.                 $this->addFlash('danger''Error while trying to move lots to auction');
  322.                 return $this->redirectToRoute('lot_index');
  323.             }
  324.             foreach ($lots as $lot) {
  325.                 $lot->setAuction($auction);
  326.             }
  327.             $doctrine->getManager()->flush();
  328.             return $response;
  329.         }
  330.         return $this->render('lot/bulk/auction.html.twig', [
  331.             'form' => $form->createView()
  332.         ]);
  333.     }
  334.     /**
  335.      * @Route("lot/bulk/return", name="lot_bulk_return", methods={"GET", "POST"})
  336.      *
  337.      * @IsGranted("ROLE_MANAGER")
  338.      *
  339.      * @param Request $request
  340.      * @param ExportService $exportService
  341.      * @param ValidatorInterface $validator
  342.      * @param LotRepository $repository
  343.      * @param ManagerRegistry $doctrine
  344.      *
  345.      * @return Response
  346.      *
  347.      * @throws TransportExceptionInterface
  348.      */
  349.     public function lotReturn(
  350.         Request $request,
  351.         ExportService $exportService,
  352.         ValidatorInterface $validator,
  353.         LotRepository $repository,
  354.         ManagerRegistry $doctrine
  355.     ): Response {
  356.         $lotIds $request->get('elements', []);
  357.         $attachmentNumber 0;
  358.         $email '';
  359.         if ($lotIds) {
  360.             $validationData $this->validateLots($lotIds$repositorytrue);
  361.             if (!empty($validationData['error'])) {
  362.                 foreach ($validationData['error'] as $error) {
  363.                     $this->addFlash('danger'$error);
  364.                 }
  365.                 return new Response(null404);
  366.             }
  367.             $attachmentNumber $validationData['number_dealer'];
  368.             $email $validationData['email'];
  369.         }
  370.         $form $this->createForm(LotBulkReturn::class, null, [
  371.             'lots' => $lotIds,
  372.             'email' => $email,
  373.             'number' => $attachmentNumber,
  374.             'action' => $this->generateUrl('lot_bulk_return'),
  375.         ]);
  376.         $form->handleRequest($request);
  377.         if ($form->isSubmitted() && $form->isValid()) {
  378.             $format $form->get('format')->getData();
  379.             $attachmentNumber $form->get('number')->getData();
  380.             $sendEmails $form->get('send')->getData();
  381.             $lotIds explode(','$form->get('lots')->getData());
  382.             if ($sendEmails) {
  383.                 $emailData $form->get('email')->getData();
  384.                 $emails explode(';'$emailData);
  385.                 $invalidEmail $this->validateBulkEmails($validator$emails);
  386.                 if ($invalidEmail) {
  387.                     $this->addFlash('danger''Invalid email address: ' $invalidEmail);
  388.                     return $this->redirect($request->headers->get('referer'));
  389.                 }
  390.             } else {
  391.                 $emails = [];
  392.             }
  393.             $lots $repository->findBy([
  394.                 'id' => $lotIds,
  395.             ]);
  396.             foreach ($lots as $lot) {
  397.                 $lot->setStatus(Lot::STATUS_RETURN);
  398.                 if ($lot->getDealer()) {
  399.                     $lot->getDealer()->setAttachmentNo($attachmentNumber);
  400.                 }
  401.             }
  402.             $doctrine->getManager()->flush();
  403.             try {
  404.                 return $exportService->returnLots($lots$attachmentNumber$emails$format);
  405.             } catch (Exception $e) {
  406.                 $this->addFlash('danger''Error while trying to return');
  407.                 return $this->redirectToRoute('lot_index');
  408.             }
  409.         }
  410.         return $this->render('lot/bulk/return.html.twig', [
  411.             'form' => $form->createView()
  412.         ]);
  413.     }
  414.     /**
  415.      * @Route("/lot/bulk/report-items-for-sale", name="lot_bulk_report_sale", methods={"GET", "POST"})
  416.      *
  417.      * @IsGranted("ROLE_MANAGER")
  418.      *
  419.      * @param Request $request
  420.      * @param ExportService $exportService
  421.      * @param ValidatorInterface $validator
  422.      * @param LotRepository $repository
  423.      * @param ManagerRegistry $doctrine
  424.      *
  425.      * @return Response
  426.      *
  427.      * @throws TransportExceptionInterface
  428.      */
  429.     public function lotReportSale(
  430.         Request $request,
  431.         ExportService $exportService,
  432.         ValidatorInterface $validator,
  433.         LotRepository $repository,
  434.         ManagerRegistry $doctrine
  435.     ): Response {
  436.         $lotIds $request->get('elements', []);
  437.         $attachmentNumber 0;
  438.         $email '';
  439.         if ($lotIds) {
  440.             $validationData $this->validateLots($lotIds$repositoryfalsefalsefalse);
  441.             if (!empty($validationData['error'])) {
  442.                 foreach ($validationData['error'] as $error) {
  443.                     $this->addFlash('danger'$error);
  444.                 }
  445.                 return new Response(null404);
  446.             }
  447.             $attachmentNumber $validationData['number_dealer'];
  448.             $email $validationData['email'];
  449.             $email .= ';customer@numisbalt.lt';
  450.         }
  451.         $form $this->createForm(LotBulkReportSale::class, null, [
  452.             'lots' => $lotIds,
  453.             'email' => $email,
  454.             'number' => $attachmentNumber,
  455.             'action' => $this->generateUrl('lot_bulk_report_sale'),
  456.         ]);
  457.         $form->handleRequest($request);
  458.         if ($form->isSubmitted() && $form->isValid()) {
  459.             $format $form->get('format')->getData();
  460.             $attachmentNumber $form->get('number')->getData();
  461.             $sendEmails $form->get('send')->getData();
  462.             $lotIds explode(','$form->get('lots')->getData());
  463.             if ($sendEmails) {
  464.                 $emailData $form->get('email')->getData();
  465.                 $emails explode(';'$emailData);
  466.                 $invalidEmail $this->validateBulkEmails($validator$emails);
  467.                 if ($invalidEmail) {
  468.                     $this->addFlash('danger''Invalid email address: ' $invalidEmail);
  469.                     return $this->redirect($request->headers->get('referer'));
  470.                 }
  471.             } else {
  472.                 $emails = [];
  473.             }
  474.             $lots $repository->findBy([
  475.                 'id' => $lotIds,
  476.             ]);
  477.             foreach ($lots as $lot) {
  478.                 if ($lot->getDealer()) {
  479.                     $lot->getDealer()->setAttachmentNo($attachmentNumber);
  480.                 }
  481.             }
  482.             $doctrine->getManager()->flush();
  483.             try {
  484.                 return $exportService->reportSale($lots$attachmentNumber$emails$format);
  485.             } catch (Exception $e) {
  486.                 $this->addFlash('danger''Error while trying to report items for sale');
  487.                 return $this->redirectToRoute('lot_index');
  488.             }
  489.         }
  490.         return $this->render('lot/bulk/report-sale.html.twig', [
  491.             'form' => $form->createView()
  492.         ]);
  493.     }
  494.     /**
  495.      * @Route("/lot/bulk/report-sold-items", name="lot_bulk_report_sold", methods={"GET", "POST"})
  496.      *
  497.      * @IsGranted("ROLE_MANAGER")
  498.      *
  499.      * @param Request $request
  500.      * @param ExportService $exportService
  501.      * @param ValidatorInterface $validator
  502.      * @param LotRepository $repository
  503.      * @param ManagerRegistry $doctrine
  504.      *
  505.      * @return Response
  506.      *
  507.      * @throws TransportExceptionInterface
  508.      */
  509.     public function lotReportSold(
  510.         Request $request,
  511.         ExportService $exportService,
  512.         ValidatorInterface $validator,
  513.         LotRepository $repository,
  514.         ManagerRegistry $doctrine
  515.     ): Response {
  516.         $lotIds $request->get('elements', []);
  517.         $attachmentNumber 0;
  518.         $email '';
  519.         if ($lotIds) {
  520.             $validationData $this->validateLots($lotIds$repositorytruefalsefalse);
  521.             if (!empty($validationData['error'])) {
  522.                 foreach ($validationData['error'] as $error) {
  523.                     $this->addFlash('danger'$error);
  524.                 }
  525.                 return new Response(null404);
  526.             }
  527.             $attachmentNumber $validationData['number_dealer'];
  528.             $email $validationData['email'];
  529.             $email .= ';customer@numisbalt.lt';
  530.         }
  531.         $form $this->createForm(LotBulkReportSold::class, null, [
  532.             'lots' => $lotIds,
  533.             'email' => $email,
  534.             'number' => $attachmentNumber,
  535.             'action' => $this->generateUrl('lot_bulk_report_sold'),
  536.         ]);
  537.         $form->handleRequest($request);
  538.         if ($form->isSubmitted() && $form->isValid()) {
  539.             $format $form->get('format')->getData();
  540.             $attachmentNumber $form->get('number')->getData();
  541.             $sendEmails $form->get('send')->getData();
  542.             $lotIds explode(','$form->get('lots')->getData());
  543.             if ($sendEmails) {
  544.                 $emailData $form->get('email')->getData();
  545.                 $emails explode(';'$emailData);
  546.                 $invalidEmail $this->validateBulkEmails($validator$emails);
  547.                 if ($invalidEmail) {
  548.                     $this->addFlash('danger''Invalid email address: ' $invalidEmail);
  549.                     return $this->redirect($request->headers->get('referer'));
  550.                 }
  551.             } else {
  552.                 $emails = [];
  553.             }
  554.             $lots $repository->findBy([
  555.                 'id' => $lotIds,
  556.             ]);
  557.             foreach ($lots as $lot) {
  558.                 $lot->setStatus(Lot::STATUS_SOLD);
  559.                 if ($lot->getDealer()) {
  560.                     $lot->getDealer()->setAttachmentNo($attachmentNumber);
  561.                 }
  562.             }
  563.             $doctrine->getManager()->flush();
  564.             try {
  565.                 return $exportService->reportSold($lots$attachmentNumber$emails$format);
  566.             } catch (Exception $e) {
  567.                 $this->addFlash('danger''Error while trying to report items for sale');
  568.                 return $this->redirectToRoute('lot_index');
  569.             }
  570.         }
  571.         return $this->render('lot/bulk/report-sold.html.twig', [
  572.             'form' => $form->createView()
  573.         ]);
  574.     }
  575.     /**
  576.      * @Route("/lotbulk/image-delete", name="lot_bulk_image_delete", methods={"POST"})
  577.      *
  578.      * @IsGranted("ROLE_ADMIN")
  579.      */
  580.     public function lotBulkImageDelete(Request $requestLotRepository $repository): Response
  581.     {
  582.         $lotIds $request->get('elements', []);
  583.         if ($lotIds) {
  584.             $validationData $this->validateLots($lotIds$repositoryfalsetruefalse);
  585.             if (!empty($validationData['error'])) {
  586.                 foreach ($validationData['error'] as $error) {
  587.                     $this->addFlash('danger'$error);
  588.                 }
  589.                 return new Response(null404);
  590.             }
  591.         }
  592.         $form $this->createForm(LotBulkImageDelete::class, null, [
  593.             'lots' => $lotIds,
  594.             'action' => $this->generateUrl('lot_bulk_image_delete'),
  595.         ]);
  596.         $form->handleRequest($request);
  597.         if ($form->isSubmitted() && $form->isValid()) {
  598.             $deleteCount 0;
  599.             $deleteSize 0;
  600.             $lotIds explode(','$form->get('lots')->getData());
  601.             $lots $repository->findBy([
  602.                 'id' => $lotIds,
  603.             ]);
  604.             foreach ($lots as $lot) {
  605.                 foreach ($lot->getImages() as $image) {
  606.                     $path $this->getParameter('images_directory') . '/' $image->getFileName();
  607.                     if (file_exists($path)) {
  608.                         $deleteSize += filesize($path);
  609.                         $deleteCount++;
  610.                         unlink($path);
  611.                     }
  612.                 }
  613.             }
  614.             $this->addFlash('info'sprintf('Deleted %d images (size: %.2f MB)'$deleteCount$deleteSize 1000000));
  615.             return $this->redirectToRoute('lot_index');
  616.         }
  617.         return $this->render('lot/bulk/image-delete.html.twig', [
  618.             'form' => $form->createView()
  619.         ]);
  620.     }
  621.     /**
  622.      * @Route("/lot/bulk/delete", name="lot_bulk_delete", methods={"POST"})
  623.      *
  624.      * @IsGranted("ROLE_ADMIN")
  625.      *
  626.      * @param Request $request
  627.      * @param LotRepository $repository
  628.      * @param ManagerRegistry $doctrine
  629.      *
  630.      * @return Response
  631.      */
  632.     public function lotBulkDelete(Request $requestLotRepository $repositoryManagerRegistry $doctrine): Response
  633.     {
  634.         $lotIds $request->get('elements', []);
  635.         if ($lotIds) {
  636.             $validationData $this->validateLots($lotIds$repositoryfalsetrue);
  637.             if (!empty($validationData['error'])) {
  638.                 foreach ($validationData['error'] as $error) {
  639.                     $this->addFlash('danger'$error);
  640.                 }
  641.                 return new Response(null404);
  642.             }
  643.         }
  644.         $form $this->createForm(LotBulkDelete::class, null, [
  645.             'lots' => $lotIds,
  646.             'action' => $this->generateUrl('lot_bulk_delete'),
  647.         ]);
  648.         $form->handleRequest($request);
  649.         if ($form->isSubmitted() && $form->isValid()) {
  650.             $lotIds explode(','$form->get('lots')->getData());
  651.             $lots $repository->findBy([
  652.                 'id' => $lotIds,
  653.             ]);
  654.             foreach ($lots as $lot) {
  655.                 $doctrine->getManager()->remove($lot);
  656.             }
  657.             $doctrine->getManager()->flush();
  658.             return $this->redirectToRoute('lot_index');
  659.         }
  660.         return $this->render('lot/bulk/delete.html.twig', [
  661.             'form' => $form->createView()
  662.         ]);
  663.     }
  664.     /**
  665.      * @Route("/lot/bulk/change-status", name="lot_bulk_change_status", methods={"GET", "POST"})
  666.      *
  667.      * @IsGranted("ROLE_MANAGER")
  668.      *
  669.      * @param Request $request
  670.      * @param LotRepository $repository
  671.      * @param ManagerRegistry $doctrine
  672.      *
  673.      * @return Response
  674.      */
  675.     public function lotBulkChangeStatus(
  676.         Request $request,
  677.         LotRepository $repository,
  678.         ManagerRegistry $doctrine
  679.     ): Response {
  680.         $lotIds $request->get('elements', []);
  681.         if ($lotIds) {
  682.             $validationData $this->validateLots($lotIds$repositoryfalsetruefalse);
  683.             if (!empty($validationData['error'])) {
  684.                 foreach ($validationData['error'] as $error) {
  685.                     $this->addFlash('danger'$error);
  686.                 }
  687.                 return new Response(null404);
  688.             }
  689.         }
  690.         $form $this->createForm(LotBulkChangeStatus::class, null, [
  691.             'lots' => $lotIds,
  692.             'method' => 'POST',
  693.             'action' => $this->generateUrl('lot_bulk_change_status'),
  694.         ]);
  695.         $form->handleRequest($request);
  696.         if ($form->isSubmitted() && $form->isValid()) {
  697.             $status $form->get('status')->getData();
  698.             $lotIds explode(','$form->get('lots')->getData());
  699.             $lots $repository->findBy([
  700.                 'id' => $lotIds,
  701.             ]);
  702.             foreach ($lots as $lot) {
  703.                 $lot->setStatus($status);
  704.             }
  705.             $doctrine->getManager()->flush();
  706.             return $this->redirectToRoute('lot_index');
  707.         }
  708.         return $this->render('lot/bulk/change-status.html.twig', [
  709.             'form' => $form->createView()
  710.         ]);
  711.     }
  712.     /**
  713.      * @param array $lotIds
  714.      * @param LotRepository $repository
  715.      * @param bool $checkAuction
  716.      * @param bool $checkExistenceOnly
  717.      * @param bool $checkReturnAndSold
  718.      *
  719.      * @return array
  720.      */
  721.     private function validateLots(
  722.         array $lotIds,
  723.         LotRepository $repository,
  724.         bool $checkAuction false,
  725.         bool $checkExistenceOnly false,
  726.         bool $checkReturnAndSold true
  727.     ): array {
  728.         $errors = [];
  729.         $lots = [];
  730.         $email null;
  731.         $attachmentNumberDealer null;
  732.         $previousLot null;
  733.         $previousAuction null;
  734.         if (!$lotIds) {
  735.             $errors[] = 'No lots selected';
  736.         }
  737.         if (!$checkExistenceOnly || $checkReturnAndSold) {
  738.             $lots $repository->findBy(['id' => $lotIds]);
  739.         }
  740.         if (!$checkExistenceOnly) {
  741.             foreach ($lots as $lot) {
  742.                 if (!$lot->getDealer()) {
  743.                     $errors[] = 'Lot doesn\'t have dealer assigned';
  744.                 }
  745.                 if (!$previousLot) {
  746.                     $previousLot $lot;
  747.                 } elseif ($previousLot instanceof Lot && $previousLot->getDealer() !== $lot->getDealer()) {
  748.                     $errors[] = 'Selected multiple dealers';
  749.                 }
  750.                 if ($checkAuction) {
  751.                     if (!$lot->getAuction()) {
  752.                         $errors[] = 'Lot doesn\'t have auction assigned';
  753.                     }
  754.                     if (!$previousAuction) {
  755.                         $previousAuction $lot;
  756.                     } elseif (
  757.                         $previousAuction instanceof Lot && $previousAuction->getAuction() !== $lot->getAuction()
  758.                     ) {
  759.                         $errors[] = 'Selected multiple auctions';
  760.                     }
  761.                 }
  762.                 $attachmentNumberDealer = (int)$lot->getDealer()->getAttachmentNo();
  763.                 $email $lot->getDealer()->getEmail();
  764.             }
  765.         }
  766.         if ($checkReturnAndSold) {
  767.             foreach ($lots as $lot) {
  768.                 if (in_array($lot->getStatus(), [Lot::STATUS_RETURNLot::STATUS_SOLD], true)) {
  769.                     $errors[] = 'No actions are allowed for Sold or Returned lots. Change lot status to make changes';
  770.                 }
  771.             }
  772.         }
  773.         return [
  774.             'number_dealer' => $attachmentNumberDealer,
  775.             'email' => $email,
  776.             'error' => $errors,
  777.         ];
  778.     }
  779.     /**
  780.      * @param ValidatorInterface $validator
  781.      * @param array $emails
  782.      *
  783.      * @return string|null
  784.      */
  785.     private function validateBulkEmails(ValidatorInterface $validator, array $emails): ?string
  786.     {
  787.         $constraintEmail = new Constraints\Email();
  788.         foreach ($emails as $email) {
  789.             if (count($validator->validate($email$constraintEmail))) {
  790.                 return $email;
  791.             }
  792.         }
  793.         return null;
  794.     }
  795.     /**
  796.      * @Route("/lot/{id}/edit", name="lot_edit", methods={"GET","POST"})
  797.      *
  798.      * @param Request $request
  799.      * @param Lot $lot
  800.      * @param ManagerRegistry $doctrine
  801.      * @param ChangeLogRepository $changeLogRepository
  802.      *
  803.      * @return Response
  804.      */
  805.     public function edit(
  806.         Request $request,
  807.         Lot $lot,
  808.         ManagerRegistry $doctrine,
  809.         ChangeLogRepository $changeLogRepository
  810.     ): Response {
  811.         if (
  812.             !$this->isGranted('ROLE_MANAGER') &&
  813.             !$this->isGranted('ROLE_QUALITY') &&
  814.             !$this->isGranted('ROLE_PHOTO')
  815.         ) {
  816.             throw $this->createAccessDeniedException();
  817.         }
  818.         $image null;
  819.         $imageA null;
  820.         $imageB null;
  821.         $imageC null;
  822.         $imageD null;
  823.         $missing $lot->getMissing();
  824.         $form $this->createForm(LotType::class, $lot, [
  825.             'missing' => $missing,
  826.         ]);
  827.         $form->handleRequest($request);
  828.         if ($form->isSubmitted() && $form->isValid()) {
  829.             $doctrine->getManager()->flush();
  830.             if ($this->isGranted('ROLE_QUALITY') && $request->get('submit') === 'checked') {
  831.                 $lot->setChecked(true);
  832.             }
  833.             if (!$lot->getMissing()) {
  834.                 $lot->setStatus(Lot::STATUS_IN_AUCTION);
  835.                 $doctrine->getManager()->flush();
  836.             }
  837.             return $this->redirectToRoute('lot_index');
  838.         }
  839.         foreach ($lot->getImages() as $lotImage) {
  840.             $name explode('.'$lotImage->getFileName());
  841.             if (substr($name[0], -1) === 'a') {
  842.                 $imageA $lotImage;
  843.             } elseif (substr($name[0], -1) === 'b') {
  844.                 $imageB $lotImage;
  845.             } elseif (substr($name[0], -1) === 'c') {
  846.                 $imageC $lotImage;
  847.             } elseif (substr($name[0], -1) === 'd') {
  848.                 $imageD $lotImage;
  849.             } else {
  850.                 $image $lotImage;
  851.             }
  852.         }
  853.         $changes $this->isGranted('ROLE_MANAGER') ? $changeLogRepository->getLotChanges($lot) : [];
  854.         return $this->render('lot/edit.html.twig', [
  855.             'lot' => $lot,
  856.             'form' => $form->createView(),
  857.             'image' => $image,
  858.             'imageA' => $imageA,
  859.             'imageB' => $imageB,
  860.             'imageC' => $imageC,
  861.             'imageD' => $imageD,
  862.             'missing' => $missing,
  863.             'changes' => $changes,
  864.         ]);
  865.     }
  866.     /**
  867.      * @Route("/data", name="lot_data", methods={"GET"})
  868.      *
  869.      * @IsGranted("ROLE_FINANCE")
  870.      *
  871.      * @param Request $request
  872.      * @param LotRepository $lotRepository
  873.      *
  874.      * @return JsonResponse
  875.      */
  876.     public function data(Request $requestLotRepository $lotRepository): JsonResponse
  877.     {
  878.         $lotId $request->get('id'null);
  879.         if (!$lotId) {
  880.             return new JsonResponse();
  881.         }
  882.         $lot $lotRepository->find($lotId);
  883.         if (!$lot) {
  884.             return new JsonResponse();
  885.         }
  886.         $data = [
  887.             'id' => $lot->getId(),
  888.             'lotId' => $lot->getLotId(),
  889.             'sum' => $lot->getSold(),
  890.             'lotName' => 'Lot name???',
  891.             'lotFee' => 'TODO fees',
  892.         ];
  893.         return new JsonResponse($data);
  894.     }
  895.     /**
  896.      * @Route("/lot/{id}", name="lot_delete", methods={"POST"})
  897.      *
  898.      * @IsGranted("ROLE_ADMIN")
  899.      *
  900.      * @param Request $request
  901.      * @param Lot $lot
  902.      * @param ManagerRegistry $doctrine
  903.      *
  904.      * @return Response
  905.      */
  906.     public function delete(Request $requestLot $lotManagerRegistry $doctrine): Response
  907.     {
  908.         if ($this->isCsrfTokenValid('delete' $lot->getId(), $request->request->get('_token'))) {
  909.             $entityManager $doctrine->getManager();
  910.             $entityManager->remove($lot);
  911.             $entityManager->flush();
  912.         }
  913.         return $this->redirectToRoute('lot_index');
  914.     }
  915. }