Skip to content
Code-Schnipsel Gruppen Projekte
Price.php 6,56 KiB
Newer Older
  • Learn to ignore specific revisions
  • <?php
    
    /**
     * This file contains QUI\ERP\Money\Price
     */
    
    namespace QUI\ERP\Money;
    
    use QUI;
    
    use QUI\ERP\Currency\Currency;
    
    use QUI\ERP\Discount\Discount;
    
    use QUI\Interfaces\Users\User;
    
    Henning Leutz's avatar
    Henning Leutz committed
    use function floatval;
    use function is_float;
    
    Henning Leutz's avatar
    Henning Leutz committed
    use function is_int;
    
    Henning Leutz's avatar
    Henning Leutz committed
    use function mb_strpos;
    use function mb_substr;
    use function preg_replace;
    use function round;
    use function str_replace;
    use function trim;
    
    
    /**
     * Class Price
     * @package QUI\ERP\Products\Price
     */
    class Price
    {
        /**
         * Netto Price
    
        protected float | int $price;
    
    
        /**
         * Price currency
         * @var QUI\ERP\Currency\Currency
         */
    
    Henning Leutz's avatar
    Henning Leutz committed
        protected QUI\ERP\Currency\Currency $Currency;
    
        /**
         * Flag for Price from
         * @var bool
         */
    
    Henning Leutz's avatar
    Henning Leutz committed
        protected bool $isMinimalPrice = false;
    
    Henning Leutz's avatar
    Henning Leutz committed
        protected array $discounts;
    
         * @var ?QUI\Interfaces\Users\User
    
        protected ?QUI\Interfaces\Users\User $User = null;
    
    Henning Leutz's avatar
    Henning Leutz committed
         * @param float|int|null $price
    
         * @param Currency $Currency
         * @param User|null $User - optional, if no user, session user are used
    
            float | int | null $price,
    
            QUI\ERP\Currency\Currency $Currency,
    
            null | QUI\Interfaces\Users\User $User = null
    
    Henning Leutz's avatar
    Henning Leutz committed
            if (!$price) {
                $price = 0;
            }
    
    
    Henning Leutz's avatar
    Henning Leutz committed
            $this->price = $price;
    
    Henning Leutz's avatar
    Henning Leutz committed
            $this->User = $User;
    
            $this->discounts = [];
    
    
            if (!QUI::getUsers()->isUser($User)) {
                $this->User = QUI::getUserBySession();
            }
        }
    
        /**
         * Return the price as array notation
         * @return array
         */
    
        public function toArray(): array
    
            return [
    
    Henning Leutz's avatar
    Henning Leutz committed
                'price' => $this->value(),
                'currency' => $this->getCurrency()->getCode(),
                'display' => $this->getDisplayPrice(),
    
                'isMinimalPrice' => $this->isMinimalPrice()
    
    Henning Leutz's avatar
    Henning Leutz committed
         * Return the real price
    
        public function getPrice(): float | int | null
    
    Henning Leutz's avatar
    Henning Leutz committed
            return $this->validatePrice($this->price);
    
        /**
         * Alias for getPrice
         *
    
        public function value(): float | int | null
    
        {
            return $this->getPrice();
        }
    
    
        /**
         * Alias for getPrice
         *
    
        public function getValue(): float | int | null
    
        {
            return $this->getPrice();
        }
    
    
        /**
         * Return the price for the view / displaying
         *
         * @return string
         */
    
        public function getDisplayPrice(): string
    
            return $this->Currency->format($this->getPrice());
    
        }
    
        /**
         * Add a discount to the price
         *
         * @param QUI\ERP\Discount\Discount $Discount
         * @throws QUI\Exception
         */
    
        public function addDiscount(Discount $Discount): void
    
        {
            /* @var $Disc Discount */
            foreach ($this->discounts as $Disc) {
                // der gleiche discount kann nur einmal enthalten sein
                if ($Disc->getId() == $Discount->getId()) {
                    return;
                }
    
                if ($Disc->canCombinedWith($Discount) === false) {
    
                    throw new QUI\Exception([
    
                        'quiqqer/products',
                        'exception.discount.not.combinable',
    
                            'id1' => $Disc->getId(),
                            'id2' => $Discount->getId()
    
                }
            }
    
            $this->discounts[] = $Discount;
        }
    
        /**
         * Return the assigned discounts
         *
         * @return array [Discount, Discount, Discount]
         */
    
        public function getDiscounts(): array
    
        {
            return $this->discounts;
        }
    
        /**
         * Return the currency from the price
         *
         * @return QUI\ERP\Currency\Currency
         */
    
        public function getCurrency(): QUI\ERP\Currency\Currency
    
        {
            return $this->Currency;
        }
    
        /**
         * calculation
         */
    
        /**
         * Validates a price value
         *
    
    Henning Leutz's avatar
    Henning Leutz committed
         * @param mixed $value
    
         * @param QUI\Locale|null $Locale - based locale, in which the price is
    
         * @return float|int|null
    
        public static function validatePrice(
            mixed $value,
            null | QUI\Locale $Locale = null
        ): float | int | null {
    
            if (is_float($value) || is_int($value)) {
    
    Henning Leutz's avatar
    Henning Leutz committed
                return round($value, QUI\ERP\Defaults::getPrecision());
    
            if ($value instanceof Price) {
                $value = $value->getPrice();
            }
    
    
    Henning Leutz's avatar
    Henning Leutz committed
            $value = (string)$value;
    
            $isNegative = str_starts_with($value, '-');
    
    
            // value cleanup
    
    Henning Leutz's avatar
    Henning Leutz committed
            $value = preg_replace('#[^\d,.]#i', '', $value);
    
    Henning Leutz's avatar
    Henning Leutz committed
            if (trim($value) === '') {
    
            if ($Locale === null) {
                $Locale = QUI::getSystemLocale();
            }
    
    
            $negativeTurn = 1;
    
            if ($isNegative) {
                $negativeTurn = -1;
            }
    
    
    Henning Leutz's avatar
    Henning Leutz committed
            $decimalSeparator = $Locale->getDecimalSeparator();
    
            $thousandSeparator = $Locale->getGroupingSeparator();
    
    Henning Leutz's avatar
    Henning Leutz committed
            $decimal = mb_strpos($value, $decimalSeparator);
    
    Henning Leutz's avatar
    Henning Leutz committed
            $thousands = mb_strpos($value, $thousandSeparator);
    
    
            if ($thousands === false && $decimal === false) {
    
    Henning Leutz's avatar
    Henning Leutz committed
                return round(floatval($value), 4) * $negativeTurn;
    
    Henning Leutz's avatar
    Henning Leutz committed
            if ($thousands !== false && $decimal === false) {
    
    Henning Leutz's avatar
    Henning Leutz committed
                if (mb_substr($value, -4, 1) === $thousandSeparator) {
                    $value = str_replace($thousandSeparator, '', $value);
    
    Henning Leutz's avatar
    Henning Leutz committed
                }
            }
    
            if ($thousands === false && $decimal !== false) {
    
    Henning Leutz's avatar
    Henning Leutz committed
                $value = str_replace($decimalSeparator, '.', $value);
    
    Henning Leutz's avatar
    Henning Leutz committed
            if ($thousands !== false && $decimal !== false) {
    
    Henning Leutz's avatar
    Henning Leutz committed
                $value = str_replace($thousandSeparator, '', $value);
                $value = str_replace($decimalSeparator, '.', $value);
    
    Henning Leutz's avatar
    Henning Leutz committed
            }
    
    Henning Leutz's avatar
    Henning Leutz committed
            $value = floatval($value);
            $value = round($value, QUI\ERP\Defaults::getPrecision());
    
         * Return if the price is minimal price and higher prices exists
    
        public function isMinimalPrice(): bool
    
        {
            return $this->isMinimalPrice;
        }
    
        /**
         * enables the minimal price
         * -> price from
         * -> ab
         */
    
        public function enableMinimalPrice(): void
    
        {
            $this->isMinimalPrice = true;
        }
    
        /**
         * enables the minimal price
         * -> price from
         * -> ab
         */
    
        public function disableMinimalPrice(): void