src/Repository/OfferRepository.php line 287

Open in your IDE?
  1. <?php
  2. namespace App\Repository;
  3. use App\Entity\Booking;
  4. use App\Entity\Offer;
  5. use App\Services\Utils;
  6. use DateInterval;
  7. use DatePeriod;
  8. use DateTime;
  9. use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
  10. use Doctrine\DBAL\Exception;
  11. use Doctrine\ORM\NonUniqueResultException;
  12. use Doctrine\ORM\OptimisticLockException;
  13. use Doctrine\ORM\ORMException;
  14. use Doctrine\ORM\Query;
  15. use Doctrine\Persistence\ManagerRegistry;
  16. /**
  17.  * @method Offer|null find($id, $lockMode = null, $lockVersion = null)
  18.  * @method Offer|null findOneBy(array $criteria, array $orderBy = null)
  19.  * @method Offer[]    findAll()
  20.  * @method Offer[]    findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
  21.  */
  22. class OfferRepository extends ServiceEntityRepository
  23. {
  24.     private Utils $utils;
  25.     public function __construct(ManagerRegistry $registryUtils $utils)
  26.     {
  27.         $this->utils $utils;
  28.         parent::__construct($registryOffer::class);
  29.     }
  30.     /**
  31.      * @param Offer $entity
  32.      * @param bool $flush
  33.      * @return void
  34.      */
  35.     public function add(Offer $entitybool $flush true): void
  36.     {
  37.         $this->_em->persist($entity);
  38.         if ($flush) {
  39.             $this->_em->flush();
  40.         }
  41.     }
  42.     /**
  43.      * @param Offer $entity
  44.      * @param bool $flush
  45.      * @return void
  46.      */
  47.     public function remove(Offer $entitybool $flush true): void
  48.     {
  49.         $this->_em->remove($entity);
  50.         if ($flush) {
  51.             $this->_em->flush();
  52.         }
  53.     }
  54.     public function englishDateToFrenchDate(DateTime $date) : string
  55.     {
  56.         $englishDay $date->format('D');
  57.         switch($englishDay) {
  58.             case 'Mon':
  59.                 $frenchDay 'lundi';
  60.                 break;
  61.             case 'Tue':
  62.                 $frenchDay 'mardi';
  63.                 break;
  64.             case 'Wed':
  65.                 $frenchDay 'mercredi';
  66.                 break;
  67.             case 'Thu':
  68.                 $frenchDay 'jeudi';
  69.                 break;
  70.             case 'Fri':
  71.                 $frenchDay 'vendredi';
  72.                 break;
  73.             case 'Sat':
  74.                 $frenchDay 'samedi';
  75.                 break;
  76.             case 'Sun':
  77.                 $frenchDay 'dimanche';
  78.                 break;
  79.             default:
  80.                 $frenchDay 'Jour inconnu';
  81.         }
  82.         return $frenchDay;
  83.     }
  84.     /**
  85.      * @param array|null $params
  86.      * @return Query
  87.      * @throws \Exception
  88.      */
  89.     public function search(?array $params)
  90.     {
  91.         $qb $this->createQueryBuilder('o')
  92.             ->leftJoin('o.territory','t')
  93.             ->leftJoin('o.weapons','w')
  94.             //->innerJoin('o.gibiers','og')
  95.             ->andWhere('o.status IN (:status)')
  96.             ->setParameter('status', [Offer::STATUS_ACTIVEOffer::STATUS_FINISHED]);
  97.         if(isset($params['huntingMode']) && count($params['huntingMode']) > 0) {
  98.             $ids = [];
  99.             foreach($params['huntingMode'] as $mode) {
  100.                 $ids[] = $mode->getId();
  101.             }
  102.             $qb->join('o.huntingMode''a');
  103.             $qb->andWhere('a.id IN (:mode)');
  104.             $qb->setParameter('mode',$ids);
  105.         }
  106.         if(isset($params['type']) && count($params['type']) > 0) {
  107.             $qb->andWhere('o.type IN (:type)');
  108.             $qb->setParameter('type'$params['type']);
  109.         }
  110.         if(isset($params['dates']) && !is_null($params['dates']) && $params['dates'] != '') {
  111.             $dates explode('-',$params['dates']);
  112.             $dates[0] = str_replace(" """$dates[0]);
  113.             $dates[1] = str_replace(" """$dates[1]);
  114.             if ($dates[0] !== $dates[1]) {
  115.                 $period = new DatePeriod(
  116.                     DateTime::createFromFormat('d/m/Y'$dates[0])->modify('midnight'),
  117.                     new DateInterval('P1D'),
  118.                     DateTime::createFromFormat('d/m/Y'$dates[1])->modify('midnight')
  119.                 );
  120.                 $datesQuery '';
  121.                 $i 0;
  122.                 foreach ($period as $date) {
  123.                     $datesQuery .= 'JSON_CONTAINS(o.disponibilities, :date'.$i.') = 1';
  124.                     $datesQuery .= ' OR o.startAt = :date'.$i.' OR o.endAt = :date'.$i.' OR ';
  125.                     $qb->setParameter('date'.$i'{"date":"'.$date->format('d/m/Y').'"}');
  126.                     $i++;
  127.                 }
  128.                 $datesQuery mb_substr($datesQuery0, -3);
  129.                 if($dates[0] != $dates[1]) {
  130.                     $qb->andWhere('(o.startAt <= :startAt AND o.endAt >= :endAt) OR (o.startAt >= :startAt AND o.endAt <= :endAt) OR (' $datesQuery ')');
  131.                     $qb->setParameter('startAt',DateTime::createFromFormat('d/m/Y'$dates[0])->modify('midnight'));
  132.                     $qb->setParameter('endAt'DateTime::createFromFormat('d/m/Y'$dates[1])->modify('midnight'));
  133.                 }
  134.             } else {
  135.                 $datetime DateTime::createFromFormat('d/m/Y'$dates[0])->modify('midnight');
  136.                 $datesQuery 'JSON_CONTAINS(o.disponibilities, :dateContains) = 1';
  137.                 $datesExceptionsQuery 'JSON_CONTAINS(o.recurrenceException, :dateContains) = 0';
  138.                 $qb->andWhere('(o.startAt <= :date AND o.endAt >= :date AND o.recurrence LIKE :dateDay' ' AND ' $datesExceptionsQuery ') OR (' $datesQuery ')');
  139.                 $qb->setParameter('dateContains''{"date":"'.$dates[0].'"}');
  140.                 $qb->setParameter('date'$datetime);
  141.                 $qb->setParameter('dateDay''%"'.$this->englishDateToFrenchDate($datetime).'"%');
  142.             }
  143.         }
  144.         if(isset($params['startDate']) && !is_null($params['startDate']) && $params['startDate'] != '') {
  145.             $qb->andWhere('o.startAt >= :startAt');
  146.             $qb->setParameter('startAt'$params['startDate']);
  147.         }
  148.         if(isset($params['endDate']) && !is_null($params['endDate']) && $params['endDate'] != '') {
  149.             $qb->andWhere('o.endAt >= :endAt');
  150.             $qb->setParameter('endAt'$params['endDate']);
  151.         }
  152.         if(isset($params['animals']) && count($params['animals']) > 0) {
  153.             $ids = [];
  154.             foreach($params['animals'] as $animal) {
  155.                 $ids[] = $animal->getId();
  156.             }
  157.             $qb->andWhere($qb->expr()->isMemberOf(':animals''o.animals'))
  158.                 ->setParameter(':animals'$ids);
  159.         }
  160.         if(isset($params['departement']) && count($params['departement']) > 0) {
  161.             $departements $params['departement'];
  162.             $qb->andWhere('t.department IN (:departments)');
  163.             $qb->setParameter('departments'$departements);
  164.         }
  165.         if(isset($params['region']) && count($params['region']) > 0) {
  166.             $regions = [];
  167.             foreach ($params['region'] as $region)
  168.                 $regions[] = $this->utils->slugify(Utils::sRegionList()[$region]);
  169.             $qb->andWhere('t.region IN (:regions)');
  170.             $qb->setParameter('regions'$regions);
  171.         }
  172.         if(isset($params['gibier']) && count($params['gibier']) > 0) {
  173.            // $qb->andWhere('og.title IN (:gibiers)');
  174.            // $qb->setParameter('gibiers', $params['gibier']);
  175.             $gibiersIds = [];
  176.             foreach($params['gibier'] as $gibier) {
  177.                 $gibiersIds[] = $gibier->getId();
  178.             }
  179.             $qb->andWhere($qb->expr()->isMemberOf(':gibiers''o.gibiers'))
  180.                 ->setParameter(':gibiers'$gibiersIds);
  181.         }
  182.         if(isset($params['weapons']) && count($params['weapons']) > 0) {
  183.             $ids = [];
  184.             foreach($params['weapons'] as $weapon) {
  185.                 $ids[] = $weapon->getId();
  186.             }
  187.             $qb->andWhere($qb->expr()->isMemberOf(':weapons''o.weapons'))
  188.                 ->setParameter(':weapons'$ids);
  189.         }
  190.         if(isset($params['priceMin'])) {
  191.             $qb->andWhere('o.price >= :priceMin');
  192.             $qb->setParameter('priceMin'$params['priceMin']);
  193.         }
  194.         if(isset($params['priceMax'])) {
  195.             $qb->andWhere('o.price <= :priceMax');
  196.             $qb->setParameter('priceMax'$params['priceMax']);
  197.         }
  198.         if(isset($params['orderSort']) && isset($params['orderBy'])) {
  199.             $qb->addOrderBy('o.'.$params['orderBy'], $params['orderSort']);
  200.         } else {
  201.             $qb->addOrderBy('o.id''DESC')
  202.                 ->addOrderBy('o.isTuchassouSelected''DESC');
  203.         }
  204.         $qb->addGroupBy('o.id');
  205.         return $qb->getQuery()->getResult();
  206.     }
  207.     /**
  208.      * @return float|int|mixed|string|null
  209.      * @throws NonUniqueResultException
  210.      */
  211.     public function getPriceBornes()
  212.     {
  213.         $query $this->createQueryBuilder('o');
  214.         $query->select('MAX(o.price) AS maxPrice, MIN(o.price) AS minPrice');
  215.         $query->where('o.status = true');
  216.         $query->setMaxResults(1);
  217.         return $query->getQuery()->getOneOrNullResult();
  218.     }
  219.     /**
  220.      * @param int|null $userId
  221.      * @return float|int|mixed|string
  222.      */
  223.     public function getHoteOffers(?int $userId)
  224.     {
  225.         $query $this->createQueryBuilder('o');
  226.         $query->where('o.status != :status')
  227.             ->setParameter('status'Offer::STATUS_DELETED)
  228.             ->andWhere('o.createdBy = :userId')
  229.             ->setParameter('userId'$userId)
  230.         ;
  231.         return $query->getQuery()->getResult();
  232.     }
  233.     /**
  234.      * @param Offer $offer
  235.      * @param int $radius
  236.      * @return float|int|mixed|string
  237.      */
  238.     public function getOffersByDistance(Offer $offerint $radius)
  239.     {
  240.         $lat $offer->getTerritory()->getLatitude();
  241.         $long $offer->getTerritory()->getLongitude();
  242.         $type $offer->getType();
  243.         $id  $offer->getId();
  244.         $q $this->createQueryBuilder('o')
  245.             ->select("o, (3959 * acos(cos(radians('".$lat."')) * cos(radians(t.latitude)) * cos(radians(t.longitude) - radians('".$long."')) + sin(radians('".$lat."')) * sin(radians(t.latitude)))) AS distance")
  246.             ->innerJoin('o.territory''t')
  247.         ;
  248.         $q->where('o.id != :id')->setParameter('id'$id);
  249.         if($type && $type != '') {
  250.             $q->andWhere('o.type = :type')->setParameter('type'$type);
  251.         }
  252.         $q->having("distance <= :distance")->setParameter('distance'$radius)
  253.             ->orderBy("distance""ASC");
  254.         return $q->getQuery()->getResult();
  255.     }
  256.     /**
  257.      * @return array|null
  258.      */
  259.     public function getMostBookedOffers($request null): ?array
  260.     {
  261.         /*$conn = $this->getEntityManager()->getConnection();
  262.         $sql = "SELECT o.id , o.title , SUM(b.total_ttc) , COUNT(b.user_id)
  263.                 FROM booking b
  264.                 LEFT JOIN offer o ON b.offer_id = o.id
  265.                 WHERE b.status = :status
  266.                 GROUP BY offer_id
  267.                 ORDER BY COUNT(b.user_id) DESC , SUM(b.total_ttc) DESC";
  268.         $stmt = $conn->prepare($sql);
  269.         $resultSet = $stmt->executeQuery(['status' => 'in_progress']);
  270.         $most_booked_offers = [];
  271.         foreach ($resultSet->fetchAllAssociative() as $item) {
  272.             $most_booked_offers[] = array_values($item);
  273.         }
  274.         return $most_booked_offers;*/
  275.         $query $this->createQueryBuilder('o');
  276.         $query->select('o.id, o.title, SUM(b.totalTtc) AS totalTtc, COUNT(b.id) AS totalBookings')
  277.             ->leftJoin('o.bookings''b')
  278.             ->where('b.status = :status')
  279.             ->setParameter('status'Booking::STATUS_ACCEPTED)
  280.             //->addOrderBy('totalTtc', 'DESC')
  281.         ;
  282.         if (isset($request['startDate'])) {
  283.             $query->andWhere('b.createdAt >= :startDate')
  284.                 ->setParameter('startDate'$request['startDate'])
  285.             ;
  286.         }
  287.         if (isset($request['endDate'])) {
  288.             $query->andWhere('b.createdAt <= :endDate')
  289.                 ->setParameter('endDate'$request['endDate'])
  290.             ;
  291.         }
  292.         if (isset($request['departement'])) {
  293.             $query->join('o.territory''t')
  294.                 ->andWhere('t.department = :department')
  295.                 ->setParameter('department'$request['departement']);
  296.         }
  297.         if (isset($request['type'])) {
  298.             $query->andWhere('o.type = :type')
  299.                 ->setParameter('type'$request['type']);
  300.         }
  301.         $query->groupBy('o.id')
  302.             ->orderBy('totalBookings''DESC');
  303.         return $query->setMaxResults(5)->getQuery()->getResult();
  304.     }
  305.     public function findOffersDashboard($request null) {
  306.         $qb $this->createQueryBuilder('o');
  307.         if ($request['startDate']) {
  308.             $qb->andWhere('o.createdAt >= :startDate')
  309.                 ->setParameter('startDate'$request['startDate']);
  310.         }
  311.         if ($request['endDate']) {
  312.             $qb->andWhere('o.createdAt <= :endDate')
  313.                 ->setParameter('endDate'$request['endDate']);
  314.         }
  315.         if ($request['departement']) {
  316.             $qb->join('o.territory''t')
  317.                 ->andWhere('t.department = :department')
  318.                 ->setParameter('department'$request['departement']);
  319.         }
  320.         if ($request['typeOffer']) {
  321.             $qb->andWhere('o.type = :type')
  322.                 ->setParameter('type'$request['typeOffer']);
  323.         }
  324.         return $qb->getQuery()->getResult();
  325.     }
  326. }