<?php
namespace App\Repository\Booking;
use App\Controller\__Sale\ProspectRequestController;
use App\DBAL\Types\Booking\BookingStep;
use App\Entity\__Contact\contact\Contact;
use App\Entity\Booking\ProspectRequest;
use App\Entity\Contact\Prospect;
use App\Entity\ParameterCodes;
use App\Entity\User\User;
use App\Migration\Entity\CsvProspectRequest;
use App\Repository\User\UserRepository;
use App\Voter\ProspectRequestVoter;
use Crea\ParameterBundle\Entity\Parameter;
use Crea\SecurityBundle\Helper\AccessHelper;
use Crea\SecurityBundle\Model\Access;
use DateTime;
use DateTimeInterface;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\ORM\NonUniqueResultException;
use Doctrine\ORM\NoResultException;
use Doctrine\ORM\QueryBuilder;
use Doctrine\Persistence\ManagerRegistry;
use Exception;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Security\Core\Security;
/**
* @method ProspectRequest|null find($id, $lockMode = null, $lockVersion = null)
* @method ProspectRequest|null findOneBy(array $criteria, array $orderBy = null)
* @method ProspectRequest[] findAll()
* @method ProspectRequest[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class ProspectRequestRepository extends ServiceEntityRepository
{
const USER_GROUP_CODE_BY_PROSPECT_REQUEST_TYPE = [
ParameterCodes::PROSPECT_REQUEST_TYPE_CONTACT => UserRepository::MARKETING_USER_GROUP_CODE,
ParameterCodes::PROSPECT_REQUEST_TYPE_QUOTE_REQUEST => UserRepository::SELLER_USER_GROUP_CODE,
ParameterCodes::PROSPECT_REQUEST_TYPE_CONTACT_ADV => UserRepository::BACK_OFFICE_USER_GROUP_CODE
];
const USER_GROUP_CODE_BY_PROSPECT_REQUEST_TYPE_DEFAULT = UserRepository::SELLER_USER_GROUP_CODE;
const NUMBER_OF_REMINDERS_BEFORE_PERMANENT_MUTED = 1;
const STATE_CONFIRMED = 'confirmed';
const STATE_CANCELLED = 'cancelled';
const ANOMALY = 'anomaly';
const CONTACT_TYPE_CLIENT = 'CONTACT_TYPE_CLIENT';
const CONTACT_TYPE_PROSPECT = 'CONTACT_TYPE_PROSPECT';
const CONTACT_TYPE_NEW_CONTACT = 'CONTACT_TYPE_NEW_CONTACT';
protected Security $security;
protected AccessHelper $accessHelper;
protected RequestStack $requestStack;
public function __construct(ManagerRegistry $registry,
Security $security,
AccessHelper $accessHelper,
RequestStack $requestStack)
{
parent::__construct($registry, ProspectRequest::class);
$this->security = $security;
$this->accessHelper = $accessHelper;
$this->requestStack = $requestStack;
}
private function getUnassignedRequestsQueryBuilder(string $select): QueryBuilder
{
$qb1 = $this->createQueryBuilder('pr1');
$qb1 = $qb1
->select($select)
->join('pr1.status', 'st1')
->andWhere('pr1.assignedUser IS NULL')
->andWhere('st1.code = :newStateTypeId')
->setParameter('newStateTypeId', ParameterCodes::PROSPECT_REQUEST_STATUS_NOT_ASSIGNED);
return $qb1;
}
public function getUnassignedRequestsQuery(): QueryBuilder
{
return $this->getUnassignedRequestsQueryBuilder('pr1');
}
private function getRequestsByTypeToAssignBaseQuery(string $typeCode, QueryBuilder $qb, string $pre = ''):QueryBuilder
{
$qb = $qb
->join( $pre.'pr.type', $pre.'prt')
->join( $pre.'pr.status', $pre.'prst')
->where($qb->expr()->eq($pre.'prt.code', ':code'))
->andWhere($qb->expr()->in($pre.'prst.code', ':statusCodes'))
->andWhere($qb->expr()->isNull($pre.'pr.assignedUser'))
->andWhere($qb->expr()->eq($pre.'pr.isActive', ':isActive'))
->andWhere($qb->expr()->eq($pre.'pr.isQuoteSent', ':isQuoteSent'))
->setParameter('code', $typeCode)
->setParameter('statusCodes', [
ParameterCodes::PROSPECT_REQUEST_STATUS_NOT_ASSIGNED
])
->setParameter('isActive', true)
->setParameter('isQuoteSent', false);
return $qb;
}
private function getRequestsByTypeBaseQuery(string $typeCode, QueryBuilder $qb, string $pre = ''):QueryBuilder
{
$qb = $qb
->join( $pre.'pr.type', $pre.'prt')
->where($qb->expr()->eq($pre.'prt.code', ':code'))
->andWhere($qb->expr()->eq($pre.'pr.isActive', ':isActive'))
->setParameter('code', $typeCode)
->setParameter('isActive', true);
if (null !== $state = $this->requestStack->getCurrentRequest()->query->get('state')) {
if ($state === self::STATE_CONFIRMED) {
$qb = $qb
->innerJoin( $pre.'pr.quotes', $pre.'prq')
->innerJoin( $pre.'prq.booking', $pre.'prb');
}
elseif ($state === self::STATE_CANCELLED) {
$qb = $qb
->leftJoin( $pre.'pr.quotes', $pre.'prq')
->leftJoin( $pre.'prq.booking', $pre.'prb')
->andWhere($qb->expr()->andX(
$qb->expr()->isNull($pre.'prb.id'),
$qb->expr()->lt($pre.'prq.quoteValidityAt', ':now')
))
->setParameter('now', new DateTime())
;
}
}
return $qb;
}
public function getRequestsByTypeToAssignQuery(string $typeCode, bool $groupByProject = false): QueryBuilder
{
$qb = $this->createQueryBuilder('pr');
$qb = $this->getRequestsByTypeToAssignBaseQuery($typeCode, $qb);
if ($groupByProject) {
$pre = 'sub_';
$qb2 = $this->createQueryBuilder($pre.'pr')
->select($pre.'pr.id');
$qb2 = $this->getRequestsByTypeToAssignBaseQuery($typeCode, $qb2, $pre)
->join( $pre.'pr.prospectProject', $pre.'prp')
->groupBy($pre.'prp.id');
$ids = array_map(function ($line) {
return $line['id'];
}, $qb2->getQuery()->getArrayResult());
if (count($ids) > 0) {
$qb->andWhere($qb->expr()->in('pr.id', $ids));
}
}
return $qb;
}
public function getRequestsByTypeQuery(string $typeCode, bool $groupByProject = false, $assigned = false): QueryBuilder
{
$qb = $this->createQueryBuilder('pr');
$qb = $this->getRequestsByTypeBaseQuery($typeCode, $qb);
if ($assigned) {
$qb = $qb->innerJoin( 'pr.assignedUser', 'u');
}
if ($typeCode === ParameterCodes::PROSPECT_REQUEST_TYPE_CONTACT) {
$hasAccess = $this->accessHelper->hasAccess(new Access([ProspectRequestVoter::SHOW_CONTACT_REQUESTS_FROM_ALL_USERS]));
}
elseif ($typeCode === ParameterCodes::PROSPECT_REQUEST_TYPE_CONTACT_ADV) {
$hasAccess = $this->accessHelper->hasAccess(new Access([ProspectRequestVoter::SHOW_ADV_CONTACT_REQUESTS_FROM_ALL_USERS]));
}
else {
$hasAccess = $this->accessHelper->hasAccess(new Access([ProspectRequestVoter::SHOW_QUOTE_REQUESTS_FROM_ALL_USERS]));
}
if (!$hasAccess) {
/** @var User $user */
$user = $this->security->getUser();
$qb = $qb
->join('pr.assignedUser', 'u')
->andWhere($qb->expr()->eq('u.id', $user->getId()));
}
if ($groupByProject) {
$pre = 'sub_';
$qb2 = $this->createQueryBuilder($pre.'pr')
->select($pre.'pr.id');
$qb2 = $this->getRequestsByTypeBaseQuery($typeCode, $qb2, $pre)
->join( $pre.'pr.prospectProject', $pre.'prp')
->groupBy($pre.'prp.id');
if ($assigned) {
$qb2 = $qb2->innerJoin( $pre.'pr.assignedUser', $pre.'u');
}
if (!$hasAccess) {
/** @var User $user */
$user = $this->security->getUser();
$qb2 = $qb2
->join($pre.'pr.assignedUser', $pre.'u')
->andWhere($qb2->expr()->eq($pre.'u.id', $user->getId()));
}
$ids = array_map(function ($line) {
return $line['id'];
}, $qb2->getQuery()->getArrayResult());
if (count($ids) > 0) {
$qb->andWhere($qb->expr()->in('pr.id', $ids));
}
}
return $qb;
}
public function getRequestsByTypeQuoteQuery(): QueryBuilder
{
return $this->getRequestsByTypeQuery(ParameterCodes::PROSPECT_REQUEST_TYPE_QUOTE_REQUEST, false, true);
}
public function getDtBaseQuery(QueryBuilder $qb, string $origin, string $typeCode, string $pre = ''): QueryBuilder
{
$qb = $qb
->join( $pre.'pr.type', $pre.'prt')
->leftJoin($pre.'pr.status', $pre.'st')
->leftJoin($pre.'pr.statusReason', $pre.'str')
->leftJoin($pre.'pr.prospectRequestOrigin', $pre.'pro')
->leftJoin($pre.'pr.contactProspect', $pre.'cp')
->leftJoin($pre.'cp.contact', $pre.'c')
->leftJoin($pre.'c.type', $pre.'cot')
->leftJoin($pre.'cp.prospect', $pre.'pros')
->leftJoin($pre.'pr.prospectProject', $pre.'pp')
->leftJoin($pre.'pr.cruiseHistory', $pre.'ch')
->leftJoin($pre.'ch.ship', $pre.'s')
->leftJoin($pre.'s.company', $pre.'com')
->leftJoin($pre.'ch.itineraryHistory', $pre.'ih')
->leftJoin($pre.'ih.destination', $pre.'d')
->leftJoin($pre.'pr.cabinCategoryHistory', $pre.'cch')
->leftJoin($pre.'cch.type', $pre.'cct')
->leftJoin($pre.'cct.cabinType', $pre.'ct')
->leftJoin($pre.'pr.partner', $pre.'p')
->leftJoin($pre.'c.partnerByContacts', $pre.'pbc')
->leftJoin($pre.'pbc.partner', $pre.'p2')
->where($qb->expr()->eq($pre.'prt.code', ':typeCode'))
->andWhere($qb->expr()->eq($pre.'pr.isActive', ':isActive'))
->andWhere($qb->expr()->eq($pre.'pr.removed', ':removed'))
->setParameter('typeCode', $typeCode)
->setParameter('isActive', true)
->setParameter('removed', false);
if ($origin === ProspectRequestController::ORIGIN_TO_ASSIGN && $typeCode === ParameterCodes::PROSPECT_REQUEST_TYPE_QUOTE_REQUEST) {
$qb = $qb
->andWhere($qb->expr()->in($pre.'st.code', ':statusCodes'))
->andWhere($qb->expr()->isNull($pre.'pr.assignedUser'))
->andWhere($qb->expr()->eq($pre.'pr.isQuoteSent', ':isQuoteSent'))
->setParameter('statusCodes', [
ParameterCodes::PROSPECT_REQUEST_STATUS_NOT_ASSIGNED
])
->setParameter('isQuoteSent', false);
}
return $qb;
}
public function getDtQuery(QueryBuilder $qb, string $origin, string $type, ?int $projectId = null): QueryBuilder
{
if ($type === ProspectRequestController::TYPE_CONTACT) {
$typeCode = ParameterCodes::PROSPECT_REQUEST_TYPE_CONTACT;
$hasAccess = $this->accessHelper->hasAccess(new Access([ProspectRequestVoter::SHOW_CONTACT_REQUESTS_FROM_ALL_USERS]));
}
elseif ($type === ProspectRequestController::TYPE_ADV) {
$typeCode = ParameterCodes::PROSPECT_REQUEST_TYPE_CONTACT_ADV;
$hasAccess = $this->accessHelper->hasAccess(new Access([ProspectRequestVoter::SHOW_ADV_CONTACT_REQUESTS_FROM_ALL_USERS]));
}
else {
$typeCode = ParameterCodes::PROSPECT_REQUEST_TYPE_QUOTE_REQUEST;
$hasAccess = $this->accessHelper->hasAccess(new Access([ProspectRequestVoter::SHOW_QUOTE_REQUESTS_FROM_ALL_USERS]));
}
if ($origin === ProspectRequestController::ORIGIN_TO_ASSIGN) {
$assigned = false;
}
else {
$assigned = true;
}
$qb = $this->getDtBaseQuery($qb, $origin, $typeCode);
if ($origin === ProspectRequestController::ORIGIN_TO_ASSIGN && $projectId === null) {
$pre = 'sub_';
$qb2 = $this->createQueryBuilder($pre.'pr')
->select($pre.'pr.id');
$qb2 = $this->getDtBaseQuery($qb2, $origin, $typeCode, $pre)
->join( $pre.'pr.prospectProject', $pre.'prp')
->groupBy($pre.'prp.id');
$ids = array_map(function ($line) {
return $line['id'];
}, $qb2->getQuery()->getArrayResult());
if (count($ids) > 0) {
$qb->andWhere($qb->expr()->in('pr.id', $ids));
}
}
elseif ($projectId !== null) {
$qb = $qb->innerJoin( 'pr.prospectProject', 'prp')
->andWhere($qb->expr()->eq('prp.id', $projectId));
}
if ($assigned) {
$qb = $qb
->leftJoin( 'pr.assignedUser', 'au')
->andWhere($qb->expr()->orX(
$qb->expr()->isNotNull('au.id'),
$qb->expr()->eq('st.code', ':stCode')
))
->setParameter('stCode', ParameterCodes::PROSPECT_REQUEST_STATUS_DONT_PROCESS);
}
else {
$qb = $qb->andWhere($qb->expr()->isNull('pr.assignedUser'));
}
if (!$hasAccess) {
/** @var User $user */
$user = $this->security->getUser();
$qb = $qb
->join('pr.assignedUser', 'u')
->andWhere($qb->expr()->eq('u.id', $user->getId()));
}
return $qb;
}
public function getRequestsByTypeContactQuery(bool $groupByProject = true, bool $assigned = true): QueryBuilder
{
return $this->getRequestsByTypeQuery(ParameterCodes::PROSPECT_REQUEST_TYPE_CONTACT, $groupByProject, $assigned);
}
public function getRequestsByTypeContactAdvQuery(bool $groupByProject = true): QueryBuilder
{
return $this->getRequestsByTypeQuery(ParameterCodes::PROSPECT_REQUEST_TYPE_CONTACT_ADV, $groupByProject);
}
public function getRequestsByTypeQuoteToAssignQuery(bool $groupByProject = true): QueryBuilder
{
return $this->getRequestsByTypeToAssignQuery(ParameterCodes::PROSPECT_REQUEST_TYPE_QUOTE_REQUEST, $groupByProject);
}
public function getRequestsByTypeContactToAssignQuery(bool $groupByProject = true): QueryBuilder
{
return $this->getRequestsByTypeToAssignQuery(ParameterCodes::PROSPECT_REQUEST_TYPE_CONTACT, $groupByProject);
}
public function getRequestsByTypeContactAdvToAssignQuery(): QueryBuilder
{
return $this->getRequestsByTypeToAssignQuery(ParameterCodes::PROSPECT_REQUEST_TYPE_CONTACT_ADV);
}
/**
* @param array $originCodes
* @param bool $groupByProject
* @return array|ProspectRequest[]
*/
public function getRequestsByTypeQuoteToAssign(array $originCodes = [], bool $groupByProject = true): array
{
$qb = $this->getRequestsByTypeQuoteToAssignQuery($groupByProject);
if (count($originCodes) > 0) {
$qb = $qb->join('pr.prospectRequestOrigin', 'pro')
->andWhere($qb->expr()->in('pro.code', ':originCodes'))
->setParameter('originCodes', $originCodes);
}
return $qb
->getQuery()
->getResult();
}
/**
* @param array $originCodes
* @param bool $groupByProject
* @return array|ProspectRequest[]
*/
public function getRequestsByTypeContactToAssign(array $originCodes = [], bool $groupByProject = true): array
{
$qb = $this->getRequestsByTypeContactToAssignQuery($groupByProject);
if (count($originCodes) > 0) {
$qb = $qb->join('pr.prospectRequestOrigin', 'pro')
->andWhere($qb->expr()->in('pro.code', ':originCodes'))
->setParameter('originCodes', $originCodes);
}
return $qb
->getQuery()
->getResult();
}
/**
* @param int $projectId
* @param $unassigned
* @param $prospectRequestTypeCode
* @return array|ProspectRequest[]
*/
public function getProjectRequests(int $projectId, $unassigned = true, $prospectRequestTypeCode = null): array
{
$qb = $this->getProjectRequestQueryBuilder($projectId, $unassigned, $prospectRequestTypeCode);
return $qb->getQuery()->getResult();
}
public function countProjectRequests(int $projectId, $unassigned = true, $prospectRequestTypeCode = null): int
{
try {
$qb = $this->getProjectRequestQueryBuilder($projectId, $unassigned, $prospectRequestTypeCode)->select('count(pr.id)');
return $qb->getQuery()->getSingleScalarResult();
}
catch (NonUniqueResultException|NoResultException $e) {
return 0;
}
}
/**
* @param Contact|Prospect $contactOrProspect
*
* @return ProspectRequest[]
*/
public function findContactOrProspectRequestsByDate($contactOrProspect, DateTimeInterface $date, Parameter $type): array
{
$queryBuilder = $this->createQueryBuilder('pr')
->join('pr.type', 'pt')
->join('pr.contactProspect', 'cp')
->andWhere('DATE_FORMAT(pr.createdAt, \'%Y-%m-%d\') = :date')
->setParameter('date', $date->format('Y-m-d'));
$queryBuilder = $queryBuilder
->andWhere($queryBuilder->expr()->eq('pt.id', ':type'))
->setParameter('type', $type->getId());
if ($contactOrProspect instanceof Contact) {
$queryBuilder
->andWhere('cp.contact = :contact')
->setParameter('contact', $contactOrProspect);
} else {
$queryBuilder
->andWhere('cp.prospect = :prospect')
->setParameter('prospect', $contactOrProspect);
}
return $queryBuilder
->getQuery()
->getResult();
}
public function findByDates(DateTime $startingDate, DateTime $endingDate): array
{
return $this->createQueryBuilder('pr')
->andWhere('pr.appointmentDate >= :startingDate')
->andWhere('pr.appointmentDate <= :endingDate')
->setParameter('startingDate', $startingDate->format('Y-m-d'))
->setParameter('endingDate', $endingDate->format('Y-m-d'))
->getQuery()
->getResult();
}
public function findBySellerAndDates(User $seller, DateTime $startingDate, DateTime $endingDate): array
{
return $this->createQueryBuilder('pr')
->join('pr.assignedUser', 's')
->where('s = :seller')
->andWhere('pr.appointmentDate >= :startingDate')
->andWhere('pr.appointmentDate <= :endingDate')
->setParameter('seller', $seller)
->setParameter('startingDate', $startingDate->format('Y-m-d'))
->setParameter('endingDate', $endingDate->format('Y-m-d'))
->getQuery()
->getResult();
}
/**
* Récupère les demandes de devis d'un contact.
*
* @return ProspectRequest[]
*/
public function findQuoteRequests(Contact $contact): array
{
return $this->createQueryBuilder('pr')
->innerJoin('pr.type', 'prt')
->innerJoin('pr.contactProspect', 'cp')
->where('cp.contact = :contact')
->andWhere('prt.code = :quoteRequest')
->setParameters([
'contact' => $contact,
'quoteRequest' => ParameterCodes::PROSPECT_REQUEST_TYPE_QUOTE_REQUEST,
])
->getQuery()
->getResult()
;
}
/**
* @return ProspectRequest[]
*/
public function findToProcessedBySeller(User $seller, array $originCodes = []): array
{
$qb = $this->createQueryBuilder('pr');
$qb = $qb
->join('pr.assignedUser', 's')
->join('pr.status', 'st')
->andWhere($qb->expr()->eq('s.id', ':sellerId'))
->andWhere($qb->expr()->in('st.code', ':statusCodes'))
->andWhere($qb->expr()->eq('pr.isActive', ':isActive'))
->setParameter('sellerId', $seller->getId())
->setParameter('isActive', true)
->setParameter('statusCodes', [
ParameterCodes::PROSPECT_REQUEST_STATUS_MUTED,
ParameterCodes::PROSPECT_REQUEST_STATUS_ATTRIBUTED_AND_NOT_PROCESSED
]);
if (count($originCodes) > 0) {
$qb = $qb
->join('pr.prospectRequestOrigin', 'pro')
->andWhere($qb->expr()->in('pro.code', ':originCodes'))
->setParameter('originCodes', $originCodes);
}
return $qb
->orderBy('pr.appointmentDate')
->getQuery()
->getResult();
}
/********************************* home-module *************************************/
public function countThisDateProspectRequest($type, $date, ?bool $assignedUser = null): int
{
$qb = $this->createQueryBuilder('pr')
->select('count(pr.id)')
->where('pr.createdAt > :date')
->andWhere('pr.type = :type');
if ($assignedUser !== null) {
$qb = $assignedUser === true ? $qb->andWhere('pr.assignedUser IS NOT NULL') : $qb->andWhere('pr.assignedUser IS NULL');
}
return $qb
->setParameter('date', $date)
->setParameter('type', $type)
->getQuery()
->getSingleScalarResult();
}
public function countBeforeThisDateProspectRequest($type, $date, ?bool $assignedUser = null): int
{
$qb = $this->createQueryBuilder('pr')
->select('count(pr.id)')
->where('pr.createdAt < :date')
->andWhere('pr.type = :type')
;
if ($assignedUser !== null) {
$qb = $assignedUser === true ? $qb->andWhere('pr.assignedUser IS NOT NULL') : $qb->andWhere('pr.assignedUser IS NULL');
}
return $qb
->setParameter('date', $date)
->setParameter('type', $type)
->getQuery()
->getSingleScalarResult()
;
}
public function countBetweenThisDateProspectRequest($type, $startDate, $endDate, ?bool $assignedUser = null): int
{
$qb = $this->createQueryBuilder('pr')
->select('count(pr.id)')
->where('pr.createdAt > :startDate')
->andWhere('pr.createdAt < :endDate')
->andWhere('pr.type = :type')
->setParameter('startDate', $startDate)
->setParameter('endDate', $endDate)
->setParameter('type', $type)
;
if ($assignedUser !== null) {
$qb = $assignedUser === true ? $qb->andWhere('pr.assignedUser IS NOT NULL') : $qb->andWhere('pr.assignedUser IS NULL');
}
return $qb
->getQuery()
->getSingleScalarResult()
;
}
public function countBetweenThisDateWithOrigin(string $originCode, ?\DateTimeInterface $startDate = null, ?\DateTimeInterface $endDate = null, ?bool $assignedUser = null, ?bool $processToQuote = null): int
{
$qb = $this->createQueryBuilder('pr')
->select('count(pr.id)')
->join('pr.prospectRequestOrigin', 'pro')
->where('pro.code = :originCode')
->setParameter('originCode', $originCode);
if ($assignedUser !== null) {
$qb = $assignedUser === true ? $qb->andWhere('pr.assignedUser IS NOT NULL') : $qb->andWhere('pr.assignedUser IS NULL');
}
if ($startDate !== null) {
$qb = $qb
->andWhere('pr.createdAt > :startDate')
->setParameter('startDate', $startDate);
}
if ($endDate !== null) {
$qb = $qb
->andWhere('pr.createdAt < :endDate')
->setParameter('endDate', $endDate);
}
if ($processToQuote !== null) {
if ($processToQuote === true) {
$qb->join('pr.quotes', 'q');
}
else {
$qb
->leftJoin('pr.quotes', 'q')
->andWhere($qb->expr()->isNull('q.id'));
}
}
return $qb
->getQuery()
->getSingleScalarResult();
}
/**
* @return ProspectRequest[]
*/
public function findQuoteRequestsMuted(): array
{
$qb = $this->createQueryBuilder('pr');
$result = $qb
->join('pr.prospectRequestOrigin', 'pro')
->join('pr.status', 'st')
->andWhere($qb->expr()->in('pro.code', ':codes'))
->andWhere($qb->expr()->eq('st.code', ':statusCode'))
->andWhere($qb->expr()->gte('pr.updatedAt', ':nowLess24'))
->andWhere($qb->expr()->gte('pr.createdAt', ':nowLess7days'))
->setParameter('codes', [
ParameterCodes::PROSPECT_REQUEST_ORIGIN_WEB,
ParameterCodes::PROSPECT_REQUEST_ORIGIN_OTHER
])
->setParameter('statusCode', ParameterCodes::PROSPECT_REQUEST_STATUS_MUTED)
->setParameter('nowLess24', (new DateTime())->modify('-24 hours'))
->setParameter('nowLess7days', (new DateTime())->modify('-7 days'))
;
return
$result
->getQuery()
->getResult()
;
}
public function findMutedWithReminderToDo(?User $seller = null): array
{
$qb = $this->createQueryBuilder('pr');
if ($seller !== null) {
$qb = $qb
->join('pr.assignedUser', 'u')
->andWhere($qb->expr()->eq('u.id', $seller->getId()));
}
return $qb
->join('pr.prospectRequestOrigin', 'pro')
->join('pr.status', 'st')
->innerJoin('pr.reminders', 'r')
->andWhere($qb->expr()->eq('st.code', ':statusCode'))
->andWhere($qb->expr()->lte('r.remindAt', ':now'))
->andWhere($qb->expr()->eq('r.muted', ':muted'))
->setParameter('now', new \DateTime())
->setParameter('muted', false)
->setParameter('statusCode', ParameterCodes::PROSPECT_REQUEST_STATUS_MUTED)
->getQuery()
->getResult()
;
}
public function findByOriginAndStateType(string $originCode, string $statusCode): array
{
$qb = $this->createQueryBuilder('pr');
return $qb
->join('pr.status', 'st')
->join('pr.assignedUser', 'u')
->join('pr.prospectRequestOrigin', 'pro')
->where($qb->expr()->eq('st.code', ':statusCode'))
->andWhere($qb->expr()->isNotNull('u.id'))
->andWhere($qb->expr()->eq('pro.code', ':originCode'))
->andWhere($qb->expr()->eq('pr.isActive', ':isActive'))
->setParameter('statusCode', $statusCode)
->setParameter('originCode', $originCode)
->setParameter('isActive', true)
->getQuery()
->getResult()
;
}
/**
* @param Contact $contact
* @param QueryBuilder|null $queryBuilder
* @return QueryBuilder
*/
private function getContactQuoteRequestsBaseQueryBuilder(Contact $contact, ?QueryBuilder $queryBuilder = null): QueryBuilder
{
if ($queryBuilder === null) {
$queryBuilder = $this->createQueryBuilder('pr');
}
else {
$queryBuilder = $queryBuilder->from(ProspectRequest::class, 'pr');
}
return $queryBuilder
->select('pr', 'pro')
->join('pr.prospectRequestOrigin', 'pro')
->join('pr.type', 'pt')
->join('pr.contactProspect', 'cp')
->join('cp.contact', 'c')
->leftJoin('pr.assignedUser', 's')
->leftJoin('pr.cruiseHistory', 'cr')
->leftJoin('pr.cabinCategoryHistory', 'cch')
->andWhere($queryBuilder->expr()->in('pt.code', ':codes'))
->andWhere($queryBuilder->expr()->eq('c.id', $contact->getId()))
->andWhere($queryBuilder->expr()->eq('pr.isActive', ':isActive'))
->setParameter('codes', [
ParameterCodes::PROSPECT_REQUEST_TYPE_QUOTE_REQUEST
])
->setParameter('isActive', true);
}
/**
* @param Contact $contact
* @param QueryBuilder|null $queryBuilder
* @return QueryBuilder
*/
public function getContactQuoteRequestsInProgressQueryBuilder(Contact $contact, ?QueryBuilder $queryBuilder = null): QueryBuilder
{
$queryBuilder = $this->getContactQuoteRequestsBaseQueryBuilder($contact, $queryBuilder);
return $queryBuilder->andWhere($queryBuilder->expr()->eq('pr.isQuoteSent', 0));
}
/**
* @param Contact $contact
* @param QueryBuilder|null $queryBuilder
* @return QueryBuilder
*/
public function getContactPastQuoteRequestsQueryBuilder(Contact $contact, ?QueryBuilder $queryBuilder = null): QueryBuilder
{
$queryBuilder = $this->getContactQuoteRequestsBaseQueryBuilder($contact, $queryBuilder);
return $queryBuilder->andWhere($queryBuilder->expr()->eq('pr.isQuoteSent', 1));
}
/**
* Get the list of current quote requests for a contact
*
* @param Contact $contact
* @return array
*/
public function getContactQuoteRequestsInProgress(Contact $contact): array
{
return $this->getContactQuoteRequestsInProgressQueryBuilder($contact)
->getQuery()
->getResult();
}
/**
* Get the list of past quote requests for a contact
*
* @param Contact $contact
* @return array
*/
public function getContactPastQuoteRequests(Contact $contact): array
{
return $this->getContactPastQuoteRequestsQueryBuilder($contact)
->getQuery()
->getResult();
}
/**
* Get the list of all quote requests for a contact
*
* @param Contact $contact
* @return array
*/
public function getContactAllQuoteRequests(Contact $contact): array
{
return $this->getContactQuoteRequestsBaseQueryBuilder($contact)
->getQuery()
->getResult();
}
/**
* @return array|ProspectRequest[]
*/
public function findProspectRequestWithAnomalies(): array
{
$qb = $this->createQueryBuilder('pr');
return $qb
->join('pr.status', 'prst')
->leftJoin('pr.statusReason', 'prr')
->where($qb->expr()->eq('prst.code', ':statusCode'))
->andWhere($qb->expr()->isNull('prr.id'))
->andWhere($qb->expr()->isNotNull('pr.statusChangeLastDate'))
->andWhere($qb->expr()->lt('pr.statusChangeLastDate', ':statusChangeLastDate'))
->setParameter('statusCode', ParameterCodes::PROSPECT_REQUEST_STATUS_WITH_DIALOG_WITHOUT_QUOTE)
->setParameter('statusChangeLastDate', (new DateTime())->modify('-7 days'))
->getQuery()
->getResult();
}
/**
* @return array|ProspectRequest[]
*/
public function findProspectRequestFromStatus(string $statusCode): array
{
$qb = $this->createQueryBuilder('pr');
return $qb
->join('pr.status', 'prst')
->where($qb->expr()->eq('prst.code', ':statusCode'))
->setParameter('statusCode', $statusCode)
->getQuery()
->getResult();
}
/**
* @return array|ProspectRequest[]
*/
public function findActiveProspectRequestsFromUser(User $user): array
{
$qb = $this->createQueryBuilder('pr');
return $qb
->join('pr.assignedUser', 'au')
->join('pr.status', 'prst')
->where($qb->expr()->eq('au.id', $user->getId()))
->andWhere($qb->expr()->eq('prst.code', ':statusCode'))
->setParameter('statusCode', ParameterCodes::PROSPECT_REQUEST_STATUS_ATTRIBUTED_AND_NOT_PROCESSED)
->getQuery()
->getResult();
}
}