Newer
Older
<?php
/**
* This file contains QUI\ERP\Accounting\Calc
*/
use QUI\ERP\Money\Price;
use QUI\Interfaces\Users\User as UserInterface;
use function array_map;
use function array_sum;
use function class_exists;
use function count;
use function floatval;
use function get_class;
use function is_array;
use function is_callable;
use function is_null;
use function is_string;
use function json_decode;
use function json_encode;
use function key;
use function round;
use function sprintf;
use function str_replace;
use function strpos;
use function strtotime;
use function time;
* @info Produkt Berechnungen sind zu finden unter: QUI\ERP\Products\Utils\Calc
*
/**
* Percentage calculation
*/
const CALCULATION_PERCENTAGE = 1;
/**
* Standard calculation
*/
const CALCULATION_COMPLEMENT = 2;

Henning Leutz
committed
/**
* Set the price for the product
*/
const CALCULATION_COMPLETE = 3;

Henning Leutz
committed
/**
* Basis calculation -> netto
*/
const CALCULATION_BASIS_NETTO = 1;
/**
* Basis calculation -> from current price
*/
const CALCULATION_BASIS_CURRENTPRICE = 2;
/**
* Basis brutto
* include all price factors (from netto calculated price)
* warning: it's not brutto VAT
*
* geht vnn der netto basis aus, welche alle price faktoren schon beinhaltet
* alle felder sind in diesem price schon enthalten
*/
const CALCULATION_BASIS_BRUTTO = 3;
/**
* Berechnet auf Basis des Preises inklusive Steuern
* Zum Beispiel MwSt
*/
const CALCULATION_BASIS_VAT_BRUTTO = 4;
/**
* Berechnet von Gesamtpreis
*/
const CALCULATION_GRAND_TOTAL = 5;

Patrick Müller
committed
/**
* Special transaction attributes for currency exchange
*/
const TRANSACTION_ATTR_TARGET_CURRENCY = 'tx_target_currency';

Patrick Müller
committed
const TRANSACTION_ATTR_TARGET_CURRENCY_EXCHANGE_RATE = 'tx_target_currency_exchange_rate';
const TRANSACTION_ATTR_SHOP_CURRENCY_EXCHANGE_RATE = 'tx_shop_currency_exchange_rate';

Patrick Müller
committed
/**
* @var UserInterface
*/
protected $User = null;
/**
* @var null|QUI\ERP\Currency\Currency
*/
protected ?QUI\ERP\Currency\Currency $Currency = null;
/**
* Calc constructor.
*
* @param UserInterface|bool $User - calculation user
*/
public function __construct($User = false)
{
if (!QUI::getUsers()->isUser($User)) {
$User = QUI::getUserBySession();
}
$this->User = $User;
}
/**
* Static instance create
*
* @param UserInterface|null $User - optional
public static function getInstance(UserInterface $User = null): Calc
{
if (!$User && QUI::isBackend()) {
$User = QUI::getUsers()->getSystemUser();
}
if (!QUI::getUsers()->isUser($User) && !QUI::getUsers()->isSystemUser($User)) {
$User = QUI::getUserBySession();
}
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
}
/**
* Set the calculation user
* All calculations are made in dependence from this user
*
* @param UserInterface $User
*/
public function setUser(UserInterface $User)
{
$this->User = $User;
}
/**
* Return the calc user
*
* @return UserInterface
*/
public function getUser()
{
return $this->User;
}
/**
* Return the currency
*
* @return QUI\ERP\Currency\Currency
*/
public function getCurrency(): ?QUI\ERP\Currency\Currency
$this->Currency = QUI\ERP\Currency\Handler::getDefaultCurrency();
}
return $this->Currency;
}
/**
* Calculate a complete article list
*
* @param ArticleList $List
* @param callable|boolean $callback - optional, callback function for the data array
* @return ArticleList
*/
public function calcArticleList(ArticleList $List, $callback = false): ArticleList
// user order address
$Order = $List->getOrder();
if ($Order) {
$this->getUser()->setAttribute('CurrentAddress', $Order->getDeliveryAddress());
}

Henning Leutz
committed
$this->Currency = $List->getCurrency();
$articles = $List->getArticles();
$isNetto = QUI\ERP\Utils\User::isNettoUser($this->getUser());
$isEuVatUser = QUI\ERP\Tax\Utils::isUserEuVatUser($this->getUser());
$Currency = $this->getCurrency();
$precision = $Currency->getPrecision();
foreach ($articles as $Article) {
// add netto price
try {
QUI::getEvents()->fireEvent(
'onQuiqqerErpCalcArticleListArticle',
);
} catch (QUI\Exception $Exception) {
QUI\System\Log::write($Exception->getMessage(), QUI\System\Log::LEVEL_ERROR);
}
$this->calcArticlePrice($Article);
$articleAttributes = $Article->toArray();
$calculated = $articleAttributes['calculated'];
$subSum = $subSum + $calculated['sum'];
$nettoSum = $nettoSum + $calculated['nettoSum'];
$articleVatArray = $calculated['vatArray'];
$vat = $articleAttributes['vat'];
if ($articleVatArray['text'] === '') {
continue;
}
$vatArray[(string)$vat] = $articleVatArray;
$vatArray[(string)$vat]['sum'] = $vatArray[(string)$vat]['sum'] + $articleVatArray['sum'];
QUI\ERP\Debug::getInstance()->log('Berechnete Artikelliste MwSt', 'quiqqer/erp');
QUI\ERP\Debug::getInstance()->log($vatArray, 'quiqqer/erp');
try {
QUI::getEvents()->fireEvent(
'onQuiqqerErpCalcArticleList',
);
} catch (QUI\Exception $Exception) {
QUI\System\Log::write($Exception->getMessage(), QUI\System\Log::LEVEL_ERROR);
}
/**
* Calc price factors
*/
$priceFactors = $List->getPriceFactors();
// nur wenn wir welche benötigen, für ERP Artikel ist dies im Moment nicht wirklich nötig
/* @var $PriceFactor QUI\ERP\Accounting\PriceFactors\Factor */
foreach ($priceFactors as $PriceFactor) {
if ($PriceFactor->getCalculationBasis() === self::CALCULATION_GRAND_TOTAL) {
$PriceFactor->setNettoSum($PriceFactor->getValue());
$PriceFactor->setValueText('');
continue;
}
if ($PriceFactor->getCalculation() === self::CALCULATION_COMPLEMENT) {
// Standard calculation - Fester Preis
$vatSum = $PriceFactor->getVatSum();
if ($isNetto) {
$PriceFactor->setSum($PriceFactor->getNettoSum());
} elseif ($PriceFactor->getCalculationBasis() === self::CALCULATION_BASIS_VAT_BRUTTO) {
$PriceFactor->setNettoSum($PriceFactor->getNettoSum() - $vatSum);
$PriceFactor->setSum($vatSum + $PriceFactor->getNettoSum());
} else {
$PriceFactor->setSum($vatSum + $PriceFactor->getNettoSum());
}
// formatted
$PriceFactor->setNettoSumFormatted($Currency->format($PriceFactor->getNettoSum()));
$PriceFactor->setSumFormatted($Currency->format($PriceFactor->getSum()));
} elseif ($PriceFactor->getCalculation() === self::CALCULATION_PERCENTAGE) {
// percent - Prozent Angabe
$calcBasis = $PriceFactor->getCalculationBasis();
$priceFactorValue = $PriceFactor->getValue();
$vatValue = $PriceFactor->getVat();
$vatValue = QUI\ERP\Tax\Utils::getTaxByUser($this->getUser())->getValue();
}
switch ($calcBasis) {
default:
case self::CALCULATION_BASIS_NETTO:
$percentage = $priceFactorValue / 100 * $nettoSubSum;
break;
case self::CALCULATION_BASIS_BRUTTO:
case self::CALCULATION_BASIS_CURRENTPRICE:
$percentage = $priceFactorValue / 100 * $nettoSum;
break;
case self::CALCULATION_BASIS_VAT_BRUTTO:
if ($isNetto) {
$bruttoSubSum = $subSum * ($vatValue / 100 + 1);
$percentage = $priceFactorValue / 100 * $bruttoSubSum;
} else {
$percentage = $priceFactorValue / 100 * $subSum;
}
break;
case self::CALCULATION_GRAND_TOTAL:
// starts later
continue 2;
$vatSum = round($PriceFactor->getVatSum(), $precision);
// set netto sum
$PriceFactor->setNettoSum($percentage);
if ($isNetto) {
$PriceFactor->setSum($PriceFactor->getNettoSum());
} elseif ($PriceFactor->getCalculationBasis() === self::CALCULATION_BASIS_VAT_BRUTTO) {
$PriceFactor->setNettoSum($PriceFactor->getNettoSum() - $vatSum);
$PriceFactor->setSum($vatSum + $PriceFactor->getNettoSum());
} else {
$PriceFactor->setSum($vatSum + $PriceFactor->getNettoSum());
}
// formatted
$PriceFactor->setNettoSumFormatted($Currency->format($PriceFactor->getNettoSum()));
$PriceFactor->setSumFormatted($Currency->format($PriceFactor->getSum()));
$nettoSum = $nettoSum + $PriceFactor->getNettoSum();
$priceFactorSum = $priceFactorSum + $PriceFactor->getNettoSum();
if ($isEuVatUser) {
$PriceFactor->setEuVatStatus(true);
}
$vat = $PriceFactor->getVat();
$vatSum = round($PriceFactor->getVatSum(), $precision);
if (!isset($vatArray[(string)$vat])) {
$vatArray[(string)$vat] = [
'text' => self::getVatText($vat, $this->getUser())
$vatArray[(string)$vat]['sum'] = $vatArray[(string)$vat]['sum'] + $vatSum;
if ($isEuVatUser) {
$vatArray = [];
}
$nettoSum = round($nettoSum, $precision);
$subSum = round($subSum, $precision);
$bruttoSum = $nettoSum;
foreach ($vatArray as $vatEntry) {
$vatLists[(string)$vat] = true; // liste für MWST texte
$vatArray[(string)$vat]['sum'] = round($vatEntry['sum'], $precision);
$bruttoSum = $bruttoSum + $vatArray[(string)$vat]['sum'];
foreach ($vatLists as $vat => $bool) {
$vatText[(string)$vat] = self::getVatText($vat, $this->getUser());
// delete 0 % vat, 0% vat is allowed to calculate more easily
if (isset($vatText[0])) {
unset($vatText[0]);
}
if (isset($vatArray[0])) {
unset($vatArray[0]);
}
// gegenrechnung, wegen rundungsfehler
if ($isNetto === false) {
$priceFactorBruttoSums = 0;
foreach ($priceFactors as $Factor) {
if ($Factor->getCalculationBasis() !== self::CALCULATION_GRAND_TOTAL) {
/* @var $Factor QUI\ERP\Products\Utils\PriceFactor */
$priceFactorBruttoSums = $priceFactorBruttoSums + round($Factor->getSum(), $precision);
}
$priceFactorBruttoSum = $subSum + $priceFactorBruttoSums;
$priceFactorBruttoSum = round($priceFactorBruttoSum, $precision);
if ($priceFactorBruttoSum !== round($bruttoSum, $precision)) {
$diff = $priceFactorBruttoSum - round($bruttoSum, $precision);
// if we have a diff, we change the first vat price factor
$added = false;
if ($Factor->getCalculationBasis() === self::CALCULATION_GRAND_TOTAL) {
continue;
}
if ($Factor instanceof QUI\ERP\Products\Interfaces\PriceFactorWithVatInterface) {
$Factor->setSum(round($Factor->getSum() - $diff, $precision));
$bruttoSum = round($bruttoSum, $precision);
if ($added === false) {
$bruttoSum = $bruttoSum + $diff;
// netto check 1cent check
$bruttoVatSum = 0;
foreach ($vatArray as $vat => $data) {
$bruttoVatSum = $bruttoVatSum + $data['sum'];
}
if ($bruttoSum - $bruttoVatSum !== $nettoSum) {
$nettoSum = $nettoSum + $diff;
}
// counterbalance - gegenrechnung
// works only for one vat entry
$netto = $bruttoSum / ($vat / 100 + 1);
$vatSum = $bruttoSum - $netto;
$vatSum = round($vatSum, $Currency->getPrecision());
$diff = abs($vatArray[(string)$vat]['sum'] - $vatSum);
if ($bruttoSum === 0 || $nettoSum === 0) {
foreach ($vatArray as $vat => $entry) {
// look if CALCULATION_GRAND_TOTAL
$grandSubSum = $bruttoSum;
foreach ($priceFactors as $Factor) {
if ($Factor->getCalculationBasis() === self::CALCULATION_GRAND_TOTAL) {
$value = $Factor->getValue();
$bruttoSum = $bruttoSum + $value;
if ($bruttoSum < 0) {
$bruttoSum = 0;
}
}
}
'sum' => $bruttoSum,
'subSum' => $subSum,
'grandSubSum' => $grandSubSum,
'nettoSum' => $nettoSum,
'nettoSubSum' => $nettoSubSum,
'vatArray' => $vatArray,
'vatText' => $vatText,
'isEuVat' => $isEuVatUser,
'isNetto' => $isNetto,
'currencyData' => $this->getCurrency()->toArray()
* Calculate the price of an article
*
* @param Article $Article
* @param bool|callable $callback
* @return mixed
public function calcArticlePrice(Article $Article, $callback = false)
// calc data
$Article->calc($this);
return $Article->getPrice();
$isNetto = QUI\ERP\Utils\User::isNettoUser($this->getUser());
$isEuVatUser = QUI\ERP\Tax\Utils::isUserEuVatUser($this->getUser());
$Currency = $Article->getCurrency();
if (!$Currency) {
$Currency = $this->getCurrency();
}
$nettoPrice = $Article->getUnitPriceUnRounded()->value();
$vat = $Article->getVat();
$basisNettoPrice = $nettoPrice;
$nettoSubSum = $this->round($nettoPrice * $Article->getQuantity());
if ($isEuVatUser) {
$vat = 0;
}
$Discount = $Article->getDiscount();
$nettoPriceNotRounded = $Article->getUnitPriceUnRounded()->getValue();
if ($Discount) {
switch ($Discount->getCalculation()) {
// einfache Zahl, Währung --- kein Prozent
case Calc::CALCULATION_COMPLEMENT:
$nettoPrice = $nettoPrice - ($Discount->getValue() / $Article->getQuantity());
$nettoPriceNotRounded = $nettoPriceNotRounded - ($Discount->getValue() / $Article->getQuantity());
break;
// Prozent Angabe
case Calc::CALCULATION_PERCENTAGE:
$percentage = $Discount->getValue() / 100 * $nettoPrice;
$nettoPrice = $nettoPrice - $percentage;
$nettoPriceNotRounded = $nettoPriceNotRounded - $percentage;
$vatSum = $nettoPrice * ($vat / 100);
$precision = $Currency->getPrecision();
$priceSum = $nettoPrice + $vatSum;
$bruttoPrice = round($priceSum, $precision);
if (!$isNetto) {
// korrektur rechnung / 1 cent problem
$checkBrutto = $nettoPriceNotRounded * ($vat / 100 + 1);
$checkBrutto = round($checkBrutto, $Currency->getPrecision());
$checkVat = $checkBrutto - $nettoPriceNotRounded;
$checkVat = round($checkVat * $Article->getQuantity(), $Currency->getPrecision());
// sum
$nettoSum = $this->round($nettoPrice * $Article->getQuantity());
$vatSum = $nettoSum * ($vat / 100);
// korrektur rechnung / 1 cent problem
if ($checkBrutto !== $bruttoPrice) {
$bruttoPrice = $checkBrutto;
// if the user is brutto
// and we have a quantity
// we need to calc first the brutto product price of one product
// -> because of 1 cent rounding error
$bruttoSum = $bruttoPrice * $Article->getQuantity();
} else {
// sum
$nettoSum = $this->round($nettoPrice * $Article->getQuantity());
$vatSum = $nettoSum * ($vat / 100);
$bruttoSum = $this->round($nettoSum + $vatSum);
}
$price = $isNetto ? $nettoPrice : $bruttoPrice;
$sum = $isNetto ? $nettoSum : $bruttoSum;
$basisPrice = $isNetto ? $basisNettoPrice : $basisNettoPrice + ($basisNettoPrice * $vat / 100);
$basisPrice = round($basisPrice, QUI\ERP\Defaults::getPrecision());
'vat' => $vat,
'sum' => $vatSum,
'text' => $this->getVatText($vat, $this->getUser())
QUI\ERP\Debug::getInstance()->log(
'Kalkulierter Artikel Preis ' . $Article->getId(),
'quiqqer/erp'
);
'price' => $price,
'sum' => $sum,
'nettoPrice' => $nettoPrice,
'nettoSubSum' => $nettoSubSum,
'nettoSum' => $nettoSum,
'currencyData' => $this->getCurrency()->toArray(),
'vatArray' => $vatArray,
'vatText' => $vatArray['text'],
'isEuVat' => $isEuVatUser,
'isNetto' => $isNetto
QUI\ERP\Debug::getInstance()->log($data, 'quiqqer/erp');
$callback($data);
return $Article->getPrice();
}
/**
* Rounds the value via shop config
*
* @return float|mixed
*/
$decimalSeparator = $this->getUser()->getLocale()->getDecimalSeparator();
$groupingSeparator = $this->getUser()->getLocale()->getGroupingSeparator();
$precision = QUI\ERP\Defaults::getPrecision();
if (strpos($value, $decimalSeparator) && $decimalSeparator != '.') {
$value = str_replace($groupingSeparator, '', $value);
$value = str_replace(',', '.', $value);
$value = floatval($value);
$value = round($value, $precision);
return $value;
}
/**
* Return the tax message for an user
*
* @return string
*/
public function getVatTextByUser()
{
try {
$Tax = QUI\ERP\Tax\Utils::getTaxByUser($this->getUser());
} catch (QUI\Exception $Exception) {
return '';
}
return $this->getVatText($Tax->getValue(), $this->getUser());
}
/**
* Return tax text
* eq: incl or zzgl
*
* @param integer $vat
* @param UserInterface $User
* @return array|string
*/
public static function getVatText(float $vat, UserInterface $User, QUI\Locale $Locale = null)
if ($Locale === null) {
$Locale = $User->getLocale();
}
if (QUI\ERP\Utils\User::isNettoUser($User)) {
if (QUI\ERP\Tax\Utils::isUserEuVatUser($User)) {
return $Locale->get(
'quiqqer/tax',
'message.vat.text.netto.EUVAT',
);
}
// vat ist leer und kein EU vat user
if (!$vat) {
return '';
}
return $Locale->get(
'quiqqer/tax',
'message.vat.text.netto',
);
}
if (QUI\ERP\Tax\Utils::isUserEuVatUser($User)) {
return $Locale->get(
'quiqqer/tax',
'message.vat.text.brutto.EUVAT',
);
}
// vat ist leer und kein EU vat user
if (!$vat) {
return '';
return $Locale->get(
'quiqqer/tax',
'message.vat.text.brutto',
/**
* Calculates the individual amounts paid of an invoice
*

Henning Leutz
committed
*

Henning Leutz
committed
*
public static function calculateInvoicePayments(Invoice $Invoice): array
return self::calculatePayments($Invoice);
}
/**
* Calculates the individual amounts paid of an invoice / order
*
* @param mixed $ToCalculate
* @throws QUI\ERP\Exception|QUI\Exception
public static function calculatePayments($ToCalculate): array
if (self::isAllowedForCalculation($ToCalculate) === false) {
QUI\ERP\Debug::getInstance()->log(
'Calc->calculatePayments(); Object is not allowed to calculate ' . get_class($ToCalculate)
throw new QUI\ERP\Exception('Object is not allowed to calculate ' . get_class($ToCalculate));
QUI\ERP\Debug::getInstance()->log(
'Calc->calculatePayments(); Transaction'
);
// if payment status is paid, take it immediately and do not query any transactions
if ($ToCalculate->getAttribute('paid_status') === QUI\ERP\Constants::PAYMENT_STATUS_PAID) {
if (!is_array($paidData)) {
$paidData = json_decode($paidData, true);
$paidData = [];
}
foreach ($paidData as $entry) {
if (isset($entry['amount'])) {
}
}
$ToCalculate->setAttribute('paid', $paid);
$ToCalculate->setAttribute('toPay', 0);
QUI\ERP\Debug::getInstance()->log([
'paidData' => $ToCalculate->getAttribute('paid_data'),
'paidDate' => $ToCalculate->getAttribute('paid_date'),
'paidStatus' => $ToCalculate->getAttribute('paid_status'),
'paid' => $ToCalculate->getAttribute('paid'),
'toPay' => $ToCalculate->getAttribute('toPay')
'paidData' => $ToCalculate->getAttribute('paid_data'),
'paidDate' => $ToCalculate->getAttribute('paid_date'),
'paidStatus' => $ToCalculate->getAttribute('paid_status'),
'paid' => $ToCalculate->getAttribute('paid'),
'toPay' => $ToCalculate->getAttribute('toPay')
$Transactions = QUI\ERP\Accounting\Payments\Transactions\Handler::getInstance();
$transactions = $Transactions->getTransactionsByHash($ToCalculate->getHash());

Henning Leutz
committed
$calculations = $ToCalculate->getArticles()->getCalculations();
if (!isset($calculations['sum'])) {
$calculations['sum'] = 0;
}
$sum = 0;
$total = $calculations['sum'];
'Calc->calculatePayments(); total: ' . $total
$isValidTimeStamp = function ($timestamp) {

Patrick Müller
committed
$CalculateCurrency = $ToCalculate->getCurrency();
$ShopCurrency = QUI\ERP\Defaults::getCurrency();

Patrick Müller
committed
if (!$Transaction->isComplete()) {
// don't add incomplete transactions
$amount = Price::validatePrice($Transaction->getAmount());

Patrick Müller
committed
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
$TransactionCurrency = $Transaction->getCurrency();
// If necessary, convert from transaction currency to calculation object currency
if ($CalculateCurrency->getCode() !== $TransactionCurrency->getCode()) {
$targetCurrencyCode = $Transaction->getData(
self::TRANSACTION_ATTR_TARGET_CURRENCY
);
$targetCurrencyExchangeRate = $Transaction->getData(
self::TRANSACTION_ATTR_TARGET_CURRENCY_EXCHANGE_RATE
);
$shopCurrencyExchangeRate = $Transaction->getData(
self::TRANSACTION_ATTR_SHOP_CURRENCY_EXCHANGE_RATE
);
/*
* $amount has to DIVIDED by the exchange rate because the exchange rate is always
* in relation to the base (shop) currency to the given currency.
*
* Example: From ETH to EUR -> The exchange rate here is the rate that turn EUR into ETH; so to
* get ETH to EUR you have to divide the ETH value by the exchange rate.
*/
if ($targetCurrencyCode === $CalculateCurrency->getCode() && $targetCurrencyExchangeRate) {
$amount /= $targetCurrencyExchangeRate;
} elseif ($ShopCurrency === $CalculateCurrency->getCode() && $shopCurrencyExchangeRate) {
$amount /= $shopCurrencyExchangeRate;
} else {
$amount = $TransactionCurrency->convert($amount, $CalculateCurrency);
QUI\System\Log::addWarning(

Patrick Müller
committed
'The currency of transaction "%s" for calculation of object %s (%s) is "%s" and differs'
. ' from the currency of the calculation object ("%s"). But the transaction does not'
. ' contain an exchange rate from "%s" to "%s". Thus, the exchange rate that is currently'
. ' live in the system is used for converting from "%s" to "%s".',

Patrick Müller
committed
$Transaction->getTxId(),
$ToCalculate->getId(),
get_class($ToCalculate),

Patrick Müller
committed
$TransactionCurrency->getCode(),
$CalculateCurrency->getCode(),
$TransactionCurrency->getCode(),
$CalculateCurrency->getCode(),
$TransactionCurrency->getCode(),
$CalculateCurrency->getCode()
)
);
}
$amount = $CalculateCurrency->amount($amount);
}
if ($isValidTimeStamp($date) === false) {
if ($isValidTimeStamp($date) === false) {
}
} else {
$date = (int)$date;
}
if ($date > $paidDate) {
$paidDate = $date;
}
// Falls das gezahlte mehr ist
if ($total < ($sum + $amount)) {
$amount = $total - $sum;
// @todo Information in Rechnung hinterlegen
// @todo Automatische Gutschrift erstellen
}
$sum = $sum + $amount;
'date' => $date,
'txid' => $Transaction->getTxId()
$paid = Price::validatePrice($sum);

Henning Leutz
committed
$toPay = Price::validatePrice($calculations['sum']);
// workaround fix
if ($ToCalculate->getAttribute('paid_date') != $paidDate) {

Henning Leutz
committed
try {
QUI::getDataBase()->update(
Handler::getInstance()->invoiceTable(),
['paid_date' => $paidDate],
['id' => $ToCalculate->getCleanId()]
);
} catch (QUI\Database\Exception $Exception) {
QUI\System\Log::writeException($Exception);
throw new QUI\ERP\Exception(
['quiqqer/erp', 'exception.something.went.wrong'],
$Exception->getCode()
);
}
$ToCalculate->setAttribute('paid_data', json_encode($paidData));
$ToCalculate->setAttribute('paid_date', $paidDate);
$ToCalculate->setAttribute('paid', $sum);
$ToCalculate->setAttribute('toPay', $toPay - $paid);
if (
$ToCalculate instanceof QUI\ERP\Order\AbstractOrder
&& $ToCalculate->getAttribute('paid_status') === QUI\ERP\Constants::PAYMENT_STATUS_PLAN
) {

Patrick Müller
committed
// Leave everything as it is because a subscription plan order can never be set to "paid"
} elseif (
$ToCalculate->getAttribute('paid_status') === QUI\ERP\Constants::TYPE_INVOICE_REVERSAL
|| $ToCalculate->getAttribute('paid_status') === QUI\ERP\Constants::TYPE_INVOICE_CANCEL
|| $ToCalculate->getAttribute('paid_status') === QUI\ERP\Constants::PAYMENT_STATUS_DEBIT
} elseif ((float)$ToCalculate->getAttribute('toPay') == 0) {
$ToCalculate->setAttribute('paid_status', QUI\ERP\Constants::PAYMENT_STATUS_PAID);
} elseif ($ToCalculate->getAttribute('paid') == 0) {
$ToCalculate->setAttribute('paid_status', QUI\ERP\Constants::PAYMENT_STATUS_OPEN);
} elseif (
$ToCalculate->getAttribute('toPay')
&& $calculations['sum'] != $ToCalculate->getAttribute('paid')
$ToCalculate->setAttribute('paid_status', QUI\ERP\Constants::PAYMENT_STATUS_PART);
QUI\ERP\Debug::getInstance()->log([
'paidData' => $paidData,
'paidDate' => $ToCalculate->getAttribute('paid_date'),
'paid' => $ToCalculate->getAttribute('paid'),
'toPay' => $ToCalculate->getAttribute('toPay'),
'paidStatus' => $ToCalculate->getAttribute('paid_status'),
'paidData' => $paidData,