Inital commit
This commit is contained in:
@@ -19,12 +19,11 @@ use Symfony\Component\Translation\TranslatorInterface;
|
||||
use Thelia\Condition\ConditionEvaluator;
|
||||
use Thelia\Core\HttpFoundation\Request;
|
||||
use Thelia\Core\Template\ParserInterface;
|
||||
use Thelia\Core\Template\TemplateHelper;
|
||||
use Thelia\Log\Tlog;
|
||||
use Thelia\Model\AddressQuery;
|
||||
use Thelia\Model\Country;
|
||||
use Thelia\Model\Coupon;
|
||||
use Thelia\Model\CouponQuery;
|
||||
use Thelia\Cart\CartTrait;
|
||||
use Thelia\Model\Currency;
|
||||
use Thelia\Model\CurrencyQuery;
|
||||
|
||||
@@ -37,10 +36,6 @@ use Thelia\Model\CurrencyQuery;
|
||||
*/
|
||||
class BaseFacade implements FacadeInterface
|
||||
{
|
||||
use CartTrait {
|
||||
CartTrait::getCart as getCartFromTrait;
|
||||
}
|
||||
|
||||
/** @var ContainerInterface Service Container */
|
||||
protected $container = null;
|
||||
|
||||
@@ -67,7 +62,7 @@ class BaseFacade implements FacadeInterface
|
||||
*/
|
||||
public function getCart()
|
||||
{
|
||||
return $this->getCartFromTrait($this->getDispatcher(), $this->getRequest());
|
||||
return $this->getRequest()->getSession()->getSessionCart($this->getDispatcher());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -78,7 +73,9 @@ class BaseFacade implements FacadeInterface
|
||||
public function getDeliveryAddress()
|
||||
{
|
||||
try {
|
||||
return AddressQuery::create()->findPk($this->getRequest()->getSession()->getOrder()->getChoosenDeliveryAddress());
|
||||
return AddressQuery::create()->findPk(
|
||||
$this->getRequest()->getSession()->getOrder()->getChoosenDeliveryAddress()
|
||||
);
|
||||
} catch (\Exception $ex) {
|
||||
throw new \LogicException("Failed to get delivery address (" . $ex->getMessage() . ")");
|
||||
}
|
||||
@@ -117,13 +114,15 @@ class BaseFacade implements FacadeInterface
|
||||
/**
|
||||
* Return Products total price
|
||||
*
|
||||
* @param bool $withItemsInPromo if true, the discounted items are included in the total
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getCartTotalPrice($withItemsInPromo = true)
|
||||
{
|
||||
$total = 0;
|
||||
|
||||
$cartItems = $this->getRequest()->getSession()->getCart()->getCartItems();
|
||||
$cartItems = $this->getRequest()->getSession()->getSessionCart($this->getDispatcher())->getCartItems();
|
||||
|
||||
foreach ($cartItems as $cartItem) {
|
||||
if ($withItemsInPromo || ! $cartItem->getPromo()) {
|
||||
@@ -137,7 +136,7 @@ class BaseFacade implements FacadeInterface
|
||||
public function getCartTotalTaxPrice($withItemsInPromo = true)
|
||||
{
|
||||
$taxCountry = $this->getContainer()->get('thelia.taxEngine')->getDeliveryCountry();
|
||||
$cartItems = $this->getRequest()->getSession()->getCart()->getCartItems();
|
||||
$cartItems = $this->getRequest()->getSession()->getSessionCart($this->getDispatcher())->getCartItems();
|
||||
|
||||
$total = 0;
|
||||
|
||||
@@ -175,7 +174,19 @@ class BaseFacade implements FacadeInterface
|
||||
*/
|
||||
public function getNbArticlesInCart()
|
||||
{
|
||||
return count($this->getRequest()->getSession()->getCart()->getCartItems());
|
||||
return count($this->getRequest()->getSession()->getSessionCart($this->getDispatcher())->getCartItems());
|
||||
}
|
||||
|
||||
public function getNbArticlesInCartIncludeQuantity()
|
||||
{
|
||||
$cartItems = $this->getCart()->getCartItems();
|
||||
$quantity = 0;
|
||||
|
||||
foreach ($cartItems as $cartItem) {
|
||||
$quantity += $cartItem->getQuantity();
|
||||
}
|
||||
|
||||
return $quantity;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -190,11 +201,23 @@ class BaseFacade implements FacadeInterface
|
||||
if (null === $couponCodes) {
|
||||
return array();
|
||||
}
|
||||
/** @var CouponFactory $couponFactory */
|
||||
$couponFactory = $this->container->get('thelia.coupon.factory');
|
||||
|
||||
$coupons = array();
|
||||
$coupons = [];
|
||||
|
||||
foreach ($couponCodes as $couponCode) {
|
||||
$coupons[] = $couponFactory->buildCouponFromCode($couponCode);
|
||||
// Only valid coupons are returned
|
||||
try {
|
||||
if (false !== $couponInterface = $couponFactory->buildCouponFromCode($couponCode)) {
|
||||
$coupons[] = $couponInterface;
|
||||
}
|
||||
} catch (\Exception $ex) {
|
||||
// Just ignore the coupon and log the problem, just in case someone realize it.
|
||||
Tlog::getInstance()->warning(
|
||||
sprintf("Coupon %s ignored, exception occurred: %s", $couponCode, $ex->getMessage())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $coupons;
|
||||
@@ -245,7 +268,9 @@ class BaseFacade implements FacadeInterface
|
||||
$this->parser = $this->container->get('thelia.parser');
|
||||
|
||||
// Define the current back-office template that should be used
|
||||
$this->parser->setTemplateDefinition(TemplateHelper::getInstance()->getActiveAdminTemplate());
|
||||
$this->parser->setTemplateDefinition(
|
||||
$this->parser->getTemplateHelper()->getActiveAdminTemplate()
|
||||
);
|
||||
}
|
||||
|
||||
return $this->parser;
|
||||
@@ -269,7 +294,7 @@ class BaseFacade implements FacadeInterface
|
||||
*/
|
||||
public function getRequest()
|
||||
{
|
||||
return $this->container->get('request');
|
||||
return $this->container->get('request_stack')->getCurrentRequest();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -303,4 +328,25 @@ class BaseFacade implements FacadeInterface
|
||||
{
|
||||
return $this->container->get('event_dispatcher');
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a coupon in session
|
||||
* @param $couponCode
|
||||
* @return mixed|void
|
||||
*/
|
||||
public function pushCouponInSession($couponCode)
|
||||
{
|
||||
$consumedCoupons = $this->getRequest()->getSession()->getConsumedCoupons();
|
||||
|
||||
if (!isset($consumedCoupons) || !$consumedCoupons) {
|
||||
$consumedCoupons = array();
|
||||
}
|
||||
|
||||
if (!isset($consumedCoupons[$couponCode])) {
|
||||
// Prevent accumulation of the same Coupon on a Checkout
|
||||
$consumedCoupons[$couponCode] = $couponCode;
|
||||
|
||||
$this->getRequest()->getSession()->setConsumedCoupons($consumedCoupons);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,9 +15,12 @@ namespace Thelia\Coupon;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Thelia\Condition\ConditionFactory;
|
||||
use Thelia\Coupon\Type\CouponInterface;
|
||||
use Thelia\Exception\CouponNotReleaseException;
|
||||
use Thelia\Exception\InactiveCouponException;
|
||||
use Thelia\Exception\CouponExpiredException;
|
||||
use Thelia\Exception\CouponNoUsageLeftException;
|
||||
use Thelia\Exception\InvalidConditionException;
|
||||
use Thelia\Exception\UnmatchableConditionException;
|
||||
use Thelia\Model\Coupon;
|
||||
|
||||
/**
|
||||
@@ -50,27 +53,45 @@ class CouponFactory
|
||||
* Build a CouponInterface from its database data
|
||||
*
|
||||
* @param string $couponCode Coupon code ex: XMAS
|
||||
*
|
||||
* @throws \Thelia\Exception\CouponExpiredException
|
||||
* @throws \Thelia\Exception\InvalidConditionException
|
||||
* @return CouponInterface ready to be processed
|
||||
* @return CouponInterface
|
||||
* @throws CouponExpiredException
|
||||
* @throws CouponNoUsageLeftException
|
||||
* @throws CouponNotReleaseException
|
||||
*/
|
||||
public function buildCouponFromCode($couponCode)
|
||||
{
|
||||
/** @var Coupon $couponModel */
|
||||
$couponModel = $this->facade->findOneCouponByCode($couponCode);
|
||||
if ($couponModel === null) {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
// check if coupon is enabled
|
||||
if (!$couponModel->getIsEnabled()) {
|
||||
throw new InactiveCouponException($couponCode);
|
||||
}
|
||||
|
||||
$nowDateTime = new \DateTime();
|
||||
|
||||
// Check coupon start date
|
||||
if ($couponModel->getStartDate() !== null && $couponModel->getStartDate() > $nowDateTime) {
|
||||
throw new CouponNotReleaseException($couponCode);
|
||||
}
|
||||
|
||||
// Check coupon expiration date
|
||||
if ($couponModel->getExpirationDate() < new \DateTime()) {
|
||||
if ($couponModel->getExpirationDate() < $nowDateTime) {
|
||||
throw new CouponExpiredException($couponCode);
|
||||
}
|
||||
|
||||
// Check coupon usage count
|
||||
if (! $couponModel->isUsageUnlimited() && $couponModel->getUsagesLeft($this->facade->getCustomer()->getId()) <= 0) {
|
||||
throw new CouponNoUsageLeftException($couponCode);
|
||||
if (! $couponModel->isUsageUnlimited()) {
|
||||
if (null === $customer = $this->facade->getCustomer()) {
|
||||
throw new UnmatchableConditionException($couponCode);
|
||||
}
|
||||
|
||||
if ($couponModel->getUsagesLeft($customer->getId()) <= 0) {
|
||||
throw new CouponNoUsageLeftException($couponCode);
|
||||
}
|
||||
}
|
||||
|
||||
/** @var CouponInterface $couponInterface */
|
||||
@@ -131,5 +152,4 @@ class CouponFactory
|
||||
|
||||
return clone $couponManager;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ namespace Thelia\Coupon;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Thelia\Condition\Implementation\ConditionInterface;
|
||||
use Thelia\Coupon\Type\CouponInterface;
|
||||
use Thelia\Exception\UnmatchableConditionException;
|
||||
use Thelia\Log\Tlog;
|
||||
use Thelia\Model\AddressQuery;
|
||||
use Thelia\Model\CouponModule;
|
||||
@@ -83,6 +84,15 @@ class CouponManager
|
||||
return $discount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $code
|
||||
* @return mixed|void
|
||||
*/
|
||||
public function pushCouponInSession($code)
|
||||
{
|
||||
$this->facade->pushCouponInSession($code);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if there is a Coupon removing Postage
|
||||
*
|
||||
@@ -102,15 +112,12 @@ 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
|
||||
// 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;
|
||||
}
|
||||
@@ -137,7 +144,6 @@ class CouponManager
|
||||
$couponModules = $coupon->getFreeShippingForModules();
|
||||
|
||||
if (! $couponModules->isEmpty()) {
|
||||
|
||||
$moduleValid = false;
|
||||
|
||||
$shippingModuleId = $order->getDeliveryModuleId();
|
||||
@@ -163,6 +169,14 @@ class CouponManager
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getCouponsKept()
|
||||
{
|
||||
return $this->sortCoupons($this->facade->getCurrentCoupons());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort Coupon to keep
|
||||
* Coupon not cumulative cancels previous
|
||||
@@ -205,8 +219,13 @@ class CouponManager
|
||||
|
||||
/** @var CouponInterface $coupon */
|
||||
foreach ($coupons as $coupon) {
|
||||
if ($coupon->isMatching($this->facade)) {
|
||||
$couponsKept[] = $coupon;
|
||||
try {
|
||||
if ($coupon->isMatching()) {
|
||||
$couponsKept[] = $coupon;
|
||||
}
|
||||
} catch (UnmatchableConditionException $e) {
|
||||
// ignore unmatchable coupon
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -297,19 +316,14 @@ class CouponManager
|
||||
public function decrementQuantity(Coupon $coupon, $customerId = null)
|
||||
{
|
||||
if ($coupon->isUsageUnlimited()) {
|
||||
$ret = true;
|
||||
return true;
|
||||
} else {
|
||||
$ret = false;
|
||||
|
||||
try {
|
||||
|
||||
$usageLeft = $coupon->getUsagesLeft($customerId);
|
||||
|
||||
if ($usageLeft > 0) {
|
||||
|
||||
// If the coupon usage is per user, add an entry to coupon customer usage count table
|
||||
if ($coupon->getPerCustomerUsageCount()) {
|
||||
|
||||
if (null == $customerId) {
|
||||
throw new \LogicException("Customer should not be null at this time.");
|
||||
}
|
||||
@@ -336,15 +350,13 @@ class CouponManager
|
||||
->save()
|
||||
;
|
||||
|
||||
$ret = $usageLeft - $newCount;
|
||||
return $usageLeft - $newCount;
|
||||
} else {
|
||||
$usageLeft--;
|
||||
|
||||
$coupon->setMaxUsage($usageLeft);
|
||||
$coupon->setMaxUsage(--$usageLeft);
|
||||
|
||||
$coupon->save();
|
||||
|
||||
$ret = $usageLeft;
|
||||
return $usageLeft;
|
||||
}
|
||||
}
|
||||
} catch (\Exception $ex) {
|
||||
@@ -353,6 +365,58 @@ class CouponManager
|
||||
}
|
||||
}
|
||||
|
||||
return $ret;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a coupon usage, for the case the related order is canceled.
|
||||
*
|
||||
* @param Coupon $coupon
|
||||
* @param int $customerId
|
||||
*/
|
||||
public function incrementQuantity(Coupon $coupon, $customerId = null)
|
||||
{
|
||||
if ($coupon->isUsageUnlimited()) {
|
||||
return true;
|
||||
} else {
|
||||
try {
|
||||
$usageLeft = $coupon->getUsagesLeft($customerId);
|
||||
|
||||
// If the coupon usage is per user, remove an entry from coupon customer usage count table
|
||||
if ($coupon->getPerCustomerUsageCount()) {
|
||||
if (null === $customerId) {
|
||||
throw new \LogicException("Customer should not be null at this time.");
|
||||
}
|
||||
|
||||
$ccc = CouponCustomerCountQuery::create()
|
||||
->filterByCouponId($coupon->getId())
|
||||
->filterByCustomerId($customerId)
|
||||
->findOne()
|
||||
;
|
||||
|
||||
if ($ccc !== null && $ccc->getCount() > 0) {
|
||||
$newCount = $ccc->getCount() - 1;
|
||||
|
||||
$ccc
|
||||
->setCount($newCount)
|
||||
->save();
|
||||
|
||||
return $usageLeft - $newCount;
|
||||
}
|
||||
} else {
|
||||
// Ad one usage to coupon
|
||||
$coupon->setMaxUsage(++$usageLeft);
|
||||
|
||||
$coupon->save();
|
||||
|
||||
return $usageLeft;
|
||||
}
|
||||
} catch (\Exception $ex) {
|
||||
// Just log the problem.
|
||||
Tlog::getInstance()->addError(sprintf("Failed to increment coupon %s: %s", $coupon->getCode(), $ex->getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,6 @@ use Thelia\Model\Coupon;
|
||||
*/
|
||||
interface FacadeInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
@@ -109,6 +108,13 @@ interface FacadeInterface
|
||||
*/
|
||||
public function getNbArticlesInCart();
|
||||
|
||||
/**
|
||||
* Return the number of Products include quantity in the Cart
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getNbArticlesInCartIncludeQuantity();
|
||||
|
||||
/**
|
||||
* Return all Coupon given during the Checkout
|
||||
*
|
||||
@@ -181,4 +187,11 @@ interface FacadeInterface
|
||||
*/
|
||||
public function getDispatcher();
|
||||
|
||||
/**
|
||||
* Add a coupon in session
|
||||
*
|
||||
* @param $couponCode
|
||||
* @return mixed|void
|
||||
*/
|
||||
public function pushCouponInSession($couponCode);
|
||||
}
|
||||
|
||||
@@ -23,10 +23,10 @@ use Thelia\Model\CartItem;
|
||||
*/
|
||||
abstract class AbstractRemove extends CouponAbstract implements AmountAndPercentageCouponInterface
|
||||
{
|
||||
/**
|
||||
/**
|
||||
* Set the value of specific coupon fields.
|
||||
*
|
||||
* @param Array $effects the Coupon effects params
|
||||
* @param array $effects the Coupon effects params
|
||||
*/
|
||||
abstract public function setFieldsValue($effects);
|
||||
|
||||
@@ -36,7 +36,7 @@ abstract class AbstractRemove extends CouponAbstract implements AmountAndPercent
|
||||
* @param CartItem $cartItem the cart item
|
||||
* @return float the discount value
|
||||
*/
|
||||
abstract public function getCartItemDiscount($cartItem);
|
||||
abstract public function getCartItemDiscount(CartItem $cartItem);
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
@@ -57,11 +57,20 @@ abstract class AbstractRemove extends CouponAbstract implements AmountAndPercent
|
||||
$freeShippingForCountries,
|
||||
$freeShippingForModules,
|
||||
$perCustomerUsageCount
|
||||
)
|
||||
{
|
||||
) {
|
||||
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,
|
||||
$perCustomerUsageCount
|
||||
@@ -71,36 +80,6 @@ abstract class AbstractRemove extends CouponAbstract implements AmountAndPercent
|
||||
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function exec()
|
||||
{
|
||||
// This coupon subtracts the specified amount from the order total
|
||||
// for each product of the selected categories.
|
||||
$discount = 0;
|
||||
|
||||
$cartItems = $this->facade->getCart()->getCartItems();
|
||||
|
||||
/** @var CartItem $cartItem */
|
||||
foreach ($cartItems as $cartItem) {
|
||||
if (! $cartItem->getPromo() || $this->isAvailableOnSpecialOffers()) {
|
||||
$categories = $cartItem->getProduct()->getCategories();
|
||||
|
||||
/** @var Category $category */
|
||||
foreach ($categories as $category) {
|
||||
|
||||
if (in_array($category->getId(), $this->category_list)) {
|
||||
$discount += $this->getCartItemDiscount($cartItem);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $discount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
|
||||
@@ -33,7 +33,7 @@ abstract class AbstractRemoveOnAttributeValues extends CouponAbstract implements
|
||||
|
||||
/**
|
||||
* Set the value of specific coupon fields.
|
||||
* @param Array $effects the Coupon effects params
|
||||
* @param array $effects the Coupon effects params
|
||||
*/
|
||||
abstract public function setFieldsValue($effects);
|
||||
|
||||
@@ -43,7 +43,7 @@ abstract class AbstractRemoveOnAttributeValues extends CouponAbstract implements
|
||||
* @param CartItem $cartItem the cart item
|
||||
* @return float the discount value
|
||||
*/
|
||||
abstract public function getCartItemDiscount($cartItem);
|
||||
abstract public function getCartItemDiscount(CartItem $cartItem);
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
@@ -64,11 +64,20 @@ abstract class AbstractRemoveOnAttributeValues extends CouponAbstract implements
|
||||
$freeShippingForCountries,
|
||||
$freeShippingForModules,
|
||||
$perCustomerUsageCount
|
||||
)
|
||||
{
|
||||
) {
|
||||
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,
|
||||
$perCustomerUsageCount
|
||||
@@ -76,7 +85,9 @@ abstract class AbstractRemoveOnAttributeValues extends CouponAbstract implements
|
||||
|
||||
$this->attributeAvList = isset($effects[self::ATTRIBUTES_AV_LIST]) ? $effects[self::ATTRIBUTES_AV_LIST] : array();
|
||||
|
||||
if (! is_array($this->attributeAvList)) $this->attributeAvList = array($this->attributeAvList);
|
||||
if (! is_array($this->attributeAvList)) {
|
||||
$this->attributeAvList = array($this->attributeAvList);
|
||||
}
|
||||
|
||||
$this->attribute = isset($effects[self::ATTRIBUTE]) ? $effects[self::ATTRIBUTE] : 0;
|
||||
|
||||
@@ -98,7 +109,6 @@ abstract class AbstractRemoveOnAttributeValues extends CouponAbstract implements
|
||||
|
||||
/** @var CartItem $cartItem */
|
||||
foreach ($cartItems as $cartItem) {
|
||||
|
||||
if (! $cartItem->getPromo() || $this->isAvailableOnSpecialOffers()) {
|
||||
$productSaleElements = $cartItem->getProductSaleElements();
|
||||
|
||||
@@ -106,7 +116,6 @@ abstract class AbstractRemoveOnAttributeValues extends CouponAbstract implements
|
||||
|
||||
/** @var AttributeCombination $combination */
|
||||
foreach ($combinations as $combination) {
|
||||
|
||||
$attrValue = $combination->getAttributeAvId();
|
||||
|
||||
if (in_array($attrValue, $this->attributeAvList)) {
|
||||
|
||||
@@ -15,6 +15,7 @@ namespace Thelia\Coupon\Type;
|
||||
use Thelia\Core\Translation\Translator;
|
||||
use Thelia\Coupon\FacadeInterface;
|
||||
use Thelia\Model\CartItem;
|
||||
use Thelia\Model\Category;
|
||||
|
||||
/**
|
||||
* Allow to remove an amount from the checkout total
|
||||
@@ -31,7 +32,7 @@ abstract class AbstractRemoveOnCategories extends CouponAbstract implements Amou
|
||||
/**
|
||||
* Set the value of specific coupon fields.
|
||||
*
|
||||
* @param Array $effects the Coupon effects params
|
||||
* @param array $effects the Coupon effects params
|
||||
*/
|
||||
abstract public function setFieldsValue($effects);
|
||||
|
||||
@@ -41,7 +42,7 @@ abstract class AbstractRemoveOnCategories extends CouponAbstract implements Amou
|
||||
* @param CartItem $cartItem the cart item
|
||||
* @return float the discount value
|
||||
*/
|
||||
abstract public function getCartItemDiscount($cartItem);
|
||||
abstract public function getCartItemDiscount(CartItem $cartItem);
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
@@ -62,11 +63,20 @@ abstract class AbstractRemoveOnCategories extends CouponAbstract implements Amou
|
||||
$freeShippingForCountries,
|
||||
$freeShippingForModules,
|
||||
$perCustomerUsageCount
|
||||
)
|
||||
{
|
||||
) {
|
||||
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,
|
||||
$perCustomerUsageCount
|
||||
@@ -74,7 +84,9 @@ abstract class AbstractRemoveOnCategories extends CouponAbstract implements Amou
|
||||
|
||||
$this->category_list = isset($effects[self::CATEGORIES_LIST]) ? $effects[self::CATEGORIES_LIST] : array();
|
||||
|
||||
if (! is_array($this->category_list)) $this->category_list = array($this->category_list);
|
||||
if (! is_array($this->category_list)) {
|
||||
$this->category_list = array($this->category_list);
|
||||
}
|
||||
|
||||
$this->setFieldsValue($effects);
|
||||
|
||||
@@ -98,7 +110,6 @@ abstract class AbstractRemoveOnCategories extends CouponAbstract implements Amou
|
||||
|
||||
/** @var Category $category */
|
||||
foreach ($categories as $category) {
|
||||
|
||||
if (in_array($category->getId(), $this->category_list)) {
|
||||
$discount += $this->getCartItemDiscount($cartItem);
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ abstract class AbstractRemoveOnProducts extends CouponAbstract implements Amount
|
||||
/**
|
||||
* Set the value of specific coupon fields.
|
||||
*
|
||||
* @param Array $effects the Coupon effects params
|
||||
* @param array $effects the Coupon effects params
|
||||
*/
|
||||
abstract public function setFieldsValue($effects);
|
||||
|
||||
@@ -43,7 +43,7 @@ abstract class AbstractRemoveOnProducts extends CouponAbstract implements Amount
|
||||
* @param CartItem $cartItem the cart item
|
||||
* @return float the discount value
|
||||
*/
|
||||
abstract public function getCartItemDiscount($cartItem);
|
||||
abstract public function getCartItemDiscount(CartItem $cartItem);
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
@@ -64,11 +64,20 @@ abstract class AbstractRemoveOnProducts extends CouponAbstract implements Amount
|
||||
$freeShippingForCountries,
|
||||
$freeShippingForModules,
|
||||
$perCustomerUsageCount
|
||||
)
|
||||
{
|
||||
) {
|
||||
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,
|
||||
$perCustomerUsageCount
|
||||
@@ -76,7 +85,9 @@ abstract class AbstractRemoveOnProducts extends CouponAbstract implements Amount
|
||||
|
||||
$this->product_list = isset($effects[self::PRODUCTS_LIST]) ? $effects[self::PRODUCTS_LIST] : array();
|
||||
|
||||
if (! is_array($this->product_list)) $this->product_list = array($this->product_list);
|
||||
if (! is_array($this->product_list)) {
|
||||
$this->product_list = array($this->product_list);
|
||||
}
|
||||
|
||||
$this->category_id = isset($effects[self::CATEGORY_ID]) ? $effects[self::CATEGORY_ID] : 0;
|
||||
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
|
||||
namespace Thelia\Coupon\Type;
|
||||
|
||||
use Thelia\Model\CartItem;
|
||||
|
||||
/**
|
||||
* Represents a Coupon ready to be processed in a Checkout process
|
||||
*
|
||||
@@ -21,10 +23,9 @@ namespace Thelia\Coupon\Type;
|
||||
*/
|
||||
interface AmountAndPercentageCouponInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* Set the value of specific coupon fields.
|
||||
* @param Array $effects the Coupon effects params
|
||||
* @param array $effects the Coupon effects params
|
||||
*/
|
||||
public function setFieldsValue($effects);
|
||||
|
||||
@@ -34,7 +35,7 @@ interface AmountAndPercentageCouponInterface
|
||||
* @param CartItem $cartItem the cart item
|
||||
* @return float the discount value
|
||||
*/
|
||||
public function getCartItemDiscount($cartItem);
|
||||
public function getCartItemDiscount(CartItem $cartItem);
|
||||
|
||||
/**
|
||||
* Renders the template which implements coupon specific user-input,
|
||||
@@ -53,7 +54,13 @@ interface AmountAndPercentageCouponInterface
|
||||
public function getBaseFieldList($otherFields);
|
||||
|
||||
/**
|
||||
* Check the value of a coupon configuration field
|
||||
*
|
||||
* @param string $fieldName
|
||||
* @param string $fieldValue
|
||||
* @return string the field value
|
||||
*
|
||||
* @throws \InvalidArgumentException is field value is not valid.
|
||||
*/
|
||||
public function checkBaseCouponFieldValue($fieldName, $fieldValue);
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
namespace Thelia\Coupon\Type;
|
||||
|
||||
use Thelia\Core\Translation\Translator;
|
||||
use Thelia\Model\CartItem;
|
||||
|
||||
/**
|
||||
* A trait to manage a coupon which removes a constant amount from the order total.
|
||||
@@ -22,8 +23,8 @@ use Thelia\Core\Translation\Translator;
|
||||
* @author Franck Allimant <franck@cqfdev.fr>
|
||||
* @package Thelia\Coupon\Type
|
||||
*/
|
||||
Trait AmountCouponTrait {
|
||||
|
||||
trait AmountCouponTrait
|
||||
{
|
||||
// The amount is already defined in CouponAbstract, and should not be redefined here.
|
||||
// protected $amount = 0;
|
||||
|
||||
@@ -45,7 +46,7 @@ Trait AmountCouponTrait {
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getCartItemDiscount($cartItem)
|
||||
public function getCartItemDiscount(CartItem $cartItem)
|
||||
{
|
||||
return $cartItem->getQuantity() * $this->amount;
|
||||
}
|
||||
@@ -77,7 +78,6 @@ Trait AmountCouponTrait {
|
||||
$this->checkBaseCouponFieldValue($fieldName, $fieldValue);
|
||||
|
||||
if ($fieldName === $this->getAmountFieldName()) {
|
||||
|
||||
if (floatval($fieldValue) < 0) {
|
||||
throw new \InvalidArgumentException(
|
||||
Translator::getInstance()->trans(
|
||||
|
||||
@@ -30,7 +30,7 @@ use Thelia\Model\CouponModule;
|
||||
*/
|
||||
abstract class CouponAbstract implements CouponInterface
|
||||
{
|
||||
/**
|
||||
/**
|
||||
* The dataset name for all coupon specific input fields, that do not appear in the CouPonCreationForm form.
|
||||
*
|
||||
* In the input form, these fields have to be created like:
|
||||
@@ -85,6 +85,9 @@ abstract class CouponAbstract implements CouponInterface
|
||||
/** @var bool if Coupon is enabled */
|
||||
protected $isEnabled = false;
|
||||
|
||||
/** @var \DateTime Coupon start date */
|
||||
protected $startDate = null;
|
||||
|
||||
/** @var \DateTime Coupon expiration date */
|
||||
protected $expirationDate = null;
|
||||
|
||||
@@ -154,8 +157,7 @@ abstract class CouponAbstract implements CouponInterface
|
||||
$freeShippingForCountries,
|
||||
$freeShippingForModules,
|
||||
$perCustomerUsageCount
|
||||
)
|
||||
{
|
||||
) {
|
||||
$this->code = $code;
|
||||
$this->title = $title;
|
||||
$this->shortDescription = $shortDescription;
|
||||
|
||||
@@ -55,7 +55,7 @@ class FreeProduct extends AbstractRemoveOnProducts
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getCartItemDiscount($cartItem)
|
||||
public function getCartItemDiscount(CartItem $cartItem)
|
||||
{
|
||||
// This method is not used, we use our own implementation of exec();
|
||||
return 0;
|
||||
@@ -67,7 +67,7 @@ class FreeProduct extends AbstractRemoveOnProducts
|
||||
protected function getSessionVarName()
|
||||
{
|
||||
return "coupon.free_product.cart_items." . $this->getCode();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Return the cart item id which contains the free product related to a given product
|
||||
*
|
||||
@@ -83,7 +83,6 @@ class FreeProduct extends AbstractRemoveOnProducts
|
||||
);
|
||||
|
||||
if (isset($cartItemIdList[$product->getId()])) {
|
||||
|
||||
$cartItemId = $cartItemIdList[$product->getId()];
|
||||
|
||||
if ($cartItemId == self::ADD_TO_CART_IN_PROCESS) {
|
||||
@@ -98,14 +97,12 @@ class FreeProduct extends AbstractRemoveOnProducts
|
||||
/** @var CartItem $cartItem */
|
||||
foreach ($cartItems as $cartItem) {
|
||||
if ($cartItem->getProduct()->getId() == $this->offeredProductId) {
|
||||
|
||||
// We found the product. Store its cart item as the free product container.
|
||||
$this->setRelatedCartItem($product, $cartItem->getId());
|
||||
|
||||
return $cartItem;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -124,7 +121,9 @@ class FreeProduct extends AbstractRemoveOnProducts
|
||||
array()
|
||||
);
|
||||
|
||||
if (! is_array($cartItemIdList)) $cartItemIdList = array();
|
||||
if (! is_array($cartItemIdList)) {
|
||||
$cartItemIdList = array();
|
||||
}
|
||||
|
||||
$cartItemIdList[$product->getId()] = $cartItemId;
|
||||
|
||||
@@ -196,15 +195,12 @@ class FreeProduct extends AbstractRemoveOnProducts
|
||||
}
|
||||
|
||||
if ($eligibleProduct !== null) {
|
||||
|
||||
// Get the cart item for the eligible product
|
||||
$freeProductCartItem = $this->getRelatedCartItem($eligibleProduct);
|
||||
|
||||
// We add the free product it only if it not yet in the cart.
|
||||
if ($freeProductCartItem === false) {
|
||||
|
||||
if (null !== $freeProduct = ProductQuery::create()->findPk($this->offeredProductId)) {
|
||||
|
||||
// Store in the session that the free product is added to the cart,
|
||||
// so that we don't enter the following infinite loop :
|
||||
//
|
||||
@@ -235,12 +231,10 @@ class FreeProduct extends AbstractRemoveOnProducts
|
||||
|
||||
if ($freeProductCartItem instanceof CartItem) {
|
||||
// The discount is the product price.
|
||||
$discount = $freeProductCartItem->getPromo() ?
|
||||
$freeProductCartItem->getPromoPrice() : $freeProductCartItem->getPrice();
|
||||
$discount = $freeProductCartItem->getRealTaxedPrice($this->facade->getDeliveryCountry());
|
||||
}
|
||||
}
|
||||
// No eligible product was found !
|
||||
else {
|
||||
// No eligible product was found !
|
||||
} else {
|
||||
// Remove all free products for this coupon, but no not remove the product from the cart.
|
||||
$this->clearFreeProductsCartItemIds();
|
||||
}
|
||||
@@ -264,7 +258,6 @@ class FreeProduct extends AbstractRemoveOnProducts
|
||||
$this->checkBaseCouponFieldValue($fieldName, $fieldValue);
|
||||
|
||||
if ($fieldName === self::OFFERED_PRODUCT_ID) {
|
||||
|
||||
if (floatval($fieldValue) < 0) {
|
||||
throw new \InvalidArgumentException(
|
||||
Translator::getInstance()->trans(
|
||||
|
||||
@@ -11,7 +11,9 @@
|
||||
/*************************************************************************************/
|
||||
|
||||
namespace Thelia\Coupon\Type;
|
||||
|
||||
use Thelia\Core\Translation\Translator;
|
||||
use Thelia\Model\CartItem;
|
||||
|
||||
/**
|
||||
* A trait to manage a coupon which removes a percentage of cart items from the order total.
|
||||
@@ -21,8 +23,8 @@ use Thelia\Core\Translation\Translator;
|
||||
* @author Franck Allimant <franck@cqfdev.fr>
|
||||
* @package Thelia\Coupon\Type
|
||||
*/
|
||||
Trait PercentageCouponTrait {
|
||||
|
||||
trait PercentageCouponTrait
|
||||
{
|
||||
public $percentage = 0;
|
||||
|
||||
/**
|
||||
@@ -43,9 +45,9 @@ Trait PercentageCouponTrait {
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getCartItemDiscount($cartItem)
|
||||
public function getCartItemDiscount(CartItem $cartItem)
|
||||
{
|
||||
return $cartItem->getQuantity() * $cartItem->getPrice() * ($this->percentage / 100);
|
||||
return $cartItem->getQuantity() * $cartItem->getRealTaxedPrice($this->facade->getDeliveryCountry()) * ($this->percentage / 100);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -75,7 +77,6 @@ Trait PercentageCouponTrait {
|
||||
$this->checkBaseCouponFieldValue($fieldName, $fieldValue);
|
||||
|
||||
if ($fieldName === $this->getPercentageFieldName()) {
|
||||
|
||||
$pcent = floatval($fieldValue);
|
||||
|
||||
if ($pcent <= 0 || $pcent > 100) {
|
||||
|
||||
@@ -61,6 +61,12 @@ class RemoveXAmount extends AbstractRemove
|
||||
*/
|
||||
public function exec()
|
||||
{
|
||||
$cartTotal = $this->facade->getCartTotalTaxPrice($this->isAvailableOnSpecialOffers());
|
||||
|
||||
if ($this->amount > $cartTotal) {
|
||||
return $cartTotal;
|
||||
}
|
||||
|
||||
return $this->amount;
|
||||
}
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ class RemoveXPercent extends AbstractRemove
|
||||
*/
|
||||
public function exec()
|
||||
{
|
||||
return round($this->facade->getCartTotalTaxPrice($this->isAvailableOnSpecialOffers()) * $this->percentage/100, 2);
|
||||
return ($this->facade->getCartTotalTaxPrice($this->isAvailableOnSpecialOffers()) * $this->percentage/100);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user