diff --git a/core/lib/Thelia/Core/HttpFoundation/Session/Session.php b/core/lib/Thelia/Core/HttpFoundation/Session/Session.php index 008f0fbfb..dbfe0d204 100644 --- a/core/lib/Thelia/Core/HttpFoundation/Session/Session.php +++ b/core/lib/Thelia/Core/HttpFoundation/Session/Session.php @@ -270,6 +270,6 @@ class Session extends BaseSession */ public function getConsumedCoupons() { - return $this->get('thelia.consumed_coupons'); + return $this->get('thelia.consumed_coupons', array()); } } diff --git a/core/lib/Thelia/Core/Template/Element/BaseLoop.php b/core/lib/Thelia/Core/Template/Element/BaseLoop.php index 1038541de..bb88f5468 100644 --- a/core/lib/Thelia/Core/Template/Element/BaseLoop.php +++ b/core/lib/Thelia/Core/Template/Element/BaseLoop.php @@ -33,7 +33,7 @@ use Thelia\Type\TypeCollection; abstract class BaseLoop { /** - * @var \Symfony\Component\HttpFoundation\Request + * @var \Thelia\Core\HttpFoundation\Request */ protected $request; diff --git a/core/lib/Thelia/Core/Template/Loop/Coupon.php b/core/lib/Thelia/Core/Template/Loop/Coupon.php index d1d26c905..145202120 100644 --- a/core/lib/Thelia/Core/Template/Loop/Coupon.php +++ b/core/lib/Thelia/Core/Template/Loop/Coupon.php @@ -49,6 +49,7 @@ class Coupon extends BaseI18nLoop implements PropelSearchLoopInterface return new ArgumentCollection( Argument::createIntListTypeArgument('id'), Argument::createBooleanOrBothTypeArgument('is_enabled'), + Argument::createBooleanTypeArgument('in_use'), new Argument( 'order', new TypeCollection( @@ -86,6 +87,18 @@ class Coupon extends BaseI18nLoop implements PropelSearchLoopInterface $search->filterByIsEnabled($isEnabled ? true : false); } + $inUse = $this->getInUse(); + + if ($inUse !== null) { + // Get the code of coupons currently in use + $consumedCoupons = $this->request->getSession()->getConsumedCoupons(); + + // Get only matching coupons. + $criteria = $inUse ? Criteria::IN : Criteria::NOT_IN; + + $search->filterByCode($consumedCoupons, $criteria); + } + $search->addAsColumn('days_left', 'DATEDIFF('.CouponTableMap::EXPIRATION_DATE.', CURDATE()) - 1'); $orders = $this->getOrder(); @@ -202,6 +215,12 @@ class Coupon extends BaseI18nLoop implements PropelSearchLoopInterface $freeShippingForModulesIds[] = $couponModule->getModuleId(); } + // If and only if the coupon is currently in use, get the coupon discount. Calling exec() on a coupon + // which is not currently in use may apply coupon on the cart. This is true for coupons such as FreeProduct, + // which adds a product to the cart. + $discount = $couponManager->isInUse() ? $couponManager->exec() : 0; + + $loopResultRow ->set("ID", $coupon->getId()) ->set("IS_TRANSLATED", $coupon->getVirtualColumn('IS_TRANSLATED')) @@ -224,6 +243,7 @@ class Coupon extends BaseI18nLoop implements PropelSearchLoopInterface ->set("SERVICE_ID", $couponManager->getServiceId()) ->set("FREE_SHIPPING_FOR_COUNTRIES_LIST", implode(',', $freeShippingForCountriesIds)) ->set("FREE_SHIPPING_FOR_MODULES_LIST", implode(',', $freeShippingForModulesIds)) + ->set("DISCOUNT_AMOUNT", $discount) ; $loopResult->addRow($loopResultRow); diff --git a/core/lib/Thelia/Coupon/Type/CouponAbstract.php b/core/lib/Thelia/Coupon/Type/CouponAbstract.php index 9766b7fbe..a0bdf2db1 100644 --- a/core/lib/Thelia/Coupon/Type/CouponAbstract.php +++ b/core/lib/Thelia/Coupon/Type/CouponAbstract.php @@ -183,6 +183,7 @@ abstract class CouponAbstract implements CouponInterface /** * @param true $perCustomerUsageCount + * @return $this */ public function setPerCustomerUsageCount($perCustomerUsageCount) { @@ -425,14 +426,14 @@ abstract class CouponAbstract implements CouponInterface * This methods checks a field value. If the field has a correct value, this value is returned * Otherwise, an InvalidArgumentException describing the problem should be thrown. * - * This method should be ovveriden to be useful. + * This method should be overriden to be useful. * - * @param $fieldName - * @param $fieldValue + * @param string $fieldName + * @param string $fieldValue * @return mixed - * @throws \InvalidArgumentException if the field valiue is not valid. + * @throws \InvalidArgumentException if the field value is not valid. */ - protected function checkCouponFieldValue($fieldName, $fieldValue) + protected function checkCouponFieldValue(/** @noinspection PhpUnusedParameterInspection */ $fieldName, $fieldValue) { return $fieldValue; } @@ -507,4 +508,11 @@ abstract class CouponAbstract implements CouponInterface { // Does nothing. Override this function as needed. } + + public function isInUse() { + return in_array( + $this->code, + $this->facade->getRequest()->getSession()->getConsumedCoupons() + ); + } } diff --git a/core/lib/Thelia/Coupon/Type/CouponInterface.php b/core/lib/Thelia/Coupon/Type/CouponInterface.php index d8190f3d7..cfd645d28 100644 --- a/core/lib/Thelia/Coupon/Type/CouponInterface.php +++ b/core/lib/Thelia/Coupon/Type/CouponInterface.php @@ -192,15 +192,15 @@ interface CouponInterface public function isExpired(); /** - * Return effects generated by the coupon - * A positive value + * Return an amount thant will be subtracted to the cart total, or zero. * - * Effects could also affect something else than the final Checkout price - * FacadeInterface $facade could be used to directly pass a Session value - * some would wish to modify - * Hence affecting a wide variety of Thelia elements + * This method could also perform something else than the calculating an amount to subtract from the cart. It may + * add a product to the cart, for example. In this case, an amount of 0 will be returned. * - * @return float Amount removed from the Total Checkout + * WARNING: this method could be called several times, so perform suitable checks before performing cart + * manipulations, so that the coupon effect will not be applied several times. + * + * @return float Amount removed from the cart total */ public function exec(); @@ -244,4 +244,8 @@ interface CouponInterface */ public function clear(); + /** + * @return bool true if the coupon is currently in use in the current order process, false otherwise + */ + public function isInUse(); } diff --git a/templates/backOffice/default/languages.html b/templates/backOffice/default/languages.html index 9678fbfe4..d5a3ec367 100644 --- a/templates/backOffice/default/languages.html +++ b/templates/backOffice/default/languages.html @@ -48,6 +48,7 @@ + {intl l="ID"} {intl l="Language name"} {intl l="ISO 639 Code"} {intl l="Locale"} @@ -58,6 +59,7 @@ {loop type="lang" name="lang.list" backend_context="1"} + {$ID} {$CODE} {$TITLE} {$CODE}