<?php
namespace App\Repository\Partner;
use App\DBAL\Types\Partner\PartnerReminderType;
use App\Entity\__Contact\contact\Contact;
use App\Entity\Cruise\CabinCategory\CabinType;
use App\Entity\Cruise\Company\Company;
use App\Entity\ParameterCodes;
use App\Entity\Partner\Partner;
use Croisiland\CommonBundle\Repository\AbstractPartnerRepository;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Query\Expr\Join;
use Doctrine\ORM\QueryBuilder;
use Doctrine\Persistence\ManagerRegistry;
use Exception;
/**
* @method Partner|null find($id, $lockMode = null, $lockVersion = null)
* @method Partner|null findOneBy(array $criteria, array $orderBy = null)
* @method Partner[] findAll()
* @method Partner[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class PartnerRepository extends AbstractPartnerRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Partner::class);
}
public function findPartnersQueryBuilderByContactsAndCompanyAndCabinType(array $contacts, Company $company, CabinType $cabinType): QueryBuilder
{
$qb = $this->createQueryBuilder('p');
return $qb
->innerJoin('p.partnerByContacts', 'pbc', Join::WITH, $qb->expr()->andX(
$qb->expr()->eq('pbc.isActive', ':isPartnerByContactActive'),
$qb->expr()->in('pbc.contact', ':contacts')
))
->innerJoin('p.partnerCompanyDiscounts', 'pcd', Join::WITH, $qb->expr()->andX(
$qb->expr()->orX(
$qb->expr()->eq('pcd.cabinType', ':cabinType'),
$qb->expr()->isNull('pcd.cabinType')
),
$qb->expr()->eq('pcd.company', ':company')
))
->where($qb->expr()->eq('p.active', 1))
->setParameters([
'isPartnerByContactActive' => true,
'contacts' => $contacts,
'company' => $company,
'cabinType' => $cabinType,
])
->orderBy('p.name', 'ASC');
}
/**
* @return QueryBuilder Returns an array of Partner objects
*/
public function findPartnerActiveQb(): QueryBuilder
{
$qb = $this->createQueryBuilder('p');
return $qb
->andWhere($qb->expr()->eq('p.active', 1))
->orderBy('p.name', 'ASC');
}
/**
* @return Partner[] Returns an array of Partner objects
*/
public function findPartnerActive(): array
{
$qb = $this->createQueryBuilder('p');
return $qb
->andWhere($qb->expr()->eq('p.active', 1))
->orderBy('p.name', 'ASC')
->getQuery()
->getResult()
;
}
/**
* @return Partner[] Returns an array of Partner objects
*/
public function findIn(array $ids): array
{
$qb = $this->createQueryBuilder('p');
return $qb
->where($qb->expr()->in('p.id', ':ids'))
->setParameter('ids', $ids)
->getQuery()
->getResult()
;
}
public function findPartnersByContact(Contact $contact): array
{
$qb = $this->createQueryBuilder('p');
return $qb
->leftJoin('p.partnerByContacts', 'pbc')
->andWhere($qb->expr()->eq('p.active', 1))
->andWhere($qb->expr()->eq('pbc.isActive', ':isContactActive'))
->andWhere($qb->expr()->eq('pbc.contact', ':contact'))
->setParameter('isContactActive', 1)
->setParameter('contact', $contact)
->orderBy('p.name', 'ASC')
->getQuery()
->getResult()
;
}
/**
* Partners list for add partner contact link in contact page
*
* @param Contact $contact
* @return QueryBuilder
*/
public function findPartnersForPartnerContactSelectionList(Contact $contact): QueryBuilder
{
$qb = $this->createQueryBuilder('p');
return $qb
->leftJoin('p.partnerByContacts', 'pbc', Join::WITH, $qb->expr()->eq("pbc.contact", ":contact"))
->andWhere($qb->expr()->eq("p.active", 1))
->andWhere($qb->expr()->isNull('pbc'))
->groupBy('p.id')
->orderBy('p.name', 'ASC')
->setParameter('contact', $contact);
}
public function getFormQueryBuilder(): QueryBuilder
{
$qb = $this->createQueryBuilder('p');
return $qb
->addOrderBy('p.name', 'ASC');
}
/**
* @return array
*/
public function getDistinctYears(): array
{
$qb = $this->createQueryBuilder('p');
return $qb->select('DISTINCT YEAR(p.createdAt) as year')
->orderBy('year', 'DESC')
->getQuery()
->getResult();
}
/*********************************** Recap ************************************************************************/
/**
* @param QueryBuilder $bookingRecapFiltersQueryBuilder Voir fonction getRecapBaseQueryBuilderForFilters du BookingRepository
*/
public function getRecapBaseQueryBuilder(QueryBuilder $bookingRecapFiltersQueryBuilder): QueryBuilder
{
$bookingRecapFiltersQueryBuilder
->andWhere($bookingRecapFiltersQueryBuilder->expr()->eq('filter_bpt.id', 'bpt.id'))
;
return $this->createQueryBuilder('p')
->select('p.name as partner')
->leftJoin('p.bookingPartnerTurnovers', 'bpt')
->leftJoin('bpt.booking', 'b')
->where('b.id IN ('.$bookingRecapFiltersQueryBuilder->getQuery()->getDQL().')')
->groupBy('p.id')
->addOrderBy('p.name', 'ASC');
}
public function findAllToRemind(): array
{
$queryBuilder = $this->createQueryBuilder('p')
->where('p.reminder = :reminder')
->setParameter('reminder', PartnerReminderType::REMIND)
;
return $queryBuilder
->getQuery()
->getResult();
}
public function getFilterGridQueryBuilder(): QueryBuilder
{
$qb = $this->createQueryBuilder('p');
return $qb
->where($qb->expr()->eq('p.active', 1))
->orderBy('p.name', 'ASC');
}
/*********************************** Accounting *******************************************************************/
/**
* @throws Exception
*/
public function getAccountingPartnersQB(string $type, ?QueryBuilder $qb = null, string $partnerAlias = 'p'): QueryBuilder
{
switch ($type) {
case "allowance":
$field = 'allowancePercentage';
break;
case "participation":
$field = 'additionalRate';
break;
default:
throw new Exception('Invalid argument in "'.__METHOD__.'" method from '.get_class($this).'. "allowance" or "participation" have to be set in type parameter.');
}
if ($qb === null) {
$qb = $this->createQueryBuilder($partnerAlias);
}
return $qb
->distinct()
->innerJoin($partnerAlias.'.partnerCompanyDiscounts', 'pcd')
->andWhere($qb->expr()->isNotNull('pcd.'.$field))
->groupBy($partnerAlias.'.id');
}
/**
* @return array|Partner[]
* @throws Exception
*/
public function getAccountingPartners(string $type, string $partnerAlias = 'p'): array
{
return $this->getAccountingPartnersQB($type, null, $partnerAlias)
->orderBy($partnerAlias.'.name')
->getQuery()
->getResult();
}
}