649 lines
14 KiB
PHP
649 lines
14 KiB
PHP
<?php
|
|
namespace PSC\Library\Calc;
|
|
|
|
use Doctrine\Persistence\ObjectRepository;
|
|
use PSC\Library\Calc\Calc\Calc;
|
|
use PSC\Library\Calc\Calc\CalcValues;
|
|
use PSC\Library\Calc\Calc\Valid;
|
|
use PSC\Library\Calc\Option\Type\Base;
|
|
use PSC\Library\Calc\Option\Type\Checkbox;
|
|
use PSC\Library\Calc\Option\Type\PaperDbSelect;
|
|
use PSC\Library\Calc\Option\Type\Select\Opt;
|
|
use PSC\Library\Calc\Option\Type\Text;
|
|
|
|
class Engine
|
|
{
|
|
|
|
/** @var \SimpleXMLElement $xml */
|
|
protected $xml;
|
|
|
|
/** @var \ArrayIterator $articles */
|
|
protected $articles;
|
|
|
|
/** @var PaperContainer $paperContainer */
|
|
protected $paperContainer;
|
|
|
|
/** @var ObjectRepository */
|
|
protected $paperRepository;
|
|
|
|
/** @var string */
|
|
protected $formulas = "";
|
|
|
|
/** @var string */
|
|
protected $parameters = "";
|
|
|
|
/** @var array */
|
|
protected $variables = array();
|
|
|
|
/** @var array */
|
|
protected $calcVariables = array();
|
|
|
|
/** @var array */
|
|
protected $ajaxVariables = array();
|
|
|
|
/** @var array */
|
|
protected $displayVariables = array();
|
|
|
|
/** @var array */
|
|
protected $debugCalcFormel = array();
|
|
|
|
/** @var array */
|
|
protected $debugCalcVariables = array();
|
|
|
|
protected $debugFlatPrice = array();
|
|
|
|
protected $preCalc = array();
|
|
|
|
protected $debugPrice = array();
|
|
/** @var float */
|
|
protected $price = 0;
|
|
|
|
protected float $weight = 0;
|
|
|
|
protected float $weightSingle = 0;
|
|
/** @var float */
|
|
protected $tax = 0;
|
|
|
|
/** @var bool */
|
|
protected $dirty = true;
|
|
|
|
public $validDirty = true;
|
|
|
|
public $validVars = [];
|
|
|
|
/** @var Article */
|
|
protected $article = null;
|
|
|
|
/** @var string */
|
|
protected $activeArticle = false;
|
|
|
|
/** @var \SimpleXMLElement $templates */
|
|
protected $templates;
|
|
|
|
protected $savedCalcValues = [];
|
|
|
|
/**
|
|
* Load XML From String
|
|
*
|
|
* @param $string XML String
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function loadString($string)
|
|
{
|
|
$this->articles = new \ArrayIterator();
|
|
$this->xml = simplexml_load_string($string);
|
|
$this->activeArticle = false;
|
|
$this->calcVariables = [];
|
|
$this->variables = [];
|
|
$this->parse();
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Parse Xml
|
|
*/
|
|
protected function parse()
|
|
{
|
|
$parser = new Parser();
|
|
$parser->setPaperContainer($this->paperContainer);
|
|
$parser->setPaperRepository($this->paperRepository);
|
|
if($this->templates) {
|
|
$parser->setTemplates($this->templates);
|
|
}
|
|
foreach ($this->xml as $article) {
|
|
$this->articles->append($parser->parse($article));
|
|
|
|
}
|
|
$this->dirty = true;
|
|
}
|
|
|
|
/**
|
|
* @return \ArrayIterator
|
|
*/
|
|
public function getArticles()
|
|
{
|
|
return $this->articles;
|
|
}
|
|
|
|
/**
|
|
* @param bool $name
|
|
* @return Article
|
|
* @throws \Exception
|
|
*/
|
|
private function getArticleByName($name = false)
|
|
{
|
|
if($name === false && $this->activeArticle === false) {
|
|
$this->activeArticle = $this->articles[0]->getName();
|
|
return $this->articles[0];
|
|
|
|
}
|
|
|
|
if($name === false && $this->activeArticle !== false) {
|
|
$name = $this->activeArticle;
|
|
|
|
}
|
|
|
|
/** @var Article $article */
|
|
foreach($this->articles as $article)
|
|
{
|
|
if($article->getName() == $name) {
|
|
return $article;
|
|
}
|
|
}
|
|
|
|
return $this->articles[0];
|
|
}
|
|
|
|
/**
|
|
* @return PaperContainer
|
|
*/
|
|
public function getPaperContainer()
|
|
{
|
|
return $this->paperContainer;
|
|
}
|
|
|
|
/**
|
|
* @param PaperContainer $paperContainer
|
|
*/
|
|
public function setPaperContainer($paperContainer)
|
|
{
|
|
$this->dirty = true;
|
|
$this->paperContainer = $paperContainer;
|
|
}
|
|
|
|
/**
|
|
* @return ObjectRepository
|
|
*/
|
|
public function getPaperRepository()
|
|
{
|
|
return $this->paperRepository;
|
|
}
|
|
|
|
/**
|
|
* @param ObjectRepository $paperRepository
|
|
*/
|
|
public function setPaperRepository($paperRepository)
|
|
{
|
|
$this->dirty = true;
|
|
$this->paperRepository = $paperRepository;
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
public function getFormulas()
|
|
{
|
|
return $this->formulas;
|
|
}
|
|
|
|
/**
|
|
* @param string $formulas
|
|
*/
|
|
public function setFormulas($formulas)
|
|
{
|
|
$this->dirty = true;
|
|
$this->formulas = $formulas;
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
public function getParameters()
|
|
{
|
|
return $this->parameters;
|
|
}
|
|
|
|
/**
|
|
* @param string $parameters
|
|
*/
|
|
public function setParameters($parameters)
|
|
{
|
|
$this->dirty = true;
|
|
$this->parameters = $parameters;
|
|
}
|
|
|
|
/**
|
|
* @return array
|
|
*/
|
|
public function getVariables()
|
|
{
|
|
return $this->variables;
|
|
}
|
|
|
|
/**
|
|
* @param array $variables
|
|
*/
|
|
public function setVariables($variables)
|
|
{
|
|
$this->dirty = true;
|
|
$this->variables = $variables;
|
|
}
|
|
|
|
public function calc() {
|
|
|
|
$this->debugCalcFormel = [];
|
|
$this->debugCalcVariables = [];
|
|
$this->debugFlatPrice = [];
|
|
$this->debugPrice = [];
|
|
$this->price = 0;
|
|
|
|
$tmp = [];
|
|
foreach ($this->variables as $key => $variable) {
|
|
if(!is_array($variable)) {
|
|
if($variable !== null) {
|
|
$tmp[$key] = str_replace(",", ".", $variable);
|
|
}
|
|
}else{
|
|
$tmp[$key] = $variable;
|
|
}
|
|
}
|
|
|
|
$this->variables = $tmp;
|
|
|
|
$this->article = $this->getArticleByName($this->activeArticle);
|
|
|
|
if($this->article === null) {
|
|
$this->dirty = false;
|
|
return true;
|
|
}
|
|
|
|
// Prefill with defaults
|
|
/** @var Base $option */
|
|
foreach($this->article->getOptions() as $option) {
|
|
$option->setSavedCalcValues($this->savedCalcValues);
|
|
|
|
if(!isset($this->variables[$option->getId()]) && $option->getDefault() !== null && !$option instanceof Text) {
|
|
if($option instanceof Checkbox) {
|
|
$this->variables[$option->getId()] = explode(",", $option->getDefault());
|
|
}else{
|
|
$this->variables[$option->getId()] = $option->getDefault();
|
|
}
|
|
}
|
|
|
|
if(isset($this->variables[$option->getId()])) {
|
|
$option->setRawValue($this->variables[$option->getId()]);
|
|
$option->processValue();
|
|
}
|
|
}
|
|
|
|
$this->processCalc();
|
|
|
|
$switchedOptions = $this->checkDoubleOptions();
|
|
if(count($switchedOptions) > 0) {
|
|
foreach($switchedOptions as $option) {
|
|
if($option->getDefault() !== null && !$option instanceof Text) {
|
|
if($option instanceof Checkbox) {
|
|
$this->variables[$option->getId()] = explode(",", $option->getDefault());
|
|
}else{
|
|
$this->variables[$option->getId()] = $option->getDefault();
|
|
}
|
|
}
|
|
|
|
if(isset($this->variables[$option->getId()])) {
|
|
$option->setRawValue($this->variables[$option->getId()]);
|
|
$option->processValue();
|
|
}
|
|
}
|
|
|
|
$this->processCalc();
|
|
}
|
|
|
|
$this->dirty = false;
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* @return mixed
|
|
*/
|
|
public function getPrice()
|
|
{
|
|
if($this->dirty) {
|
|
$this->calc();
|
|
}
|
|
return round($this->price,2);
|
|
}
|
|
|
|
/**
|
|
* @return mixed
|
|
*/
|
|
public function getTaxPrice()
|
|
{
|
|
if($this->dirty) {
|
|
$this->calc();
|
|
}
|
|
return round(($this->price/100*$this->tax),2);
|
|
}
|
|
|
|
/**
|
|
* @return mixed
|
|
*/
|
|
public function getCompletePrice()
|
|
{
|
|
if($this->dirty) {
|
|
$this->calc();
|
|
}
|
|
return round($this->price+($this->price/100*$this->tax),2);
|
|
}
|
|
|
|
/**
|
|
* @param mixed $price
|
|
*/
|
|
public function setPrice($price)
|
|
{
|
|
$this->price = $price;
|
|
}
|
|
|
|
public function addDebugCalcVariables($id, $orgVar, $var)
|
|
{
|
|
$this->debugCalcVariables[$id] = [$orgVar, $var];
|
|
}
|
|
|
|
public function getDebugCalcVariables()
|
|
{
|
|
return $this->debugCalcVariables;
|
|
}
|
|
|
|
public function addDebugCalcFormel($orgFormel, $formel)
|
|
{
|
|
$this->debugCalcFormel[] = [$orgFormel, $formel];
|
|
}
|
|
|
|
public function getDebugCalcFormel()
|
|
{
|
|
return $this->debugCalcFormel;
|
|
}
|
|
|
|
public function addDebugFlatPrice($key, $flatPrice)
|
|
{
|
|
if(!isset($this->debugFlatPrice[$key])) {
|
|
$this->debugFlatPrice[$key] = array();
|
|
}
|
|
$this->debugFlatPrice[$key][] = $flatPrice;
|
|
}
|
|
|
|
public function getDebugFlatPrice()
|
|
{
|
|
return $this->debugFlatPrice;
|
|
}
|
|
|
|
public function addDebugPrice($key, $price, $multiplicator, $result)
|
|
{
|
|
if(!isset($this->debugPrice[$key])) {
|
|
$this->debugPrice[$key] = array();
|
|
}
|
|
$this->debugPrice[$key][] = [
|
|
'price' => $price,
|
|
'multiplicator' => $multiplicator,
|
|
'result' => $result
|
|
];
|
|
}
|
|
|
|
public function getDebugPrice()
|
|
{
|
|
return $this->debugPrice;
|
|
}
|
|
/**
|
|
* @return array
|
|
*/
|
|
public function getCalcVariables()
|
|
{
|
|
return $this->calcVariables;
|
|
}
|
|
|
|
/**
|
|
* @param array $calcVariables
|
|
*/
|
|
public function setCalcVariables($calcVariables)
|
|
{
|
|
$this->calcVariables = $calcVariables;
|
|
}
|
|
|
|
/**
|
|
* @param $value
|
|
* @param array $stack
|
|
*/
|
|
public function setCalcVaribleStack($value, $stack = [])
|
|
{
|
|
$id = array_shift($stack);
|
|
foreach($stack as $row) {
|
|
$id = $id . '_' . $row;
|
|
if(!isset($this->calcVariables[$id]) || $this->calcVariables[$id] == 0) {
|
|
$this->calcVariables[$id] = $value;
|
|
}
|
|
}
|
|
}
|
|
|
|
public function addCalcVariable($id, $value) {
|
|
$this->calcVariables[$id] = $value;
|
|
}
|
|
|
|
public function setVariable($var, $value)
|
|
{
|
|
$this->dirty = true;
|
|
$this->variables[$var] = $value;
|
|
}
|
|
|
|
public function hasVariable($var): bool
|
|
{
|
|
return isset($this->variables[$var]);
|
|
}
|
|
|
|
/**
|
|
* @return float
|
|
*/
|
|
public function getTax()
|
|
{
|
|
return $this->tax;
|
|
}
|
|
|
|
/**
|
|
* @param float $tax
|
|
*/
|
|
public function setTax($tax)
|
|
{
|
|
$this->tax = $tax;
|
|
}
|
|
|
|
/**
|
|
* @return Article
|
|
*/
|
|
public function getArticle()
|
|
{
|
|
if($this->dirty) {
|
|
$this->calc();
|
|
}
|
|
return $this->article;
|
|
}
|
|
|
|
/**
|
|
* @param string $activeArticle
|
|
*/
|
|
public function setActiveArticle($activeArticle)
|
|
{
|
|
$this->activeArticle = $activeArticle;
|
|
$this->dirty = true;
|
|
}
|
|
|
|
public function setSymfonyFormVariables($data)
|
|
{
|
|
$tmp = [];
|
|
|
|
foreach($data as $key => $value) {
|
|
if($value instanceof Opt) {
|
|
$tmp[$key] = $value->getId();
|
|
}else{
|
|
$tmp[$key] = $value;
|
|
}
|
|
}
|
|
|
|
return $tmp;
|
|
}
|
|
|
|
public function setTemplates($templates)
|
|
{
|
|
$this->templates = simplexml_load_string($templates);
|
|
}
|
|
|
|
/**
|
|
* @return \SimpleXMLElement
|
|
*/
|
|
public function getTemplates()
|
|
{
|
|
return $this->templates;
|
|
}
|
|
|
|
public function setSavedCalcReferences($values)
|
|
{
|
|
$this->savedCalcValues = $values;
|
|
}
|
|
|
|
/**
|
|
* @return array
|
|
*/
|
|
public function getAjaxVariables()
|
|
{
|
|
return $this->ajaxVariables;
|
|
}
|
|
|
|
/**
|
|
* @param array $ajaxVariables
|
|
*/
|
|
public function setAjaxVariables($ajaxVariables)
|
|
{
|
|
$this->ajaxVariables = $ajaxVariables;
|
|
}
|
|
|
|
public function addAjaxVariable($key, $value)
|
|
{
|
|
$this->ajaxVariables[$key] = $value;
|
|
}
|
|
|
|
/**
|
|
* @return array
|
|
*/
|
|
public function getDisplayVariables()
|
|
{
|
|
return $this->displayVariables;
|
|
}
|
|
|
|
/**
|
|
* @param array $displayVariables
|
|
*/
|
|
public function setDisplayVariables($displayVariables)
|
|
{
|
|
$this->displayVariables = $displayVariables;
|
|
}
|
|
|
|
public function addDisplayVariable($key, $value)
|
|
{
|
|
$this->displayVariables[$key] = $value;
|
|
}
|
|
|
|
public function setWeight(float $var): void
|
|
{
|
|
$this->weight = $var;
|
|
}
|
|
|
|
public function getWeight(): float
|
|
{
|
|
if($this->dirty) {
|
|
$this->calc();
|
|
}
|
|
return $this->weight;
|
|
}
|
|
|
|
public function setWeightSingle(float $var): void
|
|
{
|
|
$this->weightSingle = $var;
|
|
}
|
|
|
|
public function getWeightSingle(): float
|
|
{
|
|
if($this->dirty) {
|
|
$this->calc();
|
|
}
|
|
return $this->weightSingle;
|
|
}
|
|
|
|
private function checkDoubleOptions(): array
|
|
{
|
|
|
|
$options = [];
|
|
$switchedOptions = [];
|
|
/** @var Base $option */
|
|
foreach($this->article->getOptions() as $option) {
|
|
if($option->isValid()) {
|
|
$options[] = $option;
|
|
}else{
|
|
$foundValid = array_filter($this->article->getOptions()->getArrayCopy(), function(Base $elm) use ($option) {
|
|
if($elm->getId() == $option->getId() && $elm->isValid()) {
|
|
return $elm;
|
|
}
|
|
});
|
|
|
|
if(count($foundValid) == 0) {
|
|
$options[] = $option;
|
|
}else{
|
|
$switchedOptions[] = array_shift($foundValid);
|
|
}
|
|
}
|
|
}
|
|
|
|
$this->article->setOptions($options);
|
|
return $switchedOptions;
|
|
}
|
|
|
|
private function processCalc(): void
|
|
{
|
|
$this->validDirty = true;
|
|
$count = 1;
|
|
// Check if Option is valid
|
|
while($this->validDirty && $count < 4) {
|
|
$this->validDirty = false;
|
|
$this->validVars = $this->variables;
|
|
|
|
$calcValid = new Valid($this, $this->article);
|
|
$calcValid->perform();
|
|
|
|
// CALC Values
|
|
$calcValues = new CalcValues($this, $this->article);
|
|
$calcValues->calc();
|
|
|
|
$count++;
|
|
}
|
|
|
|
$calcValid = new Valid($this, $this->article);
|
|
$calcValid->perform();
|
|
|
|
// CALC Values
|
|
$calcValues = new CalcValues($this, $this->article);
|
|
$calcValues->calc();
|
|
|
|
// Check if Option is valid
|
|
// CALC Formel
|
|
$calcFormel = new Calc($this, $this->article);
|
|
$this->price = $calcFormel->calc();
|
|
}
|
|
}
|