Skip to content
Code-Schnipsel Gruppen Projekte
InvoiceTemporary.php 76,3 KiB
Newer Older
  • Learn to ignore specific revisions
  • Henning Leutz's avatar
    Henning Leutz committed
    <?php
    
    
     * This file contains QUI\ERP\Accounting\Invoice\InvoiceTemporary
    
    Henning Leutz's avatar
    Henning Leutz committed
    namespace QUI\ERP\Accounting\Invoice;
    
    use QUI;
    
    use QUI\ERP\Accounting\ArticleList;
    
    use QUI\ERP\Accounting\Calculations;
    
    Henning Leutz's avatar
    Henning Leutz committed
    use QUI\ERP\Accounting\Invoice\Utils\Invoice as InvoiceUtils;
    
    Henning Leutz's avatar
    Henning Leutz committed
    use QUI\ERP\Accounting\Payments\Transactions\Transaction;
    
    Henning Leutz's avatar
    Henning Leutz committed
    use QUI\ERP\Money\Price;
    
    use QUI\ERP\Order\Handler as OrderHandler;
    
    use QUI\ERP\User;
    
    Henning Leutz's avatar
    Henning Leutz committed
    use QUI\ExceptionStack;
    
    Henning Leutz's avatar
    Henning Leutz committed
    use QUI\Utils\Security\Orthos;
    
    use QUI\ERP\ErpEntityInterface;
    use QUI\ERP\ErpTransactionsInterface;
    use QUI\ERP\ErpCopyInterface;
    
    Henning Leutz's avatar
    Henning Leutz committed
    
    use function array_flip;
    use function class_exists;
    use function date;
    use function is_array;
    use function is_numeric;
    use function is_string;
    use function json_decode;
    use function json_encode;
    use function json_last_error;
    use function mb_strpos;
    
    Henning Leutz's avatar
    Henning Leutz committed
    use function preg_replace;
    
    Henning Leutz's avatar
    Henning Leutz committed
    use function str_replace;
    use function strip_tags;
    use function strtotime;
    
    Henning Leutz's avatar
    Henning Leutz committed
    use function time;
    
    Henning Leutz's avatar
    Henning Leutz committed
    
    use const JSON_ERROR_NONE;
    
    Henning Leutz's avatar
    Henning Leutz committed
    use const PHP_INT_MAX;
    
     * Class InvoiceTemporary
    
    Henning Leutz's avatar
    Henning Leutz committed
     * - Temporary Invoice / Invoice class
     * - A temporary invoice is a non posted invoice, it is not a real invoice
    
    Henning Leutz's avatar
    Henning Leutz committed
     * - To create a correct invoice from the temporary invoice, the post method must be used
     *
     * @package QUI\ERP\Accounting\Invoice
     */
    
    class InvoiceTemporary extends QUI\QDOM implements ErpEntityInterface, ErpTransactionsInterface, ErpCopyInterface
    
    Henning Leutz's avatar
    Henning Leutz committed
    {
    
        use QUI\ERP\ErpEntityCustomerFiles;
    
        use QUI\ERP\ErpEntityData;
    
        /**
         * Special attributes
         */
    
        /**
         * If this attribute is set to this InvoiceTemporary the invoice is NOT
         * automatically send to the customer when posted REGARDLESS of the setting
         * in this module.
         */
        const SPECIAL_ATTRIBUTE_DO_NOT_SEND_CREATION_MAIL = 'do_not_send_creation_mail';
    
    
        /**
         * @var string
         */
    
    Henning Leutz's avatar
    Henning Leutz committed
        protected string $prefix;
    
    Henning Leutz's avatar
    Henning Leutz committed
        /**
    
    Henning Leutz's avatar
    Henning Leutz committed
         */
    
        protected int $id;
    
        protected mixed $globalProcessId;
    
    Henning Leutz's avatar
    Henning Leutz committed
        protected int $type;
    
        protected array $data = [];
    
        /**
         * variable data for developers
         *
         * @var array
         */
    
        protected array $customData = [];
    
    Henning Leutz's avatar
    Henning Leutz committed
        /**
         * @var array
         */
    
        protected array $paymentData = [];
    
    Henning Leutz's avatar
    Henning Leutz committed
        protected ArticleList $Articles;
    
         * @var QUI\ERP\Comments
    
    Henning Leutz's avatar
    Henning Leutz committed
        protected QUI\ERP\Comments $Comments;
    
         * @var QUI\ERP\Comments
    
    Henning Leutz's avatar
    Henning Leutz committed
        protected QUI\ERP\Comments $History;
    
        /**
         * @var integer|null
         */
    
    Henning Leutz's avatar
    Henning Leutz committed
        protected ?int $shippingId = null;
    
         * @var array|false
    
        protected array | false $addressDelivery = [];
    
    Henning Leutz's avatar
    Henning Leutz committed
        /**
    
    Henning Leutz's avatar
    Henning Leutz committed
         * @var null|QUI\ERP\Currency\Currency
    
    Henning Leutz's avatar
    Henning Leutz committed
         */
    
    Henning Leutz's avatar
    Henning Leutz committed
        protected ?QUI\ERP\Currency\Currency $Currency = null;
    
    Henning Leutz's avatar
    Henning Leutz committed
        /**
         * Invoice constructor.
         *
         * @param $id
         * @param Handler $Handler
    
    Henning Leutz's avatar
    Henning Leutz committed
         *
    
         * @throws Exception
    
         * @throws QUI\Exception
    
    Henning Leutz's avatar
    Henning Leutz committed
         */
        public function __construct($id, Handler $Handler)
        {
    
    Henning Leutz's avatar
    Henning Leutz committed
            $data = $Handler->getTemporaryInvoiceData($id);
    
    
            $this->prefix = Settings::getInstance()->getTemporaryInvoicePrefix();
    
            $this->id = $data['id'];
            $this->setAttribute('hash', $id);
    
            $this->Articles = new ArticleList();
    
            $this->History = new QUI\ERP\Comments();
    
            $this->Comments = new QUI\ERP\Comments();
    
            if (!empty($data['delivery_address'])) {
    
    Henning Leutz's avatar
    Henning Leutz committed
                $deliveryAddressData = json_decode($data['delivery_address'], true);
    
    Henning Leutz's avatar
    Henning Leutz committed
                if (json_last_error() === JSON_ERROR_NONE) {
    
                    $this->addressDelivery = $deliveryAddressData;
                } else {
                    $this->addressDelivery = false;
                }
    
    
                if (
                    empty($this->addressDelivery['company'])
    
                    && empty($this->addressDelivery['firstname'])
                    && empty($this->addressDelivery['lastname'])
                    && empty($this->addressDelivery['street_no'])
                    && empty($this->addressDelivery['zip'])
                    && empty($this->addressDelivery['city'])
                    && empty($this->addressDelivery['county'])
                ) {
                    $this->addressDelivery = false;
                }
            } else {
    
                $this->addressDelivery = false;
    
            if (isset($data['articles'])) {
    
    Henning Leutz's avatar
    Henning Leutz committed
                $articles = json_decode($data['articles'], true);
    
    Henning Leutz's avatar
    Henning Leutz committed
    
                if ($articles) {
                    try {
                        $this->Articles = new ArticleList($articles);
    
                    } catch (QUI\ERP\Exception $Exception) {
    
    Henning Leutz's avatar
    Henning Leutz committed
                        QUI\System\Log::addError($Exception->getMessage());
                    }
                }
    
    Henning Leutz's avatar
    Henning Leutz committed
    
                unset($data['articles']);
            }
    
    
            if (isset($data['history'])) {
    
                $this->History = QUI\ERP\Comments::unserialize($data['history']);
    
            }
    
            if (isset($data['comments'])) {
    
                $this->Comments = QUI\ERP\Comments::unserialize($data['comments']);
    
            if (!empty($data['global_process_id'])) {
    
                $this->globalProcessId = $data['global_process_id'];
            } else {
                $this->globalProcessId = $data['hash'];
            }
    
    
    
            // invoice extra data
    
            if (!empty($data['data'])) {
                $this->data = json_decode($data['data'], true) ?? [];
            }
    
            if (isset($data['custom_data'])) {
                $this->customData = json_decode($data['custom_data'], true) ?? [];
    
            // invoice payment data
            $paymentData = QUI\Security\Encryption::decrypt($data['payment_data']);
    
            $this->paymentData = json_decode($paymentData, true) ?? [];
    
    Henning Leutz's avatar
    Henning Leutz committed
            $this->type = QUI\ERP\Constants::TYPE_INVOICE_TEMPORARY;
    
    
            switch ((int)$data['type']) {
    
    Henning Leutz's avatar
    Henning Leutz committed
                case QUI\ERP\Constants::TYPE_INVOICE:
                case QUI\ERP\Constants::TYPE_INVOICE_TEMPORARY:
                case QUI\ERP\Constants::TYPE_INVOICE_CREDIT_NOTE:
                case QUI\ERP\Constants::TYPE_INVOICE_REVERSAL:
    
                    $this->type = (int)$data['type'];
                    break;
            }
    
            // database attributes
    
            $data['time_for_payment'] = (int)$data['time_for_payment'];
    
            if ($data['time_for_payment'] < 0) {
                $data['time_for_payment'] = 0;
            }
    
    
    Henning Leutz's avatar
    Henning Leutz committed
            $this->setAttributes($data);
    
            if ($this->getCustomer() === null && !empty($data['customer_data'])) {
    
                $customer = json_decode($data['customer_data'], true);
    
                if (!empty($customer['uuid'])) {
                    $this->setAttribute('customer_id', $customer['uuid']);
                } elseif (!empty($customer['id'])) {
                    $this->setAttribute('customer_id', $customer['id']);
                }
            }
    
    
            if ($this->getCustomer() === null) {
    
                $this->setAttribute('invoice_address', false);
                $this->setAttribute('customer_id', false);
    
            } else {
                $isBrutto = QUI\ERP\Utils\User::getBruttoNettoUserStatus($this->getCustomer());
    
                if (QUI\ERP\Utils\User::IS_NETTO_USER === $isBrutto) {
                    $this->setAttribute('isbrutto', 0);
                } else {
                    $this->setAttribute('isbrutto', 1);
                }
    
            $this->Articles->setCurrency($this->getCurrency());
    
    
    
            // consider contact person in address
    
    Henning Leutz's avatar
    Henning Leutz committed
            if (!empty($this->getAttribute('invoice_address'))) {
    
                $invoiceAddress = $this->getAttribute('invoice_address');
    
    Henning Leutz's avatar
    Henning Leutz committed
                $invoiceAddress = json_decode($invoiceAddress, true);
    
    Henning Leutz's avatar
    Henning Leutz committed
                if (!empty($this->getAttribute('contact_person'))) {
                    $invoiceAddress['contactPerson'] = $this->getAttribute('contact_person');
                }
    
                if (!empty($invoiceAddress['contactEmail'])) {
                    $this->setAttribute('contactEmail', $invoiceAddress['contactEmail']);
                }
    
    
    Henning Leutz's avatar
    Henning Leutz committed
                $this->setAttribute('invoice_address', json_encode($invoiceAddress));
    
            // shipping
    
    Henning Leutz's avatar
    Henning Leutz committed
            if (is_numeric($data['shipping_id'])) {
    
                $this->shippingId = (int)$data['shipping_id'];
            }
    
    
            // accounting currency, if exists
            $accountingCurrencyData = $this->getCustomDataEntry('accountingCurrencyData');
    
            try {
                if ($accountingCurrencyData) {
                    $this->Articles->setExchangeCurrency(
                        new QUI\ERP\Currency\Currency(
                            $accountingCurrencyData['accountingCurrency']
                        )
                    );
    
                    $this->Articles->setExchangeRate($accountingCurrencyData['rate']);
                } elseif (QUI\ERP\Currency\Conf::accountingCurrencyEnabled()) {
                    $this->Articles->setExchangeCurrency(
                        QUI\ERP\Currency\Conf::getAccountingCurrency()
                    );
                }
    
            } catch (QUI\Exception) {
    
        protected function databaseTable(): string
        {
            return Handler::getInstance()->temporaryInvoiceTable();
        }
    
    
    Henning Leutz's avatar
    Henning Leutz committed
        /**
    
         * @return int
    
    Henning Leutz's avatar
    Henning Leutz committed
         */
    
        public function getId(): int
    
            return $this->id;
    
        }
    
        /**
         * Returns only the integer id
         *
         * @return int
         */
    
        public function getCleanId(): int
    
            return $this->getId();
    
         * @return string
         * @deprecated use getUUID()
         */
        public function getHash(): string
        {
            return $this->getUUID();
        }
    
        /**
         * @return string
    
        public function getUUID(): string
    
        {
            return $this->getAttribute('hash');
        }
    
    
        /**
         * @return string
         */
        public function getPrefixedNumber(): string
        {
            return $this->prefix . $this->id;
        }
    
    
        public function getGlobalProcessId(): string
    
        /**
         * Return the invoice type
         * - Handler::TYPE_INVOICE
         * - Handler::TYPE_INVOICE_TEMPORARY
         * - Handler::TYPE_INVOICE_CREDIT_NOTE
         * - Handler::TYPE_INVOICE_REVERSAL
         *
         * @return int
         */
    
        public function getInvoiceType(): int
    
         * @return User|null
    
        public function getCustomer(): ?QUI\ERP\User
    
            $invoiceAddress = $this->getAttribute('invoice_address');
    
                $User = QUI::getUsers()->get($this->getAttribute('customer_id'));
    
    
                if (is_numeric($this->getAttribute('customer_id')) && $User->getUUID()) {
                    $this->setAttribute('customer_id', $User->getUUID());
                }
    
    Henning Leutz's avatar
    Henning Leutz committed
            } catch (QUI\Exception $Exception) {
    
                QUI\System\Log::writeDebugException($Exception);
    
                return null;
            }
    
            $userData = [
    
    Henning Leutz's avatar
    Henning Leutz committed
                'id' => $User->getUUID(),
    
                'country' => $User->getCountry(),
                'username' => $User->getUsername(),
    
                'firstname' => $User->getAttribute('firstname'),
    
                'lastname' => $User->getAttribute('lastname'),
                'lang' => $User->getLang(),
                'email' => $User->getAttribute('email')
    
            try {
                $Customer = QUI\ERP\User::convertUserToErpUser($User);
                $userData = $Customer->getAttributes();
            } catch (QUI\Exception $Exception) {
                QUI\System\Log::writeDebugException($Exception);
    
    Henning Leutz's avatar
    Henning Leutz committed
            if (is_string($invoiceAddress)) {
                $invoiceAddress = json_decode($invoiceAddress, true);
    
            }
    
            if (!isset($userData['isCompany'])) {
                $userData['isCompany'] = false;
    
                if (isset($invoiceAddress['company'])) {
                    $userData['isCompany'] = true;
                }
            }
    
            if (!empty($invoiceAddress)) {
    
                if (!empty($this->getAttribute('contact_person'))) {
                    $invoiceAddress['contactPerson'] = $this->getAttribute('contact_person');
                }
    
    
                $userData['address'] = $invoiceAddress;
    
    
                if (empty($userData['firstname']) && !empty($invoiceAddress['firstname'])) {
                    $userData['firstname'] = $invoiceAddress['firstname'];
                }
    
                if (empty($userData['lastname']) && !empty($invoiceAddress['lastname'])) {
                    $userData['lastname'] = $invoiceAddress['lastname'];
                }
    
            if (empty($userData['country'])) {
    
                try {
                    $userData['country'] = QUI\ERP\Defaults::getCountry()->getCode();
    
                } catch (\Exception) {
    
                    $userData['country'] = '';
                }
    
            }
    
            if (!empty($invoiceAddress['contactEmail'])) {
                $userData['contactEmail'] = $invoiceAddress['contactEmail'];
            }
    
    
            try {
                return new QUI\ERP\User($userData);
            } catch (QUI\Exception $Exception) {
                QUI\System\Log::writeException($Exception);
    
            $this->setAttribute('customer_id', false);
            $this->setAttribute('invoice_address', false);
    
    
        /**
         * @param string|QUI\ERP\Currency\Currency $currency
    
         * @throws QUI\Exception
    
        public function setCurrency(QUI\ERP\Currency\Currency | string $currency): void
    
    Henning Leutz's avatar
    Henning Leutz committed
            if (is_string($currency)) {
    
                try {
                    $currency = QUI\ERP\Currency\Handler::getCurrency($currency);
                } catch (QUI\Exception $Exception) {
                    QUI\System\Log::addError($Exception->getMessage());
    
                    return;
                }
            }
    
            if (!($currency instanceof QUI\ERP\Currency\Currency)) {
                return;
            }
    
    
            $this->Currency = $currency;
    
            $this->setAttribute('currency_data', $currency->toArray());
    
    Henning Leutz's avatar
    Henning Leutz committed
            $this->Articles->setCurrency($this->Currency);
            $this->Currency = $this->getCurrency();
    
        /**
         * Return the invoice currency
         *
         * @return QUI\ERP\Currency\Currency
         *
         * @throws QUI\Exception
         */
    
        public function getCurrency(): QUI\ERP\Currency\Currency
    
    Henning Leutz's avatar
    Henning Leutz committed
            if ($this->Currency !== null) {
                return $this->Currency;
            }
    
    
            $currency = $this->getAttribute('currency_data');
    
            if (!$currency) {
                return QUI\ERP\Defaults::getCurrency();
            }
    
    
    Henning Leutz's avatar
    Henning Leutz committed
            if (is_string($currency)) {
                $currency = json_decode($currency, true);
    
            }
    
            if (!$currency || !isset($currency['code'])) {
                return QUI\ERP\Defaults::getCurrency();
            }
    
    
    Henning Leutz's avatar
    Henning Leutz committed
            $Currency = QUI\ERP\Currency\Handler::getCurrency($currency['code']);
    
            if (isset($currency['rate'])) {
                $Currency->setExchangeRate($currency['rate']);
            }
    
            $this->Currency = $Currency;
    
            return $Currency;
    
        /**
         * Return the editor user
         *
         * @return null|QUI\Interfaces\Users\User
         */
    
        public function getEditor(): ?QUI\Interfaces\Users\User
    
        {
            $Employees = QUI\ERP\Employee\Employees::getInstance();
    
            if ($this->getAttribute('editor_id')) {
                try {
    
                    return QUI::getUsers()->get($this->getAttribute('editor_id'));
                } catch (QUI\Exception) {
    
                }
            }
    
            // use default advisor as editor
    
            if ($Employees->getDefaultAdvisor()) {
    
                return $Employees->getDefaultAdvisor();
            }
    
            return null;
        }
    
        /**
         * Return the ordered by user
         *
    
         * @return QUI\ERP\User|null
    
        public function getOrderedByUser(): ?QUI\ERP\User
    
        {
            if ($this->getAttribute('ordered_by')) {
                try {
    
                    $User = QUI::getUsers()->get($this->getAttribute('ordered_by'));
                    return QUI\ERP\User::convertUserToErpUser($User);
    
                } catch (QUI\Exception) {
    
        /**
         * Return all fields, attributes which are still missing to post the invoice
         *
         * @return array
    
    Henning Leutz's avatar
    Henning Leutz committed
         * @throws QUI\Exception
         * @throws ExceptionStack
    
        public function getMissingAttributes(): array
    
        {
            return Utils\Invoice::getMissingAttributes($this);
        }
    
    
         * Return an invoice view
    
    Henning Leutz's avatar
    Henning Leutz committed
         *
    
    Henning Leutz's avatar
    Henning Leutz committed
         * @throws \QUI\ERP\Accounting\Invoice\Exception
    
        public function getView(): InvoiceView
    
        public function getPayment(): Payment
    
            $paymentMethod = $this->getAttribute('payment_method');
    
            if (empty($paymentMethod)) {
                return new Payment([]);
            }
    
    
                $Payment = QUI\ERP\Accounting\Payments\Payments::getInstance()->getPayment($paymentMethod);
    
                return new Payment($this->parsePaymentForPaymentData($Payment));
    
            } catch (QUI\Exception $Exception) {
                QUI\System\Log::writeDebugException($Exception);
            }
    
    
         * @throws QUI\ERP\Exception|QUI\Exception
    
        public function getPaidStatusInformation(): array
    
        {
            QUI\ERP\Accounting\Calc::calculatePayments($this);
    
            return [
                'paidData' => $this->getAttribute('paid_data'),
                'paidDate' => $this->getAttribute('paid_date'),
    
                'paid' => $this->getAttribute('paid'),
                'toPay' => $this->getAttribute('toPay')
    
        /**
         * Return the is paid status
         *
         * @return bool
         */
    
        public function isPaid(): bool
    
        {
            try {
                if ($this->getAttribute('toPay') === false) {
                    QUI\ERP\Accounting\Calc::calculatePayments($this);
                }
            } catch (QUI\Exception $Exception) {
                QUI\System\Log::writeException($Exception);
            }
    
            return $this->getAttribute('toPay') <= 0;
        }
    
    
    Henning Leutz's avatar
    Henning Leutz committed
        /**
         * can a refund be made?
         *
         * @return bool
         */
    
        public function hasRefund(): bool
    
    Henning Leutz's avatar
    Henning Leutz committed
        {
            return false;
        }
    
    
        /**
         * Change the invoice type
         *
         * The following types can be used:
         * - Handler::TYPE_INVOICE_TEMPORARY:
         * - Handler::TYPE_INVOICE_CREDIT_NOTE:
         * - Handler::TYPE_INVOICE_REVERSAL:
         *
    
         * @param integer|string $type
    
         * @param QUI\Interfaces\Users\User|null $PermissionUser - optional
    
    Henning Leutz's avatar
    Henning Leutz committed
         *
    
         * @throws QUI\Permissions\Exception
    
    Henning Leutz's avatar
    Henning Leutz committed
         * @throws QUI\Exception
    
        public function setInvoiceType(int | string $type, null | QUI\Interfaces\Users\User $PermissionUser = null): void
    
        {
            QUI\Permissions\Permission::checkPermission(
                'quiqqer.invoice.temporary.edit',
                $PermissionUser
            );
    
            $type = (int)$type;
    
            switch ($type) {
    
    Henning Leutz's avatar
    Henning Leutz committed
                case QUI\ERP\Constants::TYPE_INVOICE_TEMPORARY:
                case QUI\ERP\Constants::TYPE_INVOICE_CREDIT_NOTE:
                case QUI\ERP\Constants::TYPE_INVOICE_REVERSAL:
    
                    break;
    
                default:
                    return;
            }
    
            $this->type = $type;
    
            $typeTitle = QUI::getLocale()->get('quiqqer/invoice', 'invoice.type.' . $type);
    
    
            $this->addHistory(
                QUI::getLocale()->get(
                    'quiqqer/invoice',
                    'history.message.temporaryInvoice.type.changed',
    
    Henning Leutz's avatar
    Henning Leutz committed
                        'typeTitle' => $typeTitle
    
    Henning Leutz's avatar
    Henning Leutz committed
        /**
    
         * Alias for update
         * (Save the current temporary invoice data to the database)
    
         * @param QUI\Interfaces\Users\User|null $PermissionUser
    
         * @throws QUI\Permissions\Exception
    
         * @throws QUI\Lock\Exception
    
    Henning Leutz's avatar
    Henning Leutz committed
         * @throws QUI\Exception
    
    Henning Leutz's avatar
    Henning Leutz committed
         */
    
        public function save(null | QUI\Interfaces\Users\User $PermissionUser = null): void
    
        {
            $this->update($PermissionUser);
        }
    
        /**
         * Save the current temporary invoice data to the database
         *
         * @param QUI\Interfaces\Users\User|null $PermissionUser
         *
         * @throws QUI\Permissions\Exception
         * @throws QUI\Lock\Exception
         * @throws QUI\Exception
         */
    
        public function update(null | QUI\Interfaces\Users\User $PermissionUser = null): void
    
            if ($PermissionUser === null) {
                $PermissionUser = QUI::getUserBySession();
            }
    
    
            //if (!$this->getCustomer() || $PermissionUser->getId() !== $this->getCustomer()->getId()) {
            QUI\Permissions\Permission::checkPermission(
                'quiqqer.invoice.temporary.edit',
                $PermissionUser
            );
            //}
    
            $this->checkLocked();
    
            QUI::getEvents()->fireEvent(
                'quiqqerInvoiceTemporaryInvoiceSaveBegin',
    
    Henning Leutz's avatar
    Henning Leutz committed
                [$this]
    
            // attributes
    
            $projectName = '';
    
    
            $isBrutto = QUI\ERP\Defaults::getBruttoNettoStatus();
    
            if ($this->getCustomer()) {
                $isBrutto = QUI\ERP\Utils\User::getBruttoNettoUserStatus($this->getCustomer());
    
    
            if ($this->getAttribute('project_name')) {
                $projectName = $this->getAttribute('project_name');
            }
    
    
    Henning's avatar
    Henning committed
            if ($this->getAttribute('time_for_payment') || $this->getAttribute('time_for_payment') === 0) {
    
                $timeForPayment = (int)$this->getAttribute('time_for_payment');
    
            } else {
                $timeForPayment = Settings::getInstance()->get('invoice', 'time_for_payment');
    
            if ($timeForPayment < 0) {
                $timeForPayment = 0;
            }
    
    
            if (
                $this->getAttribute('date')
    
                && Orthos::checkMySqlDatetimeSyntax($this->getAttribute('date'))
            ) {
                $date = $this->getAttribute('date');
            }
    
            $contactEmail = $this->getAttribute('contactEmail') ?: false;
    
    Henning Leutz's avatar
    Henning Leutz committed
                $Customer = QUI::getUsers()->get($this->getAttribute('customer_id'));
    
    Henning Leutz's avatar
    Henning Leutz committed
    
                $Address = $Customer->getAddress(
    
    Henning Leutz's avatar
    Henning Leutz committed
                    $this->getAttribute('invoice_address_id')
    
    Henning Leutz's avatar
    Henning Leutz committed
                $invoiceAddressData = $this->getAttribute('invoice_address');
    
    Henning Leutz's avatar
    Henning Leutz committed
    
                if (!is_array($invoiceAddressData)) {
                    $invoiceAddressData = json_decode($invoiceAddressData, true);
                }
    
    Henning Leutz's avatar
    Henning Leutz committed
    
                if ($invoiceAddressData) {
                    $Address->setAttributes($invoiceAddressData);
                }
    
    
                $Address->setAttribute('contactEmail', $contactEmail);
    
    
                $invoiceAddress = $Address->toJSON();
    
    Henning Leutz's avatar
    Henning Leutz committed
                $this->Articles->setUser($Customer);
    
            } catch (QUI\Exception) {
    
                $invoiceAddress = $this->getAttribute('invoice_address');
    
    Henning Leutz's avatar
    Henning Leutz committed
                if (is_string($invoiceAddress)) {
    
                    $invoiceAddressCheck = json_decode($invoiceAddress, true);
    
                    $invoiceAddressCheck['contactEmail'] = $contactEmail;
    
    
    Henning Leutz's avatar
    Henning Leutz committed
                    $invoiceAddress = json_encode($invoiceAddressCheck);
                } elseif (is_array($invoiceAddress)) {
    
                    $invoiceAddress['contactEmail'] = $contactEmail;
    
                    $invoiceAddress = json_encode($invoiceAddress);
    
                $Address = new QUI\ERP\Address(
                    json_decode($invoiceAddress, true)
                );
    
    Henning Leutz's avatar
    Henning Leutz committed
            $this->Articles->calc();
            $listCalculations = $this->Articles->getCalculations();
    
    
            // payment
    
            try {
                if ($this->getAttribute('payment_method')) {
    
                    $Payments = QUI\ERP\Accounting\Payments\Payments::getInstance();
    
                    $Payment = $Payments->getPayment($this->getAttribute('payment_method'));
    
                    $paymentMethod = $Payment->getId();
    
                }
            } catch (QUI\ERP\Accounting\Payments\Exception $Exception) {
                QUI\System\Log::addNotice($Exception->getMessage());
            }
    
    
            //invoice text
            $invoiceText = $this->getAttribute('additional_invoice_text');
    
            if ($invoiceText === false) {
                $invoiceText = QUI::getLocale()->get('quiqqer/invoice', 'additional.invoice.text');
            }
    
    
    Henning Leutz's avatar
    Henning Leutz committed
            // extra EU vat invoice text
    
    Patrick Müller's avatar
    Patrick Müller committed
            if ($listCalculations['isEuVat'] && empty($listCalculations['vatArray'])) {
    
                $Locale = $this->getCustomer()->getLocale();
    
    
    Henning Leutz's avatar
    Henning Leutz committed
                $extraText = '<br />';
    
                $extraText .= $Locale->get('quiqqer/tax', 'message.EUVAT.addition', [
    
                    'user' => $this->getCustomer()->getInvoiceName(),
    
    Henning Leutz's avatar
    Henning Leutz committed
                    'vatId' => $this->getCustomer()->getAttribute('quiqqer.erp.euVatId')
                ]);
    
    
    Henning Leutz's avatar
    Henning Leutz committed
    
                $invoiceTextClean = trim(strip_tags($invoiceText));
                $invoiceTextClean = str_replace("\n", ' ', $invoiceTextClean);
                $invoiceTextClean = html_entity_decode($invoiceTextClean);
                $invoiceTextClean = preg_replace('#( ){2,}#', "$1", $invoiceTextClean);
    
                $extraTextClean = trim(strip_tags($extraText));
                $extraTextClean = str_replace("\n", ' ', $extraTextClean);
                $extraTextClean = html_entity_decode($extraTextClean);
                $extraTextClean = preg_replace('#( ){2,}#', "$1", $extraTextClean);
    
                if (mb_strpos($invoiceTextClean, $extraTextClean) === false) {
    
    Henning Leutz's avatar
    Henning Leutz committed
                    $invoiceText .= $extraText;
                }
            }
    
    
            $Editor = $this->getEditor();
            $editorId = 0;
    
            $editorName = '';
    
            // use default advisor as editor
            if ($Editor) {
    
    Henning Leutz's avatar
    Henning Leutz committed
                $editorId = $Editor->getUUID();
    
                $editorName = $Editor->getName();
            }
    
            // Ordered By
    
            $OrderedBy = $this->getOrderedByUser();
    
    Henning Leutz's avatar
    Henning Leutz committed
            $orderedBy = $this->getAttribute('customer_id');
    
            $orderedByName = '';
    
    
            // use default advisor as editor
    
            if ($OrderedBy) {
    
                $orderedBy = $OrderedBy->getUUID();
    
                $orderedByName = $OrderedBy->getInvoiceName();
    
    Henning Leutz's avatar
    Henning Leutz committed
            } elseif ($orderedBy) {
                try {
    
                    $User = QUI::getUsers()->get($orderedBy);
    
                    $User = QUI\ERP\User::convertUserToErpUser($User);
    
    
                    $orderedBy = $User->getUUID();
    
                    $orderedByName = $User->getInvoiceName();
    
                } catch (QUI\Exception) {
    
            // shipping
    
            $shippingData = null;
    
            if ($this->getShipping()) {
    
                $shippingId = $this->getShipping()->getId();
    
                $shippingData = $this->getShipping()->toJSON();
            }
    
    
            $deliveryAddressId = null;
    
            $DeliveryAddress = $this->getDeliveryAddress();
    
            // Save delivery address separately only if it differs from invoice address
    
            if ($DeliveryAddress && !$DeliveryAddress->equals($Address)) {
    
                $deliveryAddress = $DeliveryAddress->toJSON();
    
    Henning Leutz's avatar
    Henning Leutz committed
                $deliveryAddressId = $DeliveryAddress->getUUID();
    
    
                if (empty($deliveryAddressId)) {
                    $deliveryAddressId = null;
                }
            }
    
    
            // processing status
            $processingStatus = null;
    
    
    Henning Leutz's avatar
    Henning Leutz committed
            if (is_numeric($this->getAttribute('processing_status'))) {
    
                $processingStatus = (int)$this->getAttribute('processing_status');
    
                try {
                    ProcessingStatus\Handler::getInstance()->getProcessingStatus($processingStatus);
    
                } catch (ProcessingStatus\Exception) {
    
            // contact person
            $contactPerson = '';
    
            if ($this->getAttribute('contact_person') && $this->getAttribute('contact_person') !== '') {
                $contactPerson = Orthos::clear($this->getAttribute('contact_person'));
            }
    
    
    Henning Leutz's avatar
    Henning Leutz committed
            // order date
            $orderDate = null;
    
    
            if (
                $this->getAttribute('order_date')
    
    Henning Leutz's avatar
    Henning Leutz committed
                && Orthos::checkMySqlDatetimeSyntax($this->getAttribute('order_date'))
            ) {
                $orderDate = $this->getAttribute('order_date');
            }
    
    
            // Determine payment status by order (if an order is linked to the invoice)
            $paidStatus = QUI\ERP\Constants::PAYMENT_STATUS_OPEN;
    
            $paidDate = null;
            $paidData = '';
    
            $orderId = $this->getAttribute('order_id') ?: null;
    
    
            if (!empty($orderId)) {
                $Orders = OrderHandler::getInstance();
    
                try {
    
                    $Order = $Orders->getOrderById($orderId);
    
                    $orderPaidStatusData = $Order->getPaidStatusInformation();
    
                    $paidStatus = $Order->getAttribute('paid_status');
    
                    $paidDate = $orderPaidStatusData['paidDate'];
    
                    $paidData = json_encode($orderPaidStatusData['paidData']);
    
                } catch (\Exception $Exception) {
                    QUI\System\Log::writeDebugException($Exception);
                }
            }
    
            QUI::getEvents()->fireEvent(
                'quiqqerInvoiceTemporaryInvoiceSave',
    
    Henning Leutz's avatar
    Henning Leutz committed
                [$this]
    
    Henning Leutz's avatar
    Henning Leutz committed
            QUI::getDataBase()->update(