Skip to content

Commit

Permalink
improve DQL in sales provider
Browse files Browse the repository at this point in the history
  • Loading branch information
AdamKasp committed May 13, 2020
1 parent f7d3b44 commit 6fce97d
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 24 deletions.
15 changes: 15 additions & 0 deletions UPGRADE-1.7.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,18 @@ We've moved the following templates:
Until now shipping address used to be the default address of an Order. We have changed that, so now the billing address
became the default address during checkout. It is an important change in our checkout process, please have that in mind.
## Postgres support
In case when you are using Postgres in your project, function `DATE_FORMAT` should be overridden.
Adjust configuration in `config/packages/doctrine.yaml` to change `DATE_FORMAT` implementation:
```yaml
doctrine:
orm:
entity_managers:
default:
dql:
string_functions:
DATE_FORMAT: App\Doctrine\DQL\DateFormat # OR any other path to your implementation
```
43 changes: 43 additions & 0 deletions src/Sylius/Bundle/CoreBundle/Doctrine/DQL/DateFormat.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Sylius\Bundle\CoreBundle\Doctrine\DQL;

use Doctrine\ORM\Query\AST\ArithmeticExpression;
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
use Doctrine\ORM\Query\Lexer;
use Doctrine\ORM\Query\Parser;
use Doctrine\ORM\Query\SqlWalker;

final class DateFormat extends FunctionNode
{
/** @var ArithmeticExpression|null */
public $date = null;
/** @var ArithmeticExpression|null */
public $pattern = null;

public function parse(Parser $parser)
{
$parser->match(Lexer::T_IDENTIFIER);
$parser->match(Lexer::T_OPEN_PARENTHESIS);
$this->date = $parser->ArithmeticExpression();
$parser->match(Lexer::T_COMMA);
$this->pattern = $parser->StringPrimary();
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
}

public function getSql(SqlWalker $sqlWalker)
{
return sprintf('DATE_FORMAT(%s, %s)', $this->date->dispatch($sqlWalker), $this->pattern->dispatch($sqlWalker));
}
}
4 changes: 3 additions & 1 deletion src/Sylius/Bundle/CoreBundle/Resources/config/app/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ doctrine:
entity_managers:
default:
auto_mapping: true

dql:
string_functions:
DATE_FORMAT: Sylius\Bundle\CoreBundle\Doctrine\DQL\DateFormat
knp_gaufrette:
adapters:
sylius_image:
Expand Down
38 changes: 15 additions & 23 deletions src/Sylius/Component/Core/Dashboard/SalesDataProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
namespace Sylius\Component\Core\Dashboard;

use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Sylius\Component\Core\Model\ChannelInterface;
use Sylius\Component\Core\OrderPaymentStates;
use Sylius\Component\Core\Repository\OrderRepositoryInterface;

/**
Expand All @@ -25,7 +27,7 @@ final class SalesDataProvider implements SalesDataProviderInterface
/** @var EntityManagerInterface */
private $entityManager;

/** @var OrderRepositoryInterface */
/** @var OrderRepositoryInterface|EntityRepository */
private $orderRepository;

public function __construct(EntityManagerInterface $entityManager, OrderRepositoryInterface $orderRepository)
Expand All @@ -41,15 +43,21 @@ public function getLastYearSalesSummary(ChannelInterface $channel): SalesSummary
$endDate = (new \DateTime('last day of this month'));
$endDate->setTime(23, 59, 59);

$qb = $this->orderRepository->createQueryBuilder('so');
$qb->select($this->getSelectStatement())
->where($qb->expr()->eq('so.channel', ':channel'))
->andWhere('so.checkoutCompletedAt BETWEEN :startDate AND :endDate')
/** @psalm-suppress PossiblyUndefinedMethod */
$queryBuilder = $this->orderRepository->createQueryBuilder('o')
->select("DATE_FORMAT(o.checkoutCompletedAt, '%m.%y') AS date")
->addSelect("SUM(o.total) as total")
->where('o.channel = :channel')
->andWhere('o.checkoutCompletedAt >= :startDate')
->andWhere('o.checkoutCompletedAt <= :endDate')
->andWhere('o.paymentState = :state')
->groupBy('date')
->setParameter('channel', $channel)
->setParameter('startDate', $startDate)
->setParameter('endDate', $endDate);
$result = $qb->getQuery()->getScalarResult();
->setParameter('endDate', $endDate)
->setParameter('state', OrderPaymentStates::STATE_PAID)
;
$result = $queryBuilder->getQuery()->getScalarResult();

$data = [];
foreach ($result as $item) {
Expand All @@ -62,20 +70,4 @@ public function getLastYearSalesSummary(ChannelInterface $channel): SalesSummary
$data
);
}

/**
* add DATE_FORMAT support for postgres by using
* DoctrineExtensions\Query\Postgresql\DateFormat in doctrine configuration
*
* @return string
*/
private function getSelectStatement()
{
$dateFormat = '%m.%y';
if ($this->entityManager->getConnection()->getDatabasePlatform()->getName() == 'postgresql') {
$dateFormat = 'mm.yyyy';
}

return "DATE_FORMAT(so.checkoutCompletedAt, '" . $dateFormat . "') AS date, SUM(so.total) as total";
}
}

0 comments on commit 6fce97d

Please sign in to comment.