This commit is contained in:
Thomas Peterson 2024-09-24 13:45:17 +02:00
parent d95e79b7bf
commit 498470c8d0
4 changed files with 128 additions and 38 deletions

View File

@ -16,6 +16,7 @@ use PSC\Library\Calc\General\Type\EdgeCollectionContainer;
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\Radio;
use PSC\Library\Calc\Option\Type\Select;
use PSC\Library\Calc\Tests\Mock\Paper;
@ -50,12 +51,12 @@ class Calc
$gesamt = 0;
/** @var Base $option */
foreach($this->article->getOptions() as $option) {
foreach ($this->article->getOptions() as $option) {
if($option instanceof Select || $option instanceof Checkbox) {
if ($option instanceof Select || $option instanceof Checkbox || $option instanceof Radio) {
/** @var Select\Opt $opt */
foreach($option->getOptions() as $opt) {
if($opt->isValid() && $opt->isSelected()) {
foreach ($option->getOptions() as $opt) {
if ($opt->isValid() && $opt->isSelected()) {
$gesamt = $this->parseEdgeCollection($gesamt, $option, $opt->getEdgesCollectionContainer(), [$option->getId()]);
}
}
@ -82,47 +83,49 @@ class Calc
$calcValueAccount2 = 0;
/** @var EdgeCollection $collection */
foreach($container as $collection) {
foreach ($container as $collection) {
$var = 'XXXXXXXXXXXX';
if($collection->getName() == "opt") continue;
if($collection->getFormel() != "") {
if ($collection->getName() == "opt") {
continue;
}
if ($collection->getFormel() != "") {
$formel = $this->formelCalc->parse($collection->getFormel());
eval('$var = ' . $formel . ';');
}else{
if(isset($this->engine->getVariables()[$collection->getName()])) {
} else {
if (isset($this->engine->getVariables()[$collection->getName()])) {
$var = $this->engine->getVariables()[$collection->getName()];
}
}
/** @var Edge $edge */
foreach($collection as $edge) {
foreach ($collection as $edge) {
if($var !== "XXXXXXXXXXXX" && $edge->isValid($var)) {
if ($var !== "XXXXXXXXXXXX" && $edge->isValid($var)) {
if($edge->getPauschale() != 0) {
if ($edge->getPauschale() != 0) {
eval('$gesamt += ' . $edge->getPauschale() . ';');
$this->engine->addDebugFlatPrice($collection->getName(), $edge->getPauschale());
}
if($edge->getPreis() != 0) {
eval('$gesamt += ' . ($edge->getPreis()*$var) . ';');
$this->engine->addDebugPrice($collection->getName(), $edge->getPreis(), $var, $edge->getPreis()*$var);
if ($edge->getPreis() != 0) {
eval('$gesamt += ' . ($edge->getPreis() * $var) . ';');
$this->engine->addDebugPrice($collection->getName(), $edge->getPreis(), $var, $edge->getPreis() * $var);
}
if($edge->getCalcValue() != "") {
if ($edge->getCalcValue() != "") {
$cv = $this->formelCalc->parse($edge->getCalcValue());
$orgCv = $cv;
try {
eval('@$cv = ' . $cv . ';');
$this->engine->addDebugCalcVariables($option->getId() . '_' . $collection->getName(), $edge->getCalcValue(), $orgCv . ' = ' . $cv);
}catch (\Throwable $e) {
} catch (\Throwable $e) {
$cv = 0;
}
$this->engine->addCalcVariable($option->getId() . '_' . $collection->getName(), $orgCv);
$this->engine->setCalcVaribleStack($orgCv, $calcValueId);
}
if($edge->getFormel() != "") {
if ($edge->getFormel() != "") {
$formel = $this->formelCalc->parse($edge->getFormel());
if ($formel != "" && !in_array($option->getId(), ['weight', 'weight_single']) && !$option->isAjaxExport() && !$option->isDisplayOnly() && $option->isAmount()) {
$p = 0;
@ -131,11 +134,11 @@ class Calc
try {
eval('@$p = ' . $this->eval_func($gesamt, $formel) . ';');
$this->engine->addDebugCalcFormel($edge->getFormel(), $formel . ' = ' . $p);
}catch (\Throwable $e) {
} catch (\Throwable $e) {
$this->engine->addDebugCalcFormel($edge->getFormel(), $formel . ' = error');
$p = 0;
}
if($p > 0 || $p < 0) {
if ($p > 0 || $p < 0) {
$gesamt += $p;
}
@ -148,7 +151,7 @@ class Calc
eval('@$p = ' . $this->eval_func($gesamt, $formel) . ';');
$this->engine->addAjaxVariable($option->getId(), $p);
}catch (\Throwable $e) {
} catch (\Throwable $e) {
$this->engine->addDebugCalcFormel($edge->getFormel(), $formel . ' = error');
$p = 0;
}
@ -160,19 +163,19 @@ class Calc
$this->engine->addDisplayVariable($option->getId(), $p);
}
if($formel != "" && $option->getId() == "weight_single") {
if ($formel != "" && $option->getId() == "weight_single") {
$p = 0;
$formel = str_replace("tonumber", '$this->toNumber', $formel);
eval('@$p = ' . $this->eval_func($gesamt, $formel) . ';');
$this->engine->setWeightSingle($p);
}
if($formel != "" && $option->getId() == "weight") {
if ($formel != "" && $option->getId() == "weight") {
$p = 0;
$formel = str_replace("tonumber", '$this->toNumber', $formel);
eval('@$p = ' . $this->eval_func($gesamt, $formel) . ';');
$this->engine->setWeight($p);
}
if(!$option->isAmount()) {
if (!$option->isAmount()) {
$p = 0;
$formel = str_replace("tonumber", '$this->toNumber', $formel);
@ -181,9 +184,9 @@ class Calc
}
}
if($edge->getEdgesCollectionContainer()->count() > 0) {
if ($edge->getEdgesCollectionContainer()->count() > 0) {
$calcValueId[] = $collection->getName();
$gesamt = $this->parseEdgeCollection($gesamt, $option, $edge->getEdgesCollectionContainer(), $calcValueId);
$gesamt = $this->parseEdgeCollection($gesamt, $option, $edge->getEdgesCollectionContainer(), $calcValueId);
}
}
}
@ -192,15 +195,16 @@ class Calc
return $gesamt;
}
private function eval_func($gesamt, string $formel) {
private function eval_func($gesamt, string $formel)
{
$p = 0;
try {
eval('@$p=' . $formel . ';');
}catch(\Throwable $e) {
} catch (\Throwable $e) {
if(str_contains($e->getMessage(), 'Undefined constant')) {
if (str_contains($e->getMessage(), 'Undefined constant')) {
preg_match('/Undefined constant "(.*)"/', $e->getMessage(), $output_array);
if(isset($output_array[1])) {
if (isset($output_array[1])) {
$formel = str_replace($output_array[1], "'" . $output_array[1] ."'", $formel);
$p = $this->eval_func($gesamt, $formel);
return $p;
@ -213,7 +217,7 @@ class Calc
private function toNumber($value)
{
if(strpos($value,',') == (strlen($value)-1)) {
if (strpos($value, ',') == (strlen($value) - 1)) {
return str_replace(',', '', $value);
}

View File

@ -1,4 +1,5 @@
<?php
namespace PSC\Library\Calc\Tests\Customer\DD;
use PHPUnit\Framework\TestCase;
@ -10,7 +11,6 @@ use PSC\Library\Calc\Tests\Mock\PaperRepostory;
class CalcTest extends TestCase
{
/** @var Engine */
protected $engine = null;
@ -165,24 +165,22 @@ class CalcTest extends TestCase
'rabattkalk_nopresentation' => '0',
'angebotsadresse_nopresentation' => '',
'eckenstanzecheckbox1' =>
array (
array(
0 => '1',
),
'eckenstanzecheckbox2' =>
array (
array(
0 => '1',
),
'eckenstanzecheckbox3' =>
array (
array(
0 => '1',
),
'eckenstanzecheckbox4' =>
array (
array(
0 => '1',
),
]);
echo $this->engine->getPrice().PHP_EOL;
var_dump($this->engine->getAjaxVariables()['ppreisI']);
$this->assertSame(37.74, $this->engine->getPrice());
}

View File

@ -0,0 +1,55 @@
<?php
namespace PSC\Library\Calc\Tests\Customer\R;
use PHPUnit\Framework\TestCase;
use PSC\Library\Calc\Engine;
use PSC\Library\Calc\PaperContainer;
use PSC\Library\Calc\Tests\Mock\PaperRepostory;
class RadioboxCalcTest extends TestCase
{
protected ?Engine $engine;
public function setUp(): void
{
$repository = new PaperRepostory();
$paperContainer = new PaperContainer();
$paperContainer->parse(simplexml_load_string(file_get_contents(__DIR__ . '/papierContainer.xml')));
$this->engine = new Engine();
$this->engine->setPaperContainer($paperContainer);
$this->engine->setPaperRepository($repository);
$this->engine->setFormulas(file_get_contents(__DIR__ . '/formels.txt'));
$this->engine->setParameters(file_get_contents(__DIR__ . '/parameters.txt'));
$this->engine->setTemplates(file_get_contents(__DIR__ . '/calcTemplates.xml'));
$this->engine->loadString(file_get_contents(__DIR__ . '/calc_radiobox_with_calc.xml'));
}
public function tearDown(): void
{
$this->engine = null;
}
public function testCalcDefault(): void
{
$this->assertSame(3.22, $this->engine->getPrice());
}
public function testCalcZweiseitig(): void
{
$this->engine->setVariable('bedruckung', 'beidseitig');
$this->assertSame(5.97, $this->engine->getPrice());
}
public function testCalcZweiseitig20(): void
{
$this->engine->setVariable('auflage', '20');
$this->engine->setVariable('bedruckung', 'beidseitig');
$this->assertSame(62.86, $this->engine->getPrice());
}
}

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<kalkulation>
<artikel>
<name>Checkbox Grenze Formel</name>
<kommentar></kommentar>
<option id="auflage" name="Auflage" default="1" type="Input"/>
<option id="bedruckung" name="Bedruckung" type="Radio" default="einseitig">
<opt id="einseitig" name="Einseitig">
<auflage>
<grenze formel="($Vauflage$V*3.83)*100/119">1-6</grenze>
<grenze formel="($Vauflage$V*3.30)*100/119">7-9</grenze>
<grenze formel="($Vauflage$V*2.75)*100/119">10-19</grenze>
<grenze formel="($Vauflage$V*2.42)*100/119">20-49</grenze>
<grenze formel="($Vauflage$V*2.20)*100/119">50-99</grenze>
<grenze formel="($Vauflage$V*1.93)*100/119">100-249</grenze>
<grenze formel="($Vauflage$V*1.65)*100/119">250-</grenze>
</auflage>
</opt>
<opt id="beidseitig" name="beidseitig">
<auflage>
<grenze formel="($Vauflage$V*7.10)*100/119">1-6</grenze>
<grenze formel="($Vauflage$V*6.00)*100/119">7-9</grenze>
<grenze formel="($Vauflage$V*4.84)*100/119">10-19</grenze>
<grenze formel="($Vauflage$V*3.74)*100/119">20-49</grenze>
<grenze formel="($Vauflage$V*3.20)*100/119">50-99</grenze>
<grenze formel="($Vauflage$V*2.85)*100/119">100-249</grenze>
<grenze formel="($Vauflage$V*2.42)*100/119">250-</grenze>
</auflage>
</opt>
</option>
</artikel>
</kalkulation>