Merge pull request #4864 from pamil/pricing/calculator-refactoring

[Core] Refactored AbstractCalculator
This commit is contained in:
Paweł Jędrzejewski 2016-04-26 09:49:03 +02:00
commit 2c08017aea
3 changed files with 74 additions and 47 deletions

View file

@ -11,46 +11,22 @@
namespace Sylius\Component\Core\Pricing;
use Sylius\Component\Pricing\Calculator\CalculatorInterface;
use Sylius\Component\Pricing\Model\PriceableInterface;
use Sylius\Component\Resource\Exception\UnexpectedTypeException;
use Webmozart\Assert\Assert;
/**
* @author Paweł Jędrzejewski <pawel@sylius.org>
* @author Joseph Bielawski <stloyd@gmail.com>
*/
abstract class AbstractCalculator
abstract class AbstractCalculator implements CalculatorInterface
{
protected $parameterName;
protected $className;
public function __construct()
{
if (null === $this->parameterName || null === $this->className) {
throw new \RuntimeException();
}
}
/**
* {@inheritdoc}
*/
public function calculate(PriceableInterface $subject, array $configuration, array $context = [])
final public function calculate(PriceableInterface $subject, array $configuration, array $context = [])
{
if (!array_key_exists($this->parameterName, $context)) {
return $subject->getPrice();
}
$price = null;
foreach ($context[$this->parameterName] as $object) {
if (!in_array($this->className, class_implements($object))) {
throw new UnexpectedTypeException($object, $this->className);
}
$id = $object->getId();
if (array_key_exists($id, $configuration) && (null === $price || $configuration[$id] < $price)) {
$price = (int) round($configuration[$id]);
}
}
$price = $this->getPriceForConfigurationAndContext($configuration, $context);
if (null === $price) {
return $subject->getPrice();
@ -58,4 +34,39 @@ abstract class AbstractCalculator
return $price;
}
/**
* @return string
*/
abstract protected function getParameterName();
/**
* @return string
*/
abstract protected function getClassName();
/**
* @param array $configuration
* @param array $context
*
* @return int|null
*/
private function getPriceForConfigurationAndContext(array $configuration, array $context)
{
if (!array_key_exists($this->getParameterName(), $context)) {
return null;
}
$price = null;
foreach ($context[$this->getParameterName()] as $object) {
Assert::isInstanceOf($object, $this->getClassName());
$id = $object->getId();
if (array_key_exists($id, $configuration) && (null === $price || $configuration[$id] < $price)) {
$price = (int) round($configuration[$id]);
}
}
return $price;
}
}

View file

@ -11,23 +11,13 @@
namespace Sylius\Component\Core\Pricing;
use Sylius\Component\Pricing\Calculator\CalculatorInterface;
use Sylius\Component\User\Model\GroupInterface;
/**
* Customer group based calculator.
*
* @author Paweł Jędrzejewski <pawel@sylius.org>
*/
class GroupBasedCalculator extends AbstractCalculator implements CalculatorInterface
class GroupBasedCalculator extends AbstractCalculator
{
public function __construct()
{
$this->parameterName = 'groups';
$this->className = GroupInterface::class;
parent::__construct();
}
/**
* {@inheritdoc}
*/
@ -35,4 +25,20 @@ class GroupBasedCalculator extends AbstractCalculator implements CalculatorInter
{
return Calculators::GROUP_BASED;
}
/**
* {@inheritdoc}
*/
protected function getParameterName()
{
return 'groups';
}
/**
* {@inheritdoc}
*/
protected function getClassName()
{
return GroupInterface::class;
}
}

View file

@ -12,18 +12,12 @@
namespace Sylius\Component\Core\Pricing;
use Sylius\Component\Addressing\Model\ZoneInterface;
use Sylius\Component\Pricing\Calculator\CalculatorInterface;
/**
* Address zone based calculator.
*
* @author Joseph Bielawski <stloyd@gmail.com>
*/
class ZoneBasedCalculator extends AbstractCalculator implements CalculatorInterface
class ZoneBasedCalculator extends AbstractCalculator
{
protected $parameterName = 'zones';
protected $className = ZoneInterface::class;
/**
* {@inheritdoc}
*/
@ -31,4 +25,20 @@ class ZoneBasedCalculator extends AbstractCalculator implements CalculatorInterf
{
return Calculators::ZONE_BASED;
}
/**
* {@inheritdoc}
*/
protected function getParameterName()
{
return 'zones';
}
/**
* {@inheritdoc}
*/
protected function getClassName()
{
return ZoneInterface::class;
}
}