Skip to content
Code-Schnipsel Gruppen Projekte
CouponCode.php 16,2 KiB
Newer Older
  • Learn to ignore specific revisions
  • Patrick Müller's avatar
    Patrick Müller committed
    <?php
    
    namespace QUI\ERP\Coupons;
    
    use QUI;
    use QUI\Permissions\Permission;
    
    use QUI\ERP\Discount\Handler as DiscountHandler;
    
    Patrick Müller's avatar
    Patrick Müller committed
    
    /**
    
    Patrick Müller's avatar
    Patrick Müller committed
     * Class CouponCode
    
    Patrick Müller's avatar
    Patrick Müller committed
     */
    class CouponCode
    {
        /**
    
    Patrick Müller's avatar
    Patrick Müller committed
         * CouponCode ID
    
    Patrick Müller's avatar
    Patrick Müller committed
         *
         * @var int
         */
        protected $id;
    
        /**
         * Actual code
         *
         * @var string
         */
        protected $code;
    
        /**
    
    Patrick Müller's avatar
    Patrick Müller committed
         * IDs of users that this CouponCode is restricted to
    
    Patrick Müller's avatar
    Patrick Müller committed
         *
    
         * @var int[]
    
    Patrick Müller's avatar
    Patrick Müller committed
         */
    
    Patrick Müller's avatar
    Patrick Müller committed
        protected $userIds = [];
    
    Patrick Müller's avatar
    Patrick Müller committed
    
        /**
    
    Patrick Müller's avatar
    Patrick Müller committed
         * IDs of groups that this CouponCode is restricted to
    
    Patrick Müller's avatar
    Patrick Müller committed
         *
    
         * @var int[]
    
    Patrick Müller's avatar
    Patrick Müller committed
         */
    
    Patrick Müller's avatar
    Patrick Müller committed
        protected $groupIds = [];
    
    Patrick Müller's avatar
    Patrick Müller committed
    
    
        /**
         * IDs of all linked discounts
         *
         * @var int[]
         */
        protected $discountIds = [];
    
    
    Patrick Müller's avatar
    Patrick Müller committed
        /**
    
    Patrick Müller's avatar
    Patrick Müller committed
         * List of usages of this CouponCode
    
    Patrick Müller's avatar
    Patrick Müller committed
         *
    
    Patrick Müller's avatar
    Patrick Müller committed
         * @var array
    
    Patrick Müller's avatar
    Patrick Müller committed
         */
    
    Patrick Müller's avatar
    Patrick Müller committed
        protected $usages = [];
    
    Patrick Müller's avatar
    Patrick Müller committed
    
        /**
    
    Patrick Müller's avatar
    Patrick Müller committed
         * Creation Date
    
    Patrick Müller's avatar
    Patrick Müller committed
         *
         * @var \DateTime
         */
    
    Patrick Müller's avatar
    Patrick Müller committed
        protected $CreateDate;
    
    Patrick Müller's avatar
    Patrick Müller committed
    
        /**
    
    Patrick Müller's avatar
    Patrick Müller committed
         * Date until the CouponCode is valid
    
    Patrick Müller's avatar
    Patrick Müller committed
         *
         * @var \DateTime
         */
        protected $ValidUntilDate = null;
    
        /**
    
    Patrick Müller's avatar
    Patrick Müller committed
         * CouponCode title
    
    Patrick Müller's avatar
    Patrick Müller committed
         *
         * @var string
         */
    
    Patrick Müller's avatar
    Patrick Müller committed
        protected $title = null;
    
    Patrick Müller's avatar
    Patrick Müller committed
    
        /**
    
    Patrick Müller's avatar
    Patrick Müller committed
         * Flag - Is the CouponCode valid?
    
    Patrick Müller's avatar
    Patrick Müller committed
         *
         * @var bool
         */
    
    Patrick Müller's avatar
    Patrick Müller committed
        protected $valid = true;
    
    Patrick Müller's avatar
    Patrick Müller committed
    
        /**
    
    Patrick Müller's avatar
    Patrick Müller committed
         *
    
         * @var string
    
    Patrick Müller's avatar
    Patrick Müller committed
         */
    
        protected $maxUsages = Handler::MAX_USAGE_ONCE_PER_USER;
    
    Patrick Müller's avatar
    Patrick Müller committed
    
        /**
    
    Patrick Müller's avatar
    Patrick Müller committed
         * CouponCode constructor.
    
    Patrick Müller's avatar
    Patrick Müller committed
         *
         * @param int $id - Invite Code ID
    
    Patrick Müller's avatar
    Patrick Müller committed
         * @throws \QUI\ERP\Coupons\CouponCodeException
    
    Patrick Müller's avatar
    Patrick Müller committed
         */
        public function __construct($id)
        {
    
    Patrick Müller's avatar
    Patrick Müller committed
            $result = QUI::getDataBase()->fetch([
    
    Patrick Müller's avatar
    Patrick Müller committed
                'from'  => Handler::getTable(),
    
    Patrick Müller's avatar
    Patrick Müller committed
                'where' => [
    
    Patrick Müller's avatar
    Patrick Müller committed
                    'id' => $id
    
    Patrick Müller's avatar
    Patrick Müller committed
                ]
            ]);
    
    Patrick Müller's avatar
    Patrick Müller committed
    
            if (empty($result)) {
    
    Patrick Müller's avatar
    Patrick Müller committed
                throw new CouponCodeException([
                    'quiqqer/coupons',
                    'exception.CouponCode.not_found',
                    [
    
    Patrick Müller's avatar
    Patrick Müller committed
                        'id' => $id
    
    Patrick Müller's avatar
    Patrick Müller committed
                    ]
                ], 404);
    
    Patrick Müller's avatar
    Patrick Müller committed
            }
    
            $data = current($result);
    
    
    Patrick Müller's avatar
    Patrick Müller committed
            $this->id    = (int)$data['id'];
            $this->code  = $data['code'];
            $this->title = $data['title'];
    
    Patrick Müller's avatar
    Patrick Müller committed
    
    
    Patrick Müller's avatar
    Patrick Müller committed
            if (!empty($data['usages'])) {
                $this->usages = json_decode($data['usages'], true);
    
    Patrick Müller's avatar
    Patrick Müller committed
            }
    
    
    Patrick Müller's avatar
    Patrick Müller committed
            if (!empty($data['userIds'])) {
                $this->userIds = json_decode($data['userIds'], true);
            }
    
    Patrick Müller's avatar
    Patrick Müller committed
    
    
    Patrick Müller's avatar
    Patrick Müller committed
            if (!empty($data['groupIds'])) {
                $this->groupIds = json_decode($data['groupIds'], true);
    
    Patrick Müller's avatar
    Patrick Müller committed
            }
    
    
            if (!empty($data['maxUsages'])) {
                $this->maxUsages = $data['maxUsages'];
    
    Patrick Müller's avatar
    Patrick Müller committed
            }
    
    
            if (!empty($data['discountIds'])) {
                $this->discountIds = json_decode($data['discountIds'], true);
            }
    
    
    Patrick Müller's avatar
    Patrick Müller committed
            $this->CreateDate = new \DateTime($data['createDate']);
    
    
    Patrick Müller's avatar
    Patrick Müller committed
            if (!empty($data['validUntilDate'])) {
                $this->ValidUntilDate = new \DateTime($data['validUntilDate']);
            }
    
    Patrick Müller's avatar
    Patrick Müller committed
    
            $this->checkValidity();
    
    Patrick Müller's avatar
    Patrick Müller committed
        }
    
        /**
         * @return int
         */
        public function getId()
        {
            return $this->id;
        }
    
        /**
         * @return string
         */
        public function getCode()
        {
            return $this->code;
        }
    
        /**
         * @return \DateTime
         */
        public function getCreateDate()
        {
            return $this->CreateDate;
        }
    
        /**
    
    Patrick Müller's avatar
    Patrick Müller committed
         * Get usage data
         *
    
         * @return array
    
    Patrick Müller's avatar
    Patrick Müller committed
         */
    
    Patrick Müller's avatar
    Patrick Müller committed
        public function getUsages()
    
    Patrick Müller's avatar
    Patrick Müller committed
        {
    
    Patrick Müller's avatar
    Patrick Müller committed
            return $this->usages;
    
    Patrick Müller's avatar
    Patrick Müller committed
        }
    
        /**
         * @return \DateTime|null
         */
        public function getValidUntilDate()
        {
            return $this->ValidUntilDate;
        }
    
        /**
         * @return string
         */
        public function getTitle()
        {
            return $this->title;
        }
    
    
        /**
         * @return int[]
         */
        public function getDiscountIds()
        {
            return $this->discountIds;
        }
    
    
        /**
         * Get all discounts associated with this CouponCode
         *
         * @return QUI\ERP\Discount\Discount[]
         */
        public function getDiscounts()
        {
            $discounts       = [];
            $DiscountHandler = DiscountHandler::getInstance();
    
            foreach ($this->discountIds as $discountId) {
                try {
                    $discounts[] = $DiscountHandler->getChild($discountId);
                } catch (\Exception $Exception) {
                    QUI\System\Log::writeDebugException($Exception);
                }
            }
    
            return $discounts;
        }
    
    
    Patrick Müller's avatar
    Patrick Müller committed
        /**
    
    Patrick Müller's avatar
    Patrick Müller committed
         * Redeems this CouponCode
         *
         * Hint: This may invalidate the code for future use
         *
         * @param QUI\Users\User $User - The user that redeems the CouponCode [if omitted use Session User]
    
         * @param QUI\ERP\Order\Order $Order (optional) - Link redemption to a specific Order
    
    Patrick Müller's avatar
    Patrick Müller committed
         * @return void
         * @throws CouponCodeException
    
    Patrick Müller's avatar
    Patrick Müller committed
         * @throws QUI\Exception
    
    Patrick Müller's avatar
    Patrick Müller committed
         */
    
        public function redeem($User = null, $Order = null)
    
    Patrick Müller's avatar
    Patrick Müller committed
        {
    
    Patrick Müller's avatar
    Patrick Müller committed
            if (is_null($User)) {
                $User = QUI::getUserBySession();
            }
    
            $this->checkRedemption($User);
    
    
            $Now = new \DateTime();
    
            $usage = [
                'userId'          => $User->getId(),
                'date'            => $Now->format('Y-m-d H:i:s'),
                'orderPrefixedId' => false
    
    Patrick Müller's avatar
    Patrick Müller committed
            ];
    
    
            if (!is_null($Order) && $Order instanceof QUI\ERP\Order\Order) {
                $usage['orderPrefixedId'] = $Order->getPrefixedId();
            }
    
            $this->usages[] = $usage;
    
    
    Patrick Müller's avatar
    Patrick Müller committed
            QUI::getDataBase()->update(
                Handler::getTable(),
                [
                    'usages' => json_encode($this->usages)
                ],
                [
                    'id' => $this->id
                ]
            );
    
            $this->checkValidity();
    
    Patrick Müller's avatar
    Patrick Müller committed
    
            QUI::getEvents()->fireEvent(
                'quiqqerCouponsRedeem',
                [
                    'User'       => $User,
                    'CouponCode' => $this
                ]
            );
    
    Patrick Müller's avatar
    Patrick Müller committed
        }
    
        /**
    
    Patrick Müller's avatar
    Patrick Müller committed
         * Check if the given User can redeem this CouponCode
    
    Patrick Müller's avatar
    Patrick Müller committed
         *
    
         * @param QUI\Interfaces\Users\User $User - If omitted, use session user
    
    Patrick Müller's avatar
    Patrick Müller committed
         * @return void
    
    Patrick Müller's avatar
    Patrick Müller committed
         * @throws CouponCodeException - Thrown if not redeemable by the given User
    
    Patrick Müller's avatar
    Patrick Müller committed
         */
    
        public function checkRedemption($User)
    
    Patrick Müller's avatar
    Patrick Müller committed
        {
    
            if (!$this->isValid()) {
                throw new CouponCodeException([
                    'quiqqer/coupons',
                    'exception.CouponCode.no_longer_valid'
                ]);
            }
    
    
            $DiscountHandler = DiscountHandler::getInstance();
            $discountsValid  = false;
            $discountError   = false;
    
            foreach ($this->discountIds as $discountId) {
                try {
                    /** @var QUI\ERP\Discount\Discount $Discount */
                    $Discount = $DiscountHandler->getChild($discountId);
                } catch (\Exception $Exception) {
                    $discountError = $Exception->getMessage();
                    continue;
                }
    
                if ($Discount->canUsedBy($User)) {
                    $discountsValid = true;
                    break;
                }
            }
    
            if (!$discountsValid) {
                if (count($this->discountIds) === 1) {
                    throw new CouponCodeException([
                        'quiqqer/coupons',
                        'exception.CouponCode.discount_invalid',
                        [
                            'reason' => $discountError
                        ]
                    ]);
                } else {
                    throw new CouponCodeException([
                        'quiqqer/coupons',
                        'exception.CouponCode.discounts_invalid'
                    ]);
                }
            }
    
    
            // Max usage restrictions
            switch ($this->maxUsages) {
                case Handler::MAX_USAGE_ONCE_PER_USER:
                    if ($this->hasUserRedeemed($User)) {
                        throw new CouponCodeException([
                            'quiqqer/coupons',
                            'exception.CouponCode.already_used'
                        ]);
                    }
                    break;
    
                case Handler::MAX_USAGE_ONCE:
                    if (!empty($this->usages)) {
                        throw new CouponCodeException([
                            'quiqqer/coupons',
                            'exception.CouponCode.already_used'
                        ]);
                    }
                    break;
            }
    
            // Restriction to QUIQQER user(s)
    
    Patrick Müller's avatar
    Patrick Müller committed
            if (!empty($this->userIds)) {
                if (in_array($User->getId(), $this->userIds)) {
    
                    if ($this->maxUsages !== Handler::MAX_USAGE_UNLIMITED
                        && $this->hasUserRedeemed($User)) {
    
    Patrick Müller's avatar
    Patrick Müller committed
                        throw new CouponCodeException([
                            'quiqqer/coupons',
                            'exception.CouponCode.already_used'
                        ]);
                    }
                } else {
                    throw new CouponCodeException([
                        'quiqqer/coupons',
                        'exception.CouponCode.user_not_allowed'
                    ]);
                }
    
    Patrick Müller's avatar
    Patrick Müller committed
            }
    
    
            // Restriction to QUIQQER group(s)
    
    Patrick Müller's avatar
    Patrick Müller committed
            if (!empty($this->groupIds)) {
                $userInGroup = false;
    
    Patrick Müller's avatar
    Patrick Müller committed
    
    
    Patrick Müller's avatar
    Patrick Müller committed
                foreach ($this->groupIds as $groupId) {
                    if ($User->isInGroup($groupId)) {
                        $userInGroup = true;
                        break;
                    }
                }
    
    Patrick Müller's avatar
    Patrick Müller committed
    
    
    Patrick Müller's avatar
    Patrick Müller committed
                if ($userInGroup) {
    
                    if ($this->maxUsages !== Handler::MAX_USAGE_UNLIMITED
                        && $this->hasUserRedeemed($User)) {
    
    Patrick Müller's avatar
    Patrick Müller committed
                        throw new CouponCodeException([
                            'quiqqer/coupons',
                            'exception.CouponCode.already_used'
                        ]);
                    }
                } else {
                    throw new CouponCodeException([
                        'quiqqer/coupons',
                        'exception.CouponCode.user_not_allowed_group'
                    ]);
                }
            }
    
    Patrick Müller's avatar
    Patrick Müller committed
        }
    
        /**
    
    Patrick Müller's avatar
    Patrick Müller committed
         * Check if the given User can redeem this CouponCode
    
    Patrick Müller's avatar
    Patrick Müller committed
         *
    
    Patrick Müller's avatar
    Patrick Müller committed
         * @param QUI\Users\User $User - If omitted, use session user
    
    Patrick Müller's avatar
    Patrick Müller committed
         * @return bool
         */
    
    Patrick Müller's avatar
    Patrick Müller committed
        public function isRedeemable($User = null)
    
    Patrick Müller's avatar
    Patrick Müller committed
        {
    
    Patrick Müller's avatar
    Patrick Müller committed
            try {
                $this->checkRedemption($User);
            } catch (CouponCodeException $Exception) {
                return false;
            }
    
            return true;
    
    Patrick Müller's avatar
    Patrick Müller committed
        }
    
        /**
    
    Patrick Müller's avatar
    Patrick Müller committed
         * Check if this CouponCode is still valid
    
    Patrick Müller's avatar
    Patrick Müller committed
         *
         * @return bool
         */
    
    Patrick Müller's avatar
    Patrick Müller committed
        public function isValid()
    
    Patrick Müller's avatar
    Patrick Müller committed
        {
    
    Patrick Müller's avatar
    Patrick Müller committed
            return $this->valid;
    
    Patrick Müller's avatar
    Patrick Müller committed
        }
    
        /**
    
    Patrick Müller's avatar
    Patrick Müller committed
         * Checks if an CouponCode has been redeemed by a user
    
    Patrick Müller's avatar
    Patrick Müller committed
         *
    
    Henning Leutz's avatar
    Henning Leutz committed
         * @param QUI\Interfaces\Users\User $User
    
    Patrick Müller's avatar
    Patrick Müller committed
         * @return bool
    
    Patrick Müller's avatar
    Patrick Müller committed
         */
    
    Patrick Müller's avatar
    Patrick Müller committed
        public function hasUserRedeemed($User)
    
    Patrick Müller's avatar
    Patrick Müller committed
        {
    
    Patrick Müller's avatar
    Patrick Müller committed
            $userId = $User->getId();
    
    Patrick Müller's avatar
    Patrick Müller committed
    
    
    Patrick Müller's avatar
    Patrick Müller committed
            foreach ($this->usages as $usage) {
                if ($usage['userId'] === $userId) {
                    return true;
                }
    
    Patrick Müller's avatar
    Patrick Müller committed
            }
    
    
    Patrick Müller's avatar
    Patrick Müller committed
            return false;
    
    Patrick Müller's avatar
    Patrick Müller committed
        }
    
        /**
    
    Patrick Müller's avatar
    Patrick Müller committed
         * Permanently delete this CouponCode
    
    Patrick Müller's avatar
    Patrick Müller committed
         *
         * @return void
    
         * @throws \QUI\Permissions\Exception
    
    Patrick Müller's avatar
    Patrick Müller committed
         */
        public function delete()
        {
            Permission::checkPermission(Handler::PERMISSION_DELETE);
    
            QUI::getDataBase()->delete(
                Handler::getTable(),
    
    Patrick Müller's avatar
    Patrick Müller committed
                [
    
    Patrick Müller's avatar
    Patrick Müller committed
                    'id' => $this->id
    
    Patrick Müller's avatar
    Patrick Müller committed
                ]
    
    Patrick Müller's avatar
    Patrick Müller committed
         * Get CouponCode attributes as array
    
    Patrick Müller's avatar
    Patrick Müller committed
         *
         * @return array
         */
        public function toArray()
        {
    
    Patrick Müller's avatar
    Patrick Müller committed
            $data = [
    
    Patrick Müller's avatar
    Patrick Müller committed
                'id'             => $this->getId(),
                'code'           => $this->getCode(),
    
    Patrick Müller's avatar
    Patrick Müller committed
                'userIds'        => $this->userIds,
                'groupIds'       => $this->groupIds,
    
    Patrick Müller's avatar
    Patrick Müller committed
                'createDate'     => $this->getCreateDate()->format('Y-m-d H:i:s'),
    
    Patrick Müller's avatar
    Patrick Müller committed
                'usages'         => $this->usages,
    
    Patrick Müller's avatar
    Patrick Müller committed
                'validUntilDate' => false,
                'title'          => $this->getTitle() ?: false,
    
    Patrick Müller's avatar
    Patrick Müller committed
                'isValid'        => $this->isValid(),
    
                'maxUsages'      => $this->maxUsages,
    
                'discountIds'    => $this->discountIds
    
    Patrick Müller's avatar
    Patrick Müller committed
            ];
    
    Patrick Müller's avatar
    Patrick Müller committed
    
    
    Patrick Müller's avatar
    Patrick Müller committed
            $ValidUntilDate = $this->getValidUntilDate();
    
    Patrick Müller's avatar
    Patrick Müller committed
    
    
    Patrick Müller's avatar
    Patrick Müller committed
            if ($ValidUntilDate) {
    
                $data['validUntilDate'] = $ValidUntilDate->format('Y-m-d');
    
    Patrick Müller's avatar
    Patrick Müller committed
            }
    
    
    Patrick Müller's avatar
    Patrick Müller committed
            return $data;
        }
    
    Patrick Müller's avatar
    Patrick Müller committed
    
    
    Patrick Müller's avatar
    Patrick Müller committed
        /**
         * Checks if this CouponCode is still valid
         *
         * @return void
         */
        protected function checkValidity()
        {
            // Check if the expiration date has been reached
            if (!empty($this->ValidUntilDate)) {
                $Now = new \DateTime();
    
    Patrick Müller's avatar
    Patrick Müller committed
    
    
    Patrick Müller's avatar
    Patrick Müller committed
                if ($Now > $this->ValidUntilDate) {
                    $this->valid = false;
                    return;
                }
            }
    
    Patrick Müller's avatar
    Patrick Müller committed
    
    
            if ($this->maxUsages === Handler::MAX_USAGE_UNLIMITED) {
                return;
            }
    
            if ($this->maxUsages === Handler::MAX_USAGE_ONCE && !empty($this->usages)) {
                $this->valid = false;
    
    Patrick Müller's avatar
    Patrick Müller committed
                return;
    
    Patrick Müller's avatar
    Patrick Müller committed
            }
    
    
    Patrick Müller's avatar
    Patrick Müller committed
            // If the CouponCode is restricted to certain users -> Check if all those
            // users have already redeemed the code
            if (!empty($this->userIds)) {
                $usedByAllUsers = true;
    
                foreach ($this->userIds as $userId) {
                    foreach ($this->usages as $usage) {
                        if ($userId == $usage['userId']) {
                            continue 2;
                        }
                    }
    
                    $usedByAllUsers = false;
                    break;
                }
    
                if ($usedByAllUsers) {
                    $this->valid = false;
    
    Patrick Müller's avatar
    Patrick Müller committed
                    return;
                }
    
            }
        }
    
        /**
         * @param QUI\ERP\Order\OrderInProcess $Order
         * @throws QUI\Exception
         */
        public function addToOrder(QUI\ERP\Order\OrderInProcess $Order)
        {
            $coupons = $Order->getDataEntry('quiqqer-coupons');
    
            if (!$coupons) {
                return;
            }
    
            if (!is_array($coupons)) {
    
                return;
    
    Patrick Müller's avatar
    Patrick Müller committed
            }
    
    
            $priceFactors = [];
    
    Henning Leutz's avatar
    Henning Leutz committed
            $articles     = [];
    
    
            foreach ($coupons as $coupon) {
                /* @var $Coupon CouponCode */
                try {
                    $Coupon = Handler::getCouponCodeByCode($coupon);
                } catch (\Exception $Exception) {
                    continue;
                }
    
                // coupon check
                if (!$Coupon->isRedeemable($Order->getCustomer())) {
                    continue;
                }
    
                /* @var $Discount QUI\ERP\Discount\Discount */
                $discounts = $Coupon->getDiscounts();
    
                foreach ($discounts as $Discount) {
                    $PriceFactor = $Discount->toPriceFactor();
                    $PriceFactor->setTitle(
                        QUI::getLocale()->get('quiqqer/coupons', 'coupon.discount.title', [
                            'code' => $Coupon->getCode()
                        ])
                    );
    
                    $priceFactors[] = $PriceFactor;
    
    Henning Leutz's avatar
    Henning Leutz committed
    
                    $articles[] = new QUI\ERP\Accounting\Invoice\Articles\Text([
                        'id'          => '-',
                        'articleNo'   => $Coupon->getCode(),
                        'title'       => $PriceFactor->getTitle(),
                        'description' => '',
                        'unitPrice'   => 0,
                        'control'     => '',
                        'quantity'    => 1,
                        'customData'  => [
                            'package' => 'quiqqer/coupon',
                            'code'    => $Coupon->getCode()
                        ]
                    ]);
    
    Henning Leutz's avatar
    Henning Leutz committed
            if (empty($priceFactors)) {
                return;
    
    Henning Leutz's avatar
    Henning Leutz committed
    
            /**
             * @param QUI\ERP\Accounting\Invoice\Articles\Text $Article
             * @return boolean
             */
            $isInArticles = function ($Article) use ($Order) {
                $articles = $Order->getArticles();
                $code     = $Article->getCustomData()['code'];
    
                foreach ($articles as $Entry) {
                    if (!method_exists($Entry, 'getCustomData')) {
                        continue;
                    }
    
                    $customData = $Entry->getCustomData();
    
                    if (!$customData || !is_array($customData)) {
                        continue;
                    }
    
                    if (!isset($customData['package']) || !isset($customData['code'])) {
                        continue;
                    }
    
                    return $customData['package'] === 'quiqqer/coupon'
                           && $customData['code'] === $code;
                }
    
                return false;
            };
    
            foreach ($articles as $Article) {
                /* @var $PriceFactor QUI\ERP\Accounting\Invoice\Articles\Text */
                if ($isInArticles($Article) === false) {
                    $Order->addArticle($Article);
                }
            }
    
            $Order->update();
            $Order->addPriceFactors($priceFactors);
    
    Patrick Müller's avatar
    Patrick Müller committed
        }
    }