Skip to content
Code-Schnipsel Gruppen Projekte
ShippingRule.php 26,2 KiB
Newer Older
<?php

/**
 * This file contains QUI\ERP\Shipping\Rules\ShippingRule
 */

namespace QUI\ERP\Shipping\Rules;

use QUI;
use QUI\CRUD\Factory;
use QUI\ERP\Areas\Utils as AreaUtils;
Henning Leutz's avatar
Henning Leutz committed
use QUI\ERP\Products\Handler\Fields;
use QUI\ERP\Products\Handler\Products;
use QUI\ERP\Products\Utils\Fields as FieldUtils;
Henning Leutz's avatar
Henning Leutz committed
use QUI\ERP\Shipping\Debug;
use QUI\ERP\Shipping\Exceptions\ShippingCanNotBeUsed;
Henning Leutz's avatar
Henning Leutz committed
use QUI\ERP\Shipping\Rules\Factory as RuleFactory;
use QUI\Permissions\Permission;
use QUI\Translator;
Henning Leutz's avatar
Henning Leutz committed
use function array_filter;
use function array_flip;
use function array_map;
use function array_merge;
use function array_unique;
Henning Leutz's avatar
Henning Leutz committed
use function count;
Henning Leutz's avatar
Henning Leutz committed
use function explode;
use function floatval;
use function is_array;
use function is_numeric;
use function is_string;
use function json_decode;
use function json_encode;
use function round;
Henning Leutz's avatar
Henning Leutz committed
use function strpos;
Henning Leutz's avatar
Henning Leutz committed
use function strtotime;
use function time;
use function trim;

/**
 * Class ShippingEntry
 * A user created shipping entry
 *
 * @package QUI\ERP\Shipping\Types
 */
class ShippingRule extends QUI\CRUD\Child
{
    /**
     * Shipping constructor.
     *
     * @param int $id
     * @param Factory $Factory
     */
    public function __construct($id, Factory $Factory)
    {
        parent::__construct($id, $Factory);

        $this->Events->addEvent('onDeleteBegin', function () {
            Permission::checkPermission('quiqqer.shipping.delete');

            // delete locale
            $id = $this->getId();

Henning Leutz's avatar
Henning Leutz committed
            QUI\Translator::delete('quiqqer/shipping', 'shipping.' . $id . '.rule.title');
            QUI\Translator::delete('quiqqer/shipping', 'shipping.' . $id . '.rule.workingTitle');
        });

        $this->Events->addEvent('onSaveBegin', function () {
            Permission::checkPermission('quiqqer.shipping.edit');
Henning Leutz's avatar
Henning Leutz committed

            $id         = $this->getId();
            $attributes = $this->getAttributes();

Henning Leutz's avatar
Henning Leutz committed
            if (is_array($attributes['title'])) {
                QUI\Translator::edit(
Henning Leutz's avatar
Henning Leutz committed
                    'quiqqer/shipping',
Henning Leutz's avatar
Henning Leutz committed
                    'shipping.' . $id . '.rule.title',
Henning Leutz's avatar
Henning Leutz committed
                    'quiqqer/shipping',
                    $attributes['title']
                );
Henning Leutz's avatar
Henning Leutz committed

Henning Leutz's avatar
Henning Leutz committed
            if (is_array($attributes['workingTitle'])) {
                QUI\Translator::edit(
Henning Leutz's avatar
Henning Leutz committed
                    'quiqqer/shipping',
Henning Leutz's avatar
Henning Leutz committed
                    'shipping.' . $id . '.rule.workingTitle',
Henning Leutz's avatar
Henning Leutz committed
                    'quiqqer/shipping',
                    $attributes['workingTitle']
                );
Henning Leutz's avatar
Henning Leutz committed

            QUI\Translator::publish('quiqqer/shipping');
Henning Leutz's avatar
Henning Leutz committed
            $attributes['discount'] = floatval($attributes['discount']);
Henning Leutz's avatar
Henning Leutz committed
            if (is_numeric($attributes['discount_type']) || empty($attributes['discount_type'])) {
                $attributes['discount_type'] = (int)$attributes['discount_type'];
            }

            if ($attributes['discount_type'] === RuleFactory::DISCOUNT_TYPE_PERCENTAGE ||
                $attributes['discount_type'] === 'PERCENTAGE'
            ) {
                $attributes['discount_type'] = RuleFactory::DISCOUNT_TYPE_PERCENTAGE;
            } elseif ($attributes['discount_type'] === RuleFactory::DISCOUNT_TYPE_PC_ORDER ||
Henning Leutz's avatar
Henning Leutz committed
                $attributes['discount_type'] === 'PERCENTAGE_ORDER') {
                $attributes['discount_type'] = RuleFactory::DISCOUNT_TYPE_PC_ORDER;
            } else {
                $attributes['discount_type'] = RuleFactory::DISCOUNT_TYPE_ABS;
            }

Henning Leutz's avatar
Henning Leutz committed
            if (empty($attributes['articles_only'])) {
                $attributes['articles_only'] = 0;
            } else {
                $attributes['articles_only'] = (int)$attributes['articles_only'];
            }

Henning Leutz's avatar
Henning Leutz committed
            if (empty($attributes['no_rule_after'])) {
                $attributes['no_rule_after'] = 0;
            } else {
                $attributes['no_rule_after'] = (int)$attributes['no_rule_after'];
            }

Henning Leutz's avatar
Henning Leutz committed
            if (isset($attributes['unit_terms']) && is_array($attributes['unit_terms'])) {
                $attributes['unit_terms'] = json_encode($attributes['unit_terms']);
Henning Leutz's avatar
Henning Leutz committed
            }

            // null fix
            $nullEmpty = [
                'purchase_quantity_from',
                'purchase_quantity_until',
                'purchase_value_from',
                'purchase_value_until',
Henning Leutz's avatar
Henning Leutz committed
                'unit_terms'
            ];

            foreach ($nullEmpty as $k) {
                if (empty($attributes[$k])) {
                    $attributes[$k] = null;
                }

            // update for saving
            $this->setAttributes($attributes);
    /**
     * Return the payment as an array
     *
     * @return array
     */
    public function toArray()
    {
        $lg = 'quiqqer/shipping';
        $id = $this->getId();

        $attributes = $this->getAttributes();
        $Locale     = QUI::getLocale();

Henning Leutz's avatar
Henning Leutz committed
        $availableLanguages = QUI\Translator::getAvailableLanguages();

        foreach ($availableLanguages as $language) {
            $attributes['title'][$language] = $Locale->getByLang(
                $language,
                $lg,
Henning Leutz's avatar
Henning Leutz committed
                'shipping.' . $id . '.rule.title'
            );

            $attributes['workingTitle'][$language] = $Locale->getByLang(
                $language,
                $lg,
Henning Leutz's avatar
Henning Leutz committed
                'shipping.' . $id . '.rule.workingTitle'
Henning Leutz's avatar
Henning Leutz committed
        $attributes['unit_terms'] = $this->getUnitTerms();

        return $attributes;
    }

    /**
     * Return the shipping rule title
     *
     * @param null $Locale
     * @return string
     */
    public function getTitle($Locale = null)
    {
        if ($Locale === null) {
            $Locale = QUI::getLocale();
        }

        $language = $Locale->getCurrent();
        $id       = $this->getId();

        return $Locale->getByLang(
            $language,
            'quiqqer/shipping',
Henning Leutz's avatar
Henning Leutz committed
            'shipping.' . $id . '.rule.title'
        );
    }

    /**
     * Return the shipping rule priority
     *
     * @return int
     */
    public function getPriority()
    {
        return (int)$this->getAttribute('priority');
    }

    /**
     * Return the shipping rule discount value
     *
     * @return float
     */
    public function getDiscount()
    {
Henning Leutz's avatar
Henning Leutz committed
        return floatval($this->getAttribute('discount'));
    /**
     * is the user allowed to use this shipping
     *
     * @param QUI\Interfaces\Users\User $User
     * @return boolean
     */
    public function canUsedBy(QUI\Interfaces\Users\User $User)
    {
        if ($this->isActive() === false) {
Henning Leutz's avatar
Henning Leutz committed
            Debug::addLog("{$this->getTitle()} :: is not active");

            return false;
        }

        if ($User instanceof QUI\ERP\User) {
            try {
                $User = QUI::getUsers()->get($User->getId());
            } catch (QUI\Exception $Exception) {
            }
        }

        try {
            QUI::getEvents()->fireEvent('quiqqerShippingCanUsedBy', [$this, $User]);
        } catch (ShippingCanNotBeUsed $Exception) {
            return false;
        } catch (QUI\Exception $Exception) {
            QUI\System\Log::writeDebugException($Exception);

            return false;
        }


        // usage definitions / limits
        $dateFrom  = $this->getAttribute('date_from');
        $dateUntil = $this->getAttribute('date_until');
Henning Leutz's avatar
Henning Leutz committed
        $now       = time();
Henning Leutz's avatar
Henning Leutz committed
        if ($dateFrom && strtotime($dateFrom) > $now) {
Henning Leutz's avatar
Henning Leutz committed
            Debug::addLog("{$this->getTitle()} :: date from is not valid {$dateFrom} > {$now}");

            return false;
        }

Henning Leutz's avatar
Henning Leutz committed
        if ($dateUntil && strtotime($dateUntil) < $now) {
Henning Leutz's avatar
Henning Leutz committed
            Debug::addLog("{$this->getTitle()} :: date from is not valid {$dateFrom} < {$now}");

            return false;
        }

        // assignment
        $userGroupValue = $this->getAttribute('user_groups');
        $areasValue     = $this->getAttribute('areas');

        // if groups and areas are empty, everybody is allowed
        if (empty($userGroupValue) && empty($areasValue)) {
Henning Leutz's avatar
Henning Leutz committed
            Debug::addLog("{$this->getTitle()} :: empty user and areas [ok]");

            return true;
        }

        // not in area
        // address need to be checked via order
        // user checking
        $userGroups = QUI\Utils\UserGroups::parseUsersGroupsString(
            $this->getAttribute('user_groups')
        );

        $discountUsers  = $userGroups['users'];
        $discountGroups = $userGroups['groups'];

        if (empty($discountUsers) && empty($discountGroups)) {
Henning Leutz's avatar
Henning Leutz committed
            Debug::addLog("{$this->getTitle()} :: empty discount [ok]");

            return true;
        }

        foreach ($discountUsers as $uid) {
            if ($User->getId() == $uid) {
Henning Leutz's avatar
Henning Leutz committed
                Debug::addLog("{$this->getTitle()} :: user is found in users [ok]");

                return true;
            }
        }

        // group checking
        $groupsOfUser = $User->getGroups();

        /* @var $Group QUI\Groups\Group */
        foreach ($discountGroups as $gid) {
            foreach ($groupsOfUser as $Group) {
                if ($Group->getId() == $gid) {
Henning Leutz's avatar
Henning Leutz committed
                    Debug::addLog("{$this->getTitle()} :: group is found in groups [ok]");

Henning Leutz's avatar
Henning Leutz committed
        Debug::addLog("{$this->getTitle()} :: shipping rule is not valid. is not found in users and groups");

        return false;
    }

    /**
     * Is this shipping rule allowed for this address?
     *
     * @param QUI\ERP\Address|QUI\Users\Address $Address
     * @return bool
     */
    public function canUsedWithAddress($Address)
    {
        $areasValue = $this->getAttribute('areas');

        if ($areasValue) {
Henning Leutz's avatar
Henning Leutz committed
            $areasValue = explode(',', $areasValue);
            $areasValue = array_filter($areasValue);
        }

        if (!empty($areasValue) && !AreaUtils::isAddressInArea($Address, $areasValue)) {
            Debug::addLog("{$this->getTitle()} :: user address is not in areas");

            return false;
        }

        return true;
    }

    /**
     * is the shipping allowed in the order?
     *
     * @param QUI\ERP\Order\OrderInterface $Order
     * @return bool
     */
    public function canUsedInOrder($Order)
        if (!$this->isValid()) {
Henning Leutz's avatar
Henning Leutz committed
            Debug::addLog("{$this->getTitle()} :: is not valid");

            return false;
        }

        if (!($Order instanceof QUI\ERP\Order\OrderInterface)) {
            return true;
        }

        if (!$this->canUsedBy($Order->getCustomer())) {
Henning Leutz's avatar
Henning Leutz committed
            Debug::addLog("{$this->getTitle()} :: can not be used by {$Order->getCustomer()->getId()}");

            return false;
        }

        $DeliveryAddress = $Order->getDeliveryAddress();

        if (!$this->canUsedWithAddress($DeliveryAddress)) {
            Debug::addLog("{$this->getTitle()} :: can not be used with address");

            return false;
        }

        /* @var $Order QUI\ERP\Order\Order */
        $Articles    = $Order->getArticles();
        $articleList = $Articles->getArticles();

        if (!$Articles->count()) {
            return false;
        }

        $articles    = $this->getAttribute('articles');
Henning Leutz's avatar
Henning Leutz committed
        $categories  = $this->getAttribute('categories');
        $articleOnly = (int)$this->getAttribute('articles_only');
Henning Leutz's avatar
Henning Leutz committed
        $unitTerms   = $this->getUnitTerms();

        $quantityFrom  = $this->getAttribute('purchase_quantity_from');     // Einkaufsmenge ab
        $quantityUntil = $this->getAttribute('purchase_quantity_until');    // Einkaufsmenge bis
        $purchaseFrom  = $this->getAttribute('purchase_value_from');        // Einkaufswert ab
        $purchaseUntil = $this->getAttribute('purchase_value_until');       // Einkaufswert bis

        // article checks
Henning Leutz's avatar
Henning Leutz committed
        $Shipping     = QUI\ERP\Shipping\Shipping::getInstance();
        $unitIds      = $Shipping->getShippingRuleUnitFieldIds();
        $articleFound = true;
        $articleUnits = [];
Henning Leutz's avatar
Henning Leutz committed
        $debugUnits   = [];

        if (!empty($articles)) {
            $articleFound = false;

Henning Leutz's avatar
Henning Leutz committed
            if (is_string($articles)) {
                $articles = explode(',', $articles);
                $articles = array_filter($articles);
Henning Leutz's avatar
Henning Leutz committed
            if (!is_array($articles)) {
                $articles = [$articles];
            }

Henning Leutz's avatar
Henning Leutz committed
            $articles = array_flip($articles);
        } else {
            $articleOnly = 0;
        $categoryIdsInOrder = [];

        foreach ($articleList as $Article) {
            $aid             = $Article->getId();
            $articleQuantity = $Article->getQuantity();
Henning Leutz's avatar
Henning Leutz committed
            // get product because of units
                $Product           = Products::getProduct($aid);
                $productCategories = $Product->getCategories();

Henning Leutz's avatar
Henning Leutz committed
                $categoryIds = array_map(function ($Category) {
                    return $Category->getId();
                }, $productCategories);

Henning Leutz's avatar
Henning Leutz committed
                $categoryIdsInOrder = array_merge($categoryIdsInOrder, $categoryIds);
Henning Leutz's avatar
Henning Leutz committed
                foreach ($unitIds as $unitId) {
                    $Weight = $Product->getField($unitId);
                    $weight = $Weight->getValue();

                    if ((int)$unitId === Fields::FIELD_WEIGHT) {
Henning Leutz's avatar
Henning Leutz committed
                        $weight = FieldUtils::weightFieldToKilogram($Weight);
                    }

Henning Leutz's avatar
Henning Leutz committed
                    if (is_array($weight)) {
                        $weight = $weight['quantity'];
                    }

Henning Leutz's avatar
Henning Leutz committed
                    if (!isset($articleUnits[$unitId])) {
                        $articleUnits[$unitId] = 0;
                    }

                    $articleUnits[$unitId] = $articleUnits[$unitId] + ($weight * $articleQuantity);
Henning Leutz's avatar
Henning Leutz committed

                    $debugUnits[$unitId] = [
                        'field'  => $Weight->getTitle(),
                        'amount' => $articleUnits[$unitId]
                    ];
            } catch (QUI\Exception $Exception) {
                QUI\System\Log::writeDebugException($Exception);
            }

            if (empty($articles)) {
                continue;
            }

            if (isset($articles[$aid])) {
                $articleFound = true;
                break;
            }
        }

Henning Leutz's avatar
Henning Leutz committed
        if (QUI\ERP\Shipping\Debug::isEnabled()) {
            foreach ($debugUnits as $debugUnit) {
                QUI\ERP\Shipping\Debug::addLog(
                    "- Check units {$debugUnit['field']} -> {$debugUnit['amount']}"
                );
            }
        }

Henning Leutz's avatar
Henning Leutz committed
        if ($articleFound && $articleOnly && count($articleList) !== 1) {
Henning Leutz's avatar
Henning Leutz committed
            QUI\ERP\Shipping\Debug::addLog(
                "{$this->getTitle()} :: is not a single article"
            );

        if ($articleFound === false) {
Henning Leutz's avatar
Henning Leutz committed
            QUI\ERP\Shipping\Debug::addLog(
                "{$this->getTitle()} :: article not found for this rule"
            );

            return false;
        }

        // category check
Henning Leutz's avatar
Henning Leutz committed
        $categoryIdsInOrder = array_unique($categoryIdsInOrder);

        $categories = trim($categories, ',');
        $categories = explode(',', $categories);
Henning Leutz's avatar
Henning Leutz committed
        $categories = array_map('intval', $categories);

        if (!empty($categoryIdsInOrder)
            && !empty($categories)
Henning Leutz's avatar
Henning Leutz committed
            && (count($categories) === 1 && $categories[0] !== 0)
        ) {
            $found = false;

            foreach ($categories as $cid) {
Henning Leutz's avatar
Henning Leutz committed
                if (in_array($cid, $categoryIdsInOrder)) {
                    $found = true;
                    break;
                }
            }

            if ($found === false) {
                return false;
            }
        }

Henning Leutz's avatar
Henning Leutz committed
        // unit terms check
        if (!empty($unitTerms)) {
            foreach ($unitTerms as $unitTerm) {
Henning Leutz's avatar
Henning Leutz committed
                if (!is_array($unitTerm)) {
Henning Leutz's avatar
Henning Leutz committed
                    continue;
                }
                if (!isset($unitTerm['value'])) {
                    $unitTerm['value'] = '';
                }

                if (!isset($unitTerm['value2'])) {
                    $unitTerm['value2'] = '';
                }

                if ($unitTerm['value'] === '' && $unitTerm['value2'] === '') {
                if (empty($unitTerm['term'])) {
                    $unitTerm['term'] = 'gt';
                }

                if (empty($unitTerm['term2'])) {
                    $unitTerm['term2'] = 'gt';
                }

Henning Leutz's avatar
Henning Leutz committed
                $id    = (int)$unitTerm['id'];
                $unit  = $unitTerm['unit'];
Henning Leutz's avatar
Henning Leutz committed
                $value = floatval($unitTerm['value']);
Henning Leutz's avatar
Henning Leutz committed
                $term  = $unitTerm['term'];
Henning Leutz's avatar
Henning Leutz committed
                $hTerm = FieldUtils::termToHuman($term);
Henning Leutz's avatar
Henning Leutz committed

                if (!isset($articleUnits[$id])) {
                    continue;
                }

                if ($id === Fields::FIELD_WEIGHT) {
                    $unitValue = FieldUtils::weightToKilogram($value, $unit);
                    $compare   = FieldUtils::compare($articleUnits[$id], $unitValue, $term);

                    if ($compare === false) {
Henning Leutz's avatar
Henning Leutz committed
                        QUI\ERP\Shipping\Debug::addLog(
Henning Leutz's avatar
Henning Leutz committed
                            "{$this->getTitle()} :: weight is not valid {$articleUnits[$id]} {$hTerm} {$unitValue}"
Henning Leutz's avatar
Henning Leutz committed
                        return false;
                    }

                    // term 2
                    if (!empty($unitTerm['value2'])) {
Henning Leutz's avatar
Henning Leutz committed
                        $value2 = floatval($unitTerm['value2']);
Henning Leutz's avatar
Henning Leutz committed
                        $hTerm2 = FieldUtils::termToHuman($term2);

                        $unitValue = FieldUtils::weightToKilogram($value2, $unit);
                        $compare2  = FieldUtils::compare($articleUnits[$id], $unitValue, $term2);

                        if ($compare2 === false) {
Henning Leutz's avatar
Henning Leutz committed
                            QUI\ERP\Shipping\Debug::addLog(
Henning Leutz's avatar
Henning Leutz committed
                                "{$this->getTitle()} :: weight is not valid {$articleUnits[$id]} {$hTerm2} {$unitValue}"
Henning Leutz's avatar
Henning Leutz committed
                    continue;
                }

                $compare = FieldUtils::compare($articleUnits[$id], $value, $term);

                if ($compare === false) {
Henning Leutz's avatar
Henning Leutz committed
                    QUI\ERP\Shipping\Debug::addLog(
Henning Leutz's avatar
Henning Leutz committed
                        "{$this->getTitle()} :: unit term is not valid {$articleUnits[$id]} {$hTerm} {$value}"
Henning Leutz's avatar
Henning Leutz committed
                    return false;
                }
Henning Leutz's avatar
Henning Leutz committed
                    $value2   = floatval($unitTerm['value2']);
Henning Leutz's avatar
Henning Leutz committed
                    $hTerm2   = FieldUtils::termToHuman($term2);
                    $compare2 = FieldUtils::compare($articleUnits[$id], $value2, $term2);

                    if ($compare2 === false) {
Henning Leutz's avatar
Henning Leutz committed
                        QUI\ERP\Shipping\Debug::addLog(
Henning Leutz's avatar
Henning Leutz committed
                            "{$this->getTitle()} :: unit term is not valid {$articleUnits[$id]} {$hTerm2} {$value2}"
            }
        }


        // quantity check
        $count = $Order->count();

        if (!empty($quantityFrom) && $quantityFrom < $count) {
Henning Leutz's avatar
Henning Leutz committed
            QUI\ERP\Shipping\Debug::addLog(
                "{$this->getTitle()} :: quantity from is not valid, {$count} < {$quantityFrom}"
            );

            return false;
        }

        if (!empty($quantityUntil) && $quantityFrom > $count) {
Henning Leutz's avatar
Henning Leutz committed
            QUI\ERP\Shipping\Debug::addLog(
                "{$this->getTitle()} :: quantity until is not valid, {$count} > {$quantityFrom}"
            );

            return false;
        }

        // purchase
        try {
Henning Leutz's avatar
Henning Leutz committed
            $Calculation    = $Order->getPriceCalculation();
            $Currency       = $Order->getCurrency();
            $PriceFactors   = $Order->getArticles()->getPriceFactors();
            $ShippingFactor = null;

            /* @var $Factor QUI\ERP\Products\Interfaces\PriceFactorInterface */
            foreach ($PriceFactors as $Factor) {
Henning Leutz's avatar
Henning Leutz committed
                if (strpos($Factor->getIdentifier(), 'shipping-pricefactor') !== false) {
Henning Leutz's avatar
Henning Leutz committed
                    $ShippingFactor = $Factor;
                    break;
                }
            }

            $Sum = $Calculation->getNettoSum();
            $sum = $Sum->precision($Currency->getPrecision())->get();

            /* quiqqer/shipping#25 */
            if ($ShippingFactor) {
Henning Leutz's avatar
Henning Leutz committed
                $sum = $sum - round($ShippingFactor->getNettoSum(), $Currency->getPrecision());
        } catch (QUI\Exception $Exception) {
            QUI\System\Log::writeDebugException($Exception);

            return false;
        }

        if (!empty($purchaseFrom)) {
            $purchaseFrom = QUI\Erp\Money\Price::validatePrice($purchaseFrom);
Henning Leutz's avatar
Henning Leutz committed
                QUI\ERP\Shipping\Debug::addLog(
                    "{$this->getTitle()} :: purchase from is not valid, {$purchaseFrom} < {$sum}"
                );

                return false;
            }
        }

        if (!empty($purchaseUntil)) {
            $purchaseUntil = QUI\Erp\Money\Price::validatePrice($purchaseUntil);
Henning Leutz's avatar
Henning Leutz committed
                QUI\ERP\Shipping\Debug::addLog(
                    "{$this->getTitle()} :: purchase from is not valid, {$purchaseFrom} > {$sum}"
                );

        // categories check
        try {
            QUI::getEvents()->fireEvent('shippingCanUsedInOrder', [$this, $Order]);
        } catch (ShippingCanNotBeUsed $Exception) {
            return false;
        } catch (QUI\Exception $Exception) {
            QUI\System\Log::addDebug($Exception->getMessage());

            return false;
        }

Henning Leutz's avatar
Henning Leutz committed
        QUI\ERP\Shipping\Debug::addLog(
            "{$this->getTitle()} :: is valid [ok]"
        );

        return true;
    }

    /**
     * no further rules are used after this rule
     *
     * @return bool
     */
    public function noRulesAfter()
    {
        if ($this->existsAttribute('no_rule_after')) {
            return !!$this->getAttribute('no_rule_after');
        }

        return false;
    }

    /**
     * Return the validation status of this rule
     * can the rule be used?
     */
    public function isValid()
    {
        if (!$this->isActive()) {
Henning Leutz's avatar
Henning Leutz committed
            QUI\ERP\Shipping\Debug::addLog(
Henning Leutz's avatar
Henning Leutz committed
                $this->getTitle() . " :: is not active"
            return false;
        }

        // check date
        $usageFrom  = $this->getAttribute('date_from');
        $usageUntil = $this->getAttribute('date_until');
Henning Leutz's avatar
Henning Leutz committed
        $time       = time();

        if (!empty($usageFrom)) {
Henning Leutz's avatar
Henning Leutz committed
            $usageFrom = strtotime($usageFrom);

            if ($usageFrom > $time) {
Henning Leutz's avatar
Henning Leutz committed
                QUI\ERP\Shipping\Debug::addLog(
Henning Leutz's avatar
Henning Leutz committed
                    $this->getTitle() . " :: usage from is not ok, {$usageFrom} > {$time}"
                return false;
            }
        }

        if (!empty($usageUntil)) {
Henning Leutz's avatar
Henning Leutz committed
            $usageUntil = strtotime($usageUntil);

            if ($usageUntil < $time) {
Henning Leutz's avatar
Henning Leutz committed
                QUI\ERP\Shipping\Debug::addLog(
Henning Leutz's avatar
Henning Leutz committed
                    $this->getTitle() . " :: usage from is not ok, {$usageFrom} < {$time}"
Henning Leutz's avatar
Henning Leutz committed
        QUI\ERP\Shipping\Debug::addLog(
Henning Leutz's avatar
Henning Leutz committed
            $this->getTitle() . " :: is valid, date from to is valid"
    /**
     * Return the discount type
     *
     * @return int
     */
    public function getDiscountType()
    {
        return (int)$this->getAttribute('discount_type');
    }

Henning Leutz's avatar
Henning Leutz committed
    /**
     * Return the unit terms
     *
     * @return bool|array
     */
    public function getUnitTerms()
    {
        $unitTerms = $this->getAttribute('unit_terms');

        if (empty($unitTerms)) {
            return false;
        }

Henning Leutz's avatar
Henning Leutz committed
        $unitTerms = json_decode($unitTerms, true);
Henning Leutz's avatar
Henning Leutz committed

        if ($unitTerms) {
            return $unitTerms;
        }

        return false;
    }

    // region activation / deactivation

    /**
     * Activate the shipping type
     *
     * @throws QUI\ExceptionStack|QUI\Exception
     */
    public function activate()
    {
        $this->setAttribute('active', 1);
        $this->update();
        $this->refresh();
    }

    /**
     * Is the shipping active?
     *
     * @return bool
     */
    public function isActive()
    {
        return !!$this->getAttribute('active');
    }

    /**
     * Deactivate the shipping type
     *
     * @throws QUI\ExceptionStack|QUI\Exception
     */
    public function deactivate()
    {
        $this->setAttribute('active', 0);
        $this->update();
        $this->refresh();
    }

    //endregion

    //region setter

    /**
     * Set the title
     *
     * @param array $titles
     */
    public function setTitle(array $titles)
    {
        $this->setLocaleVar(
Henning Leutz's avatar
Henning Leutz committed
            'shipping.' . $this->getId() . '.rule.title',
            $titles
        );
    }

    /**
     * Set the working title
     *
     * @param array $titles
     */
    public function setWorkingTitle(array $titles)
    {
        $this->setLocaleVar(
Henning Leutz's avatar
Henning Leutz committed
            'shipping.' . $this->getId() . '.rule.workingTitle',
            $titles
        );
    }

    /**
     * Creates a locale
     *
     * @param string $var
     * @param array $title
     */
    protected function setLocaleVar($var, $title)
    {
        $data = [
            'datatype' => 'php,js',
            'package'  => 'quiqqer/shipping'
        ];

        $languages = QUI::availableLanguages();

        foreach ($languages as $language) {
            if (!isset($title[$language])) {
                continue;
            }

Henning Leutz's avatar
Henning Leutz committed
            $data[$language]           = $title[$language];
            $data[$language . '_edit'] = $title[$language];
        }

        $exists = Translator::getVarData('quiqqer/shipping', $var, 'quiqqer/shipping');

        try {
            if (empty($exists)) {
                Translator::addUserVar('quiqqer/shipping', $var, $data);
            } else {
                Translator::edit('quiqqer/shipping', $var, 'quiqqer/shipping', $data);
            }
        } catch (QUI\Exception $Exception) {
            QUI\System\Log::addNotice($Exception->getMessage());
        }

        try {
            Translator::publish('quiqqer/shipping');
        } catch (QUi\Exception $Exception) {
            QUI\System\Log::writeException($Exception);
        }
    }

    //endregion