WIP : Coupon event dispatcher + action

This commit is contained in:
gmorel
2013-09-12 17:21:49 +02:00
parent 6d914c5676
commit 2e7e31285e
14 changed files with 145 additions and 62 deletions

View File

@@ -29,6 +29,7 @@ use Thelia\Constraint\ConstraintFactory;
use Thelia\Core\Event\Coupon\CouponConsumeEvent; use Thelia\Core\Event\Coupon\CouponConsumeEvent;
use Thelia\Core\Event\Coupon\CouponCreateOrUpdateEvent; use Thelia\Core\Event\Coupon\CouponCreateOrUpdateEvent;
use Thelia\Core\Event\TheliaEvents; use Thelia\Core\Event\TheliaEvents;
use Thelia\Core\HttpFoundation\Request;
use Thelia\Coupon\CouponFactory; use Thelia\Coupon\CouponFactory;
use Thelia\Coupon\CouponManager; use Thelia\Coupon\CouponManager;
use Thelia\Coupon\Type\CouponInterface; use Thelia\Coupon\Type\CouponInterface;
@@ -101,10 +102,24 @@ class Coupon extends BaseAction implements EventSubscriberInterface
/** @var CouponInterface $coupon */ /** @var CouponInterface $coupon */
$coupon = $couponFactory->buildCouponFromCode($event->getCode()); $coupon = $couponFactory->buildCouponFromCode($event->getCode());
$isValid = $coupon->isMatching(); $isValid = $coupon->isMatching();
if ($isValid) { if ($isValid) {
/** @var Request $request */
$request = $this->container->get('request');
$consumedCoupons = $request->getSession()->getConsumedCoupons();
if (!isset($consumedCoupons) || !$consumedCoupons) {
$consumedCoupons = array();
}
// Prevent accumulation of the same Coupon on a Checkout
$consumedCoupons[$event->getCode()] = $event->getCode();
$request->getSession()->setConsumedCoupons($consumedCoupons);
$totalDiscount = $couponManager->getDiscount(); $totalDiscount = $couponManager->getDiscount();
// @todo modify Cart total discount
} }
$event->setIsValid($isValid); $event->setIsValid($isValid);

View File

@@ -230,6 +230,8 @@
<service id="thelia.constraint.factory" class="Thelia\Constraint\ConstraintFactory"> <service id="thelia.constraint.factory" class="Thelia\Constraint\ConstraintFactory">
<argument type="service" id="service_container" /> <argument type="service" id="service_container" />
</service> </service>
<service id="thelia.constraint.validator" class="Thelia\Constraint\ConstraintValidator">
</service>
<service id="thelia.constraint.rule.available_for_everyone" class="Thelia\Constraint\Rule\AvailableForEveryoneManager"> <service id="thelia.constraint.rule.available_for_everyone" class="Thelia\Constraint\Rule\AvailableForEveryoneManager">
<argument type="service" id="thelia.adapter" /> <argument type="service" id="thelia.adapter" />
<tag name="thelia.coupon.addRule"/> <tag name="thelia.coupon.addRule"/>

View File

@@ -52,7 +52,7 @@ class ConstraintValidator
* *
* @return bool * @return bool
*/ */
public function test(CouponRuleCollection $rules) public function isMatching(CouponRuleCollection $rules)
{ {
$isMatching = true; $isMatching = true;
/** @var CouponRuleInterface $rule */ /** @var CouponRuleInterface $rule */

View File

@@ -25,7 +25,6 @@ namespace Thelia\Constraint\Rule;
use Symfony\Component\Intl\Exception\NotImplementedException; use Symfony\Component\Intl\Exception\NotImplementedException;
use Symfony\Component\Translation\Translator; use Symfony\Component\Translation\Translator;
use Thelia\Constraint\ConstraintValidator;
use Thelia\Coupon\CouponAdapterInterface; use Thelia\Coupon\CouponAdapterInterface;
use Thelia\Constraint\Validator\PriceParam; use Thelia\Constraint\Validator\PriceParam;
use Thelia\Constraint\Validator\RuleValidator; use Thelia\Constraint\Validator\RuleValidator;
@@ -168,13 +167,12 @@ class AvailableForTotalAmountManager extends CouponRuleAbstract
return false; return false;
} }
$constrainValidator = new ConstraintValidator(); $constraint1 = $this->constraintValidator->variableOpComparison(
$constraint1 =$constrainValidator->variableOpComparison(
$this->adapter->getCartTotalPrice(), $this->adapter->getCartTotalPrice(),
$this->operators[self::INPUT1], $this->operators[self::INPUT1],
$this->values[self::INPUT1] $this->values[self::INPUT1]
); );
$constraint2 =$constrainValidator->variableOpComparison( $constraint2 = $this->constraintValidator->variableOpComparison(
$this->adapter->getCheckoutCurrency(), $this->adapter->getCheckoutCurrency(),
$this->operators[self::INPUT2], $this->operators[self::INPUT2],
$this->values[self::INPUT2] $this->values[self::INPUT2]

View File

@@ -126,8 +126,7 @@ class AvailableForXArticlesManager extends CouponRuleAbstract
*/ */
public function isMatching() public function isMatching()
{ {
$constrainValidator = new ConstraintValidator(); $constraint1 = $this->constraintValidator->variableOpComparison(
$constraint1 =$constrainValidator->variableOpComparison(
$this->adapter->getNbArticlesInCart(), $this->adapter->getNbArticlesInCart(),
$this->operators[self::INPUT1], $this->operators[self::INPUT1],
$this->values[self::INPUT1] $this->values[self::INPUT1]

View File

@@ -82,6 +82,7 @@ abstract class CouponRuleAbstract implements CouponRuleInterface
{ {
$this->adapter = $adapter; $this->adapter = $adapter;
$this->translator = $adapter->getTranslator(); $this->translator = $adapter->getTranslator();
$this->constraintValidator = $adapter->getConstraintValidator();
} }
// /** // /**

View File

@@ -495,7 +495,7 @@ class CouponController extends BaseAdminController
$couponConsumeEvent $couponConsumeEvent
); );
var_dump('test'); var_dump('test', $couponConsumeEvent->getCode(), $couponConsumeEvent->getDiscount(), $couponConsumeEvent->getIsValid());
exit(); exit();
} }

View File

@@ -220,4 +220,29 @@ class Session extends BaseSession
{ {
return $this->get("thelia.delivery_id"); return $this->get("thelia.delivery_id");
} }
/**
* Set consumed coupons by the Customer
*
* @param array $couponsCode An array of Coupon code
*
* @return $this
*/
public function setConsumedCoupons(array $couponsCode)
{
$this->set('thelia.consumed_coupons', $couponsCode);
return $this;
}
/**
* Get Customer consumed coupons
*
* @return array $couponsCode An array of Coupon code
*/
public function getConsumedCoupons()
{
return $this->get('thelia.consumed_coupons');
}
} }

View File

@@ -155,4 +155,18 @@ interface CouponAdapterInterface
*/ */
public function getMainCurrency(); public function getMainCurrency();
/**
* Return request
*
* @return Request
*/
public function getRequest();
/**
* Return Constraint Validator
*
* @return ConstraintValidator
*/
public function getConstraintValidator();
} }

View File

@@ -27,6 +27,7 @@ use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Translation\Translator; use Symfony\Component\Translation\Translator;
use Symfony\Component\Translation\TranslatorInterface; use Symfony\Component\Translation\TranslatorInterface;
use Thelia\Constraint\ConstraintValidator;
use Thelia\Core\HttpFoundation\Request; use Thelia\Core\HttpFoundation\Request;
use Thelia\Core\Security\SecurityContext; use Thelia\Core\Security\SecurityContext;
use Thelia\Coupon\Type\CouponInterface; use Thelia\Coupon\Type\CouponInterface;
@@ -155,6 +156,11 @@ class CouponBaseAdapter implements CouponAdapterInterface
*/ */
public function getCurrentCoupons() public function getCurrentCoupons()
{ {
// @todo implement
// $consumedCoupons = $this->getRequest()->getSession()->getConsumedCoupons();
// @todo convert coupon code to coupon Interface
$couponFactory = $this->container->get('thelia.coupon.factory'); $couponFactory = $this->container->get('thelia.coupon.factory');
// @todo get from cart // @todo get from cart
@@ -250,4 +256,14 @@ class CouponBaseAdapter implements CouponAdapterInterface
{ {
return $this->container->get('request'); return $this->container->get('request');
} }
/**
* Return Constraint Validator
*
* @return ConstraintValidator
*/
public function getConstraintValidator()
{
return $this->container->get('thelia.constraint.validator');
}
} }

View File

@@ -183,6 +183,7 @@ class CouponManager
$discount = 0.00; $discount = 0.00;
/** @var CouponInterface $coupon */ /** @var CouponInterface $coupon */
foreach ($coupons as $coupon) { foreach ($coupons as $coupon) {
// @todo modify Cart with discount for each cart item
$discount += $coupon->getDiscount($this->adapter); $discount += $coupon->getDiscount($this->adapter);
} }

View File

@@ -26,6 +26,7 @@ namespace Thelia\Coupon\Type;
use Symfony\Component\Intl\Exception\NotImplementedException; use Symfony\Component\Intl\Exception\NotImplementedException;
use Thelia\Constraint\ConstraintManager; use Thelia\Constraint\ConstraintManager;
use Thelia\Constraint\ConstraintValidator; use Thelia\Constraint\ConstraintValidator;
use Thelia\Core\Translation\Translator;
use Thelia\Coupon\CouponAdapterInterface; use Thelia\Coupon\CouponAdapterInterface;
use Thelia\Coupon\CouponRuleCollection; use Thelia\Coupon\CouponRuleCollection;
use Thelia\Coupon\RuleOrganizerInterface; use Thelia\Coupon\RuleOrganizerInterface;
@@ -44,9 +45,6 @@ use Thelia\Exception\InvalidRuleException;
*/ */
abstract class CouponAbstract implements CouponInterface abstract class CouponAbstract implements CouponInterface
{ {
/** @var string Service Id */
protected $serviceId = null;
/** @var CouponAdapterInterface Provide necessary value from Thelia */ /** @var CouponAdapterInterface Provide necessary value from Thelia */
protected $adapter = null; protected $adapter = null;
@@ -62,9 +60,19 @@ abstract class CouponAbstract implements CouponInterface
/** @var ConstraintValidator Constraint validator */ /** @var ConstraintValidator Constraint validator */
protected $constraintValidator = null; protected $constraintValidator = null;
/** @var string Service Id */
protected $serviceId = null;
/** @var float Amount that will be removed from the Checkout (Coupon Effect) */
protected $amount = 0;
/** @var string Coupon code (ex: XMAS) */ /** @var string Coupon code (ex: XMAS) */
protected $code = null; protected $code = null;
/** @var string Coupon title (ex: Coupon for XMAS) */ /** @var string Coupon title (ex: Coupon for XMAS) */
protected $title = null; protected $title = null;
@@ -74,6 +82,8 @@ abstract class CouponAbstract implements CouponInterface
/** @var string Coupon description */ /** @var string Coupon description */
protected $description = null; protected $description = null;
/** @var bool if Coupon is enabled */ /** @var bool if Coupon is enabled */
protected $isEnabled = false; protected $isEnabled = false;
@@ -86,9 +96,6 @@ abstract class CouponAbstract implements CouponInterface
/** @var bool if Coupon is removing postage */ /** @var bool if Coupon is removing postage */
protected $isRemovingPostage = false; protected $isRemovingPostage = false;
/** @var float Amount that will be removed from the Checkout (Coupon Effect) */
protected $amount = 0;
/** @var int Max time a Coupon can be used (-1 = unlimited) */ /** @var int Max time a Coupon can be used (-1 = unlimited) */
protected $maxUsage = -1; protected $maxUsage = -1;
@@ -105,6 +112,7 @@ abstract class CouponAbstract implements CouponInterface
{ {
$this->adapter = $adapter; $this->adapter = $adapter;
$this->translator = $adapter->getTranslator(); $this->translator = $adapter->getTranslator();
$this->constraintValidator = $adapter->getConstraintValidator();
} }
/** /**
@@ -220,17 +228,6 @@ abstract class CouponAbstract implements CouponInterface
return $this; return $this;
} }
/**
* Check if the current Coupon is matching its conditions (Rules)
* Thelia variables are given by the CouponAdapterInterface
*
* @return bool
*/
public function isMatching()
{
return $this->constraintValidator->test($this->rules);
}
/** /**
* Return Coupon expiration date * Return Coupon expiration date
* *
@@ -302,4 +299,16 @@ abstract class CouponAbstract implements CouponInterface
} }
/**
* Check if the current Coupon is matching its conditions (Rules)
* Thelia variables are given by the CouponAdapterInterface
*
* @return bool
*/
public function isMatching()
{
return $this->constraintValidator->isMatching($this->rules);
}
} }

View File

@@ -39,6 +39,27 @@ use Thelia\Coupon\CouponRuleCollection;
*/ */
interface CouponInterface interface CouponInterface
{ {
/**
* Get I18n name
*
* @return string
*/
public function getName();
/**
* Get I18n tooltip
*
* @return string
*/
public function getToolTip();
/**
* Get Coupon Manager service Id
*
* @return string
*/
public function getServiceId();
/** /**
* Set Coupon * Set Coupon
* *
@@ -114,18 +135,7 @@ interface CouponInterface
*/ */
public function isRemovingPostage(); public function isRemovingPostage();
/**
* Return effects generated by the coupon
* A positive value
*
* Effects could also affect something else than the final Checkout price
* CouponAdapter $adapter could be use to directly pass a Session value
* some would wish to modify
* Hence affecting a wide variety of Thelia elements
*
* @return float Amount removed from the Total Checkout
*/
public function getDiscount();
/** /**
* Return condition to validate the Coupon or not * Return condition to validate the Coupon or not
@@ -134,14 +144,6 @@ interface CouponInterface
*/ */
public function getRules(); public function getRules();
/**
* Check if the current Coupon is matching its conditions (Rules)
* Thelia variables are given by the CouponAdapterInterface
*
* @return bool
*/
public function isMatching();
/** /**
* Replace the existing Rules by those given in parameter * Replace the existing Rules by those given in parameter
* If one Rule is badly implemented, no Rule will be added * If one Rule is badly implemented, no Rule will be added
@@ -191,25 +193,26 @@ interface CouponInterface
*/ */
public function isExpired(); public function isExpired();
/**
* Get I18n name
*
* @return string
*/
public function getName();
/** /**
* Get I18n tooltip * Return effects generated by the coupon
* A positive value
* *
* @return string * Effects could also affect something else than the final Checkout price
* CouponAdapter $adapter could be use to directly pass a Session value
* some would wish to modify
* Hence affecting a wide variety of Thelia elements
*
* @return float Amount removed from the Total Checkout
*/ */
public function getToolTip(); public function getDiscount();
/** /**
* Get Coupon Manager service Id * Check if the current Coupon is matching its conditions (Rules)
* Thelia variables are given by the CouponAdapterInterface
* *
* @return string * @return bool
*/ */
public function getServiceId(); public function isMatching();
} }

View File

@@ -79,7 +79,7 @@ class ConstraintValidatorTest extends \PHPUnit_Framework_TestCase
$rules = new CouponRuleCollection(); $rules = new CouponRuleCollection();
$rules->add($rule1); $rules->add($rule1);
$isValid = $ConstraintValidator->test($rules); $isValid = $ConstraintValidator->isMatching($rules);
$expected = true; $expected = true;
$actual =$isValid; $actual =$isValid;
@@ -113,7 +113,7 @@ class ConstraintValidatorTest extends \PHPUnit_Framework_TestCase
$rules = new CouponRuleCollection(); $rules = new CouponRuleCollection();
$rules->add($rule1); $rules->add($rule1);
$isValid = $ConstraintValidator->test($rules); $isValid = $ConstraintValidator->isMatching($rules);
$expected = false; $expected = false;
$actual =$isValid; $actual =$isValid;
@@ -160,7 +160,7 @@ class ConstraintValidatorTest extends \PHPUnit_Framework_TestCase
$rules->add($rule1); $rules->add($rule1);
$rules->add($rule2); $rules->add($rule2);
$isValid = $ConstraintValidator->test($rules); $isValid = $ConstraintValidator->isMatching($rules);
$expected = true; $expected = true;
$actual =$isValid; $actual =$isValid;
@@ -207,7 +207,7 @@ class ConstraintValidatorTest extends \PHPUnit_Framework_TestCase
$rules->add($rule1); $rules->add($rule1);
$rules->add($rule2); $rules->add($rule2);
$isValid = $ConstraintValidator->test($rules); $isValid = $ConstraintValidator->isMatching($rules);
$expected = false; $expected = false;
$actual =$isValid; $actual =$isValid;