diff --git a/core/lib/Thelia/Action/Coupon.php b/core/lib/Thelia/Action/Coupon.php
index aaa827a9d..8fbb4d378 100644
--- a/core/lib/Thelia/Action/Coupon.php
+++ b/core/lib/Thelia/Action/Coupon.php
@@ -202,7 +202,9 @@ class Coupon extends BaseAction implements EventSubscriberInterface
$event->isCumulative(),
$event->getMaxUsage(),
$defaultSerializedRule,
- $event->getLocale()
+ $event->getLocale(),
+ $event->getFreeShippingForCountries(),
+ $event->getFreeShippingForMethods()
);
$event->setCouponModel($coupon);
@@ -235,8 +237,9 @@ class Coupon extends BaseAction implements EventSubscriberInterface
*/
public function testFreePostage(OrderEvent $event)
{
- if ($this->couponManager->isCouponRemovingPostage()) {
- $order = $event->getOrder();
+ $order = $event->getOrder();
+
+ if ($this->couponManager->isCouponRemovingPostage($order)) {
$order->setPostage(0);
diff --git a/core/lib/Thelia/Action/Order.php b/core/lib/Thelia/Action/Order.php
index bd8534219..9b710a858 100644
--- a/core/lib/Thelia/Action/Order.php
+++ b/core/lib/Thelia/Action/Order.php
@@ -82,7 +82,7 @@ class Order extends BaseAction implements EventSubscriberInterface
{
$order = $event->getOrder();
- $order->chosenDeliveryAddress = $event->getDeliveryAddress();
+ $order->setChoosenDeliveryAddress($event->getDeliveryAddress());
$event->setOrder($order);
}
@@ -125,7 +125,7 @@ class Order extends BaseAction implements EventSubscriberInterface
{
$order = $event->getOrder();
- $order->chosenInvoiceAddress = $event->getInvoiceAddress();
+ $order->setChoosenInvoiceAddress($event->getInvoiceAddress());
$event->setOrder($order);
}
@@ -153,9 +153,9 @@ class Order extends BaseAction implements EventSubscriberInterface
$placedOrder = $sessionOrder->copy();
$placedOrder->setDispatcher($dispatcher);
- $deliveryAddress = AddressQuery::create()->findPk($sessionOrder->chosenDeliveryAddress);
+ $deliveryAddress = AddressQuery::create()->findPk($sessionOrder->getChoosenDeliveryAddress());
$taxCountry = $deliveryAddress->getCountry();
- $invoiceAddress = AddressQuery::create()->findPk($sessionOrder->chosenInvoiceAddress);
+ $invoiceAddress = AddressQuery::create()->findPk($sessionOrder->getChoosenInvoiceAddress());
$cartItems = $cart->getCartItems();
/* fulfill order */
diff --git a/core/lib/Thelia/Config/Resources/coupon.xml b/core/lib/Thelia/Config/Resources/coupon.xml
index 68de33c37..68486c969 100644
--- a/core/lib/Thelia/Config/Resources/coupon.xml
+++ b/core/lib/Thelia/Config/Resources/coupon.xml
@@ -4,32 +4,40 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://thelia.net/schema/dic/config http://thelia.net/schema/dic/config/thelia-1.0.xsd">
-
-
-
+
+
+
+
+
+
+
+
+
+
+
@@ -83,5 +91,4 @@
-
diff --git a/core/lib/Thelia/Controller/Admin/CouponController.php b/core/lib/Thelia/Controller/Admin/CouponController.php
index 2cade8a78..6931d1345 100644
--- a/core/lib/Thelia/Controller/Admin/CouponController.php
+++ b/core/lib/Thelia/Controller/Admin/CouponController.php
@@ -32,6 +32,8 @@ use Thelia\Form\CouponCreationForm;
use Thelia\Form\Exception\FormValidationException;
use Thelia\Log\Tlog;
use Thelia\Model\Coupon;
+use Thelia\Model\CouponCountry;
+use Thelia\Model\CouponModule;
use Thelia\Model\CouponQuery;
use Thelia\Model\LangQuery;
use Thelia\Tools\Rest\ResponseRest;
@@ -152,6 +154,21 @@ class CouponController extends BaseAdminController
$coupon->getSerializedConditions()
);
+ $freeShippingForCountries = $freeShippingForModules = [];
+
+ /** @var CouponCountry $item */
+ foreach($coupon->getFreeShippingForCountries() as $item) {
+ $freeShippingForCountries[] = $item->getCountryId();
+ }
+
+ /** @var CouponModule $item */
+ foreach($coupon->getFreeShippingForModules() as $item) {
+ $freeShippingForModules[] = $item->getModuleId();
+ }
+
+ if (empty($freeShippingForCountries)) $freeShippingForCountries[] = 0;
+ if (empty($freeShippingForModules)) $freeShippingForModules[] = 0;
+
$data = [
'code' => $coupon->getCode(),
'title' => $coupon->getTitle(),
@@ -167,6 +184,8 @@ class CouponController extends BaseAdminController
'maxUsage' => $coupon->getMaxUsage(),
'conditions' => $conditions,
'locale' => $this->getCurrentEditionLocale(),
+ 'freeShippingForCountries' => $freeShippingForCountries,
+ 'freeShippingForModules' => $freeShippingForModules
];
$args['conditions'] = $this->cleanConditionForTemplate($conditions);
@@ -557,7 +576,7 @@ class CouponController extends BaseAdminController
$condition['serviceId'] = $availableCoupon->getServiceId();
$condition['name'] = $availableCoupon->getName();
$condition['toolTip'] = $availableCoupon->getToolTip();
- $condition['inputName'] = $availableCoupon->getInputName();
+ // $condition['inputName'] = $availableCoupon->getInputName();
$cleanedCoupons[] = $condition;
}
@@ -702,7 +721,7 @@ class CouponController extends BaseAdminController
$couponManager = $this->container->get($serviceId);
$effects = [CouponAbstract::INPUT_AMOUNT_NAME => $data[CouponAbstract::INPUT_AMOUNT_NAME]];
$effects = $this->addExtendedLogic($effects, $couponManager->getExtendedInputs());
-
+var_dump($data);
$couponEvent = new CouponCreateOrUpdateEvent(
$data['code'],
$serviceId,
@@ -716,7 +735,9 @@ class CouponController extends BaseAdminController
$data['isCumulative'],
$data['isRemovingPostage'],
$data['maxUsage'],
- $data['locale']
+ $data['locale'],
+ $data['freeShippingForCountries'],
+ $data['freeShippingForModules']
);
// If Update mode
@@ -774,7 +795,9 @@ class CouponController extends BaseAdminController
$coupon->getIsCumulative(),
$coupon->getIsRemovingPostage(),
$coupon->getMaxUsage(),
- $coupon->getLocale()
+ $coupon->getLocale(),
+ $coupon->getFreeShippingForCountries(),
+ $coupon->getFreeShippingForModules()
);
$couponEvent->setCouponModel($coupon);
$couponEvent->setConditions($conditions);
diff --git a/core/lib/Thelia/Controller/Front/BaseFrontController.php b/core/lib/Thelia/Controller/Front/BaseFrontController.php
index e9bc4754b..665b63400 100644
--- a/core/lib/Thelia/Controller/Front/BaseFrontController.php
+++ b/core/lib/Thelia/Controller/Front/BaseFrontController.php
@@ -15,10 +15,10 @@ namespace Thelia\Controller\Front;
use Symfony\Component\Routing\Router;
use Thelia\Controller\BaseController;
use Thelia\Core\HttpFoundation\Response;
+use Thelia\Core\Template\TemplateDefinition;
use Thelia\Core\Template\TemplateHelper;
use Thelia\Model\AddressQuery;
use Thelia\Model\ModuleQuery;
-
use Thelia\Tools\URL;
class BaseFrontController extends BaseController
@@ -65,7 +65,15 @@ class BaseFrontController extends BaseController
protected function checkValidDelivery()
{
$order = $this->getSession()->getOrder();
- if (null === $order || null === $order->chosenDeliveryAddress || null === $order->getDeliveryModuleId() || null === AddressQuery::create()->findPk($order->chosenDeliveryAddress) || null === ModuleQuery::create()->findPk($order->getDeliveryModuleId())) {
+ if (null === $order
+ ||
+ null === $order->getChoosenDeliveryAddress()
+ ||
+ null === $order->getDeliveryModuleId()
+ ||
+ null === AddressQuery::create()->findPk($order->getChoosenDeliveryAddress())
+ ||
+ null === ModuleQuery::create()->findPk($order->getDeliveryModuleId())) {
$this->redirectToRoute("order.delivery");
}
}
@@ -73,13 +81,21 @@ class BaseFrontController extends BaseController
protected function checkValidInvoice()
{
$order = $this->getSession()->getOrder();
- if (null === $order || null === $order->chosenInvoiceAddress || null === $order->getPaymentModuleId() || null === AddressQuery::create()->findPk($order->chosenInvoiceAddress) || null === ModuleQuery::create()->findPk($order->getPaymentModuleId())) {
+ if (null === $order
+ ||
+ null === $order->getChoosenInvoiceAddress()
+ ||
+ null === $order->getPaymentModuleId()
+ ||
+ null === AddressQuery::create()->findPk($order->getChoosenInvoiceAddress())
+ ||
+ null === ModuleQuery::create()->findPk($order->getPaymentModuleId())) {
$this->redirectToRoute("order.invoice");
}
}
/**
- * @return ParserInterface instance parser
+ * @return TemplateDefinition the template
*/
protected function getParser($template = null)
{
diff --git a/core/lib/Thelia/Core/Event/Coupon/CouponConsumeEvent.php b/core/lib/Thelia/Core/Event/Coupon/CouponConsumeEvent.php
index a6875105a..096efc4e9 100644
--- a/core/lib/Thelia/Core/Event/Coupon/CouponConsumeEvent.php
+++ b/core/lib/Thelia/Core/Event/Coupon/CouponConsumeEvent.php
@@ -31,19 +31,41 @@ class CouponConsumeEvent extends ActionEvent
/** @var bool If Coupon is valid or if Customer meets coupon conditions */
protected $isValid = null;
+ /** @var bool true if coupon offers free shipping */
+ protected $freeShipping = false;
+
/**
* Constructor
*
* @param string $code Coupon code
* @param float $discount Total discount given by this coupon
- * @param bool $isValid If Coupon is valid or
- * if Customer meets coupon conditions
+ * @param bool $isValid If Coupon is valid or f Customer meets coupon conditions
+ * @param bool $freeShipping true if coupon offers free shipping
*/
- public function __construct($code, $discount = null, $isValid = null)
+ public function __construct($code, $discount = null, $isValid = null, $freeShipping = false)
{
$this->code = $code;
$this->discount = $discount;
- $this->isValid = $isValid;
+ $this->discount = $discount;
+
+ $this->freeShipping = $freeShipping;
+ }
+
+ /**
+ * @param boolean $freeShipping
+ */
+ public function setFreeShipping($freeShipping)
+ {
+ $this->freeShipping = $freeShipping;
+ return $this;
+ }
+
+ /**
+ * @return boolean
+ */
+ public function getFreeShipping()
+ {
+ return $this->freeShipping;
}
/**
diff --git a/core/lib/Thelia/Core/Event/Coupon/CouponCreateOrUpdateEvent.php b/core/lib/Thelia/Core/Event/Coupon/CouponCreateOrUpdateEvent.php
index b5a79ba36..041ea9fc3 100644
--- a/core/lib/Thelia/Core/Event/Coupon/CouponCreateOrUpdateEvent.php
+++ b/core/lib/Thelia/Core/Event/Coupon/CouponCreateOrUpdateEvent.php
@@ -73,6 +73,12 @@ class CouponCreateOrUpdateEvent extends ActionEvent
/** @var string Language code ISO (ex: fr_FR) */
protected $locale = null;
+ /** @var array ID of Countries to which shipping is free */
+ protected $freeShippingForCountries;
+
+ /** @var array ID of Shipping modules for which shipping is free */
+ protected $freeShippingForMethods;
+
/**
* Constructor
*
@@ -91,8 +97,13 @@ class CouponCreateOrUpdateEvent extends ActionEvent
* @param boolean $isRemovingPostage Is removing Postage
* @param int $maxUsage Coupon quantity
* @param string $locale Coupon Language code ISO (ex: fr_FR)
+ * @param array $freeShippingForCountries ID of Countries to which shipping is free
+ * @param array $freeShippingForMethods ID of Shipping modules for which shipping is free
*/
- public function __construct($code, $serviceId, $title, array $effects, $shortDescription, $description, $isEnabled, \DateTime $expirationDate, $isAvailableOnSpecialOffers, $isCumulative, $isRemovingPostage, $maxUsage, $locale)
+ public function __construct(
+ $code, $serviceId, $title, array $effects, $shortDescription, $description,
+ $isEnabled, \DateTime $expirationDate, $isAvailableOnSpecialOffers, $isCumulative,
+ $isRemovingPostage, $maxUsage, $locale, $freeShippingForCountries, $freeShippingForMethods)
{
$this->code = $code;
$this->description = $description;
@@ -107,6 +118,44 @@ class CouponCreateOrUpdateEvent extends ActionEvent
$this->serviceId = $serviceId;
$this->locale = $locale;
$this->setEffects($effects);
+ $this->freeShippingForCountries = $freeShippingForCountries;
+ $this->freeShippingForMethods = $freeShippingForMethods;
+ }
+
+ /**
+ * @param array $freeShippingForCountries
+ * @return $this
+ */
+ public function setFreeShippingForCountries($freeShippingForCountries)
+ {
+ $this->freeShippingForCountries = $freeShippingForCountries;
+ return $this;
+ }
+
+ /**
+ * @return array
+ */
+ public function getFreeShippingForCountries()
+ {
+ return $this->freeShippingForCountries;
+ }
+
+ /**
+ * @param array $freeShippingForMethods
+ * @return $this
+ */
+ public function setFreeShippingForMethods($freeShippingForMethods)
+ {
+ $this->freeShippingForMethods = $freeShippingForMethods;
+ return $this;
+ }
+
+ /**
+ * @return array
+ */
+ public function getFreeShippingForMethods()
+ {
+ return $this->freeShippingForMethods;
}
/**
diff --git a/core/lib/Thelia/Core/Template/Loop/Coupon.php b/core/lib/Thelia/Core/Template/Loop/Coupon.php
index 7d0a3899d..1aca06a12 100644
--- a/core/lib/Thelia/Core/Template/Loop/Coupon.php
+++ b/core/lib/Thelia/Core/Template/Loop/Coupon.php
@@ -178,7 +178,9 @@ class Coupon extends BaseI18nLoop implements PropelSearchLoopInterface
$coupon->getIsAvailableOnSpecialOffers(),
$coupon->getIsEnabled(),
$coupon->getMaxUsage(),
- $coupon->getExpirationDate()
+ $coupon->getExpirationDate(),
+ $coupon->getFreeShippingForCountries(),
+ $coupon->getFreeShippingForModules()
);
$cleanedConditions = array();
diff --git a/core/lib/Thelia/Core/Template/Smarty/Plugins/DataAccessFunctions.php b/core/lib/Thelia/Core/Template/Smarty/Plugins/DataAccessFunctions.php
index d439e7d63..588cbe76d 100644
--- a/core/lib/Thelia/Core/Template/Smarty/Plugins/DataAccessFunctions.php
+++ b/core/lib/Thelia/Core/Template/Smarty/Plugins/DataAccessFunctions.php
@@ -204,9 +204,9 @@ class DataAccessFunctions extends AbstractSmartyPlugin
case 'discount':
return $order->getDiscount();
case 'delivery_address':
- return $order->chosenDeliveryAddress;
+ return $order->getChoosenDeliveryAddress();
case 'invoice_address':
- return $order->chosenInvoiceAddress;
+ return $order->getChoosenInvoiceAddress();
case 'delivery_module':
return $order->getDeliveryModuleId();
case 'payment_module':
diff --git a/core/lib/Thelia/Core/Template/Smarty/Plugins/Security.php b/core/lib/Thelia/Core/Template/Smarty/Plugins/Security.php
index 85ebb4257..83f697025 100644
--- a/core/lib/Thelia/Core/Template/Smarty/Plugins/Security.php
+++ b/core/lib/Thelia/Core/Template/Smarty/Plugins/Security.php
@@ -82,7 +82,7 @@ class Security extends AbstractSmartyPlugin
$order = $this->request->getSession()->getOrder();
/* Does address and module still exists ? We assume address owner can't change neither module type */
if ($order !== null) {
- $checkAddress = AddressQuery::create()->findPk($order->chosenDeliveryAddress);
+ $checkAddress = AddressQuery::create()->findPk($order->getChoosenDeliveryAddress());
$checkModule = ModuleQuery::create()->findPk($order->getDeliveryModuleId());
}
if (null === $order || null == $checkAddress || null === $checkModule) {
diff --git a/core/lib/Thelia/Coupon/BaseFacade.php b/core/lib/Thelia/Coupon/BaseFacade.php
index eac753376..3a4a74b33 100644
--- a/core/lib/Thelia/Coupon/BaseFacade.php
+++ b/core/lib/Thelia/Coupon/BaseFacade.php
@@ -77,7 +77,7 @@ class BaseFacade implements FacadeInterface
public function getDeliveryAddress()
{
try {
- return AddressQuery::create()->findPk($this->getRequest()->getSession()->getOrder()->chosenDeliveryAddress);
+ return AddressQuery::create()->findPk($this->getRequest()->getSession()->getOrder()->getChoosenDeliveryAddress());
}
catch(\Exception $ex) {
throw new \LogicException("Failed to get delivery address (" . $ex->getMessage() . ")");
diff --git a/core/lib/Thelia/Coupon/CouponFactory.php b/core/lib/Thelia/Coupon/CouponFactory.php
index e577061b7..271e74847 100644
--- a/core/lib/Thelia/Coupon/CouponFactory.php
+++ b/core/lib/Thelia/Coupon/CouponFactory.php
@@ -107,7 +107,9 @@ class CouponFactory
$model->getIsAvailableOnSpecialOffers(),
$model->getIsEnabled(),
$model->getMaxUsage(),
- $model->getExpirationDate()
+ $model->getExpirationDate(),
+ $model->getFreeShippingForCountries(),
+ $model->getFreeShippingForModules()
);
/** @var ConditionFactory $conditionFactory */
diff --git a/core/lib/Thelia/Coupon/CouponManager.php b/core/lib/Thelia/Coupon/CouponManager.php
index 779b28c11..6d7b5f433 100644
--- a/core/lib/Thelia/Coupon/CouponManager.php
+++ b/core/lib/Thelia/Coupon/CouponManager.php
@@ -15,7 +15,14 @@ namespace Thelia\Coupon;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Thelia\Condition\Implementation\ConditionInterface;
use Thelia\Coupon\Type\CouponInterface;
+use Thelia\Log\Tlog;
+use Thelia\Model\AddressQuery;
+use Thelia\Model\Base\CouponModule;
use Thelia\Model\Coupon;
+use Thelia\Model\CouponCountry;
+use Thelia\Model\Order;
+use Thelia\Model\OrderAddress;
+use Thelia\Model\OrderAddressQuery;
/**
* Manage how Coupons could interact with a Checkout
@@ -78,9 +85,10 @@ class CouponManager
* Check if there is a Coupon removing Postage
* @return bool
*/
- public function isCouponRemovingPostage()
+ public function isCouponRemovingPostage(Order $order)
{
$coupons = $this->facade->getCurrentCoupons();
+
if (count($coupons) == 0) {
return false;
}
@@ -89,7 +97,60 @@ class CouponManager
/** @var CouponInterface $coupon */
foreach ($couponsKept as $coupon) {
+
if ($coupon->isRemovingPostage()) {
+
+ // Check if delivery country is on the list of countries for which delivery is free
+ // If the list is empty, the shipping is free for all countries.
+ $couponCountries = $coupon->getFreeShippingForCountries();
+
+ if (! $couponCountries->isEmpty()) {
+
+ if (null === $deliveryAddress = AddressQuery::create()->findPk($order->getChoosenDeliveryAddress())) {
+ continue;
+ }
+
+ $countryValid = false;
+
+ $deliveryCountryId = $deliveryAddress->getCountryId();
+
+ /** @var CouponCountry $couponCountry */
+ foreach($couponCountries as $couponCountry) {
+ if ($deliveryCountryId == $couponCountry->getCountryId()) {
+ $countryValid = true;
+ break;
+ }
+ }
+
+ if (! $countryValid) {
+ continue;
+ }
+ }
+
+ // Check if shipping method is on the list of methods for which delivery is free
+ // If the list is empty, the shipping is free for all methods.
+ $couponModules = $coupon->getFreeShippingForModules();
+
+ if (! $couponModules->isEmpty()) {
+
+ $moduleValid = false;
+
+ $shippingModuleId = $order->getDeliveryModuleId();
+
+ /** @var CouponModule $couponModule */
+ foreach($couponModules as $couponModule) {
+ if ($shippingModuleId == $couponModule->getModuleId()) {
+ $moduleValid = true;
+ break;
+ }
+ }
+
+ if (! $moduleValid) {
+ continue;
+ }
+ }
+
+ // All conditions are met, the shipping is free !
return true;
}
}
diff --git a/core/lib/Thelia/Coupon/Type/CouponAbstract.php b/core/lib/Thelia/Coupon/Type/CouponAbstract.php
index dee230edc..8ba08fc35 100644
--- a/core/lib/Thelia/Coupon/Type/CouponAbstract.php
+++ b/core/lib/Thelia/Coupon/Type/CouponAbstract.php
@@ -12,11 +12,13 @@
namespace Thelia\Coupon\Type;
+use Thelia\Condition\ConditionCollection;
use Thelia\Condition\ConditionEvaluator;
+use Thelia\Condition\ConditionOrganizerInterface;
use Thelia\Core\Translation\Translator;
use Thelia\Coupon\FacadeInterface;
-use Thelia\Condition\ConditionCollection;
-use Thelia\Condition\ConditionOrganizerInterface;
+use Thelia\Model\CouponCountry;
+use Thelia\Model\CouponModule;
/**
* Assist in writing a CouponInterface
@@ -88,6 +90,12 @@ abstract class CouponAbstract implements CouponInterface
/** @var bool if Coupon is available for Products already on special offers */
protected $isAvailableOnSpecialOffers = false;
+ /** @var CouponCountry[] list of country IDs for which shipping is free. All if empty*/
+ protected $freeShippingForCountries = [];
+
+ /** @var CouponModule[] list of shipping module IDs for which shippiog is free. All if empty*/
+ protected $freeShippingForModules = [];
+
/**
* Constructor
*
@@ -115,23 +123,7 @@ abstract class CouponAbstract implements CouponInterface
}
/**
- * Set Coupon
- *
- * @param FacadeInterface $facade Provides necessary value from Thelia
- * @param string $code Coupon code (ex: XMAS)
- * @param string $title Coupon title (ex: Coupon for XMAS)
- * @param string $shortDescription Coupon short description
- * @param string $description Coupon description
- * @param array $effects Coupon effects params
- * @param bool $isCumulative If Coupon is cumulative
- * @param bool $isRemovingPostage If Coupon is removing postage
- * @param bool $isAvailableOnSpecialOffers If available on Product already
- * on special offer price
- * @param bool $isEnabled False if Coupon is disabled by admin
- * @param int $maxUsage How many usage left
- * @param \Datetime $expirationDate When the Code is expiring
- *
- * @return $this
+ * @inheritdoc
*/
public function set(
FacadeInterface $facade,
@@ -145,7 +137,9 @@ abstract class CouponAbstract implements CouponInterface
$isAvailableOnSpecialOffers,
$isEnabled,
$maxUsage,
- \DateTime $expirationDate
+ \DateTime $expirationDate,
+ $freeShippingForCountries,
+ $freeShippingForModules
)
{
$this->code = $code;
@@ -165,6 +159,9 @@ abstract class CouponAbstract implements CouponInterface
$this->effects = $effects;
$this->amount = $effects[self::INPUT_AMOUNT_NAME];
+ $this->freeShippingForCountries = $freeShippingForCountries;
+ $this->freeShippingForModules = $freeShippingForModules;
+
return $this;
}
@@ -230,6 +227,20 @@ abstract class CouponAbstract implements CouponInterface
return $this->isRemovingPostage;
}
+ /**
+ * @return array list of country IDs for which shipping is free. All if empty
+ */
+ public function getFreeShippingForCountries() {
+ return $this->freeShippingForCountries;
+ }
+
+ /**
+ * @return array list of module IDs for which shipping is free. All if empty
+ */
+ public function getFreeShippingForModules() {
+ return $this->freeShippingForModules;
+ }
+
/**
* Return effects generated by the coupon
* A negative value
diff --git a/core/lib/Thelia/Coupon/Type/CouponInterface.php b/core/lib/Thelia/Coupon/Type/CouponInterface.php
index 12b54db15..d667b4865 100644
--- a/core/lib/Thelia/Coupon/Type/CouponInterface.php
+++ b/core/lib/Thelia/Coupon/Type/CouponInterface.php
@@ -12,8 +12,11 @@
namespace Thelia\Coupon\Type;
+use Propel\Runtime\Collection\ObjectCollection;
use Thelia\Condition\ConditionCollection;
use Thelia\Coupon\FacadeInterface;
+use Thelia\Model\CouponCountry;
+use Thelia\Model\CouponModule;
/**
* Represents a Coupon ready to be processed in a Checkout process
@@ -31,13 +34,6 @@ interface CouponInterface
*/
public function getName();
- /**
- * Get I18n amount input name
- *
- * @return string
- */
- public function getInputName();
-
/**
* Get I18n tooltip
*
@@ -68,6 +64,9 @@ interface CouponInterface
* @param bool $isEnabled False if Coupon is disabled by admin
* @param int $maxUsage How many usage left
* @param \Datetime $expirationDate When the Code is expiring
+ * @param ObjectCollection $freeShippingForCountries list of countries which shipping is free. All if empty
+ * @param ObjectCollection $freeShippingForModules list of modules for which shipping is free. All if empty
+
*/
public function set(
FacadeInterface $facade,
@@ -81,7 +80,10 @@ interface CouponInterface
$isAvailableOnSpecialOffers,
$isEnabled,
$maxUsage,
- \DateTime $expirationDate);
+ \DateTime $expirationDate,
+ $freeShippingForCountries,
+ $freeShippingForModules
+ );
/**
* Return Coupon code (ex: XMAS)
@@ -218,4 +220,13 @@ interface CouponInterface
*/
public function getExtendedInputs();
+ /**
+ * @return ObjectCollection list of country IDs for which shipping is free. All if empty
+ */
+ public function getFreeShippingForCountries();
+
+ /**
+ * @return ObjectCollection list of module IDs for which shipping is free. All if empty
+ */
+ public function getFreeShippingForModules();
}
diff --git a/core/lib/Thelia/Coupon/Type/RemoveXPercent.php b/core/lib/Thelia/Coupon/Type/RemoveXPercent.php
index 83c625d9c..3cc95737c 100644
--- a/core/lib/Thelia/Coupon/Type/RemoveXPercent.php
+++ b/core/lib/Thelia/Coupon/Type/RemoveXPercent.php
@@ -35,23 +35,7 @@ class RemoveXPercent extends CouponAbstract
);
/**
- * Set Coupon
- *
- * @param FacadeInterface $facade Provides necessary value from Thelia
- * @param string $code Coupon code (ex: XMAS)
- * @param string $title Coupon title (ex: Coupon for XMAS)
- * @param string $shortDescription Coupon short description
- * @param string $description Coupon description
- * @param array $effects Coupon effects params
- * @param bool $isCumulative If Coupon is cumulative
- * @param bool $isRemovingPostage If Coupon is removing postage
- * @param bool $isAvailableOnSpecialOffers If available on Product already
- * on special offer price
- * @param bool $isEnabled False if Coupon is disabled by admin
- * @param int $maxUsage How many usage left
- * @param \Datetime $expirationDate When the Code is expiring
- *
- * @return $this
+ * @inheritdoc
*/
public function set(
FacadeInterface $facade,
@@ -65,12 +49,18 @@ class RemoveXPercent extends CouponAbstract
$isAvailableOnSpecialOffers,
$isEnabled,
$maxUsage,
- \DateTime $expirationDate
+ \DateTime $expirationDate,
+ $freeShippingForCountries,
+ $freeShippingForModules
)
{
parent::set(
- $facade, $code, $title, $shortDescription, $description, $effects, $isCumulative, $isRemovingPostage, $isAvailableOnSpecialOffers, $isEnabled, $maxUsage, $expirationDate
+ $facade, $code, $title, $shortDescription, $description, $effects,
+ $isCumulative, $isRemovingPostage, $isAvailableOnSpecialOffers, $isEnabled, $maxUsage, $expirationDate,
+ $freeShippingForCountries,
+ $freeShippingForModules
);
+
$this->percentage = $effects[self::INPUT_PERCENTAGE_NAME];
return $this;
diff --git a/core/lib/Thelia/Form/CouponCreationForm.php b/core/lib/Thelia/Form/CouponCreationForm.php
index dbd271e50..904d8ea7f 100644
--- a/core/lib/Thelia/Form/CouponCreationForm.php
+++ b/core/lib/Thelia/Form/CouponCreationForm.php
@@ -18,7 +18,14 @@ use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\NotEqualTo;
use Symfony\Component\Validator\ExecutionContextInterface;
use Thelia\Core\Translation\Translator;
+use Thelia\Model\Base\CountryI18n;
+use Thelia\Model\Base\CountryQuery;
use Thelia\Model\Base\LangQuery;
+use Thelia\Model\Base\ModuleQuery;
+use Thelia\Model\CountryI18nQuery;
+use Thelia\Model\Module;
+use Thelia\Model\ModuleI18nQuery;
+use Thelia\Module\BaseModule;
/**
* Allow to build a form Coupon
@@ -36,6 +43,33 @@ class CouponCreationForm extends BaseForm
*/
protected function buildForm()
{
+ // Create countries and shipping modules list
+ $countries = [0 => ' '];
+
+ $list = CountryQuery::create()->find();
+
+ /** @var Country $item */
+ foreach($list as $item) {
+ $countries[$item->getId()] = $item->getTitle();
+ }
+
+ asort($countries);
+
+ $countries[0] = Translator::getInstance()->trans("All countries");
+
+ $modules = [0 => ' '];
+
+ $list = ModuleQuery::create()->filterByActivate(BaseModule::IS_ACTIVATED)->filterByType(BaseModule::DELIVERY_MODULE_TYPE)->find();
+
+ /** @var Module $item */
+ foreach($list as $item) {
+ $modules[$item->getId()] = $item->getTitle();
+ }
+
+ asort($modules);
+
+ $modules[0] = Translator::getInstance()->trans("All shipping methods");
+
$this->formBuilder
->add(
'code',
@@ -116,6 +150,22 @@ class CouponCreationForm extends BaseForm
'text',
array()
)
+ ->add(
+ 'freeShippingForCountries',
+ 'choice',
+ array(
+ 'multiple' => true,
+ 'choices' => $countries
+ )
+ )
+ ->add(
+ 'freeShippingForModules',
+ 'choice',
+ array(
+ 'multiple' => true,
+ 'choices' => $modules
+ )
+ )
->add(
'isAvailableOnSpecialOffers',
'text',
diff --git a/core/lib/Thelia/Model/Coupon.php b/core/lib/Thelia/Model/Coupon.php
index 20cb4d24b..7537e29b9 100644
--- a/core/lib/Thelia/Model/Coupon.php
+++ b/core/lib/Thelia/Model/Coupon.php
@@ -25,6 +25,8 @@ namespace Thelia\Model;
use Propel\Runtime\Propel;
use Thelia\Model\Base\Coupon as BaseCoupon;
+use Thelia\Model\Base\CouponCountryQuery;
+use Thelia\Model\Base\CouponModuleQuery;
use Thelia\Model\Exception\InvalidArgumentException;
use Thelia\Model\Map\CouponTableMap;
use Thelia\Model\Tools\ModelEventDispatcherTrait;
@@ -127,11 +129,13 @@ class Coupon extends BaseCoupon
;
}
+ $con->commit();
+
} catch (\Exception $ex) {
- $con->rollback();
+ $con->rollback();
- throw $ex;
+ throw $ex;
}
}
@@ -248,4 +252,21 @@ class Coupon extends BaseCoupon
return $effects;
}
+
+ /**
+ * Return the countries for which free shipping is valid
+ * @return array|mixed|\Propel\Runtime\Collection\ObjectCollection
+ */
+ public function getFreeShippingForCountries() {
+ return CouponCountryQuery::create()->filterByCouponId($this->getId())->find();
+ }
+
+ /**
+ * Return the modules for which free shipping is valid
+ *
+ * @return array|mixed|\Propel\Runtime\Collection\ObjectCollection
+ */
+ public function getFreeShippingForModules() {
+ return CouponModuleQuery::create()->filterByCouponId($this->getId())->find();
+ }
}
\ No newline at end of file
diff --git a/core/lib/Thelia/TaxEngine/TaxEngine.php b/core/lib/Thelia/TaxEngine/TaxEngine.php
index 04d5fe4fa..e680902dd 100644
--- a/core/lib/Thelia/TaxEngine/TaxEngine.php
+++ b/core/lib/Thelia/TaxEngine/TaxEngine.php
@@ -121,8 +121,8 @@ class TaxEngine
/* is there a logged in customer ? */
if (null !== $customer = $this->session->getCustomerUser()) {
if (null !== $this->session->getOrder()
- && null !== $this->session->getOrder()->chosenDeliveryAddress
- && null !== $currentDeliveryAddress = AddressQuery::create()->findPk($this->session->getOrder()->chosenDeliveryAddress)) {
+ && null !== $this->session->getOrder()->getChoosenDeliveryAddress()
+ && null !== $currentDeliveryAddress = AddressQuery::create()->findPk($this->session->getOrder()->getChoosenDeliveryAddress())) {
$this->taxCountry = $currentDeliveryAddress->getCountry();
} else {
$customerDefaultAddress = $customer->getDefaultAddress();
diff --git a/core/lib/Thelia/Tests/Action/OrderTest.php b/core/lib/Thelia/Tests/Action/OrderTest.php
index 48527ae7f..0963fafad 100644
--- a/core/lib/Thelia/Tests/Action/OrderTest.php
+++ b/core/lib/Thelia/Tests/Action/OrderTest.php
@@ -196,7 +196,7 @@ class OrderTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(
321,
- $this->orderEvent->getOrder()->chosenDeliveryAddress
+ $this->orderEvent->getOrder()->getChoosenDeliveryAddress()
);
}
@@ -208,7 +208,7 @@ class OrderTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(
654,
- $this->orderEvent->getOrder()->chosenInvoiceAddress
+ $this->orderEvent->getOrder()->getChoosenInvoiceAddress()
);
}
@@ -263,8 +263,8 @@ class OrderTest extends \PHPUnit_Framework_TestCase
$paymentModuleClass = $paymentModule->getFullNamespace();
$this->container->set(sprintf('module.%s', $paymentModule->getCode()), new $paymentModuleClass());
- $this->orderEvent->getOrder()->chosenDeliveryAddress = $validDeliveryAddress->getId();
- $this->orderEvent->getOrder()->chosenInvoiceAddress = $validInvoiceAddress->getId();
+ $this->orderEvent->getOrder()->setChoosenDeliveryAddress($validDeliveryAddress->getId());
+ $this->orderEvent->getOrder()->setChoosenInvoiceAddress($validInvoiceAddress->getId());
$this->orderEvent->getOrder()->setDeliveryModuleId($deliveryModule->getId());
$this->orderEvent->getOrder()->setPostage(20);
$this->orderEvent->getOrder()->setPaymentModuleId($paymentModule->getId());
diff --git a/core/lib/Thelia/Tests/Coupon/CouponManagerTest.php b/core/lib/Thelia/Tests/Coupon/CouponManagerTest.php
index 79bf4ba9a..af0858c86 100644
--- a/core/lib/Thelia/Tests/Coupon/CouponManagerTest.php
+++ b/core/lib/Thelia/Tests/Coupon/CouponManagerTest.php
@@ -11,6 +11,7 @@
/*************************************************************************************/
namespace Thelia\Coupon;
+use Propel\Runtime\Collection\ObjectCollection;
use Thelia\Condition\ConditionCollection;
use Thelia\Condition\ConditionEvaluator;
use Thelia\Condition\ConditionFactory;
@@ -18,7 +19,9 @@ use Thelia\Condition\Implementation\MatchForTotalAmount;
use Thelia\Condition\Operators;
use Thelia\Coupon\Type\RemoveXAmount;
use Thelia\Model\Coupon;
+use Thelia\Model\CouponCountry;
use Thelia\Model\CurrencyQuery;
+use Thelia\Model\Order;
/**
* Unit Test CouponManager Class
@@ -167,8 +170,13 @@ Sed facilisis pellentesque nisl, eu tincidunt erat scelerisque a. Nullam malesua
$actual = $couponManager->getDiscount();
$expected = 21 + 21.50;
+ $order = new Order();
+
+ $order->setChoosenDeliveryAddress(1);
+ $order->setDeliveryModuleId(1);
+
$this->assertEquals($expected, $actual);
- $this->assertTrue($couponManager->isCouponRemovingPostage());
+ $this->assertTrue($couponManager->isCouponRemovingPostage($order));
}
/**
@@ -390,7 +398,12 @@ Sed facilisis pellentesque nisl, eu tincidunt erat scelerisque a. Nullam malesua
$coupon = new RemoveXAmount($stubFacade);
$date = new \DateTime();
- $coupon->set($stubFacade, 'XMAS', '', '', '', array('amount' => 21.00), true, true, true, true, 254, $date->setTimestamp(strtotime("today + 3 months")) );
+ $coupon->set(
+ $stubFacade, 'XMAS', '', '', '', array('amount' => 21.00),
+ true, true, true, true, 254, $date->setTimestamp(strtotime("today + 3 months")),
+ new ObjectCollection(),
+ new ObjectCollection()
+ );
$condition1 = new MatchForTotalAmount($stubFacade);
$operators = array(
@@ -455,7 +468,12 @@ Sed facilisis pellentesque nisl, eu tincidunt erat scelerisque a. Nullam malesua
$coupon = new RemoveXAmount($stubFacade);
$date = new \DateTime();
- $coupon->set($stubFacade, 'XMAS', '', '', '', array('amount' => 21.00), true, true, true, true, 254, $date->setTimestamp(strtotime("today + 3 months")) );
+ $coupon->set(
+ $stubFacade, 'XMAS', '', '', '', array('amount' => 21.00),
+ true, true, true, true, 254, $date->setTimestamp(strtotime("today + 3 months")),
+ new ObjectCollection(),
+ new ObjectCollection()
+ );
$condition1 = new MatchForTotalAmount($stubFacade);
$operators = array(
diff --git a/core/lib/Thelia/Tests/Coupon/Type/RemoveXAmountTest.php b/core/lib/Thelia/Tests/Coupon/Type/RemoveXAmountTest.php
index b2cd23e13..cee516bc3 100644
--- a/core/lib/Thelia/Tests/Coupon/Type/RemoveXAmountTest.php
+++ b/core/lib/Thelia/Tests/Coupon/Type/RemoveXAmountTest.php
@@ -11,6 +11,7 @@
/*************************************************************************************/
namespace Thelia\Coupon\Type;
+use Propel\Runtime\Collection\ObjectCollection;
use Thelia\Condition\ConditionCollection;
use Thelia\Condition\ConditionEvaluator;
use Thelia\Condition\Implementation\MatchForTotalAmount;
@@ -114,7 +115,12 @@ class RemoveXAmountTest extends \PHPUnit_Framework_TestCase
Sed facilisis pellentesque nisl, eu tincidunt erat scelerisque a. Nullam malesuada tortor vel erat volutpat tincidunt. In vehicula diam est, a convallis eros scelerisque ut. Donec aliquet venenatis iaculis. Ut a arcu gravida, placerat dui eu, iaculis nisl. Quisque adipiscing orci sit amet dui dignissim lacinia. Sed vulputate lorem non dolor adipiscing ornare. Morbi ornare id nisl id aliquam. Ut fringilla elit ante, nec lacinia enim fermentum sit amet. Aenean rutrum lorem eu convallis pharetra. Cras malesuada varius metus, vitae gravida velit. Nam a varius ipsum, ac commodo dolor. Phasellus nec elementum elit. Etiam vel adipiscing leo.';
- $coupon->set($stubFacade, 'XMAS', 'XMAS Coupon', 'Coupon for Springbreak removing 10€ if you have a cart between 40.00€ and 400.00€ (excluded)', $description, array('amount' => 10.00), true, true, true, true, 254, $date->setTimestamp(strtotime("today + 3 months")) );
+ $coupon->set(
+ $stubFacade, 'XMAS', 'XMAS Coupon', 'Coupon for Springbreak removing 10€ if you have a cart between 40.00€ and 400.00€ (excluded)',
+ $description, array('amount' => 10.00), true, true, true, true, 254, $date->setTimestamp(strtotime("today + 3 months")),
+ new ObjectCollection(),
+ new ObjectCollection()
+ );
$condition1 = new MatchForTotalAmount($stubFacade);
$operators = array(
diff --git a/core/lib/Thelia/Tests/Coupon/Type/RemoveXPercentTest.php b/core/lib/Thelia/Tests/Coupon/Type/RemoveXPercentTest.php
index d22918b57..9f21324a7 100644
--- a/core/lib/Thelia/Tests/Coupon/Type/RemoveXPercentTest.php
+++ b/core/lib/Thelia/Tests/Coupon/Type/RemoveXPercentTest.php
@@ -11,6 +11,7 @@
/*************************************************************************************/
namespace Thelia\Coupon\Type;
+use Propel\Runtime\Collection\ObjectCollection;
use Thelia\Condition\ConditionCollection;
use Thelia\Condition\ConditionEvaluator;
use Thelia\Condition\Implementation\MatchForTotalAmount;
@@ -103,7 +104,13 @@ class RemoveXPercentTest extends \PHPUnit_Framework_TestCase
Sed facilisis pellentesque nisl, eu tincidunt erat scelerisque a. Nullam malesuada tortor vel erat volutpat tincidunt. In vehicula diam est, a convallis eros scelerisque ut. Donec aliquet venenatis iaculis. Ut a arcu gravida, placerat dui eu, iaculis nisl. Quisque adipiscing orci sit amet dui dignissim lacinia. Sed vulputate lorem non dolor adipiscing ornare. Morbi ornare id nisl id aliquam. Ut fringilla elit ante, nec lacinia enim fermentum sit amet. Aenean rutrum lorem eu convallis pharetra. Cras malesuada varius metus, vitae gravida velit. Nam a varius ipsum, ac commodo dolor. Phasellus nec elementum elit. Etiam vel adipiscing leo.';
- $coupon->set($stubFacade, 'XMAS', 'XMAS Coupon', 'Coupon for Springbreak removing 10% if you have a cart between 40.00€ and 400.00€ (excluded)', $description, array('amount' => 0.00, 'percentage' => 10.00), true, true, true, true, 254, $date->setTimestamp(strtotime("today + 3 months")) );
+ $coupon->set(
+ $stubFacade, 'XMAS', 'XMAS Coupon', 'Coupon for Springbreak removing 10% if you have a cart between 40.00€ and 400.00€ (excluded)',
+ $description, array('amount' => 0.00, 'percentage' => 10.00), true, true, true, true,
+ 254, $date->setTimestamp(strtotime("today + 3 months")),
+ new ObjectCollection(),
+ new ObjectCollection()
+ );
$condition1 = new MatchForTotalAmount($stubFacade);
$operators = array(
diff --git a/local/modules/Front/Controller/CartController.php b/local/modules/Front/Controller/CartController.php
index 431124dbe..cc9cf860a 100644
--- a/local/modules/Front/Controller/CartController.php
+++ b/local/modules/Front/Controller/CartController.php
@@ -174,7 +174,7 @@ class CartController extends BaseFrontController
$order = $this->getSession()->getOrder();
if (null !== $order) {
$deliveryModule = $order->getModuleRelatedByDeliveryModuleId();
- $deliveryAddress = AddressQuery::create()->findPk($order->chosenDeliveryAddress);
+ $deliveryAddress = AddressQuery::create()->findPk($order->getChoosenDeliveryAddress());
if (null !== $deliveryModule && null !== $deliveryAddress) {
$moduleInstance = $deliveryModule->getModuleInstance($this->container);
diff --git a/local/modules/Front/Controller/CouponController.php b/local/modules/Front/Controller/CouponController.php
index 03c57edba..98333dd0a 100644
--- a/local/modules/Front/Controller/CouponController.php
+++ b/local/modules/Front/Controller/CouponController.php
@@ -72,7 +72,7 @@ class CouponController extends BaseFrontController
if (null !== $order) {
$deliveryModule = $order->getModuleRelatedByDeliveryModuleId();
- $deliveryAddress = AddressQuery::create()->findPk($order->chosenDeliveryAddress);
+ $deliveryAddress = AddressQuery::create()->findPk($order->getChoosenDeliveryAddress());
if (null !== $deliveryModule && null !== $deliveryAddress) {
diff --git a/templates/backOffice/default/assets/js/coupon.js b/templates/backOffice/default/assets/js/coupon.js
index 53f932e12..2004de9a7 100644
--- a/templates/backOffice/default/assets/js/coupon.js
+++ b/templates/backOffice/default/assets/js/coupon.js
@@ -303,5 +303,17 @@ $(function($){
});
};
+ // Shipping conditions
+ $('#is-removing-postage').change(function(ev) {
+ if ($(this).is(':checked')) {
+ $('.free-postage-conditions').stop().slideDown();
+ }
+ else {
+ $('.free-postage-conditions').stop().slideUp();
+ }
+ })
+
$.couponManager.onUsageUnlimitedChange();
+
+ $('#is-removing-postage').change();
});
\ No newline at end of file
diff --git a/templates/backOffice/default/coupon/condition-fragments/cart-contains-categories-condition.html b/templates/backOffice/default/coupon/condition-fragments/cart-contains-categories-condition.html
index 5da1c7469..cf5b72646 100644
--- a/templates/backOffice/default/coupon/condition-fragments/cart-contains-categories-condition.html
+++ b/templates/backOffice/default/coupon/condition-fragments/cart-contains-categories-condition.html
@@ -6,7 +6,7 @@