← Back
Editing: ReportRepository.php
<?php declare(strict_types=1); namespace App\Repository; use App\Entity\Report; use App\Entity\ReportItem; use App\Entity\User; use App\Enum\ReportStatusType; use App\Enum\ReportType; use App\Service\SolutionService; use App\Service\Utils; use App\Session\Filter\Role\SupervisorSessionFilters; use App\Session\Filter\SessionFiltersContainer; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\ORM\QueryBuilder; use Doctrine\Persistence\ManagerRegistry; use Symfony\Component\Form\FormInterface; use Symfony\Component\Security\Core\User\UserInterface; /** * @extends ServiceEntityRepository<Report> * * @method Report|null find($id, $lockMode = null, $lockVersion = null) * @method Report|null findOneBy(array $criteria, array $orderBy = null) * @method Report[] findAll() * @method Report[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) */ class ReportRepository extends ServiceEntityRepository { public function __construct( ManagerRegistry $registry, private readonly SolutionService $solution, private readonly SessionFiltersContainer $sessionFiltersContainer ) { parent::__construct($registry, Report::class); } public function save(Report $entity, bool $flush = false): void { $this->getEntityManager()->persist($entity); if ($flush) { $this->getEntityManager()->flush(); } } public function remove(Report $entity, bool $flush = false): void { $this->getEntityManager()->remove($entity); if ($flush) { $this->getEntityManager()->flush(); } } public function getReportsQueryBuilder( ?UserInterface $manager = null, ?FormInterface $filters = null, $type = ReportType::WRECK, array $agenciesId = [] ): QueryBuilder { $qb = $this->createQueryBuilder('r') ->leftJoin('r.agent', 'a') ->innerJoin('a.solutions', 's'); if ($manager) { $qb->andWhere('r.manager = :manager') ->setParameter('manager', $manager); } $qb->andWhere('r.type = :type') ->setParameter('type', $type); $qb->andWhere('s = :solution') ->setParameter('solution', $this->solution->getCurrent()) ->orderBy('r.createdAt', 'desc'); $this->filterReports($qb, $filters); if (!empty($agenciesId)) { $qb->andWhere('a.agency IN ('.implode(',', $agenciesId).')'); } return $qb; } public function getReportsForCart(?UserInterface $user): array { $qb = $this->createQueryBuilder('r') ->leftJoin('r.agent', 'a'); if (in_array('ROLE_MANAGER', $user->getRoles())) { $qb->andWhere('r.manager = :manager') ->setParameter('manager', $user); } if (in_array('ROLE_SUPERVISOR', $user->getRoles())) { $qb->andWhere('a.agency = :agency') ->setParameter('agency', $user->getAgency()); } $qb->andWhere('r.status != :status') ->setParameter('status', ReportStatusType::REPORT_STATUS_CLOSED) ->orderBy('r.createdAt', 'desc'); return $qb->getQuery()->getResult(); } public function getReportsForChart(?UserInterface $user, ?ReportType $reportType): array { $qb = $this->createQueryBuilder('r') ->select('ri.id, count(ri.id) as number, ri.label') ->leftJoin('r.agent', 'a') ->leftJoin('r.reportItem', 'ri'); if (in_array('ROLE_MANAGER', $user->getRoles())) { $qb->andWhere('r.manager = :manager') ->setParameter('manager', $user); } if (in_array('ROLE_SUPERVISOR', $user->getRoles())) { $qb->andWhere('a.agency = :agency') ->setParameter('agency', $user->getAgency()); } if (null !== $reportType) { $qb->andWhere('r.type = :reportType') ->setParameter('reportType', $reportType); } $qb->groupBy('ri.id'); return $qb->getQuery()->getResult(); } public function countByMonth( ReportType $reportType, ?FormInterface $filter = null, bool $previous = false, ?ReportItem $parent = null, ?User $manager = null, ?User $supervisor = null ): array { $qb = $this->createQueryBuilder('r') ->select('COUNT(r.id) as cnt') ->addSelect('DATE_FORMAT(r.createdAt, \'%Y-%m\') as month') ->andWhere('r.type = :type') ->setParameter('type', $reportType) ->groupBy('month'); if (null !== $filter) { $this->filterReports($qb, $filter, $previous); } if (null !== $manager) { $qb ->andWhere('r.manager = :manager') ->setParameter('manager', $manager); } if (null !== $supervisor) { $qb->andWhere('r.manager IN (:managers)') ->setParameter('managers', $supervisor->getAgency()->getManagers()); } if (null !== $parent) { $qb->leftJoin('r.reportItem', 'ri') ->andWhere($qb->expr()->orX('ri.parent = :parent', 'ri = :parent')) ->setParameter('parent', $parent); } $utils = new Utils(); $results = $qb->getQuery()->getResult(); $timeline = $utils->getMonthsTimeline( startDate: $this->sessionFiltersContainer->getCurrent()->getDateRange()->getDateStart(), endDate: $this->sessionFiltersContainer->getCurrent()->getDateRange()->getDateEnd(), format: 'Y-MM' ); $data = []; foreach ($timeline as $monthKey => $month) { $cnt = array_reduce( $results, fn (int $carry, $result) => $result['month'] === $monthKey ? $result['cnt'] : $carry, 0 ); $data[$monthKey] = $cnt; } return $data; } public function countByMonthByAgencies( ReportType $reportType, ?FormInterface $filter = null, array $agenciesId = [], bool $previous = false, ?ReportItem $parent = null ): array { $qb = $this->createQueryBuilder('r') ->select('COUNT(r.id) as cnt') ->addSelect('DATE_FORMAT(r.createdAt, \'%Y-%m\') as month') ->leftJoin('r.agent', 'a') ->andWhere('r.type = :type') ->setParameter('type', $reportType) ->groupBy('month'); if (null !== $filter) { $this->filterReports($qb, $filter, $previous); } if (!empty($agenciesId)) { $qb->andWhere('a.agency IN ('.implode(',', $agenciesId).')'); } if (null !== $parent) { $qb->leftJoin('r.reportItem', 'ri') ->andWhere($qb->expr()->orX('ri.parent = :parent', 'ri = :parent')) ->setParameter('parent', $parent); } $utils = new Utils(); $results = $qb->getQuery()->getResult(); $timeline = $utils->getMonthsTimeline( startDate: $this->sessionFiltersContainer->getCurrent()->getDateRange()->getDateStart(), endDate: $this->sessionFiltersContainer->getCurrent()->getDateRange()->getDateEnd(), format: 'Y-MM' ); $data = []; foreach ($timeline as $monthKey => $month) { $cnt = array_reduce( $results, fn (int $carry, $result) => $result['month'] === $monthKey ? $result['cnt'] : $carry, 0 ); $data[$monthKey] = $cnt; } return $data; } public function filterReports(QueryBuilder $qb, ?FormInterface $filters, bool $previous = false): void { $sessionFilters = $this->sessionFiltersContainer->getCurrent(); if ($sessionFilters->getDateRange()) { $from = clone $sessionFilters->getDateRange()->getDateStart(); $to = clone $sessionFilters->getDateRange()->getDateEnd(); $to->add(new \DateInterval('P1D')); $qb->andWhere( $qb->expr()->between('r.createdAt', ':from', ':to') ) ->setParameter('from', $from) ->setParameter('to', $to); } // Apply session filters (from header filter form) if ($sessionFilters instanceof SupervisorSessionFilters) { $this->applySessionFilters($qb, $sessionFilters); } if ($filters && $filters->getData()) { $data = $filters->getData(); if ($data['location']) { $qb->andWhere('r.location LIKE :location') ->setParameter('location', '%'.$data['location'].'%'); } if ($data['agent']) { $qb->andWhere('r.agent = :filterAgent') ->setParameter('filterAgent', $data['agent']); } if ($data['reportItem']) { $qb->andWhere('r.reportItem = :reportItem') ->setParameter('reportItem', $data['reportItem']); } if (isset($data['status'])) { $qb->andWhere('r.status = :status') ->setParameter('status', $data['status']); } } } private function applySessionFilters(QueryBuilder $qb, SupervisorSessionFilters $sessionFilters): void { // Filter by agent from session if (null !== $sessionFilters->getAgent()) { $qb->andWhere('r.agent = :sessionAgent') ->setParameter('sessionAgent', $sessionFilters->getAgent()); } // Filter by sector (manager of the agent) if (null !== $sessionFilters->getSector()) { // Ensure 'a' alias exists for agent $aliases = $qb->getAllAliases(); if (!in_array('a', $aliases)) { $qb->leftJoin('r.agent', 'a'); } $qb->andWhere('a.manager = :sector') ->setParameter('sector', $sessionFilters->getSector()); } // Filter by city (search in location text) if (null !== $sessionFilters->getCity()) { $qb->andWhere('r.location LIKE :sessionCity') ->setParameter('sessionCity', '%'.$sessionFilters->getCity().'%'); } // Filter by provider - find reports from agents who work on addresses with this provider if (null !== $sessionFilters->getProvider()) { $aliases = $qb->getAllAliases(); if (!in_array('a', $aliases)) { $qb->leftJoin('r.agent', 'a'); } $qb->leftJoin('a.userAddresses', 'ua') ->leftJoin('ua.address', 'addr') ->leftJoin('addr.prestataires', 'p') ->andWhere('p.id = :providerId') ->setParameter('providerId', $sessionFilters->getProvider()->getId()); } // Filter by address - find reports from agents assigned to this address if (null !== $sessionFilters->getAddress()) { $aliases = $qb->getAllAliases(); if (!in_array('a', $aliases)) { $qb->leftJoin('r.agent', 'a'); } if (!in_array('ua', $aliases)) { $qb->leftJoin('a.userAddresses', 'ua'); } $qb->andWhere('ua.address = :sessionAddress') ->setParameter('sessionAddress', $sessionFilters->getAddress()); } } }
Save File
Cancel