Files
kupshop/class/class.Pos.php
2025-08-02 16:30:27 +02:00

286 lines
7.8 KiB
PHP

<?php
use Query\Operator;
/**
* Class Pos.
*/
class PosBase
{
use \DatabaseCommunication;
protected $start_datetime;
protected $end_datetime;
protected $specific_pos = false;
/* @var Decimal sum sum */
protected $sum;
public const METHODS = [
0 => 'Zaokrouhlení',
1 => 'Zaplaceno v hotovosti',
2 => 'Zaplaceno kartou',
3 => 'Zadáno na fakturu',
4 => 'Vloženo do kasy',
5 => 'Vybráno z kasy',
6 => 'Zaplaceno převodem',
7 => 'Zaplaceno dobírkou',
8 => 'Zaplaceno online',
9 => 'Vyrovnání pokladny',
101 => 'SK EET Úhrada faktury - hotově',
102 => 'SK EET Úhrada faktury - kartou',
];
public function __construct()
{
$this->sum = DecimalConstants::zero();
}
public function getPayments()
{
$stats = [];
$vats = $this->getQueryBuilder()->select('*')->from('vats');
if (findModule(\Modules::OSS_VATS)) {
$vats->andWhere(Operator::equals(['automanaged' => 0]));
}
foreach ($vats->execute()->fetchAll() as $vat) {
$stats[Payment::METHOD_CASH][$vat['vat']] = $this->getSumByVat(Payment::METHOD_CASH, $vat['vat']);
$stats[Payment::METHOD_CARD][$vat['vat']] = $this->getSumByVat(Payment::METHOD_CARD, $vat['vat']);
$stats[Payment::METHOD_INVOICE][$vat['vat']] = $this->getSumByVat(Payment::METHOD_INVOICE, $vat['vat']);
}
$stats[Payment::METHOD_CASH_INSERTION] = $this->getSum(Payment::METHOD_CASH_INSERTION);
$this->sum = $this->sum->sub($stats[Payment::METHOD_CASH_INSERTION]);
$stats[Payment::METHOD_CASH_SELECTION] = $this->getSum(Payment::METHOD_CASH_SELECTION);
$this->sum = $this->sum->sub($stats[Payment::METHOD_CASH_INSERTION]);
$stats[Payment::METHOD_COMPENSATION] = $this->getSum(Payment::METHOD_COMPENSATION);
$stats[0] = &$this->sum;
return $stats;
}
protected function getSumByVat($method, $vat)
{
$qb = $this->getQueryBuilder()
->select('DISTINCT (oi.id)')
->from('order_items', 'oi')
->leftJoin('oi', 'order_payments', 'op', 'oi.id_order = op.id_order')
->andWhere(
$this->getQueryBuilder()->expr()->eq('op.method', $method)
)
->andWhere(
$this->getQueryBuilder()->expr()->eq('oi.tax', $vat)
);
$this->addDates($qb);
$this->selectPOS($qb);
$qb2 = $this->getQueryBuilder()
->select('SUM(oi2.total_price)')
->from('order_items', 'oi2')
->where(
$this->getQueryBuilder()->expr()->in('oi2.id', $qb->getSQL())
)
->setParameters($qb->getParameters());
$qr = $qb2->execute();
$val = $qr->fetchColumn();
$this->sum = $this->sum->sub(toDecimal($val)->addVat($vat));
return toDecimal($val);
}
protected function getSum($method)
{
$qb = $this->getQueryBuilder()
->select('SUM(price) as sum')
->from('order_payments', 'op')
->andWhere(
$this->getQueryBuilder()->expr()->eq('op.method', $method)
);
$this->addDates($qb);
$this->selectPOS($qb);
$qr = $qb->execute();
$val = $qr->fetchColumn();
return toDecimal($val);
}
public function getActuallyCashInPOS()
{
$qb = $this->getQueryBuilder()
->select('SUM(price) as sum')
->from('order_payments', 'op')
->andWhere(
$this->getQueryBuilder()->expr()->orX(
$this->getQueryBuilder()->expr()->eq('method', ':cash'),
$this->getQueryBuilder()->expr()->eq('method', ':selection'),
$this->getQueryBuilder()->expr()->eq('method', ':insertion'),
$this->getQueryBuilder()->expr()->eq('method', ':compensation')
)
)
->setParameters([
'cash' => Payment::METHOD_CASH,
'selection' => Payment::METHOD_CASH_SELECTION,
'insertion' => Payment::METHOD_CASH_INSERTION,
'compensation' => Payment::METHOD_COMPENSATION,
]);
if ($this->getEndDatetime()) {
$qb->andWhere('op.date < :end_datetime')
->setParameter('end_datetime', $this->getEndDatetime());
}
$this->selectPOS($qb);
$qr = $qb->execute();
return toDecimal($qr->fetchColumn());
}
public function getSales()
{
$qb = $this->getQueryBuilder()
->select('SUM(price)')
->from('order_payments', 'op')
->andWhere(
$this->getQueryBuilder()->expr()->orX(
$this->getQueryBuilder()->expr()->eq('method', ':cash'),
$this->getQueryBuilder()->expr()->eq('method', ':card'),
$this->getQueryBuilder()->expr()->eq('method', ':invoice')
)
)
->setParameters([
'cash' => Payment::METHOD_CASH,
'card' => Payment::METHOD_CARD,
'invoice' => Payment::METHOD_INVOICE,
]);
$this->addDates($qb);
$this->selectPOS($qb);
$qr = $qb->execute();
$val = $qr->fetchColumn();
$this->sum = $this->sum->add(toDecimal($val));
return toDecimal($val);
}
public function getDiscounts()
{
$qb = $this->getQueryBuilder()
->select('DISTINCT (oi.id)')
->from('order_items', 'oi')
->leftJoin('oi', 'order_payments', 'op', 'oi.id_order = op.id_order');
$this->addDates($qb);
$this->selectPOS($qb);
$qb2 = $this->getQueryBuilder()
->select('SUM(((oi2.total_price / (100) * (100 + oi2.tax)) / (100 - oi2.discount) * oi2.discount))')
->from('order_items', 'oi2')
->where(
$this->getQueryBuilder()->expr()->in('oi2.id', $qb->getSQL())
)
->setParameters($qb->getParameters());
$qr = $qb2->execute();
$val = $qr->fetchColumn();
return toDecimal($val);
}
protected function selectPOS(&$qb)
{
if ($this->getSpecificPos()) {
$qb->andWhere($this->getQueryBuilder()->expr()->eq('op.admin', $this->getSpecificPos()));
}
}
protected function addDates(&$qb)
{
if ($this->getStartDatetime()) {
$qb->andWhere('op.date > :start_datetime')
->setParameter('start_datetime', $this->getStartDatetime());
}
if ($this->getEndDatetime()) {
$qb->andWhere('op.date < :end_datetime')
->setParameter('end_datetime', $this->getEndDatetime());
}
}
public static function getMethodDescr($method_id)
{
return static::METHODS[$method_id];
}
/**
* @param mixed $start_datetime In format %d-%m-%Y %H:%M:%S
*/
public function setStartDatetime($start_datetime)
{
$this->start_datetime = $this->prepareDateTime($start_datetime);
}
/**
* @param mixed $end_datetime In format %d-%m-%Y %H:%M:%S
*/
public function setEndDatetime($end_datetime)
{
$this->end_datetime = $this->prepareDateTime($end_datetime);
}
public function getStartDatetime()
{
return $this->start_datetime;
}
public function getEndDatetime()
{
return $this->end_datetime;
}
public function getSpecificPos()
{
return $this->specific_pos;
}
/**
* @param null $specific_pos
*/
public function setSpecificPos($specific_pos)
{
$this->specific_pos = $specific_pos;
}
}
if (empty($subclass)) {
class Pos extends PosBase
{
}
}