Newer
Older
* This file contains QUI\ERP\Order\Basket\Basket
*/
namespace QUI\ERP\Order\Basket;
use QUI;
use QUI\Database\Exception;
use QUI\ERP\Order\AbstractOrder;
use QUI\ERP\Order\Handler;
use QUI\ERP\Products\Product\ProductList;
use function is_array;
use function json_decode;
use function json_encode;
* Coordinates the order process, (order -> payment -> invoice)
*
* @package QUI\ERP\Order\Basket
*/
class Basket
{
/**
* @var QUI\ERP\Products\Product\ProductList|null
protected ?ProductList $List = null;
protected ?QUI\Interfaces\Users\User $User = null;
* @var QUI\ERP\Comments|null
protected ?QUI\ERP\Comments $FrontendMessages = null;
* @param bool|integer $basketId - ID of the basket
* @param ?QUI\Interfaces\Users\User $User
* @throws ExceptionStack
public function __construct(bool | int $basketId, null | QUI\Interfaces\Users\User $User = null)
if (!$User) {
$User = QUI::getUserBySession();
$this->List = new ProductList();
$this->List->duplicate = true;
if (!QUI::getUsers()->isUser($User) || $User->getType() == QUI\Users\Nobody::class) {

Henning Leutz
committed
return;
$this->List->setUser($User);
$this->FrontendMessages = new QUI\ERP\Comments();
if (is_bool($basketId)) {
try {
$Basket = Handler::getInstance()->getBasketFromUser(QUI::getUserBySession());
$basketId = $Basket->getId();
} catch (QUI\Exception) {
}
}
try {
$data = Handler::getInstance()->getBasketData($basketId, $User);
} catch (QUI\Exception $Exception) {

Henning Leutz
committed
QUI\System\Log::writeDebugException($Exception);
return;
$this->hash = $data['hash'];
if (!empty($data['products'])) {
$this->import(json_decode($data['products'], true));
}
$this->List->setCurrency(QUI\ERP\Defaults::getUserCurrency());
* Return the basket ID
public function getId(): bool | int
/**
* Clear the basket
*/
{
$this->List->clear();
}
/**
* Set the basket as ordered successful
*/
{
$this->List->clear();
$this->hash = null;
}
/**
* @return int
*/
public function count(): int
{
return $this->List->count();
}
//region product handling
* @return ProductList
public function getProducts(): ProductList
*
* @throws QUI\Exception
* @throws QUI\ERP\Products\Product\Exception
public function addProduct(Product $Product): void
if ($this->hasOrder()) {
try {
$this->getOrder()->addArticle($Product->toArticle());
* @param array|null $products
public function import(array | null $products = []): void
if (!is_array($products)) {
$Order = $this->getOrder();
$this->List->setOrder($Order);
$OrderOrBasket = $Order;

Henning Leutz
committed
$this->List = QUI\ERP\Order\Utils\Utils::importProductsToBasketList(
$this->List,

Henning Leutz
committed
);
try {
$this->List->recalculate();
} catch (QUI\Exception $Exception) {
QUI\System\Log::writeDebugException($Exception);
}
QUI::getEvents()->fireEvent(
'quiqqerBasketImport',
[$this, $this->List]
);
if (!$this->User) {
return;
}
// save only product ids with custom fields, we need not more
$products = $this->List->getProducts();
foreach ($products as $Product) {
/* @var $Product Product */
$fields = $Product->getFields();
foreach ($fields as $Field) {
$Field->setChangeableStatus(false);
}
'id' => $Product->getId(),

Patrick Müller
committed
'uuid' => $Product->getUuid(),
'productSetParentUuid' => $Product->getProductSetParentUuid(),
'title' => $Product->getTitle(),
'description' => $Product->getDescription(),
'quantity' => $Product->getQuantity(),
'fields' => []
foreach ($fields as $Field) {
if ($Field->isCustomField()) {
$productData['fields'][] = $Field->getAttributes();
}
}
$result[] = $productData;
}
try {
QUI::getDataBase()->update(
QUI\ERP\Order\Handler::getInstance()->tableBasket(),
[
'products' => json_encode($result),
]
);
} catch (\Exception $Exception) {
QUI\System\Log::writeException($Exception);
}
* Return the basket as array
*
* @return array
public function toArray(): array
$Products = $this->getProducts();
$products = $Products->getProducts();
/* @var $Product Product */
foreach ($products as $Product) {
foreach ($Product->getFields() as $Field) {

Patrick Müller
committed
if (!$Field->isPublic() && !$Field->isCustomField()) {
$fields[$Field->getId()] = $Field->getView()->getAttributes();
'id' => $Product->getId(),

Patrick Müller
committed
'uuid' => $Product->getUuid(),
'productSetParentUuid' => $Product->getProductSetParentUuid(),
// calc data
$calculations = [];

Henning Leutz
committed
$data = $Products->getFrontendView()->toArray();
$unformatted = $Products->toArray();

Henning Leutz
committed
unset($data['attributes']);
unset($data['products']);
$calculations = $data;
} catch (QUI\Exception $Exception) {
QUI\System\Log::writeDebugException($Exception);
}
'id' => $this->getId(),
'products' => $result,
'calculations' => $calculations,
'unformatted' => $unformatted
//region hash & orders
/**
* Set the process number
* - Vorgangsnummer
*
* @param $hash
*/
{
$this->hash = $hash;
}
/**
* Return the process number
*
public function getHash(): ?string
{
return $this->hash;
}
/**
* Does the basket have an assigned order?
*
* @return bool
*/
public function hasOrder(): bool
{
if (empty($this->hash)) {
return false;
}
try {
$this->getOrder();
return false;
}
return true;
}
/**
* Return the assigned order from the basket
*
* @throws Exception
* @throws QUI\ERP\Order\Exception
*/
public function getOrder(): QUI\ERP\Order\AbstractOrder
if (empty($this->hash)) {
throw new Exception(
QUI::getLocale()->get('quiqqer/order', 'exception.order.not.found'),
QUI\ERP\Order\Handler::ERROR_ORDER_NOT_FOUND
);
}
return QUI\ERP\Order\Handler::getInstance()->getOrderByHash($this->hash);
}
/**
* If the basket has an order, it set the basket data to the order
* There is a comparison between goods basket and order
*
* @throws QUI\Exception
*/
{
try {
$Order = $this->getOrder();
} catch (QUI\Exception $Exception) {
if ($Exception->getCode() !== QUI\ERP\Order\Handler::ERROR_ORDER_NOT_FOUND) {
QUI\System\Log::writeDebugException($Exception);
return;
}
$Order = $this->createNewOrder();
}

Henning Leutz
committed
$this->toOrder($Order);

Henning Leutz
committed
}
/**

Henning Leutz
committed
*

Henning Leutz
committed
* @throws QUI\ERP\Exception

Henning Leutz
committed
* @throws QUI\Exception
* @throws QUI\Permissions\Exception
*/
public function toOrder(QUI\ERP\Order\AbstractOrder $Order): void

Henning Leutz
committed
{
try {
// insert basket products into the articles
$Products = $this->getProducts()->calc();
} catch (QUI\Exception $Exception) {
QUI\System\Log::writeDebugException($Exception);
return;
}
// update the data
$products = $Products->getProducts();
$InvoiceAddress = $Order->getInvoiceAddress();
$DeliveryAddress = $Order->getDeliveryAddress();

Henning Leutz
committed
$Order->clear();
foreach ($products as $Product) {
try {
/* @var QUI\ERP\Order\Basket\Product $Product */
$Order->addArticle($Product->toArticle(null, false));
} catch (QUI\Users\Exception $Exception) {
QUI\System\Log::writeDebugException($Exception);
}
}
$Order->setInvoiceAddress($InvoiceAddress);
$Order->setDeliveryAddress($DeliveryAddress);
QUI::getEvents()->fireEvent(
'quiqqerOrderBasketToOrder',
[$this, $Order, $Products]
);

Henning Leutz
committed
$PriceFactors = $Products->getPriceFactors();

Henning Leutz
committed

Henning Leutz
committed
$PriceFactors->toErpPriceFactorList()
QUI::getEvents()->fireEvent(
'quiqqerOrderBasketToOrderEnd',
[$this, $Order, $Products]
);
}
/**
* @return QUI\ERP\Order\OrderInProcess
*
* @throws QUI\Exception
* @throws QUI\ERP\Order\Exception
*/
protected function createNewOrder(): QUI\ERP\Order\OrderInProcess
{
$Orders = QUI\ERP\Order\Handler::getInstance();
$User = QUI::getUserBySession();
// create a new order
try {
// select the last order in processing
return $Orders->getLastOrderInProcessFromUser($User);
return QUI\ERP\Order\Factory::getInstance()->createOrderInProcess();
//region frontend message
/**
* Add a frontend message
*
* @param string $message
*/
public function addFrontendMessage(string $message): void
{
$this->FrontendMessages->addComment($message);
}
/**
* Return the frontend message object
*
* @return null|QUI\ERP\Comments
*/
public function getFrontendMessages(): ?QUI\ERP\Comments
{
return $this->FrontendMessages;
}
/**
* Clears the messages and save this status to the database
*/
{
$this->FrontendMessages->clear();
}
//endregion