. */ /* */ /**********************************************************************************/ namespace Thelia\Coupon; use Symfony\Component\DependencyInjection\ContainerInterface; use Thelia\Condition\ConditionManagerInterface; use Thelia\Coupon\Type\CouponInterface; /** * Created by JetBrains PhpStorm. * Date: 8/19/13 * Time: 3:24 PM * * Manage how Coupons could interact with a Checkout * * @package Coupon * @author Guillaume MOREL * */ class CouponManager { /** @var AdapterInterface Provides necessary value from Thelia */ protected $adapter = null; /** @var ContainerInterface Service Container */ protected $container = null; /** @var array CouponInterface to process*/ protected $coupons = array(); /** @var array Available Coupons (Services) */ protected $availableCoupons = array(); /** @var array Available Conditions (Services) */ protected $availableConditions = array(); /** * Constructor * * @param ContainerInterface $container Service container */ public function __construct(ContainerInterface $container) { $this->container = $container; $this->adapter = $container->get('thelia.adapter'); $this->coupons = $this->adapter->getCurrentCoupons(); } /** * Get Discount for the given Coupons * * @api * @return float checkout discount */ public function getDiscount() { $discount = 0.00; if (count($this->coupons) > 0) { $couponsKept = $this->sortCoupons($this->coupons); $isRemovingPostage = $this->isCouponRemovingPostage($couponsKept); $discount = $this->getEffect($couponsKept); if ($isRemovingPostage) { $postage = $this->adapter->getCheckoutPostagePrice(); $discount += $postage; } // Just In Case test $checkoutTotalPrice = $this->adapter->getCartTotalPrice(); if ($discount >= $checkoutTotalPrice) { $discount = $checkoutTotalPrice; } } return $discount; } /** * Check if there is a Coupon removing Postage * * @param array $couponsKept Array of CouponInterface sorted * * @return bool */ protected function isCouponRemovingPostage(array $couponsKept) { $isRemovingPostage = false; /** @var CouponInterface $coupon */ foreach ($couponsKept as $coupon) { if ($coupon->isRemovingPostage()) { $isRemovingPostage = true; } } return $isRemovingPostage; } /** * Sort Coupon to keep * Coupon not cumulative cancels previous * * @param array $coupons CouponInterface to process * * @return array Array of CouponInterface sorted */ protected function sortCoupons(array $coupons) { $couponsKept = array(); /** @var CouponInterface $coupon */ foreach ($coupons as $coupon) { if (!$coupon->isExpired()) { if ($coupon->isCumulative()) { if (isset($couponsKept[0])) { /** @var CouponInterface $previousCoupon */ $previousCoupon = $couponsKept[0]; if ($previousCoupon->isCumulative()) { // Add Coupon $couponsKept[] = $coupon; } else { // Reset Coupons, add last $couponsKept = array($coupon); } } else { // Reset Coupons, add last $couponsKept = array($coupon); } } else { // Reset Coupons, add last $couponsKept = array($coupon); } } } $coupons = $couponsKept; $couponsKept = array(); /** @var CouponInterface $coupon */ foreach ($coupons as $coupon) { if ($coupon->isMatching($this->adapter)) { $couponsKept[] = $coupon; } } return $couponsKept; } /** * Process given Coupon in order to get their cumulative effects * * @param array $coupons CouponInterface to process * * @return float discount */ protected function getEffect(array $coupons) { $discount = 0.00; /** @var CouponInterface $coupon */ foreach ($coupons as $coupon) { // @todo modify Cart with discount for each cart item $discount += $coupon->getDiscount($this->adapter); } return $discount; } /** * Build a ConditionManagerInterface from data coming from a form * * @param string $conditionServiceId Condition service id you want to instantiate * @param array $operators Condition Operator set by the Admin * @param array $values Condition Values set by the Admin * * @return ConditionManagerInterface */ public function buildRuleFromForm($conditionServiceId, array $operators, array $values) { $condition = false; try { if ($this->container->has($conditionServiceId)) { /** @var ConditionManagerInterface $condition */ $condition = $this->container->get($conditionServiceId); $condition->populateFromForm($operators, $values); } } catch (\InvalidArgumentException $e) { } return $condition; } /** * Add an available CouponManager (Services) * * @param CouponInterface $coupon CouponManager */ public function addAvailableCoupon(CouponInterface $coupon) { $this->availableCoupons[] = $coupon; } /** * Get all available CouponManagers (Services) * * @return array */ public function getAvailableCoupons() { return $this->availableCoupons; } /** * Add an available ConstraintManager (Services) * * @param ConditionManagerInterface $condition ConditionManagerInterface */ public function addAvailableRule(ConditionManagerInterface $condition) { $this->availableConditions[] = $condition; } /** * Get all available ConstraintManagers (Services) * * @return array */ public function getAvailableConditions() { return $this->availableConditions; } }