214 lines
7.1 KiB
PHP
214 lines
7.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace KupShop\OrderingBundle\Feed;
|
|
|
|
use KupShop\AdminBundle\Util\Filter\OrdersFilterSpecs;
|
|
use KupShop\FeedGeneratorBundle\Feed\ConfigurableFeedTrait;
|
|
use KupShop\FeedGeneratorBundle\Feed\IConfigurableFeed;
|
|
use KupShop\FeedsBundle\Feed\IFeed;
|
|
use KupShop\KupShopBundle\Context\ContextManager;
|
|
use KupShop\OrderingBundle\Feed\Wrapper\OrderWrapper;
|
|
use KupShop\OrderingBundle\OrderList\OrderCollection;
|
|
use Query\Operator;
|
|
use Query\QueryBuilder;
|
|
use Symfony\Component\HttpFoundation\RequestStack;
|
|
use Symfony\Contracts\Service\Attribute\Required;
|
|
|
|
class OrderConfigurableFeed implements IFeed, IConfigurableFeed
|
|
{
|
|
use \DatabaseCommunication;
|
|
use ConfigurableFeedTrait;
|
|
|
|
/** @var string */
|
|
public static $type = 'orderConfigurable';
|
|
|
|
/** @var string */
|
|
public static $alias = 'Objednávky';
|
|
|
|
/** @var string */
|
|
public static $objectType = 'order';
|
|
|
|
/** @var \Query\QueryBuilder */
|
|
protected $query;
|
|
|
|
/** @var OrdersFilterSpecs */
|
|
protected $ordersFilterSpecs;
|
|
|
|
protected $contextManager;
|
|
|
|
protected RequestStack $requestStack;
|
|
|
|
#[Required]
|
|
public function setRequestStack(RequestStack $requestStack): void
|
|
{
|
|
$this->requestStack = $requestStack;
|
|
}
|
|
|
|
public static function isAllowed(): bool
|
|
{
|
|
return (bool) findModule(\Modules::ORDERS);
|
|
}
|
|
|
|
public function __construct(OrderWrapper $orderWrapper, ContextManager $contextManager)
|
|
{
|
|
$this->objectWrapper = $orderWrapper;
|
|
$this->contextManager = $contextManager;
|
|
}
|
|
|
|
/**
|
|
* @required
|
|
*/
|
|
public function setOrdersFilterSpecs(OrdersFilterSpecs $ordersFilterSpecs)
|
|
{
|
|
$this->ordersFilterSpecs = $ordersFilterSpecs;
|
|
}
|
|
|
|
public function getQuery(array $feedRow): QueryBuilder
|
|
{
|
|
$qb = sqlQueryBuilder()->select('o.*')
|
|
->from('orders', 'o');
|
|
|
|
$settings = json_decode($feedRow['settings'] ?? '', true) ?? [];
|
|
$filter = $settings['filter'] ?? [];
|
|
|
|
$days = $filter['order_days'] ?? 1;
|
|
if (empty($days)) {
|
|
$days = 1;
|
|
}
|
|
|
|
if ($this->requestStack->getMainRequest()?->get('date_from')) {
|
|
// date is from GET parameter, its formated as Y-m-d
|
|
$date = $this->requestStack->getMainRequest()?->get('date_from');
|
|
|
|
if (!$date_from = \DateTime::createFromFormat('Y-m-d H:i:s', $date)) {
|
|
$date_from = $date.' 00:00:00';
|
|
} else {
|
|
$date_from = $date_from->format('Y-m-d H:i:s');
|
|
}
|
|
} else {
|
|
// date is from admin field, we need to format it
|
|
$date_from = $filter['date_created']['from'] ?? null;
|
|
$date_from = empty($date_from) ? null : $this->prepareDate($date_from).' 00:00:00';
|
|
}
|
|
|
|
if ($this->requestStack->getMainRequest()?->get('date_to')) {
|
|
$date = $this->requestStack->getMainRequest()?->get('date_to');
|
|
|
|
if (!$date_to = \DateTime::createFromFormat('Y-m-d H:i:s', $date)) {
|
|
$date_to = $date.' 23:59:59';
|
|
} else {
|
|
$date_to = $date_to->format('Y-m-d H:i:s');
|
|
}
|
|
} else {
|
|
$date_to = $filter['date_created']['to'] ?? null;
|
|
$date_to = empty($date_to) ? null : $this->prepareDate($date_to).' 23:59:59';
|
|
}
|
|
|
|
// we handle date_created and date_updated manually, so we unset them to skip them in OrdersfIlterSpecs
|
|
unset($filter['date_created']);
|
|
|
|
if ($date_to || $date_from) {
|
|
$qb->andWhere(Operator::orX(
|
|
Operator::between('o.date_created', new \Range($date_from, $date_to)),
|
|
));
|
|
}
|
|
|
|
if (empty($filter['date_handled']['from']) && empty($filter['date_handled']['to']) && empty($date_from) && empty($date_to)) {
|
|
// max days limit
|
|
if ($filter['use_date_updated'] ?? false) {
|
|
$qb->andWhere('COALESCE(date_updated, date_created) >= (DATE(NOW()) - INTERVAL :days DAY)')
|
|
->setParameter('days', $days);
|
|
} else {
|
|
$qb->andWhere('date_created >= (DATE(NOW()) - INTERVAL :days DAY)')
|
|
->setParameter('days', $days);
|
|
}
|
|
if ($filter['order_days_min'] ?? false) {
|
|
// min days limit
|
|
if ($filter['use_date_updated'] ?? false) {
|
|
$qb->andWhere('COALESCE(date_updated, date_created) < (DATE(NOW()) - INTERVAL :days_min DAY)')
|
|
->setParameter('days_min', $filter['order_days_min']);
|
|
} else {
|
|
$qb->andWhere('date_created < (DATE(NOW()) - INTERVAL :days_min DAY)')
|
|
->setParameter('days_min', $filter['order_days_min']);
|
|
}
|
|
}
|
|
}
|
|
|
|
// orders filter
|
|
$filterSpecs = null;
|
|
if ($filter) {
|
|
$filterSpecs = $this->ordersFilterSpecs->getSpecs($filter);
|
|
}
|
|
|
|
if ($filterSpecs) {
|
|
$qb->andWhere($filterSpecs);
|
|
}
|
|
|
|
// Hard limit
|
|
$qb->setMaxResults(100000);
|
|
|
|
foreach ($this->specs as $spec) {
|
|
$qb->andWhere($spec);
|
|
}
|
|
|
|
$this->query = $qb;
|
|
|
|
return $qb;
|
|
}
|
|
|
|
public function filterByObjectID($objectID): void
|
|
{
|
|
$this->specs[] = function (QueryBuilder $qb) use ($objectID) {
|
|
$qb->andWhere(Operator::equals(['o.id' => $objectID]));
|
|
};
|
|
}
|
|
|
|
public function getData(array $feedRow, ?int $limit = null): \Generator
|
|
{
|
|
$qb = $this->query ?? $this->getQuery($feedRow);
|
|
|
|
$countQuery = (clone $qb)
|
|
->select('count(o.id) AS c')
|
|
->resetQueryPart('groupBy');
|
|
$count = (int) $countQuery->execute()->fetch()['c'];
|
|
|
|
// use batching only if limit is NOT set
|
|
$iterationLimit = isset($limit) ? 1 : ($count / (float) static::$batchSize);
|
|
for ($i = 0; $i < $iterationLimit; $i++) {
|
|
$qb->setFirstResult($i * static::$batchSize);
|
|
$qb->setMaxResults($limit ?? static::$batchSize);
|
|
$orders = new OrderCollection();
|
|
foreach ($qb->execute() as $row) {
|
|
// TODO: predelat na OrdersList s multifetchama az jednou bude
|
|
$order = new \Order();
|
|
$order->createFromArray($row);
|
|
|
|
$orders->set((int) $row['id'], $order); // cast to (object) to force reference
|
|
}
|
|
$this->objectWrapper->setOrders($orders);
|
|
foreach ($orders as $order) {
|
|
yield $this->prepareSingleObject($order);
|
|
}
|
|
}
|
|
}
|
|
|
|
protected function initFeedGenerator(array $feedRow): void
|
|
{
|
|
if (isset($this->forcedFeedGenerator)) {
|
|
$this->feedGenerator = $this->forcedFeedGenerator;
|
|
} else {
|
|
$this->feedGenerator = $this->v8FeedGenerator;
|
|
}
|
|
|
|
if (method_exists($this->feedGenerator, 'setBuildItemCallback')) {
|
|
$this->feedGenerator->setBuildItemCallback(function (callable $callback, $v8Object) {
|
|
/** @var $itemWrapper OrderWrapper */
|
|
$itemWrapper = $v8Object->value;
|
|
$itemWrapper->activateOrderFor($callback);
|
|
});
|
|
}
|
|
}
|
|
}
|