Newer
Older
<?php
/**
* This file contains QUI\ERP\Accounting\ArticleList
*/
namespace QUI\ERP\Accounting;
use QUI\ERP\Accounting\PriceFactors\FactorList as ErpFactorList;
use Traversable;
use function array_map;
use function class_exists;
use function class_implements;
use function count;
use function dirname;
use function file_exists;
use function file_get_contents;
use function is_string;
use function json_decode;
use function json_encode;
/**
* Class ArticleListUnique
*
* @package QUI\ERP\Accounting
*/
class ArticleListUnique implements IteratorAggregate
{
/**
/**
* @var bool|mixed
*/
protected $showHeader;
protected ErpFactorList $PriceFactors;

Henning Leutz
committed
/**
* @var QUI\Interfaces\Users\User
*/
protected $User = null;
protected ?QUI\ERP\Currency\Currency $ExchangeCurrency = null;
/**
* ArticleList constructor.
*
* @param array $attributes

Henning Leutz
committed
* @param null|QUI\Interfaces\Users\User|QUI\Users\User $User
public function __construct(array $attributes = [], $User = null)
$this->Locale = QUI::getLocale();
$needles = ['articles', 'calculations'];
foreach ($needles as $needle) {
if (!isset($attributes[$needle])) {
throw new QUI\ERP\Exception(
'Missing needle for ArticleListUnique',
400,
'class' => 'ArticleListUnique',
$articles = $attributes['articles'];
$currency = QUI\ERP\Currency\Handler::getDefaultCurrency()->getCode();
if (isset($attributes['calculations']['currencyData']['code'])) {
$currency = $attributes['calculations']['currencyData']['code'];
}
// sorting
$articles = $this->sortArticlesWithParents($articles);
// adding
foreach ($articles as $article) {
if (!isset($article['currency'])) {
$article['currency'] = $currency;
}
if (!isset($article['class'])) {
$this->articles[] = new Article($article);
continue;
}
$class = $article['class'];
$this->articles[] = new Article($article);
continue;
}
if (isset($interfaces[ArticleInterface::class])) {
$this->articles[] = new $class($article);
continue;
}
$this->articles[] = new Article($article);
}

Henning Leutz
committed
if ($User) {
$this->User = $User;
foreach ($this->articles as $Article) {
$Article->setUser($this->User);
}
}
$this->calculations = $attributes['calculations'];
$this->showHeader = $attributes['showHeader'] ?? true;
$this->PriceFactors = new ErpFactorList();
if (isset($attributes['priceFactors'])) {
$this->PriceFactors = new ErpFactorList($attributes['priceFactors']);
} catch (QUI\ERP\Exception $Exception) {
QUI\System\Log::writeRecursive(
$attributes['priceFactors'],
QUI\System\Log::LEVEL_DEBUG
);
QUI\System\Log::writeDebugException($Exception);
}
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
/**
* Sorts items within the list by parent-child relationship.
*
* Items without `productSetParentUuid` are considered parents and positioned before their children,
* with each child directly assigned to its parent via `productSetParentUuid`.
*
* Children follow immediately after their parents in the sorted list.
* Each item is assigned a consecutive position, which reflects its order in the sorted list.
*
* @param array $articles - The input list of items, articles
* @return array The sorted list of items with added 'position' keys, starting with 1.
*/
protected function sortArticlesWithParents(array $articles = []): array
{
if (empty($articles)) {
return [];
}
$sortedArticles = [];
$children = [];
foreach ($articles as $article) {
if (!is_null($article['productSetParentUuid'])) {
$children[$article['productSetParentUuid']][] = $article;
}
}
$positionCounter = 1; // Starte die Positionierung bei 1
foreach ($articles as $article) {
if (!is_null($article['productSetParentUuid'])) {
continue;
}
$article['position'] = $positionCounter;
$sortedArticles[] = $article;
$uuid = $article['uuid'];
if (isset($children[$uuid])) {
$subPosition = 0.1;
foreach ($children[$uuid] as $child) {
$child['position'] = $positionCounter + $subPosition;
$sortedArticles[] = $child;
$subPosition += 0.1;
}
}
$positionCounter++;
}
return $sortedArticles;
}
/**
* placeholder. unique list cant be recalculate
* recalculate makes the unique article list compatible to the article list
*
* @param $Calc
*/
public function recalculate($Calc = null)
{
// placeholder. unique list cant be recalculate
}
/**
* placeholder. unique list cant be calc
* calc makes the unique article list compatible to the article list
*
* @param $Calc
* @return ArticleListUnique
public function calc($Calc = null): ArticleListUnique
{
// placeholder. unique list cant be calc
return $this;
}
/**
* Set locale
*
* @param QUI\Locale $Locale
*/
public function setLocale(QUI\Locale $Locale)
{
$this->Locale = $Locale;
}
/**
* Creates a list from a stored representation
*
* @return ArticleListUnique
public static function unserialize($data): ArticleListUnique
if (is_string($data)) {
$data = json_decode($data, true);
}
return new self($data);
}
/**
* Generates a storable representation of the list
*
* @return string
*/

Henning Leutz
committed
public function serialize(): string
/**
* Return the calculation array
*
* @return array
*/

Henning Leutz
committed
public function getCalculations(): array
{
return $this->calculations;
}
/**
* Return the list articles
*

Henning Leutz
committed
public function getArticles(): array
{
return $this->articles;
}
/**
* Return the number of articles
*
* @return int
*/

Henning Leutz
committed
public function count(): int
/**
* Generates a storable json representation of the list
* Alias for serialize()
*
* @return string
*/

Henning Leutz
committed
public function toJSON(): string
{
return $this->serialize();
}
/**
* Return the list as an array
*
* @return array
*/

Henning Leutz
committed
public function toArray(): array
return $Article->toArray();
}, $this->articles);
$this->PriceFactors->toArray();
'calculations' => $this->calculations,
'priceFactors' => $this->PriceFactors->toArray()
];
/**
* Display of the header = true
*/
public function displayHeader()
{
$this->showHeader = true;
}
/**
* Display of the header = false
*/
public function hideHeader()
{
$this->showHeader = false;
}
/**
* @param QUI\ERP\Currency\Currency $Currency
*/
public function setExchangeCurrency(QUI\ERP\Currency\Currency $Currency)
{
$this->ExchangeCurrency = $Currency;
}
/**
* @param float $rate
*/
public function setExchangeRate(float $rate)
{
$this->exchangeRate = $rate;
}
* Return the Article List as HTML, without CSS
* @return string

Henning Leutz
committed
public function toHTML($template = false): string
$Engine = QUI::getTemplateManager()->getEngine();

Henning Leutz
committed
if (!$this->count()) {
return '';
}
$Currency = QUI\ERP\Currency\Handler::getCurrency(
$this->calculations['currencyData']['code']
);
if (isset($this->calculations['currencyData']['rate'])) {
$Currency->setExchangeRate($this->calculations['currencyData']['rate']);
}
if ($this->calculations['vatArray']) {
$vatArray = $this->calculations['vatArray'];
}
// price display
foreach ($vatArray as $key => $vat) {
$vatArray[$key]['sum'] = $Currency->format($vat['sum']);
$this->calculations['sum'] = $Currency->format($this->calculations['sum']);

Patrick Müller
committed
$this->calculations['subSum'] = $Currency->format($this->calculations['subSum']);
// Fallback for older unique article lists
if (!isset($this->calculations['grandSubSum'])) {
$this->calculations['grandSubSum'] = $this->calculations['sum'];
}
$this->calculations['grandSubSum'] = $Currency->format($this->calculations['grandSubSum']);
$this->calculations['nettoSum'] = $Currency->format($this->calculations['nettoSum']);
$this->calculations['nettoSubSum'] = $Currency->format($this->calculations['nettoSubSum']);
$View = $Article->getView();
$View->setCurrency($Currency);
if (floor($position) % 2) {
$View->setAttribute('odd', true);
} else {
$View->setAttribute('even', true);
}
$ExchangeCurrency = $this->ExchangeCurrency;
$showExchangeRate = $this->showExchangeRate;
$exchangeRateText = '';
if (!$ExchangeCurrency || $ExchangeCurrency->getCode() === $Currency->getCode()) {
if ($this->exchangeRate) {
$Currency->setExchangeRate($this->exchangeRate);
}
$exchangeRate = $Currency->getExchangeRate($ExchangeCurrency);
$exchangeRate = $ExchangeCurrency->format($exchangeRate);
$exchangeRateText = $this->Locale->get('quiqqer/erp', 'exchangerate.text', [
'startCurrency' => $Currency->format(1),
// if currency of list is other currency like the default one
// currency = BTC, Default = EUR
// exchange rate must be displayed
if ($ExchangeCurrency && $ExchangeCurrency->getCode() !== QUI\ERP\Defaults::getCurrency()->getCode()) {
$showExchangeRate = true;
$DefaultCurrency = QUI\ERP\Defaults::getCurrency();
$exchangeRate = $ExchangeCurrency->getExchangeRate($DefaultCurrency);
$exchangeRate = $ExchangeCurrency->format($exchangeRate);
$exchangeRateText = $this->Locale->get('quiqqer/erp', 'exchangerate.text', [
'startCurrency' => $DefaultCurrency->format(1),
'rate' => $exchangeRate
]);
}
foreach ($this->PriceFactors as $Factor) {
if ($Factor->getCalculationBasis() === QUI\ERP\Accounting\Calc::CALCULATION_GRAND_TOTAL) {
$grandTotal[] = $Factor->toArray();
continue;
}
$priceFactors[] = $Factor->toArray();
}
'priceFactors' => $priceFactors,
'grandTotal' => $grandTotal,
'showHeader' => $this->showHeader,
'this' => $this,
'articles' => $articles,
'calculations' => $this->calculations,
'vatArray' => $vatArray,
'Locale' => $this->Locale,
'showExchangeRate' => $showExchangeRate,
'exchangeRate' => $exchangeRate,
'exchangeRateText' => $exchangeRateText,
'Currency' => $Currency
return $Engine->fetch(dirname(__FILE__) . '/ArticleList.html');
/**
* @return string
* @throws QUI\Exception
*/

Henning Leutz
committed
public function toMailHTML(): string
return $this->toHTML(dirname(__FILE__) . '/ArticleList.Mail.html');
/**
* Return the Article List as HTML, with CSS
*
* @return string

Henning Leutz
committed
public function toHTMLWithCSS(): string
$style .= file_get_contents(dirname(__FILE__) . '/ArticleList.css');
/**
* Alias for toHTMLWithCSS
*
* @return string
{
return $this->toHTMLWithCSS();
}
/**
* Render the article list for mails
*
* @return string
*
* @throws QUI\Exception
*/

Henning Leutz
committed
public function renderForMail(): string
{
$style = '<style>';
$style .= file_get_contents(dirname(__FILE__) . '/ArticleList.Mail.css');
$style .= '</style>';
//region Price Factors
/**
* Return the price factors list (list of price indicators)
*
public function getPriceFactors(): ErpFactorList
{
return $this->PriceFactors;
}
//endregion

Henning Leutz
committed
//region iterator
/**
* Iterator helper
*

Henning Leutz
committed
*/
public function getIterator()
{

Henning Leutz
committed
}
//endregion