306 lines
12 KiB
PHP
306 lines
12 KiB
PHP
<?php
|
|
|
|
namespace KupShop\POSBundle\Util;
|
|
|
|
use KupShop\GraphQLBundle\ApiAdmin\Types\Collection\ProductCollection;
|
|
use KupShop\GraphQLBundle\ApiPos\Types\Collection\PosCollection;
|
|
use KupShop\GraphQLBundle\ApiPos\Types\Collection\PosIframeCollection;
|
|
use KupShop\GraphQLBundle\ApiPos\Types\Collection\PosModulesCollection;
|
|
use KupShop\GraphQLBundle\ApiPos\Types\Collection\PosOrderHistoryCollection;
|
|
use KupShop\GraphQLBundle\ApiPos\Types\Collection\PosOrderStatusCollection;
|
|
use KupShop\GraphQLBundle\ApiPos\Types\Collection\PosPermissionCollection;
|
|
use KupShop\GraphQLBundle\ApiPos\Types\Collection\PosVatCollection;
|
|
use KupShop\GraphQLBundle\ApiPos\Types\Order\PosOrderHistoryItem;
|
|
use KupShop\GraphQLBundle\ApiPos\Types\Order\PosOrderStatus;
|
|
use KupShop\GraphQLBundle\ApiPos\Types\Pos;
|
|
use KupShop\GraphQLBundle\ApiPos\Types\PosAdditionalData;
|
|
use KupShop\GraphQLBundle\ApiPos\Types\PosDeliverySetting;
|
|
use KupShop\GraphQLBundle\ApiPos\Types\PosIframe;
|
|
use KupShop\GraphQLBundle\ApiPos\Types\PosTerminal;
|
|
use KupShop\GraphQLBundle\ApiPos\Types\PosVat;
|
|
use KupShop\GraphQLBundle\ApiPos\Types\Stats\PosPaymentStats;
|
|
use KupShop\GraphQLBundle\ApiPos\Types\Stats\PosStats;
|
|
use KupShop\GraphQLBundle\ApiPos\Types\Stats\PosStatVatPrice;
|
|
use KupShop\GraphQLBundle\ApiPos\Types\Stats\PosSummaryStats;
|
|
use KupShop\GraphQLBundle\ApiShared\Types\DateInterval;
|
|
use KupShop\KupShopBundle\Context\CountryContext;
|
|
use KupShop\KupShopBundle\Context\CurrencyContext;
|
|
use KupShop\KupShopBundle\Context\PosContext;
|
|
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
|
|
use KupShop\KupShopBundle\Util\Contexts;
|
|
use KupShop\POSBundle\Email\InvoiceEmail;
|
|
use Query\Operator;
|
|
use Symfony\Component\DependencyInjection\ServiceLocator;
|
|
|
|
class PosUtil
|
|
{
|
|
private const ORDER_HISTORY_PER_PAGE = 10;
|
|
|
|
/** @var CurrencyContext */
|
|
private $currencyContext;
|
|
|
|
private CountryContext $countryContext;
|
|
|
|
/** @var PosTabInterface[] */
|
|
private ServiceLocator $serviceLocator;
|
|
|
|
public function __construct(ServiceLocator $serviceLocator)
|
|
{
|
|
$this->serviceLocator = $serviceLocator;
|
|
$this->currencyContext = ServiceContainer::getService(CurrencyContext::class);
|
|
$this->countryContext = ServiceContainer::getService(CountryContext::class);
|
|
}
|
|
|
|
public function getPointsOfSale(): PosCollection
|
|
{
|
|
$qb = sqlQueryBuilder()
|
|
->select('id, name')
|
|
->from('pos')
|
|
->execute()
|
|
->fetchAll();
|
|
|
|
$posCollection = [];
|
|
|
|
foreach ($qb as $item) {
|
|
$posCollection[] = new Pos(
|
|
intval($item['id']),
|
|
$item['name']
|
|
);
|
|
}
|
|
|
|
return new PosCollection($posCollection);
|
|
}
|
|
|
|
public function getFastAccessProducts(int $idPos): ProductCollection
|
|
{
|
|
$fastAccessIds = sqlQueryBuilder()
|
|
->select("JSON_EXTRACT(data, '$.fast_access_products') as products")
|
|
->from('pos')
|
|
->where('id = :id_pos')
|
|
->setParameter('id_pos', $idPos)
|
|
->execute()
|
|
->fetch();
|
|
$fastAccessProducts = new \KupShop\CatalogBundle\ProductList\ProductCollection();
|
|
foreach (json_decode($fastAccessIds['products']) as $id) {
|
|
$product = new \Product();
|
|
$product->createFromDB($id);
|
|
$product->fetchImages(1);
|
|
$fastAccessProducts->set($id, $product);
|
|
}
|
|
|
|
return new ProductCollection($fastAccessProducts);
|
|
}
|
|
|
|
public function getOrderHistory(int $idPos, int $page): PosOrderHistoryCollection
|
|
{
|
|
// op.method konstanty jsou z class.Payment.php
|
|
$qb = sqlQueryBuilder()
|
|
->select('o.order_no, o.date_created, u.name, u.surname, u.email, o.id, SUM(op.price) as paid, o.total_price, u.id as user_id, o.status, o.status_storno')
|
|
->addSelect("
|
|
GROUP_CONCAT(
|
|
CASE
|
|
WHEN op.method = 1 THEN 'Hotově'
|
|
WHEN op.method = 2 THEN 'Kartou'
|
|
WHEN op.method = 3 THEN 'Na fakturu'
|
|
ELSE 'Neznámý způsob'
|
|
END
|
|
SEPARATOR ', '
|
|
) AS payment_methods
|
|
")
|
|
->from('orders', 'o')
|
|
->leftJoin('o', 'users', 'u', 'o.id_user = u.id')
|
|
->leftJoin('o', 'order_payments', 'op', 'o.id = op.id_order AND op.status = :payment_status_finished')
|
|
->setParameter('payment_status_finished', \Payment::STATUS_FINISHED)
|
|
->where('o.pos = :id_pos')
|
|
->groupBy('o.order_no, o.date_created')
|
|
->orderBy('o.date_created DESC, o.order_no')
|
|
->setParameter('id_pos', $idPos)
|
|
->setMaxResults(10)
|
|
->setFirstResult(($page - 1) * static::ORDER_HISTORY_PER_PAGE);
|
|
|
|
if (findModule(\Modules::CURRENCIES)) {
|
|
$qb->leftJoin('o', 'currencies', 'c', 'o.currency=c.id')
|
|
->addSelect('c.symbol as currency_symbol');
|
|
} else {
|
|
$qb->addSelect("'Kč' as currency_symbol");
|
|
}
|
|
|
|
$historyCollection = [];
|
|
foreach ($qb->execute()->fetchAll() as $order) {
|
|
$historyCollection[] = new PosOrderHistoryItem($order);
|
|
}
|
|
|
|
return new PosOrderHistoryCollection(
|
|
items: $historyCollection
|
|
);
|
|
}
|
|
|
|
public function getPosStats(int $idPos, ?DateInterval $interval = null): PosStats
|
|
{
|
|
$posEntity = new PosEntity();
|
|
$posEntity->createFromDB($idPos)->activateContexts();
|
|
|
|
$posAppStats = new PosAppStats();
|
|
$posAppStats->setPosEntity($posEntity);
|
|
$posAppStats->setDatetimeInterval($interval);
|
|
$posAppStats->fetchStats();
|
|
|
|
return new PosStats(
|
|
$this->loadStatsForMethod($posAppStats->getStats(), \Payment::METHOD_CASH),
|
|
$this->loadStatsForMethod($posAppStats->getStats(), \Payment::METHOD_CARD),
|
|
$this->loadStatsForMethod($posAppStats->getStats(), \Payment::METHOD_INVOICE),
|
|
$posAppStats->getPaidOfTheInvoiceCash(),
|
|
$posAppStats->getPaidOfTheInvoiceCard(),
|
|
new PosSummaryStats(
|
|
$posAppStats->getCashInsertion(),
|
|
$posAppStats->getCashSelection(),
|
|
$posAppStats->getCompensation(),
|
|
$posAppStats->getRounding(),
|
|
$posAppStats->getDiscounts(),
|
|
$posAppStats->getSales(),
|
|
$posAppStats->getActualCashInPos(),
|
|
$posAppStats->getNonHandledOrdersCount(),
|
|
$posAppStats->getNonHandledOrdersPriceSum(),
|
|
)
|
|
);
|
|
}
|
|
|
|
public function sendInvoiceByEmail($idOrder): int
|
|
{
|
|
$emailService = ServiceContainer::getService(InvoiceEmail::class);
|
|
$order = new \Order();
|
|
$order->createFromDB($idOrder);
|
|
|
|
$emailService->setOrder($order);
|
|
$message = $emailService->getEmail();
|
|
|
|
// Send it
|
|
$emailService->sendEmail($message);
|
|
|
|
return 0;
|
|
}
|
|
|
|
private function loadStatsForMethod($stats, $method): PosPaymentStats
|
|
{
|
|
$vats = [];
|
|
foreach ($stats[$method] as $vat => $price) {
|
|
$vats[] = new PosStatVatPrice($vat, $price);
|
|
}
|
|
|
|
return new PosPaymentStats($vats);
|
|
}
|
|
|
|
public function loadAdditionalData(int $idPos): PosAdditionalData
|
|
{
|
|
if (!$idPos) {
|
|
throw new \Exception('Není vybrána žádná pokladna');
|
|
}
|
|
|
|
Contexts::get(PosContext::class)->activate($idPos);
|
|
$posEntity = Contexts::get(PosContext::class)->getActive();
|
|
|
|
// Loads modules to pos
|
|
$modules = $posEntity->getCheckedModules();
|
|
|
|
// Load permissions to pos
|
|
$permissions = $posEntity->getCheckedPermissions();
|
|
|
|
$delivery_types = sqlQueryBuilder()
|
|
->select('CONCAT(cash_dtp.name, " - ", cash_dtd.name) as cash')
|
|
->addSelect('CONCAT(card_dtp.name, " - ", card_dtd.name) as card')
|
|
->addSelect('CONCAT(invoice_dtp.name, " - ", invoice_dtd.name) as invoice')
|
|
->addSelect('custom_dtp.name as custom')
|
|
->from('pos', 'pos')
|
|
->leftJoin('pos', 'delivery_type', 'cash_dt', 'cash_dt.id=pos.cash_delivery_type')
|
|
->leftJoin('cash_dt', 'delivery_type_delivery', 'cash_dtd', 'cash_dtd.id=cash_dt.id_delivery')
|
|
->leftJoin('cash_dt', 'delivery_type_payment', 'cash_dtp', 'cash_dtp.id=cash_dt.id_payment')
|
|
->leftJoin('pos', 'delivery_type', 'card_dt', 'card_dt.id=pos.card_delivery_type')
|
|
->leftJoin('card_dt', 'delivery_type_delivery', 'card_dtd', 'card_dtd.id=card_dt.id_delivery')
|
|
->leftJoin('card_dt', 'delivery_type_payment', 'card_dtp', 'card_dtp.id=card_dt.id_payment')
|
|
->leftJoin('pos', 'delivery_type', 'invoice_dt', 'invoice_dt.id=pos.invoice_delivery_type')
|
|
->leftJoin('invoice_dt', 'delivery_type_delivery', 'invoice_dtd', 'invoice_dtd.id=invoice_dt.id_delivery')
|
|
->leftJoin('invoice_dt', 'delivery_type_payment', 'invoice_dtp', 'invoice_dtp.id=invoice_dt.id_payment')
|
|
->leftJoin('pos', 'delivery_type', 'custom_dt', 'custom_dt.id=pos.custom_delivery_type')
|
|
->leftJoin('custom_dt', 'delivery_type_payment', 'custom_dtp', 'custom_dtp.id=custom_dt.id_payment')
|
|
->where(Operator::equals(['pos.id' => $idPos]))
|
|
->execute()
|
|
->fetchAssociative();
|
|
|
|
$statuses = [];
|
|
foreach (getOrderStatuses() as $key => $orderStatus) {
|
|
$statuses[] = new PosOrderStatus($key, $orderStatus['name'] ?? '', getStatuses('handled')[0] == $key ? 'handled' : null);
|
|
}
|
|
|
|
$iframes = [];
|
|
foreach ($this->serviceLocator->getProvidedServices() as $className) {
|
|
if ($this->serviceLocator->has($className)) {
|
|
/** @var PosTabInterface $service */
|
|
$service = $this->serviceLocator->get($className);
|
|
if ($service->isAllowed()) {
|
|
$iframes[] = new PosIframe($service->getId(), $service->getTitle(), $service->getUrl());
|
|
}
|
|
}
|
|
}
|
|
|
|
return new PosAdditionalData(
|
|
$posEntity->getName(),
|
|
$this->loadVats(),
|
|
$this->currencyContext->getActive(),
|
|
$this->countryContext->getActive(),
|
|
new PosModulesCollection($modules),
|
|
new PosDeliverySetting($delivery_types),
|
|
new PosOrderStatusCollection($statuses),
|
|
new PosIframeCollection($iframes),
|
|
new PosPermissionCollection($permissions),
|
|
new PosTerminal($posEntity->getTerminalData()),
|
|
$posEntity->getStores(),
|
|
$posEntity->getWarehousePositions()
|
|
);
|
|
}
|
|
|
|
private function loadVats(): PosVatCollection
|
|
{
|
|
$qb = sqlQueryBuilder()
|
|
->select('descr, vat, is_default')
|
|
->from('vats');
|
|
|
|
if (findModule(\Modules::OSS_VATS)) {
|
|
$qb->addSelect('id_country');
|
|
} else {
|
|
$qb->addSelect("'{$this->countryContext->getActive()->getId()}' AS id_country");
|
|
}
|
|
|
|
$vats = [];
|
|
foreach ($qb->execute()->fetchAll() as $vat) {
|
|
$vats[] = new PosVat($vat['descr'], $vat['vat'], $vat['is_default'], $vat['id_country']);
|
|
}
|
|
|
|
return new PosVatCollection($vats);
|
|
}
|
|
|
|
public function getPosDeliveryType($idPos, $methodPayment)
|
|
{
|
|
$paymentMethod = strtolower($methodPayment);
|
|
|
|
return sqlQueryBuilder()
|
|
->select('dt.id, CONCAT(dtp.name, " - ", dtd.name) as name, dtd.class as delivery_class, dtp.class as payment_class, dtp.id as payment_id')
|
|
->from('pos', 'pos')
|
|
->leftJoin('pos', 'delivery_type', 'dt', "dt.id=pos.{$paymentMethod}_delivery_type")
|
|
->leftJoin('dt', 'delivery_type_delivery', 'dtd', 'dtd.id=dt.id_delivery')
|
|
->leftJoin('dt', 'delivery_type_payment', 'dtp', 'dtp.id=dt.id_payment')
|
|
->where(Operator::equals(['pos.id' => $idPos]))
|
|
->execute()
|
|
->fetch();
|
|
}
|
|
|
|
public static function getHandledOrderStatus(): int
|
|
{
|
|
$settingsStatus = \Settings::getDefault()->loadValue('pos')['handle_status'] ?? -1;
|
|
if ($settingsStatus >= 0) {
|
|
return (int) $settingsStatus;
|
|
}
|
|
|
|
return (int) getStatuses('handled')[0];
|
|
}
|
|
}
|