<?php
/**
* Boxmaker extension for Contao Open Source CMS
*
* Copyright (C) 2013-2014 bekanntmacher
*
* @author Yanick Witschi <yanick.witschi@terminal42.ch>
* @license commercial
*/
namespace Bekanntmacher\BoxmakerBundle\Calculation;
class PriceCalculator
{
private $objType = null;
private $objConfig = null;
private $objUserInput = null;
private $arrPrices = array();
private $floatM2piece = 0;
public $cheapestProductionMethod;
public $cheapestPrintingMethod = array();
/**
* Initialize a new PriceCalculator object
*/
public function __construct($objType, $objConfig, $objUserInput)
{
$this->objType = $objType;
$this->objConfig = $objConfig;
$this->objUserInput = $objUserInput;
// Fläche pro Stück
$surface = new Surface(
$this->objType->formula_laenge,
$this->objType->formula_breite,
$this->objUserInput->getAll()
);
$this->floatM2piece = $this->arrPrices['floatM2piece'] = $surface->getM2PerPiece();
$this->calculatePrices();
}
public function __get($key)
{
return $this->get($key);
}
public function get($key)
{
if(key_exists($key, $this->arrPrices) !== false)
{
return $this->arrPrices[$key];
}
return false;
}
public function getAll()
{
return $this->arrPrices;
}
public function getCheapestProductionMethod()
{
$lowestEp = null;
$ep = 0;
foreach($GLOBALS['BOXMAKER']['productionMethods'] as $method)
{
$ep = $this->getMaterialPrice($method, $this->objUserInput->welle, $this->objUserInput->farbe);
$ep += $this->getStanzenPrice($method);
$ep += $this->getKlebenPrice($method);
if ($lowestEp === null || $ep < $lowestEp)
{
$lowestEp = $ep;
$this->cheapestProductionMethod = $method;
}
}
return $this->cheapestProductionMethod;
}
public function getCheapestPrintingMethod()
{
$arrLowest = array ( '_1f' => null, '_4f' => null );
$arrF = array('_1f','_4f');
foreach ($arrF as $strF)
{
foreach($GLOBALS['BOXMAKER']['printingMethods'] as $method)
{
if($method == 'blank' || strpos($method, $strF) === false || ($method == 'offsetdruck_1f')) {
continue;
}
$ep = $this->getDruckPrice($strF, $method);
// echo $method . ' ' . $ep ."\r\n";
if (($arrLowest[$strF] === null || $ep < $arrLowest[$strF]) && $ep != 0)
{
$arrLowest[$strF] = $ep;
$this->cheapestPrintingMethod[$strF] = $method;
}
}
$this->cheapestPrintingMethod[$strF];
}
return $this->cheapestPrintingMethod;
}
public function getMaterialPrice($method, $welle, $farbe)
{
return $this->arrPrices['material'][$method][$welle]['farbe_' . $farbe];
}
public function getProduktionPrice($method=null)
{
if($method == null)
{
return $this->arrPrices['allProduktionPrices'][$this->cheapestProductionMethod];
}
else
{
return $this->arrPrices['allProduktionPrices'][$method];
}
}
public function getStanzenPrice($method=null)
{
if($method === null)
{
$method = $this->cheapestProductionMethod;
}
return $this->arrPrices['stanzen'][$method]['stanzen_per_stk'];
}
public function getStanzmesserPrice($method=null)
{
if($method === null)
{
$method = $this->cheapestProductionMethod;
}
return $this->arrPrices['stanzen'][$method]['stanzmesser'];
}
public function getKlebenPrice($method=null)
{
if($method === null)
{
$method = $this->cheapestProductionMethod;
}
return $this->arrPrices['kleben'][$method]['kleben_per_stk'];
}
public function getDruckPrice($color, $printing_method)
{
$color = str_replace('_','', $color);
return $this->arrPrices['druck'][$color][$printing_method];
}
public function getAllDruckPrices()
{
return $this->arrPrices['druck'];
}
private function calculatePrices()
{
// Materialkosten berechnen
$this->calculateMaterialkostenPerStueck();
// Produktionskosten
$this->calculateProduktionskostenPerStueck();
// Günstigste Produktionsmethode
$this->getCheapestProductionMethod();
// Druckkosten
foreach ($GLOBALS['BOXMAKER']['printingMethods'] as $method) {
if ($this->objUserInput->stk < $this->objType->{$method . '_min'} && $this->getCheapestProductionMethod() !== 'ap') {
continue;
}
$einrichten_per_stk = $this->objType->{$method . '_einrichten'} / $this->objUserInput->stk;
if ($method == 'digitaldruck_1f' || $method == 'digitaldruck_4f' || $method == 'digitaldruckeco_4f') {
$druck_per_stk = ($this->objType->{$method . '_perm2'} * $this->floatM2piece);
$this->arrPrices['druck']['1f'][$method] = $einrichten_per_stk + $druck_per_stk;
$this->arrPrices['druck']['4f'][$method] = $einrichten_per_stk + $druck_per_stk;
} elseif ($method == 'siebdruck_1f') {
$druck_per_stk = $this->objType->{$method . '_klischee'} / $this->objUserInput->stk;
$druck_per_stk += $this->objType->{$method . '_perstueck'};
$druck_per_stk += ($this->objType->{$method . '_perm2'} * $this->floatM2piece);
$this->arrPrices['druck']['1f'][$method] = $einrichten_per_stk + $druck_per_stk;
$this->arrPrices['druck']['4f'][$method] = null;
} elseif ($method == 'offsetdruck_1f') {
$einrichten_per_stk = $this->objType->{'offsetdruck_4f_einrichten'} / $this->objUserInput->stk;
$druck_per_stk = $this->objType->{'offsetdruck_4f_klischee'} / $this->objUserInput->stk;
$druck_per_stk += $this->objType->{'offsetdruck_4f_perstueck'};
$druck_per_stk += ($this->objType->{'offsetdruck_4f_perm2'} * $this->floatM2piece);
$this->arrPrices['druck']['1f'][$method] = $einrichten_per_stk + $druck_per_stk;
$this->arrPrices['druck']['4f'][$method] = $einrichten_per_stk + $druck_per_stk;
} elseif ($method == 'offsetdruck_4f') {
$druck_per_stk = $this->objType->{$method . '_klischee'} / $this->objUserInput->stk;
$druck_per_stk += $this->objType->{$method . '_perstueck'};
$druck_per_stk += ($this->objType->{$method . '_perm2'} * $this->floatM2piece);
$this->arrPrices['druck']['1f'][$method] = $einrichten_per_stk + $druck_per_stk;
$this->arrPrices['druck']['4f'][$method] = $einrichten_per_stk + $druck_per_stk;
} elseif ($method == 'flexodruck_1f') {
$druck_per_stk = $this->objType->{$method . '_klischee'} / $this->objUserInput->stk;
$druck_per_stk += ($this->objType->{$method . '_klischee_perm2'} * $this->floatM2piece) / $this->objUserInput->stk;
$druck_per_stk += $this->objType->{$method . '_perstueck'};
$druck_per_stk += ($this->objType->{$method . '_perm2'} * $this->floatM2piece);
$this->arrPrices['druck']['1f'][$method] = $einrichten_per_stk + $druck_per_stk;
$this->arrPrices['druck']['4f'][$method] = null;
} elseif ($method == 'blank') {
$this->arrPrices['druck']['1f'][$method] = 0;
$this->arrPrices['druck']['4f'][$method] = 0;
}
}
$this->getCheapestPrintingMethod();
return $this->arrPrices;
}
private function calculateMaterialkostenPerStueck()
{
foreach ($GLOBALS['BOXMAKER']['productionMethods'] as $method)
{
$arrMethodePricing = $this->objType->{$method . '_pricing'};
foreach ($arrMethodePricing as $arrWellePricing)
{
$idWelle = array_shift($arrWellePricing);
foreach ($arrWellePricing as $farbe => $value)
{
// welle in der Farbe nicht erhältlich
if($value == 0)
continue;
$this->arrPrices['material'][$method][$idWelle][$farbe] = $value * $this->floatM2piece;
}
}
}
}
private function calculateProduktionskostenPerStueck()
{
$lowestProductionCosts = null;
foreach($GLOBALS['BOXMAKER']['productionMethods'] as $method)
{
$produktion = $this->calculateStanzkostenPerStk($method) + $this->calculateKlebekostenPerStk($method);
$this->arrPrices['allProduktionPrices'][$method] = $produktion;
}
}
private function calculateStanzkostenPerStk($method)
{
foreach($GLOBALS['BOXMAKER']['productionMethods'] as $m)
{
$einrichten_per_stk = $this->objType->{$m . '_stanzen_einrichten'} / $this->objUserInput->stk;
if ($m === 'p') {
$stanzen_per_stk = $this->objType->p_stanzen_perm2 * $this->floatM2piece;
$stanzmesser_per_stk = 0;
}
else // Handtiegel / Autoplatine
{
$stanzen_per_stk = $this->getFormulaResult($this->objType->{$m . '_stanzen_perstueck'}, $this->objUserInput->getAll());
$stanzmesser = $this->objType->{$m . '_stanzen_stanzmesser'};
$stanzmesser += ($this->objType->{$m . '_stanzen_stanzmesser_perm2'} * $this->floatM2piece);
$stanzmesser_per_stk = $stanzmesser / $this->objUserInput->stk;
}
// falls unterhalb der minimalen Stückzahl für dieses Verfahren
if($m == 'ap' && $this->objUserInput->stk < $this->objType->ap_minimal_stk)
{
$einrichten_per_stk = $einrichten_per_stk + 100000000000;
}
$this->arrPrices['stanzen'][$m]['stanzen_per_stk'] = $einrichten_per_stk + $stanzen_per_stk + $stanzmesser_per_stk;
$this->arrPrices['stanzen'][$m]['stanzmesser'] = $stanzmesser_per_stk * $this->objUserInput->stk;
}
return $this->arrPrices['stanzen'][$method]['stanzen_per_stk'];
}
private function calculateKlebekostenPerStk($method)
{
$einrichten_per_stk = $this->objType->{$method . '_kleben_einrichten'} / $this->objUserInput->stk;
$kleben_per_stk = $this->objType->{$method . '_kleben_perstueck'};
$kleben_per_stk += $this->objType->{$method . '_kleben_permm'} * $this->objUserInput->hoehe;
$kleben_total_per_stk = $einrichten_per_stk + $kleben_per_stk;
$this->arrPrices['kleben'][$method]['kleben_per_stk'] = $kleben_total_per_stk;
return $kleben_total_per_stk;
}
private function getFormulaResult($code, $arrData)
{
$code = 'return ' . \StringUtil::parseSimpleTokens($code, $arrData) . ';';
return (float) eval($code);
}
}