Skip to content
Code-Schnipsel Gruppen Projekte
ArticleList.php 13,5 KiB
Newer Older
  • Learn to ignore specific revisions
  • <?php
    
    /**
     * This file contains QUI\ERP\Accounting\ArticleList
     */
    
    namespace QUI\ERP\Accounting;
    
    
    Henning Leutz's avatar
    Henning Leutz committed
    use IteratorAggregate;
    
    use QUI\ERP\Accounting\PriceFactors\Factor;
    use QUI\ERP\Currency\Currency;
    use QUI\ERP\Exception;
    use QUI\Interfaces\Users\User;
    
    
    Henning Leutz's avatar
    Henning Leutz committed
    use function count;
    use function is_null;
    
    use function key;
    use function round;
    
    /**
     * Class ArticleList
     *
     * @package QUI\ERP\Accounting
     */
    
    Henning Leutz's avatar
    Henning Leutz committed
    class ArticleList extends ArticleListUnique implements IteratorAggregate
    
        /**
         * is the article list calculated?
         * @var bool
         */
    
    Henning Leutz's avatar
    Henning Leutz committed
        protected bool $calculated = false;
    
         * @var int|float
    
        /**
         * @var int|float
         */
    
        protected int|float $grandSubSum;
    
         * @var ?QUI\Interfaces\Users\User
    
        protected QUI\Interfaces\Users\User|null $User = null;
    
    Henning Leutz's avatar
    Henning Leutz committed
         * @var ?QUI\ERP\Order\AbstractOrder
    
    Henning Leutz's avatar
    Henning Leutz committed
        protected ?QUI\ERP\Order\AbstractOrder $Order = null;
    
    Henning Leutz's avatar
    Henning Leutz committed
         * @var ?QUI\ERP\Currency\Currency
    
    Henning Leutz's avatar
    Henning Leutz committed
        protected ?QUI\ERP\Currency\Currency $Currency = null;
    
         * @var int|float
    
         * @var int|float
    
        protected int|float $nettoSum;
    
         * @var int|float
    
        protected int|float $nettoSubSum;
    
    Henning Leutz's avatar
    Henning Leutz committed
         * key 19% value[sum] = sum value[text] = text value[display_sum] formatted
         *
    
    Henning Leutz's avatar
    Henning Leutz committed
        protected array $vatArray = [];
    
    Henning Leutz's avatar
    Henning Leutz committed
         * key 19% value[sum] = sum value[text] = text value[display_sum] formatted
         *
         * @var array
    
    Henning Leutz's avatar
    Henning Leutz committed
        protected array $vatText;
    
    
        /**
         * Prüfen ob EU Vat für den Benutzer in Frage kommt
         */
    
    Henning Leutz's avatar
    Henning Leutz committed
        protected bool $isEuVat = false;
    
    
        /**
         * Wird Brutto oder Netto gerechnet
    
    Henning Leutz's avatar
    Henning Leutz committed
        protected bool $isNetto = true;
    
    
        /**
         * Currency information
    
    Henning Leutz's avatar
    Henning Leutz committed
        protected array $currencyData = [
    
            'currency_sign' => '',
            'currency_code' => '',
            'user_currency' => '',
            'currency_rate' => ''
    
    
        /**
         * ArticleList constructor.
    
         * @param array $attributes
    
         * @throws Exception|QUI\Exception
    
        public function __construct(array $attributes = [])
    
        {
            if (!isset($attributes['calculations'])) {
    
                $attributes['calculations'] = [];
    
            }
    
            if (!isset($attributes['articles'])) {
    
                $attributes['articles'] = [];
            }
    
            if (!isset($attributes['priceFactors'])) {
                $attributes['priceFactors'] = [];
    
            }
    
            parent::__construct($attributes);
    
    Henning Leutz's avatar
    Henning Leutz committed
    
            if (!empty($this->calculations)) {
                $this->calculated = true;
            }
    
        }
    
        /**
         * Set the user for the list
         * User for calculation
         *
         * @param QUI\Interfaces\Users\User $User
         */
    
        public function setUser(QUI\Interfaces\Users\User $User): void
    
            $this->User = $User;
    
    
            foreach ($this->articles as $Article) {
                $Article->setUser($User);
            }
    
            $this->calc();
    
        }
    
        /**
         * Return the list user
         *
    
    Henning Leutz's avatar
    Henning Leutz committed
        public function getUser(): ?QUI\Interfaces\Users\User
    
        /**
         * Return the currency
         *
    
        public function getCurrency(): ?QUI\ERP\Currency\Currency
    
    Henning Leutz's avatar
    Henning Leutz committed
            if (!is_null($this->Currency)) {
    
    Henning Leutz's avatar
    Henning Leutz committed
            if (!empty($this->currencyData['currency_code'])) {
    
                try {
                    $this->Currency = QUI\ERP\Currency\Handler::getCurrency(
                        $this->currencyData['currency_code']
                    );
    
                    return $this->Currency;
    
        }
    
        /**
         * Set the currency for the list
         *
         * @param QUI\ERP\Currency\Currency $Currency
         */
    
        public function setCurrency(QUI\ERP\Currency\Currency $Currency): void
    
            $this->Currency = $Currency;
    
    
            $this->currencyData = [
                'currency_sign' => $this->Currency->getSign(),
                'currency_code' => $this->Currency->getCode(),
                'user_currency' => '',
                'currency_rate' => $this->Currency->getExchangeRate()
            ];
    
            if (isset($this->calculations['currencyData'])) {
                $this->calculations['currencyData'] = [
                    'code' => $this->Currency->getCode(),
                    'sign' => $this->Currency->getSign(),
                    'rate' => $this->Currency->getExchangeRate()
                ];
            }
    
    Henning Leutz's avatar
    Henning Leutz committed
            if (count($this->articles)) {
    
                foreach ($this->articles as $Article) {
                    $Article->setCurrency($Currency);
                }
            }
    
    Henning Leutz's avatar
    Henning Leutz committed
    
            $PriceFactors = $this->getPriceFactors();
            $priceFactors = $PriceFactors->toArray();
    
            foreach ($priceFactors as $k => $factor) {
    
                $priceFactors[$k]['sumFormatted'] = $Currency->format($factor['sum']);
    
    Henning Leutz's avatar
    Henning Leutz committed
                $priceFactors[$k]['nettoSumFormatted'] = $Currency->format($factor['nettoSum']);
    
                $priceFactors[$k]['valueText'] = $priceFactors[$k]['sumFormatted'];
    
    Henning Leutz's avatar
    Henning Leutz committed
    
                if ($factor['sum'] > 0) {
                    $priceFactors[$k]['valueText'] = '+' . $priceFactors[$k]['sumFormatted'];
                }
            }
    
            $this->PriceFactors = new QUI\ERP\Accounting\PriceFactors\FactorList($priceFactors);
    
        }
    
        /**
         * Return the list as an array
         *
         * @return array
         */
    
        public function toArray(): array
    
        {
            $data = parent::toArray();
    
            if (empty($data['calculations'])) {
                return $data;
            }
    
            $Currency = $this->getCurrency();
    
            // format
    
            $articles = $data['articles'];
    
            $calculations = $data['calculations'];
    
    
            $calculations['currencyData'] = $Currency->toArray();
    
    
            $calculations['vatSum'] = QUI\ERP\Accounting\Calc::calculateTotalVatOfInvoice(
                $calculations['vatArray']
            );
    
            $calculations['display_subSum'] = $Currency->format($calculations['subSum']);
    
            $calculations['display_sum'] = $Currency->format($calculations['sum']);
    
            $calculations['display_vatSum'] = $Currency->format($calculations['vatSum']);
    
            foreach ($articles as $key => $article) {
    
                $articles[$key]['position'] = $key + 1;
                $articles[$key]['display_sum'] = $Currency->format($article['sum']);
    
                $articles[$key]['display_unitPrice'] = $Currency->format($article['unitPrice']);
            }
    
    
            $data['articles'] = $articles;
    
            $data['calculations'] = $calculations;
    
    
            /* @var $Factor PriceFactors\Factor */
            foreach ($this->PriceFactors as $Factor) {
    
                if (!$Factor->isVisible()) {
                    continue;
                }
    
    
                $key = 'attributes';
    
                if ($Factor->getCalculationBasis() === QUI\ERP\Accounting\Calc::CALCULATION_GRAND_TOTAL) {
                    $key = 'grandTotalFactors';
                }
    
                $data[$key][] = [
    
                    'title' => $Factor->getTitle(),
                    'value' => $Factor->getSumFormatted(),
    
                    'valueText' => ''
    
        /**
         * Parse this ArticleList to an ArticleListUnique
         *
         * @return ArticleListUnique
    
         * @throws QUI\Exception
    
        public function toUniqueList(): ArticleListUnique
    
            $List = new ArticleListUnique($this->toArray(), $this->getUser());
    
            if ($this->ExchangeCurrency) {
                $List->setExchangeCurrency($this->ExchangeCurrency);
            }
    
            return $List;
    
         * @param ?QUI\ERP\Accounting\Calc $Calc
    
        public function recalculate(?QUI\ERP\Accounting\Calc $Calc = null): void
    
    
            foreach ($this->articles as $Article) {
    
                if ($this->User) {
                    $Article->setUser($this->User);
                }
    
         * @param null|QUI\ERP\Accounting\Calc $Calc $Calc
    
        public function calc(?QUI\ERP\Accounting\Calc $Calc = null): ArticleList
    
            if (!$Calc) {
                $Calc = Calc::getInstance();
    
                if ($this->User) {
                    $Calc->setUser($this->User);
                }
            }
    
    
            $Calc->calcArticleList($this, function ($data) {
                $self = $this;
    
                $self->sum = $data['sum'];
                $self->grandSubSum = $data['grandSubSum'];
                $self->subSum = $data['subSum'];
                $self->nettoSum = $data['nettoSum'];
                $self->nettoSubSum = $data['nettoSubSum'];
                $self->vatArray = $data['vatArray'];
                $self->vatText = $data['vatText'];
                $self->isEuVat = $data['isEuVat'];
                $self->isNetto = $data['isNetto'];
    
                $self->currencyData = $data['currencyData'];
    
    
                $this->calculations = [
    
                    'sum' => $self->sum,
                    'grandSubSum' => $self->grandSubSum,
                    'subSum' => $self->subSum,
                    'nettoSum' => $self->nettoSum,
                    'nettoSubSum' => $self->nettoSubSum,
                    'vatArray' => $self->vatArray,
                    'vatText' => $self->vatText,
                    'isEuVat' => $self->isEuVat,
                    'isNetto' => $self->isNetto,
    
                    'currencyData' => $self->currencyData
    
                $self->setCurrency($self->getCurrency());
    
                $self->calculated = true;
            });
    
            return $this;
        }
    
        //region Article Management
    
    
        /**
         * Add an article to the list
         *
         * @param Article $Article
         */
    
        public function addArticle(Article $Article): void
    
            $this->calculated = false;
    
    
            if ($this->User) {
                $Article->setUser($this->User);
            }
    
    
            if ($this->Currency) {
                $Article->setCurrency($this->Currency);
            }
    
        }
    
        /**
         * Remove an article by its index position
         *
         * @param integer $index
         */
    
        public function removeArticle(int $index): void
    
        {
            if (isset($this->articles[$index])) {
                unset($this->articles[$index]);
            }
        }
    
    
        /**
         * @param $pos
         * @return Article|null
         */
    
        public function getArticle($pos): ?Article
    
        {
            if (isset($this->articles[$pos])) {
                return $this->articles[$pos];
            }
    
            return null;
        }
    
    
        /**
         * Replace an article at a specific position
         *
         * @param Article $Article
         * @param integer $index
         */
    
        public function replaceArticle(Article $Article, int $index): void
    
        {
            $this->articles[$index] = $Article;
        }
    
        /**
         * Clears the list
         */
    
            $this->articles = [];
    
         * Return the length of the list
    
         * @return int
    
        public function count(): int
    
    Henning Leutz's avatar
    Henning Leutz committed
            return count($this->articles);
    
    
        //region Price Factors
    
        /**
         * Import a price factor list
         *
    
         * @param QUI\ERP\Accounting\PriceFactors\FactorList $PriceFactors
    
        public function importPriceFactors(QUI\ERP\Accounting\PriceFactors\FactorList $PriceFactors): void
    
        {
            $this->PriceFactors = $PriceFactors;
        }
    
    
         * @param Factor|QUI\ERP\Products\Utils\PriceFactor $PriceFactor
    
        public function addPriceFactor(Factor|QUI\ERP\Products\Utils\PriceFactor $PriceFactor): void
    
        {
            if ($PriceFactor instanceof QUI\ERP\Products\Utils\PriceFactor) {
    
                $isNetto = $this->isNetto;
                $vat = 0;
                $netto = $PriceFactor->getNettoSum();
    
                $precision = $this->getCurrency()->getPrecision();
    
                if (count($this->vatArray)) {
                    $vat = key($this->vatArray);
                }
    
    
                if ($PriceFactor->getVat()) {
                    $vat = $PriceFactor->getVat();
                }
    
    
                $PriceFactor->setVat($vat);
    
                $brutto = $netto * ((100 + $vat) / 100);
                $brutto = round($brutto, $precision);
    
                if ($isNetto) {
                    $PriceFactor->setSum($netto);
                } else {
                    $PriceFactor->setSum($brutto);
                }
    
    
                $PriceFactor = new Factor($PriceFactor->toArray());
    
            }
    
            $this->PriceFactors->addFactor($PriceFactor);
            $this->recalculate();
        }
    
    
    
        //region order
    
        /**
         * @param QUI\ERP\Order\AbstractOrder $Order
         */
    
        public function setOrder(QUI\ERP\Order\AbstractOrder $Order): void
    
        {
            $this->Order = $Order;
        }
    
        /**
         * @return QUI\ERP\Order\AbstractOrder|null
         */
    
        public function getOrder(): ?QUI\ERP\Order\AbstractOrder
    
        {
            return $this->Order;
        }
    
        //endregion
    
    Henning Leutz's avatar
    Henning Leutz committed
    
        //render
    
        public function renderForMail(): string
        {
            return $this->toUniqueList()->renderForMail();
        }
    
    
        public function toHTMLWithCSS(
            bool|string $template = false,
    
            bool|string $articleTemplate = false,
            ?QUI\Interfaces\Template\EngineInterface $Engine = null,
    
            return $this->toUniqueList()->toHTMLWithCSS($template, $articleTemplate, $Engine);
    
    Henning Leutz's avatar
    Henning Leutz committed
        }
    
        //endregion