Newer
Older
use QUI\ERP\Customer\Utils as CustomerUtils;
use QUI\ERP\Order\Basket\Basket;
use QUI\ERP\Order\Basket\Exception;
use QUI\ERP\Order\Basket\ExceptionBasketNotFound;
use QUI\ExceptionStack;
use QUI\Utils\Singleton;
use function array_merge;
use function class_exists;
* Class Handler
* - Handles orders and order in process
*
* @package QUI\ERP\Order
*/
class Handler extends Singleton
{
const ERROR_ORDER_NOT_FOUND = 604; // a specific order wasn't found
const ERROR_NO_ORDERS_FOUND = 605; // Search or last orders don't get results
const ERROR_ORDER_ID_ALREADY_EXISTS = 606; // attempt to create a new order with an already existing id
/**
* Default empty value (placeholder for empty values)
*/
/**
* Return all order process Provider
*
* @return array
*/
{
$cacheProvider = 'package/quiqqer/order/providerOrderProcess';
try {
$providers = QUI\Cache\Manager::get($cacheProvider);
$packages = array_map(function ($package) {
return $package['name'];
}, QUI::getPackageManager()->getInstalled());
$providers = [];
foreach ($packages as $package) {
try {
$Package = QUI::getPackage($package);
if ($Package->isQuiqqerPackage()) {
$providers = array_merge($providers, $Package->getProvider('orderProcess'));
try {
QUI\Cache\Manager::set($cacheProvider, $providers);
} catch (\Exception $Exception) {
QUI\System\Log::writeDebugException($Exception);
}
}
// filter provider
$result = [];
foreach ($providers as $provider) {
continue;
}
$Provider = new $provider();
if (!($Provider instanceof AbstractOrderProcessProvider)) {
continue;
}
$result[] = $Provider;
}
return $result;
}
/**
* Return the order table
*
* @return string
*/
public function table(): string
{
return QUI::getDBTableName('orders');
}
/**
* Return a specific Order
*
* @throws QUI\ERP\Order\Exception
* @throws QUI\Exception
/**
* Return the specific order via its hash
* If an order exists with the hash, this will be returned
* An order has higher priority as an order in process
*
* @param string $hash - Order Hash
*
* @throws QUI\Exception
public function getOrderByHash(string $hash): OrderInProcess|Order
$result = QUI::getDataBase()->fetch([
'from' => $this->table(),
'where' => [
'limit' => 1
if (isset($result[0])) {
return $this->get($result[0]['id']);
}
$result = QUI::getDataBase()->fetch([
'from' => $this->tableOrderProcess(),
'where' => [
'limit' => 1
QUI::getLocale()->get('quiqqer/order', 'exception.order.not.found'),
self::ERROR_ORDER_NOT_FOUND
);
}
return $this->getOrderInProcess($result[0]['id']);
}
* Return an order via its global process id
* If an order exists with the id, this will be returned
* An order has higher priority as an order in process
*
* If you want to get all orders, use getOrdersByGlobalProcessId()
*
* @param string|int $id - Global process id
* @return Order
*
* @throws QUI\Exception
* @throws Exception
*/
public function getOrderByGlobalProcessId(int|string $id): Order
{
$result = QUI::getDataBase()->fetch([
'select' => 'id',
'from' => $this->table(),
'hash' => $id,
'limit' => 1
QUI::getLocale()->get('quiqqer/order', 'exception.order.not.found'),
self::ERROR_ORDER_NOT_FOUND
);
}
return $this->get($result[0]['id']);
}
/**
* Return all orders via its global process id
*
* @param string $id - Global process id
public function getOrdersByGlobalProcessId(string $id): array
{
$dbData = QUI::getDataBase()->fetch([
'select' => 'id',
'from' => $this->table(),
'where_or' => [
'hash' => $id,
'global_process_id' => $id
]
]);
if (!count($dbData)) {
return [];
}
foreach ($dbData as $entry) {
try {
$result[] = $this->get($entry['id']);
} catch (QUI\Exception $Exception) {
QUI\System\Log::writeDebugException($Exception);
}
}
return $result;
}
/**
* Return the specific order via its id
* If an order exists with the hash, this will be returned
* An order has higher priority as an order in process
*
* @return Order|OrderInProcess
*
* @throws QUI\Exception
* @throws Exception
*/
public function getOrderById(int|string $id): OrderInProcess|Order
$result = QUI::getDataBase()->fetch([
'select' => 'id',
'from' => $this->table(),
'where' => [
'hash' => $id
],
'limit' => 1
]);
if (isset($result[0])) {
return $this->get($result[0]['id']);
}
$result = QUI::getDataBase()->fetch([
'from' => $this->table(),
'where' => [
'limit' => 1
if (isset($result[0])) {
return $this->get($result[0]['id']);
}
$result = QUI::getDataBase()->fetch([
'from' => $this->tableOrderProcess(),
'where' => [
'limit' => 1
QUI::getLocale()->get('quiqqer/order', 'exception.order.not.found'),
self::ERROR_ORDER_NOT_FOUND
);
}
return $this->getOrderInProcess($result[0]['id']);
}
/**
* Return the data of a wanted order
*
* @throws QUI\Database\Exception|QUI\ERP\Order\Exception
public function getOrderData(int|string $orderId): array
$result = QUI::getDataBase()->fetch([
'from' => $this->table(),
'where' => [
if (empty($result)) {
$result = QUI::getDataBase()->fetch([
'from' => $this->table(),
'where' => [
'id' => $orderId
],
'limit' => 1
]);
}
QUI::getLocale()->get('quiqqer/order', 'exception.order.not.found'),
self::ERROR_ORDER_NOT_FOUND
/**
* @param QUI\Interfaces\Users\User $User
* @return Order[]
public function getOrdersByUser(QUI\Interfaces\Users\User $User, array $params = []): array
'select' => ['id', 'customerId', 'hash'],
'from' => $this->table(),
'where' => [
];
if (isset($params['order'])) {
switch ($params['order']) {
case 'id':
case 'id ASC':
case 'id DESC':
case 'status':
case 'status ASC':
case 'status DESC':
case 'c_date':
case 'c_date ASC':
case 'c_date DESC':
case 'paid_date':
case 'paid_date ASC':
case 'paid_date DESC':
$query['order'] = $params['order'];
}
}
if (isset($params['limit'])) {
$query['limit'] = $params['limit'];
}
try {
$data = QUI::getDataBase()->fetch($query);
return [];
}
$result = [];
foreach ($data as $entry) {
try {
$result[] = new Order($entry['hash']);
} catch (QUI\Exception $Exception) {
QUI\System\Log::writeException($Exception);
}
}
return $result;
}
/**
* Return the number of orders from the user
*
* @param QUI\Interfaces\Users\User $User
* @return int
*
* @throws QUI\Database\Exception
public function countOrdersByUser(QUI\Interfaces\Users\User $User): int
'count' => 'id',
'from' => $this->table(),
'where' => [
]
]);
if (isset($data[0]['id'])) {
return (int)$data[0]['id'];
}
return 0;
}
/**
* Sends email to an order customer with successful (full) payment info.
*
* @param AbstractOrder $Order
* @return void
*/
public function sendOrderPaymentSuccessMail(AbstractOrder $Order): void
{
$Customer = $Order->getCustomer();
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
$CustomerLocale = $Customer->getLocale();
$subject = $CustomerLocale->get(
'quiqqer/order',
'mail.payment_success.subject',
$this->getLocaleVarsForOrderMail($Order)
);
$body = $CustomerLocale->get(
'quiqqer/order',
'mail.payment_success.body',
$this->getLocaleVarsForOrderMail($Order)
);
$Mailer = QUI::getMailManager()->getMailer();
$Mailer->setSubject($subject);
$Mailer->setBody($body);
$Mailer->addRecipient(CustomerUtils::getInstance()->getEmailByCustomer($Customer));
try {
$Mailer->send();
} catch (\Exception $Exception) {
QUI\System\Log::writeException($Exception);
}
}
/**
* Get all placeholder variables for order mails.
*
* @param AbstractOrder $Order
* @return array
*/
protected function getLocaleVarsForOrderMail(AbstractOrder $Order): array
{
$Customer = $Order->getCustomer();
$CustomerLocale = $Customer->getLocale();
$CustomerAddress = $Customer->getAddress();
$user = $CustomerAddress->getAttribute('contactPerson');
if (empty($user)) {
$user = $Customer->getName();
}
if (empty($user)) {
$user = $Customer->getAddress()->getName();
}
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
// contact person
$ContactPersonAddress = CustomerUtils::getInstance()->getContactPersonAddress($Customer);
if ($ContactPersonAddress) {
$contactPerson = $ContactPersonAddress->getName();
}
if (empty($contactPerson)) {
$contactPerson = $user;
}
$contactPersonOrName = $contactPerson;
if (empty($contactPersonOrName)) {
$contactPersonOrName = $user;
}
// Customer
$Address = $Order->getInvoiceAddress();
// customer name
$user = $Address->getAttribute('contactPerson');
if (empty($user)) {
$user = $Customer->getName();
}
if (empty($user)) {
$user = $Address->getName();
}
// email
$email = $Customer->getAttribute('email');
if (empty($email)) {
$mailList = $Address->getMailList();
if (isset($mailList[0])) {
$email = $mailList[0];
}
}
// Customer company
$customerCompany = $Address->getAttribute('company');
$companyOrName = $customerCompany;
if (empty($companyOrName)) {
$companyOrName = $user;
}
// Shop company
$company = '';
try {
$Conf = QUI::getPackage('quiqqer/erp')->getConfig();
$company = $Conf->get('company', 'name');
} catch (\Exception $Exception) {
QUI\System\Log::writeException($Exception);
}
return [
'orderId' => $Order->getPrefixedNumber(),
'hash' => $Order->getUUID(),
'date' => $CustomerLocale->formatDate(strtotime($Order->getCreateDate())),
'contactPerson' => $contactPerson,
'contactPersonOrName' => $contactPersonOrName,
'user' => $user,
'name' => $user,
'company' => $Address->getAttribute('company'),
'address' => $Address->render(),
'email' => $email,
'salutation' => $Address->getAttribute('salutation'),
'firstname' => $Address->getAttribute('firstname'),
'lastname' => $Address->getAttribute('lastname')
public function tableOrderProcess(): string

Henning Leutz
committed
return QUI::getDBTableName('orders_process');
* @return OrderInProcess
* @throws QUI\ERP\Order\Exception
* @throws QUI\ERP\Exception
* @throws QUI\Database\Exception
public function getOrderInProcess($orderId): OrderInProcess
return new OrderInProcess($orderId);
*
* @param string $hash - hash of the order
* @return OrderInProcess
*
* @throws QUI\ERP\Order\Exception
* @throws QUI\ERP\Exception
public function getOrderInProcessByHash(string $hash): OrderInProcess
{
$result = QUI::getDataBase()->fetch([
'select' => 'id',
'from' => $this->tableOrderProcess(),
'where' => [
'limit' => 1
QUI::getLocale()->get('quiqqer/order', 'exception.order.not.found'),
self::ERROR_ORDER_NOT_FOUND
);
}
return $this->getOrderInProcess($result[0]['id']);
}
/**
* Return all orders in process from a user
*
* @param QUI\Interfaces\Users\User $User
* @return array
*
* @throws QUI\Database\Exception
public function getOrdersInProcessFromUser(QUI\Interfaces\Users\User $User): array
$result = [];
$list = QUI::getDataBase()->fetch([
'from' => $this->tableOrderProcess(),
'where' => [
]
]);
$result[] = $this->getOrderInProcess($entry['hash']);
/**
* Return order in process number form a user
*
* @param QUI\Interfaces\Users\User $User
* @return int
*
* @throws QUI\Database\Exception
public function countOrdersInProcessFromUser(QUI\Interfaces\Users\User $User): int
'count' => 'id',
'select' => 'id',
'from' => $this->tableOrderProcess(),
'where' => [
if (isset($data[0]['id'])) {
return (int)$data[0]['id'];
/**
* Return the last order in process from a user
*
* @param QUI\Interfaces\Users\User $User
* @return OrderInProcess
*
* @throws QUI\ERP\Order\Exception
* @throws QUI\ERP\Exception
public function getLastOrderInProcessFromUser(QUI\Interfaces\Users\User $User): OrderInProcess
$result = QUI::getDataBase()->fetch([
'from' => $this->tableOrderProcess(),
'where' => [
try {
$result = QUI::getEvents()->fireEvent('orderProcessGetOrder');
foreach ($result as $Order) {
if ($Order instanceof OrderInProcess) {
return $Order;
}
}
}
QUI::getLocale()->get('quiqqer/order', 'exception.no.orders.found'),
self::ERROR_NO_ORDERS_FOUND
return $this->getOrderInProcess($result[0]['hash']);
* @throws QUI\ERP\Order\Exception
public function getOrderProcessData(int|string $orderId): array
$result = QUI::getDataBase()->fetch([
'from' => $this->tableOrderProcess(),
'where_or' => [
'id' => $orderId,
'hash' => $orderId
QUI::getLocale()->get('quiqqer/order', 'exception.order.not.found'),
self::ERROR_ORDER_NOT_FOUND
);
}
return $result[0];
}
//endregion
//region basket
/**
* Return the table for baskets
*
* @return string
*/
{
return QUI::getDBTableName('baskets');
}
/**
* Return a basket by its string
* Can be a basket id or a basket hash
*
* @param integer|string $str - hash or basket id
* @param null $User - optional, user of the basket
* @throws Exception
* @throws ExceptionBasketNotFound
* @throws ExceptionStack
public function getBasket(int|string $str, $User = null): Basket
return self::getBasketById($str, $User);
}
return self::getBasketByHash($str, $User);
}
* @param null $User - optional, user of the basket
public function getBasketById(int|string $basketId, $User = null): Basket
$data = QUI::getDataBase()->fetch([
'from' => QUI\ERP\Order\Handler::getInstance()->tableBasket(),
'where' => [
'quiqqer/order',
'exception.basket.not.found'
if ($User === null) {
$User = QUI::getUserBySession();
} else {
$basketData = $data[0];
$User = QUI::getUsers()->get($basketData['uid']);
* @param string $hash
* @param null $User - optional, user of the basket
* @throws Exception
* @throws ExceptionBasketNotFound
* @throws ExceptionStack
public function getBasketByHash(string $hash, $User = null): Basket
$data = QUI::getDataBase()->fetch([
'from' => QUI\ERP\Order\Handler::getInstance()->tableBasket(),
'where' => [
'hash' => $hash
'limit' => 1
if (!isset($data[0])) {
'exception.basket.not.found'
if ($User === null) {
$User = QUI::getUserBySession();
} else {
$basketData = $data[0];
$User = QUI::getUsers()->get($basketData['uid']);
$this->checkBasketPermissions($User);
}
/**
* @param QUI\Interfaces\Users\User $User
* @return QUI\ERP\Order\Basket\Basket
*
* @throws Exception
* @throws ExceptionBasketNotFound
*/
public function getBasketFromUser(QUI\Interfaces\Users\User $User): Basket
{
$this->checkBasketPermissions($User);
$data = QUI::getDataBase()->fetch([
'from' => QUI\ERP\Order\Handler::getInstance()->tableBasket(),
'where' => [
'limit' => 1
* Return the data from a basket
*
* @param null|QUI\Interfaces\Users\User $User
* @return array
* @throws Exception
* @throws ExceptionBasketNotFound
public function getBasketData(int|string $basketId, QUI\Interfaces\Users\User $User = null): array
{
if ($User === null) {
$User = QUI::getUserBySession();
}
$this->checkBasketPermissions($User);
$data = QUI::getDataBase()->fetch([
'from' => QUI\ERP\Order\Handler::getInstance()->tableBasket(),
'where' => [
'id' => (int)$basketId,
/**
* Basket permission check
*
* @param QUI\Interfaces\Users\User $User
*/
protected function checkBasketPermissions(QUI\Interfaces\Users\User $User): void
{
$hasPermissions = function () use ($User) {
if (QUI::getUserBySession()->isSU()) {
return true;
}
if (QUI::getUsers()->isSystemUser(QUI::getUserBySession())) {
return true;
}
if ($User->getUUID() === QUI::getUserBySession()->getUUID()) {
return true;
}
return false;
};
if ($hasPermissions() === false) {
'exception.basket.no.permissions'
}
}