Skip to content
Code-Schnipsel Gruppen Projekte
Basket.php 13,3 KiB
Newer Older
  • Learn to ignore specific revisions
  • <?php
    
    /**
    
     * This file contains QUI\ERP\Order\Basket\Basket
    
     */
    
    namespace QUI\ERP\Order\Basket;
    
    use QUI;
    
    Henning Leutz's avatar
    Henning Leutz committed
    use QUI\Database\Exception;
    use QUI\ERP\Order\AbstractOrder;
    
    Henning Leutz's avatar
    Henning Leutz committed
    use QUI\ERP\Products\Field\UniqueField;
    
    use QUI\ERP\Products\Product\ProductList;
    
    Henning Leutz's avatar
    Henning Leutz committed
    use QUI\ExceptionStack;
    
    
    use function is_array;
    use function json_decode;
    use function json_encode;
    
    /**
     * Class Basket
    
    Henning Leutz's avatar
    Henning Leutz committed
     * Coordinates the order process, (order -> payment -> invoice)
    
     *
     * @package QUI\ERP\Order\Basket
     */
    class Basket
    {
        /**
    
         * Basket id
         *
    
    Henning Leutz's avatar
    Henning Leutz committed
         * @var integer|bool
    
        protected int | bool $id = false;
    
    Henning Leutz's avatar
    Henning Leutz committed
        /**
    
         * List of products
         *
    
         * @var QUI\ERP\Products\Product\ProductList|null
    
    Henning Leutz's avatar
    Henning Leutz committed
         */
    
        protected ?ProductList $List = null;
    
    Henning Leutz's avatar
    Henning Leutz committed
         * @var ?QUI\Interfaces\Users\User
    
    Henning Leutz's avatar
    Henning Leutz committed
        protected ?QUI\Interfaces\Users\User $User = null;
    
    Henning Leutz's avatar
    Henning Leutz committed
         * @var ?string
    
    Henning Leutz's avatar
    Henning Leutz committed
        protected ?string $hash = null;
    
    Henning Leutz's avatar
    Henning Leutz committed
        /**
    
         * @var QUI\ERP\Comments|null
    
    Henning Leutz's avatar
    Henning Leutz committed
         */
    
        protected ?QUI\ERP\Comments $FrontendMessages = null;
    
        /**
         * Basket constructor.
         *
    
    Henning Leutz's avatar
    Henning Leutz committed
         * @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) {
    
            $this->List->setUser($User);
    
    Henning Leutz's avatar
    Henning Leutz committed
            $this->FrontendMessages = new QUI\ERP\Comments();
    
    Henning Leutz's avatar
    Henning Leutz committed
    
    
            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) {
    
                QUI\System\Log::writeDebugException($Exception);
    
                return;
    
            $this->id = $basketId;
    
            $this->User = $User;
    
            $this->hash = $data['hash'];
    
    Henning Leutz's avatar
    Henning Leutz committed
    
    
            if (!empty($data['products'])) {
                $this->import(json_decode($data['products'], true));
            }
    
    
            $this->List->setCurrency(QUI\ERP\Defaults::getUserCurrency());
    
    Henning Leutz's avatar
    Henning Leutz committed
        /**
    
    Henning Leutz's avatar
    Henning Leutz committed
         * @return bool|int
    
    Henning Leutz's avatar
    Henning Leutz committed
         */
    
        public function getId(): bool | int
    
            return $this->id;
    
    Henning Leutz's avatar
    Henning Leutz committed
        public function clear(): void
    
    Henning Leutz's avatar
    Henning Leutz committed
        /**
         * Set the basket as ordered successful
         */
    
    Henning Leutz's avatar
    Henning Leutz committed
        public function successful(): void
    
    Henning Leutz's avatar
    Henning Leutz committed
        {
            $this->List->clear();
            $this->hash = null;
        }
    
    
        public function count(): int
    
        {
            return $this->List->count();
        }
    
        //region product handling
    
    
         * Return the product list
    
         * @return ProductList
    
        public function getProducts(): ProductList
    
            return $this->List;
    
         * Add a product to the basket
    
         * @param Product $Product
    
         *
         * @throws QUI\Exception
         * @throws QUI\ERP\Products\Product\Exception
    
    Henning Leutz's avatar
    Henning Leutz committed
        public function addProduct(Product $Product): void
    
            $this->List->addProduct($Product);
    
            if ($this->hasOrder()) {
                try {
                    $this->getOrder()->addArticle($Product->toArticle());
    
    Henning Leutz's avatar
    Henning Leutz committed
                } catch (QUI\Exception) {
    
         * Import the products to the basket
    
    Henning Leutz's avatar
    Henning Leutz committed
         * @throws ExceptionStack
    
        public function import(array | null $products = []): void
    
            $this->clear();
    
    
            if (!is_array($products)) {
    
    Henning Leutz's avatar
    Henning Leutz committed
                $products = [];
    
    Henning Leutz's avatar
    Henning Leutz committed
            $OrderOrBasket = $this;
    
    
    Henning Leutz's avatar
    Henning Leutz committed
                $Order = $this->getOrder();
                $this->List->setOrder($Order);
    
                $OrderOrBasket = $Order;
    
    Henning Leutz's avatar
    Henning Leutz committed
            } catch (QUI\Exception) {
    
            $this->List = QUI\ERP\Order\Utils\Utils::importProductsToBasketList(
                $this->List,
    
    Henning Leutz's avatar
    Henning Leutz committed
                $products,
                $OrderOrBasket
    
    
            try {
                $this->List->recalculate();
            } catch (QUI\Exception $Exception) {
                QUI\System\Log::writeDebugException($Exception);
            }
    
    
            $this->save();
    
    
    
            QUI::getEvents()->fireEvent(
                'quiqqerBasketImport',
                [$this, $this->List]
            );
    
         * Save the basket
    
    Henning Leutz's avatar
    Henning Leutz committed
        public function save(): void
    
            if (!$this->List) {
                return;
            }
    
    
            // save only product ids with custom fields, we need not more
    
            $products = $this->List->getProducts();
    
            foreach ($products as $Product) {
    
                if (
                    !method_exists($Product, 'getUuid')
                    || !method_exists($Product, 'getProductSetParentUuid')
                    || !method_exists($Product, 'getQuantity')
                    || !method_exists($Product, 'toArticle')
                ) {
                    continue;
                }
    
    
                $fields = $Product->getFields();
    
    
                foreach ($fields as $Field) {
                    $Field->setChangeableStatus(false);
                }
    
    
    Henning Leutz's avatar
    Henning Leutz committed
                $productData = [
    
                    'id' => $Product->getId(),
    
                    'productSetParentUuid' => $Product->getProductSetParentUuid(),
    
                    'title' => $Product->getTitle(),
    
                    'description' => $Product->getDescription(),
    
                    'quantity' => $Product->getQuantity(),
                    'fields' => []
    
    Henning Leutz's avatar
    Henning Leutz committed
                ];
    
    
                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),
    
                        'hash' => $this->hash
    
                        'id' => $this->getId(),
    
    Henning Leutz's avatar
    Henning Leutz committed
                        'uid' => $this->User->getUUID()
    
                    ]
                );
            } 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();
    
    
            foreach ($products as $Product) {
    
                if (
                    !method_exists($Product, 'getUuid')
                    || !method_exists($Product, 'getProductSetParentUuid')
                    || !method_exists($Product, 'getQuantity')
                ) {
                    continue;
                }
    
    
    Henning Leutz's avatar
    Henning Leutz committed
                $fields = [];
    
    
                foreach ($Product->getFields() as $Field) {
    
                    if (!$Field->isPublic() && !$Field->isCustomField()) {
    
                    $fields[$Field->getId()] = $Field->getView()->getAttributes();
    
    Henning Leutz's avatar
    Henning Leutz committed
                $result[] = [
    
                    'id' => $Product->getId(),
    
                    'productSetParentUuid' => $Product->getProductSetParentUuid(),
    
                    'quantity' => $Product->getQuantity(),
    
                    'fields' => $fields
    
    Henning Leutz's avatar
    Henning Leutz committed
                ];
    
            // calc data
            $calculations = [];
    
            $unformatted = [];
    
                $data = $Products->getFrontendView()->toArray();
    
                $unformatted = $Products->toArray();
    
    
                unset($data['attributes']);
                unset($data['products']);
    
                $calculations = $data;
    
            } catch (QUI\Exception $Exception) {
                QUI\System\Log::writeDebugException($Exception);
            }
    
    
    Henning Leutz's avatar
    Henning Leutz committed
            return [
    
                'id' => $this->getId(),
                'products' => $result,
    
                'calculations' => $calculations,
    
                'unformatted' => $unformatted
    
    Henning Leutz's avatar
    Henning Leutz committed
            ];
    
    
        //region hash & orders
    
        /**
         * Set the process number
         * - Vorgangsnummer
         *
         * @param $hash
         */
    
    Henning Leutz's avatar
    Henning Leutz committed
        public function setHash($hash): void
    
        {
            $this->hash = $hash;
        }
    
        /**
         * Return the process number
         *
    
    Henning Leutz's avatar
    Henning Leutz committed
         * @return string|null
    
        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();
    
    Henning Leutz's avatar
    Henning Leutz committed
            } catch (QUi\Exception) {
    
                return false;
            }
    
            return true;
        }
    
        /**
         * Return the assigned order from the basket
         *
         * @throws Exception
    
         * @throws QUI\Exception
    
         * @throws QUI\ERP\Order\Exception
         */
    
    Henning Leutz's avatar
    Henning Leutz committed
        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);
        }
    
    
    Henning Leutz's avatar
    Henning Leutz committed
        /**
         * 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
         */
    
    Henning Leutz's avatar
    Henning Leutz committed
        public function updateOrder(): void
    
    Henning Leutz's avatar
    Henning Leutz committed
        {
            try {
                $Order = $this->getOrder();
            } catch (QUI\Exception $Exception) {
                if ($Exception->getCode() !== QUI\ERP\Order\Handler::ERROR_ORDER_NOT_FOUND) {
                    QUI\System\Log::writeDebugException($Exception);
    
    Henning Leutz's avatar
    Henning Leutz committed
                    return;
                }
    
                $Order = $this->createNewOrder();
            }
    
    
    Henning Leutz's avatar
    Henning Leutz committed
            $this->setHash($Order->getUUID());
    
    Henning Leutz's avatar
    Henning Leutz committed
         * @param AbstractOrder $Order
    
    Henning Leutz's avatar
    Henning Leutz committed
         * @throws ExceptionStack
         * @throws Exception
    
    Henning Leutz's avatar
    Henning Leutz committed
         * @throws QUI\ERP\Order\Exception
    
         * @throws QUI\Exception
         * @throws QUI\Permissions\Exception
         */
    
    Henning Leutz's avatar
    Henning Leutz committed
        public function toOrder(QUI\ERP\Order\AbstractOrder $Order): void
    
        {
            try {
                // insert basket products into the articles
                $Products = $this->getProducts()->calc();
            } catch (QUI\Exception $Exception) {
                QUI\System\Log::writeDebugException($Exception);
    
                return;
            }
    
    
    Henning Leutz's avatar
    Henning Leutz committed
            // update the data
            $products = $Products->getProducts();
    
    
            $InvoiceAddress = $Order->getInvoiceAddress();
    
    Henning Leutz's avatar
    Henning Leutz committed
            $DeliveryAddress = $Order->getDeliveryAddress();
    
    
    Henning Leutz's avatar
    Henning Leutz committed
    
            foreach ($products as $Product) {
    
                if (!method_exists($Product, 'toArticle')) {
                    continue;
                }
    
    
    Henning Leutz's avatar
    Henning Leutz committed
                try {
                    $Order->addArticle($Product->toArticle(null, false));
                } catch (QUI\Users\Exception $Exception) {
                    QUI\System\Log::writeDebugException($Exception);
                }
            }
    
    
    Henning Leutz's avatar
    Henning Leutz committed
            $Order->setInvoiceAddress($InvoiceAddress);
            $Order->setDeliveryAddress($DeliveryAddress);
    
    Henning Leutz's avatar
    Henning Leutz committed
            $Order->update();
    
            QUI::getEvents()->fireEvent(
                'quiqqerOrderBasketToOrder',
                [$this, $Order, $Products]
            );
    
            $PriceFactors = $Products->getPriceFactors();
    
    Henning Leutz's avatar
    Henning Leutz committed
            $Order->getArticles()->importPriceFactors(
    
            $Order->getArticles()->calc();
    
    Henning Leutz's avatar
    Henning Leutz committed
            $Order->update();
    
    
            QUI::getEvents()->fireEvent(
                'quiqqerOrderBasketToOrderEnd',
                [$this, $Order, $Products]
            );
    
    Henning Leutz's avatar
    Henning Leutz committed
        }
    
        /**
         * @return QUI\ERP\Order\OrderInProcess
         *
         * @throws QUI\Exception
         * @throws QUI\ERP\Order\Exception
         */
    
        protected function createNewOrder(): QUI\ERP\Order\OrderInProcess
    
    Henning Leutz's avatar
    Henning Leutz committed
        {
            $Orders = QUI\ERP\Order\Handler::getInstance();
    
            $User = QUI::getUserBySession();
    
    Henning Leutz's avatar
    Henning Leutz committed
    
            // create a new order
            try {
                // select the last order in processing
    
                return $Orders->getLastOrderInProcessFromUser($User);
    
            } catch (QUI\ERP\Order\Exception) {
    
            return QUI\ERP\Order\Factory::getInstance()->createOrderInProcess();
    
    Henning Leutz's avatar
    Henning Leutz committed
    
        //region frontend message
    
        /**
         * Add a frontend message
         *
         * @param string $message
         */
    
    Henning Leutz's avatar
    Henning Leutz committed
        public function addFrontendMessage(string $message): void
    
    Henning Leutz's avatar
    Henning Leutz committed
        {
            $this->FrontendMessages->addComment($message);
        }
    
        /**
         * Return the frontend message object
         *
         * @return null|QUI\ERP\Comments
         */
    
        public function getFrontendMessages(): ?QUI\ERP\Comments
    
    Henning Leutz's avatar
    Henning Leutz committed
        {
            return $this->FrontendMessages;
        }
    
        /**
         * Clears the messages and save this status to the database
         */
    
    Henning Leutz's avatar
    Henning Leutz committed
        public function clearFrontendMessages(): void
    
    Henning Leutz's avatar
    Henning Leutz committed
        {
            $this->FrontendMessages->clear();
        }
    
        //endregion