Merge pull request #473 from roadster31/coupon-end

Major coupon types refactoring.
This commit is contained in:
Manuel Raynaud
2014-06-17 21:11:14 +02:00
66 changed files with 6545 additions and 903 deletions

View File

@@ -109,6 +109,17 @@ class Coupon extends BaseAction implements EventSubscriberInterface
$this->createOrUpdateCondition($modelCoupon, $event);
}
/**
* Clear all coupons in session.
*/
public function clearAllCoupons()
{
// Tell coupons to clear any data they may have stored
$this->couponManager->clear();
$this->request->getSession()->setConsumedCoupons(array());
}
/**
* Occurring when a Coupon condition is about to be consumed
*
@@ -139,21 +150,22 @@ class Coupon extends BaseAction implements EventSubscriberInterface
$consumedCoupons[$event->getCode()] = $event->getCode();
$this->request->getSession()->setConsumedCoupons($consumedCoupons);
$totalDiscount = $this->couponManager->getDiscount();
$this->request
->getSession()
->getCart()
->setDiscount($totalDiscount)
->save();
$this->request
->getSession()
->getOrder()
->setDiscount($totalDiscount)
;
}
}
$totalDiscount = $this->couponManager->getDiscount();
$this->request
->getSession()
->getCart()
->setDiscount($totalDiscount)
->save();
$this->request
->getSession()
->getOrder()
->setDiscount($totalDiscount)
;
}
}
$event->setIsValid($isValid);
@@ -339,7 +351,8 @@ class Coupon extends BaseAction implements EventSubscriberInterface
}
}
$this->request->getSession()->setConsumedCoupons(array());
// Clear all coupons.
$event->getDispatcher()->dispatch(TheliaEvents::COUPON_CLEAR_ALL);
}
/**
@@ -368,6 +381,7 @@ class Coupon extends BaseAction implements EventSubscriberInterface
TheliaEvents::COUPON_CREATE => array("create", 128),
TheliaEvents::COUPON_UPDATE => array("update", 128),
TheliaEvents::COUPON_CONSUME => array("consume", 128),
TheliaEvents::COUPON_CLEAR_ALL => array("clearAllCoupons", 128),
TheliaEvents::COUPON_CONDITION_UPDATE => array("updateCondition", 128),
TheliaEvents::ORDER_SET_POSTAGE => array("testFreePostage", 132),
TheliaEvents::ORDER_BEFORE_PAYMENT => array("afterOrder", 128),

View File

@@ -55,6 +55,8 @@ class StartDate extends ConditionAbstract
*/
public function setValidatorsFromForm(array $operators, array $values)
{
$this->checkComparisonOperatorValue($operators, self::START_DATE);
if (! isset($values[self::START_DATE])) {
$values[self::START_DATE] = time();
}

View File

@@ -50,6 +50,7 @@ return array(
'Cart item count is' => 'Cart item count is',
'Cart total amount' => 'Cart total amount',
'Cart total amount is' => 'Cart total amount is',
'Catalog' => 'Catalog',
'Category title *' => 'Category title *',
'Cellphone' => 'Cellphone',
'Chapo' => 'Chapo',
@@ -111,14 +112,18 @@ return array(
'First Name' => 'First Name',
'Firstname' => 'Firstname',
'Fixed Amount Discount' => 'Fixed Amount Discount',
'Fixed amount discount for selected attribute values' => 'Fixed amount discount for selected attribute values',
'Fixed amount discount for selected categories' => 'Fixed amount discount for selected categories',
'Fixed amount discount for selected products' => 'Fixed amount discount for selected products',
'Folder' => 'Folder',
'Folder title *' => 'Folder title *',
'For one ore more customers' => 'For one ore more customers',
'Free product when buying one or more selected products' => 'Free product when buying one or more selected products',
'Full Name' => 'Full Name',
'Greater than' => 'Greater than',
'Greater than or equals' => 'Greater than or equals',
'HTML Message' => 'HTML Message',
'Home' => 'Home',
'Host' => 'Host',
'I would like to receive the newsletter or the latest news.' => 'I would like to receive the newsletter or the latest news.',
'ISO 4217 code *' => 'ISO 4217 code *',
@@ -190,6 +195,7 @@ return array(
'Password *' => 'Password *',
'Password confirmation' => 'Password confirmation',
'Per customer' => 'Per customer',
'Percentage discount for selected attribute values' => 'Percentage discount for selected attribute values',
'Percentage discount for selected categories' => 'Percentage discount for selected categories',
'Percentage discount for selected products' => 'Percentage discount for selected products',
'Percentage of the product price' => 'Percentage of the product price',
@@ -199,8 +205,12 @@ return array(
'Please enter your email address' => 'Please enter your email address',
'Please enter your password' => 'Please enter your password',
'Please select a category' => 'Please select a category',
'Please select an attribute' => 'Please select an attribute',
'Please select at least one attribute value' => 'Please select at least one attribute value',
'Please select at least one category' => 'Please select at least one category',
'Please select at least one product' => 'Please select at least one product',
'Please select the category of the offred product' => 'Please select the category of the offred product',
'Please select the offered product' => 'Please select the offered product',
'Please specify either \'path\' or \'file\' parameter in {url} function.' => 'Please specify either \'path\' or \'file\' parameter in {url} function.',
'Port' => 'Port',
'Post Scriptum' => 'Post Scriptum',
@@ -288,10 +298,13 @@ return array(
'This category is online.' => 'This category is online.',
'This condition is always true' => 'This condition is always true',
'This content is online.' => 'This content is online.',
'This coupon adds a free product to the cart if one of the selected products is in the cart.' => 'This coupon adds a free product to the cart if one of the selected products is in the cart.',
'This coupon does not exists' => 'This coupon does not exists',
'This coupon subtracts from the order total a percentage of the price of each product which belongs to the selected categories. If the discount is greater than the total order, the customer will only pay the shipping, or nothing if the coupon also provides free shipping.' => 'This coupon subtracts from the order total a percentage of the price of each product which belongs to the selected categories. If the discount is greater than the total order, the customer will only pay the shipping, or nothing if the coupon also provides free shipping.',
'This coupon subtracts from the order total the specified percentage of each product price which uses the selected attribute values. If the discount is greater than the total order, the customer will only pay the shipping, or nothing if the coupon also provides free shipping.' => 'This coupon subtracts from the order total the specified percentage of each product price which uses the selected attribute values. If the discount is greater than the total order, the customer will only pay the shipping, or nothing if the coupon also provides free shipping.',
'This coupon subtracts from the order total the specified percentage of each selected product price. If the discount is greater than the total order, the customer will only pay the shipping, or nothing if the coupon also provides free shipping.' => 'This coupon subtracts from the order total the specified percentage of each selected product price. If the discount is greater than the total order, the customer will only pay the shipping, or nothing if the coupon also provides free shipping.',
'This coupon subtracts the specified amount from the order total for each product which belongs to the selected categories. If the discount is greater than the total order, the customer will only pay the shipping, or nothing if the coupon also provides free shipping.' => 'This coupon subtracts the specified amount from the order total for each product which belongs to the selected categories. If the discount is greater than the total order, the customer will only pay the shipping, or nothing if the coupon also provides free shipping.',
'This coupon subtracts the specified amount from the order total for each product which uses the selected attribute values. If the discount is greater than the total order, the customer will only pay the shipping, or nothing if the coupon also provides free shipping.' => 'This coupon subtracts the specified amount from the order total for each product which uses the selected attribute values. If the discount is greater than the total order, the customer will only pay the shipping, or nothing if the coupon also provides free shipping.',
'This coupon subtracts the specified amount from the order total for each selected product. If the discount is greater than the total order, the customer will only pay the shipping, or nothing if the coupon also provides free shipping.' => 'This coupon subtracts the specified amount from the order total for each selected product. If the discount is greater than the total order, the customer will only pay the shipping, or nothing if the coupon also provides free shipping.',
'This coupon will offert a flat percentage off a shopper\'s entire order (not applied to shipping costs or tax rates). If the discount is greater than the total order corst, the customer will only pay the shipping, or nothing if the coupon also provides free shipping.' => 'This coupon will offert a flat percentage off a shopper\'s entire order (not applied to shipping costs or tax rates). If the discount is greater than the total order corst, the customer will only pay the shipping, or nothing if the coupon also provides free shipping.',
'This coupon will subtracts a set amount from the total cost of an order. If the discount is greater than the total order corst, the customer will only pay the shipping, or nothing if the coupon also provides free shipping.' => 'This coupon will subtracts a set amount from the total cost of an order. If the discount is greater than the total order corst, the customer will only pay the shipping, or nothing if the coupon also provides free shipping.',
@@ -324,7 +337,6 @@ return array(
'Valid only from %date% to the coupon expiration date' => 'Valide à partir du %date% jusqu\'à la date d\'expiration',
'Value' => 'Value',
'Value %val for Discount Amount is invalid. Please enter a positive value.' => 'Value %val for Discount Amount is invalid. Please enter a positive value.',
'Value %val for Disount Amount is invalid. Please enter a positive value.' => 'Value %val for Disount Amount is invalid. Please enter a positive value.',
'Value %val for Percent Discount is invalid. Please enter a positive value between 1 and 100.' => 'Value %val for Percent Discount is invalid. Please enter a positive value between 1 and 100.',
'Value *' => 'Value *',
'Warnings' => 'Warnings',

View File

@@ -50,6 +50,7 @@ return array(
'Cart item count is' => 'Le nombre d\'articles dans le panier est',
'Cart total amount' => 'Montant total du panier',
'Cart total amount is' => 'Le total du panier est',
'Catalog' => 'Catalogue',
'Category title *' => 'Titre de la catégorie *',
'Cellphone' => 'Numéro de portable',
'Chapo' => 'Chapeau',
@@ -111,14 +112,18 @@ return array(
'First Name' => 'Prénom',
'Firstname' => 'Prénom',
'Fixed Amount Discount' => 'Remise d\'un montant fixe',
'Fixed amount discount for selected attribute values' => 'Remise constante pour certaines valeurs de déclinaison',
'Fixed amount discount for selected categories' => 'Remise fixe pour certaines catégories',
'Fixed amount discount for selected products' => 'Remise fixe pour certains produits',
'Folder' => 'Dossier',
'Folder title *' => 'Titre du dossier *',
'For one ore more customers' => 'Valable pour un ou plusieurs clients',
'Free product when buying one or more selected products' => 'Un produit offert pour l\'achat d\'un ou plusieurs produits',
'Full Name' => 'Nom complet',
'Greater than' => 'Supérieur à',
'Greater than or equals' => 'Supérieur ou égal à',
'HTML Message' => 'Message au format HTML',
'Home' => 'Accueil',
'Host' => 'Nom de l\'hôte',
'I would like to receive the newsletter or the latest news.' => 'Je souhaite recevoir la lettre d\'information ou les dernières actualités.',
'ISO 4217 code *' => 'Code ISO 4217 *',
@@ -190,6 +195,7 @@ return array(
'Password *' => 'Mot de passe *',
'Password confirmation' => 'Confirmation du mot de passe.',
'Per customer' => 'Par client',
'Percentage discount for selected attribute values' => 'Remise en pourcentage pour certaines valeurs de déclinaison',
'Percentage discount for selected categories' => 'Remise en pourcentage pour certaines catégories',
'Percentage discount for selected products' => 'Remise en pourcentage pour certains produits',
'Percentage of the product price' => 'Pourcentage du prix du produit',
@@ -199,8 +205,12 @@ return array(
'Please enter your email address' => 'Renseignez votre adresse mail',
'Please enter your password' => 'Entrez votre mot de passe.',
'Please select a category' => 'Merci de choisir une catégorie',
'Please select an attribute' => 'Merci de choisir une déclinaison',
'Please select at least one attribute value' => 'Merci de choisir au moins une valeur de déclinaison',
'Please select at least one category' => 'Merci de choisir au moins une catégorie.',
'Please select at least one product' => 'Merci de choisir au moins un produit',
'Please select the category of the offred product' => 'Merci de choisir la catégorie du produit offert',
'Please select the offered product' => 'Merci de choisir le produit offert',
'Please specify either \'path\' or \'file\' parameter in {url} function.' => 'Veuillez spécifier soit le paramètre \'chemin\' ou \'fichier\' dans la fonction {url}',
'Port' => 'Port',
'Post Scriptum' => 'Post-scriptum',
@@ -288,10 +298,13 @@ return array(
'This category is online.' => 'Cette catégorie est en ligne.',
'This condition is always true' => 'Cette condition est troujours vérifiée',
'This content is online.' => 'Ce contenu est en ligne.',
'This coupon adds a free product to the cart if one of the selected products is in the cart.' => 'Ce coupon ajoute un produit gratuit (sous forme de remise) au panier, si un des produits indiqués est présent dans le panier.',
'This coupon does not exists' => 'Ce code promo n\'existe pas',
'This coupon subtracts from the order total a percentage of the price of each product which belongs to the selected categories. If the discount is greater than the total order, the customer will only pay the shipping, or nothing if the coupon also provides free shipping.' => 'Ce code promo retire du total de la commande le pourcentage indiqué du prix de chacun des produits appartenant aux catégories sélectionnées. Si la remise est supérieure au total de la commande, seul le port sera dû, à moins que le code promo n\'offre aussi le port.',
'This coupon subtracts from the order total the specified percentage of each product price which uses the selected attribute values. If the discount is greater than the total order, the customer will only pay the shipping, or nothing if the coupon also provides free shipping.' => 'Ce code promo retire du total de la commande le pourcentage indiqué du prix de chacun des produits ayant au moins une des valeurs de déclinaisons indiquées. Si la remise est supérieure au total de la commande, seul le port sera dû, à moins que le code promo n\'offre aussi le port.',
'This coupon subtracts from the order total the specified percentage of each selected product price. If the discount is greater than the total order, the customer will only pay the shipping, or nothing if the coupon also provides free shipping.' => 'Ce code promo retire du total de la commande le pourcentage indiqué du prix de chacun des produits sélectionnés. Si la remise est supérieure au total de la commande, seul le port sera dû, à moins que le code promo n\'offre aussi le port.',
'This coupon subtracts the specified amount from the order total for each product which belongs to the selected categories. If the discount is greater than the total order, the customer will only pay the shipping, or nothing if the coupon also provides free shipping.' => 'Ce code promo retire le montant indiqué du total de la commande pour chacun des produits appartenant aux catégories sélectionnées. Si la remise est supérieure au total de la commande, seul le port sera dû, à moins que le code promo n\'offre aussi le port.',
'This coupon subtracts the specified amount from the order total for each product which uses the selected attribute values. If the discount is greater than the total order, the customer will only pay the shipping, or nothing if the coupon also provides free shipping.' => 'Ce code promo retire le montant indiqué du total de la commande pour chacun des produits ayant au moins une des valeurs de déclinaisons indiquées. Si la remise est supérieure au total de la commande, seul le port sera dû, à moins que le code promo n\'offre aussi le port.',
'This coupon subtracts the specified amount from the order total for each selected product. If the discount is greater than the total order, the customer will only pay the shipping, or nothing if the coupon also provides free shipping.' => 'Ce code promo retire le montant indiqué du total de la commande pour chacun des produits sélectionnés. Si la remise est supérieure au total de la commande, seul le port sera dû, à moins que le code promo n\'offre aussi le port.',
'This coupon will offert a flat percentage off a shopper\'s entire order (not applied to shipping costs or tax rates). If the discount is greater than the total order corst, the customer will only pay the shipping, or nothing if the coupon also provides free shipping.' => 'Ce code promo retire le pourcentage indiqué du total de la commande, hors frais de port et taxes. Si la remise est supérieur au total de la commande, seul le port sera facturé, à moins que le code promo n\'offre aussi les frais port.',
'This coupon will subtracts a set amount from the total cost of an order. If the discount is greater than the total order corst, the customer will only pay the shipping, or nothing if the coupon also provides free shipping.' => 'Ce code promo retire le montant indiqué du total de la commande, hors frais de port et taxes. Si la remise est supérieur au total de la commande, seul le port sera facturé, à moins que le code promo n\'offre aussi les frais port.',
@@ -324,7 +337,6 @@ return array(
'Valid only from %date% to the coupon expiration date' => 'Valide à partir de %date% jusqu\'à la date d\'expoiration',
'Value' => 'Valeur',
'Value %val for Discount Amount is invalid. Please enter a positive value.' => 'La valeur %val pour le montant de la remise est invalide. Merci d\'indiquer une valeur positive.',
'Value %val for Disount Amount is invalid. Please enter a positive value.' => 'La valeur %val pour le montant de la remise est invalide. Merci d\'indiquer une valeur positive.',
'Value %val for Percent Discount is invalid. Please enter a positive value between 1 and 100.' => 'La valeur %val pour le pourcentage de remise est invalide. Merci d\'indiquer un nombre entre 1 et 100',
'Value *' => 'Valeur *',
'Warnings' => 'Avertissements',

View File

@@ -51,6 +51,25 @@
<tag name="thelia.coupon.addCoupon"/>
</service>
<service id="thelia.coupon.type.remove_percentage_on_products" class="Thelia\Coupon\Type\RemovePercentageOnProducts">
<argument type="service" id="thelia.facade" />
<tag name="thelia.coupon.addCoupon"/>
</service>
<service id="thelia.coupon.type.remove_amount_on_attribute_av" class="Thelia\Coupon\Type\RemoveAmountOnAttributeValues">
<argument type="service" id="thelia.facade" />
<tag name="thelia.coupon.addCoupon"/>
</service>
<service id="thelia.coupon.type.remove_percentage_on_attribute_av" class="Thelia\Coupon\Type\RemovePercentageOnAttributeValues">
<argument type="service" id="thelia.facade" />
<tag name="thelia.coupon.addCoupon"/>
</service>
<service id="thelia.coupon.type.free_product" class="Thelia\Coupon\Type\FreeProduct">
<argument type="service" id="thelia.facade" />
<tag name="thelia.coupon.addCoupon"/>
</service>
<!-- Condition module -->

View File

@@ -14,6 +14,7 @@ namespace Thelia\Core\Event\Cart;
use Thelia\Core\Event\ActionEvent;
use Thelia\Model\Cart;
use Thelia\Model\CartItem;
class CartEvent extends ActionEvent
{
@@ -31,7 +32,8 @@ class CartEvent extends ActionEvent
}
/**
* @param mixed $append
* @param bool $append
* @return CartEvent
*/
public function setAppend($append)
{
@@ -41,7 +43,7 @@ class CartEvent extends ActionEvent
}
/**
* @return mixed
* @return bool
*/
public function getAppend()
{
@@ -49,7 +51,8 @@ class CartEvent extends ActionEvent
}
/**
* @param mixed $cartItem
* @param CartItem $cartItem
* @return CartEvent
*/
public function setCartItem($cartItem)
{
@@ -59,7 +62,7 @@ class CartEvent extends ActionEvent
}
/**
* @return mixed
* @return CartItem
*/
public function getCartItem()
{
@@ -67,7 +70,8 @@ class CartEvent extends ActionEvent
}
/**
* @param mixed $newness
* @param bool $newness
* @return CartEvent
*/
public function setNewness($newness)
{
@@ -77,7 +81,7 @@ class CartEvent extends ActionEvent
}
/**
* @return mixed
* @return bool
*/
public function getNewness()
{
@@ -85,7 +89,8 @@ class CartEvent extends ActionEvent
}
/**
* @param mixed $product
* @param int $product the product ID
* @return CartEvent
*/
public function setProduct($product)
{
@@ -95,7 +100,7 @@ class CartEvent extends ActionEvent
}
/**
* @return mixed
* @return int the product ID
*/
public function getProduct()
{
@@ -103,7 +108,8 @@ class CartEvent extends ActionEvent
}
/**
* @param mixed $productSaleElementsId
* @param int $productSaleElementsId
* @return CartEvent
*/
public function setProductSaleElementsId($productSaleElementsId)
{
@@ -113,7 +119,7 @@ class CartEvent extends ActionEvent
}
/**
* @return mixed
* @return int
*/
public function getProductSaleElementsId()
{
@@ -121,7 +127,8 @@ class CartEvent extends ActionEvent
}
/**
* @param mixed $quantity
* @param int $quantity
* @return CartEvent
*/
public function setQuantity($quantity)
{
@@ -131,7 +138,7 @@ class CartEvent extends ActionEvent
}
/**
* @return mixed
* @return int
*/
public function getQuantity()
{

View File

@@ -464,6 +464,11 @@ final class TheliaEvents
*/
const COUPON_CONSUME = "action.consume_coupon";
/**
* Sent when all coupons in the current session should be cleared
*/
const COUPON_CLEAR_ALL = "action.clear_all_coupon";
/**
* Sent just before an attempt to use a Coupon
*/

View File

@@ -21,6 +21,7 @@ use Thelia\Core\HttpFoundation\Request;
use Thelia\Core\Template\ParserInterface;
use Thelia\Core\Template\TemplateHelper;
use Thelia\Model\AddressQuery;
use Thelia\Model\Country;
use Thelia\Model\Coupon;
use Thelia\Model\CouponQuery;
use Thelia\Cart\CartTrait;
@@ -149,6 +150,14 @@ class BaseFacade implements FacadeInterface
return $total;
}
/**
* @return Country the delivery country
*/
public function getDeliveryCountry()
{
return $this->getContainer()->get('thelia.taxEngine')->getDeliveryCountry();
}
/**
* Return the Checkout currency EUR|USD
*

View File

@@ -69,7 +69,7 @@ class CouponFactory
}
// Check coupon usage count
if ($couponModel->getUsagesLeft($this->facade->getCustomer()->getId()) <= 0) {
if (! $couponModel->isUsageUnlimited() && $couponModel->getUsagesLeft($this->facade->getCustomer()->getId()) <= 0) {
throw new CouponNoUsageLeftException($couponCode);
}

View File

@@ -58,14 +58,15 @@ class CouponManager
/**
* Get Discount for the given Coupons
*
* @api
* @return float checkout discount
*/
public function getDiscount()
{
$discount = 0.00;
$coupons = $this->facade->getCurrentCoupons();
if (count($coupons) > 0) {
$couponsKept = $this->sortCoupons($coupons);
@@ -73,6 +74,7 @@ class CouponManager
// Just In Case test
$checkoutTotalPrice = $this->facade->getCartTotalTaxPrice();
if ($discount >= $checkoutTotalPrice) {
$discount = $checkoutTotalPrice;
}
@@ -83,6 +85,9 @@ class CouponManager
/**
* Check if there is a Coupon removing Postage
*
* @param Order $order the order for which we have to check if postage is free
*
* @return bool
*/
public function isCouponRemovingPostage(Order $order)
@@ -266,6 +271,19 @@ class CouponManager
return $this->availableConditions;
}
/**
* Clear all data kept by coupons
*/
public function clear()
{
$coupons = $this->facade->getCurrentCoupons();
/** @var CouponInterface $coupon */
foreach ($coupons as $coupon) {
$coupon->clear();
}
}
/**
* Decrement this coupon quantity
*
@@ -278,57 +296,61 @@ class CouponManager
*/
public function decrementQuantity(Coupon $coupon, $customerId = null)
{
$ret = false;
if ($coupon->isUsageUnlimited()) {
$ret = true;
} else {
$ret = false;
try {
try {
$usageLeft = $coupon->getUsagesLeft($customerId);
$usageLeft = $coupon->getUsagesLeft($customerId);
if ($usageLeft > 0) {
if ($usageLeft > 0) {
// If the coupon usage is per user, add an entry to coupon customer usage count table
if ($coupon->getPerCustomerUsageCount()) {
// 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.");
}
if (null == $customerId) {
throw new \LogicException("Customer should not be null at this time.");
}
$ccc = CouponCustomerCountQuery::create()
->filterByCouponId($coupon->getId())
->filterByCustomerId($customerId)
->findOne()
;
$ccc = CouponCustomerCountQuery::create()
->filterByCouponId($coupon->getId())
->filterByCustomerId($customerId)
->findOne()
;
if ($ccc === null) {
$ccc = new CouponCustomerCount();
if ($ccc === null) {
$ccc = new CouponCustomerCount();
$ccc
->setCustomerId($customerId)
->setCouponId($coupon->getId())
->setCount(0);
}
$newCount = 1 + $ccc->getCount();
$ccc
->setCustomerId($customerId)
->setCouponId($coupon->getId())
->setCount(0);
->setCount($newCount)
->save()
;
$ret = $usageLeft - $newCount;
} else {
$usageLeft--;
$coupon->setMaxUsage($usageLeft);
$coupon->save();
$ret = $usageLeft;
}
$newCount = 1 + $ccc->getCount();
$ccc
->setCount($newCount)
->save()
;
$ret = $usageLeft - $newCount;
} else {
$usageLeft--;
$coupon->setMaxUsage($usageLeft);
$coupon->save();
$ret = $usageLeft;
}
} catch (\Exception $ex) {
// Just log the problem.
Tlog::getInstance()->addError(sprintf("Failed to decrement coupon %s: %s", $coupon->getCode(), $ex->getMessage()));
}
} catch (\Exception $ex) {
// Just log the problem.
Tlog::getInstance()->addError(sprintf("Failed to decrement coupon %s: %s", $coupon->getCode(), $ex->getMessage()));
}
return $ret;

View File

@@ -18,6 +18,7 @@ use Symfony\Component\Translation\TranslatorInterface;
use Thelia\Condition\ConditionEvaluator;
use Thelia\Core\HttpFoundation\Request;
use Thelia\Core\Template\ParserInterface;
use Thelia\Model\Country;
use Thelia\Model\Coupon;
/**
@@ -51,6 +52,11 @@ interface FacadeInterface
*/
public function getDeliveryAddress();
/**
* @return Country the delivery country
*/
public function getDeliveryCountry();
/**
* Return an Customer a CouponManager can process
*

View File

@@ -0,0 +1,128 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\Coupon\Type;
use Thelia\Coupon\FacadeInterface;
use Thelia\Model\CartItem;
/**
* Allow to remove an amount from the checkout total
*
* @package Coupon
* @author Franck Allimant <franck@cqfdev.fr>
*/
abstract class AbstractRemove extends CouponAbstract implements AmountAndPercentageCouponInterface
{
/**
* Set the value of specific coupon fields.
*
* @param Array $effects the Coupon effects params
*/
abstract public function setFieldsValue($effects);
/**
* Get the discount for a specific cart item.
*
* @param CartItem $cartItem the cart item
* @return float the discount value
*/
abstract public function getCartItemDiscount($cartItem);
/**
* @inheritdoc
*/
public function set(
FacadeInterface $facade,
$code,
$title,
$shortDescription,
$description,
array $effects,
$isCumulative,
$isRemovingPostage,
$isAvailableOnSpecialOffers,
$isEnabled,
$maxUsage,
\DateTime $expirationDate,
$freeShippingForCountries,
$freeShippingForModules,
$perCustomerUsageCount
)
{
parent::set(
$facade, $code, $title, $shortDescription, $description, $effects,
$isCumulative, $isRemovingPostage, $isAvailableOnSpecialOffers, $isEnabled, $maxUsage, $expirationDate,
$freeShippingForCountries,
$freeShippingForModules,
$perCustomerUsageCount
);
$this->setFieldsValue($effects);
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
*/
public function drawBaseBackOfficeInputs($templateName, $otherFields)
{
return $this->facade->getParser()->render($templateName, $otherFields);
}
/**
* @inheritdoc
*/
public function getBaseFieldList($otherFields)
{
return array_merge($otherFields);
}
/**
* @inheritdoc
*/
public function checkBaseCouponFieldValue($fieldName, $fieldValue)
{
return $fieldValue;
}
}

View File

@@ -0,0 +1,180 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\Coupon\Type;
use Thelia\Core\Translation\Translator;
use Thelia\Coupon\FacadeInterface;
use Thelia\Model\AttributeCombination;
use Thelia\Model\CartItem;
/**
* The base class to process a discount related to Attribute values.
*
* @package Coupon
* @author Franck Allimant <franck@cqfdev.fr>
*/
abstract class AbstractRemoveOnAttributeValues extends CouponAbstract implements AmountAndPercentageCouponInterface
{
const ATTRIBUTES_AV_LIST = 'attribute_avs';
const ATTRIBUTE = 'attribute_id';
public $attributeAvList = array();
public $attribute = 0;
/**
* Set the value of specific coupon fields.
* @param Array $effects the Coupon effects params
*/
abstract public function setFieldsValue($effects);
/**
* Get the discount for a specific cart item.
*
* @param CartItem $cartItem the cart item
* @return float the discount value
*/
abstract public function getCartItemDiscount($cartItem);
/**
* @inheritdoc
*/
public function set(
FacadeInterface $facade,
$code,
$title,
$shortDescription,
$description,
array $effects,
$isCumulative,
$isRemovingPostage,
$isAvailableOnSpecialOffers,
$isEnabled,
$maxUsage,
\DateTime $expirationDate,
$freeShippingForCountries,
$freeShippingForModules,
$perCustomerUsageCount
)
{
parent::set(
$facade, $code, $title, $shortDescription, $description, $effects,
$isCumulative, $isRemovingPostage, $isAvailableOnSpecialOffers, $isEnabled, $maxUsage, $expirationDate,
$freeShippingForCountries,
$freeShippingForModules,
$perCustomerUsageCount
);
$this->attributeAvList = isset($effects[self::ATTRIBUTES_AV_LIST]) ? $effects[self::ATTRIBUTES_AV_LIST] : array();
if (! is_array($this->attributeAvList)) $this->attributeAvList = array($this->attributeAvList);
$this->attribute = isset($effects[self::ATTRIBUTE]) ? $effects[self::ATTRIBUTE] : 0;
$this->setFieldsValue($effects);
return $this;
}
/**
* @inheritdoc
*/
public function exec()
{
// This coupon subtracts the specified amount from the order total
// for each product which uses the selected attributes
$discount = 0;
$cartItems = $this->facade->getCart()->getCartItems();
/** @var CartItem $cartItem */
foreach ($cartItems as $cartItem) {
if (! $cartItem->getPromo() || $this->isAvailableOnSpecialOffers()) {
$productSaleElements = $cartItem->getProductSaleElements();
$combinations = $productSaleElements->getAttributeCombinations();
/** @var AttributeCombination $combination */
foreach ($combinations as $combination) {
$attrValue = $combination->getAttributeAvId();
if (in_array($attrValue, $this->attributeAvList)) {
$discount += $this->getCartItemDiscount($cartItem);
break;
}
}
}
}
return $discount;
}
/**
* Renders the template which implements coupon specific user-input,
* using the provided template file, and a list of specific input fields.
*
* @param string $templateName the path to the template
* @param array $otherFields the list of additional fields fields
*
* @return string the rendered template.
*/
public function drawBaseBackOfficeInputs($templateName, $otherFields)
{
return $this->facade->getParser()->render($templateName, array_merge($otherFields, [
// The attributes list field
'attribute_field_name' => $this->makeCouponFieldName(self::ATTRIBUTE),
'attribute_value' => $this->attribute,
// The attributes list field
'attribute_av_field_name' => $this->makeCouponFieldName(self::ATTRIBUTES_AV_LIST),
'attribute_av_values' => $this->attributeAvList
]));
}
/**
* @inheritdoc
*/
public function getBaseFieldList($otherFields)
{
return array_merge($otherFields, [self::ATTRIBUTE, self::ATTRIBUTES_AV_LIST]);
}
/**
* @inheritdoc
*/
public function checkBaseCouponFieldValue($fieldName, $fieldValue)
{
if ($fieldName === self::ATTRIBUTE) {
if (empty($fieldValue)) {
throw new \InvalidArgumentException(
Translator::getInstance()->trans(
'Please select an attribute'
)
);
}
} elseif ($fieldName === self::ATTRIBUTES_AV_LIST) {
if (empty($fieldValue)) {
throw new \InvalidArgumentException(
Translator::getInstance()->trans(
'Please select at least one attribute value'
)
);
}
}
return $fieldValue;
}
}

View File

@@ -0,0 +1,152 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\Coupon\Type;
use Thelia\Core\Translation\Translator;
use Thelia\Coupon\FacadeInterface;
use Thelia\Model\CartItem;
/**
* Allow to remove an amount from the checkout total
*
* @package Coupon
* @author Franck Allimant <franck@cqfdev.fr>
*/
abstract class AbstractRemoveOnCategories extends CouponAbstract implements AmountAndPercentageCouponInterface
{
const CATEGORIES_LIST = 'categories';
protected $category_list = array();
/**
* Set the value of specific coupon fields.
*
* @param Array $effects the Coupon effects params
*/
abstract public function setFieldsValue($effects);
/**
* Get the discount for a specific cart item.
*
* @param CartItem $cartItem the cart item
* @return float the discount value
*/
abstract public function getCartItemDiscount($cartItem);
/**
* @inheritdoc
*/
public function set(
FacadeInterface $facade,
$code,
$title,
$shortDescription,
$description,
array $effects,
$isCumulative,
$isRemovingPostage,
$isAvailableOnSpecialOffers,
$isEnabled,
$maxUsage,
\DateTime $expirationDate,
$freeShippingForCountries,
$freeShippingForModules,
$perCustomerUsageCount
)
{
parent::set(
$facade, $code, $title, $shortDescription, $description, $effects,
$isCumulative, $isRemovingPostage, $isAvailableOnSpecialOffers, $isEnabled, $maxUsage, $expirationDate,
$freeShippingForCountries,
$freeShippingForModules,
$perCustomerUsageCount
);
$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);
$this->setFieldsValue($effects);
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
*/
public function drawBaseBackOfficeInputs($templateName, $otherFields)
{
return $this->facade->getParser()->render($templateName, array_merge($otherFields, [
// The categories list field
'categories_field_name' => $this->makeCouponFieldName(self::CATEGORIES_LIST),
'categories_values' => $this->category_list
]));
}
/**
* @inheritdoc
*/
public function getBaseFieldList($otherFields)
{
return array_merge($otherFields, [self::CATEGORIES_LIST]);
}
/**
* @inheritdoc
*/
public function checkBaseCouponFieldValue($fieldName, $fieldValue)
{
if ($fieldName === self::CATEGORIES_LIST) {
if (empty($fieldValue)) {
throw new \InvalidArgumentException(
Translator::getInstance()->trans(
'Please select at least one category'
)
);
}
}
return $fieldValue;
}
}

View File

@@ -0,0 +1,162 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\Coupon\Type;
use Thelia\Core\Translation\Translator;
use Thelia\Coupon\FacadeInterface;
use Thelia\Model\CartItem;
/**
* Allow to remove an amount from the checkout total
*
* @package Coupon
* @author Franck Allimant <franck@cqfdev.fr>
*/
abstract class AbstractRemoveOnProducts extends CouponAbstract implements AmountAndPercentageCouponInterface
{
const CATEGORY_ID = 'category_id';
const PRODUCTS_LIST = 'products';
public $category_id = 0;
public $product_list = array();
/**
* Set the value of specific coupon fields.
*
* @param Array $effects the Coupon effects params
*/
abstract public function setFieldsValue($effects);
/**
* Get the discount for a specific cart item.
*
* @param CartItem $cartItem the cart item
* @return float the discount value
*/
abstract public function getCartItemDiscount($cartItem);
/**
* @inheritdoc
*/
public function set(
FacadeInterface $facade,
$code,
$title,
$shortDescription,
$description,
array $effects,
$isCumulative,
$isRemovingPostage,
$isAvailableOnSpecialOffers,
$isEnabled,
$maxUsage,
\DateTime $expirationDate,
$freeShippingForCountries,
$freeShippingForModules,
$perCustomerUsageCount
)
{
parent::set(
$facade, $code, $title, $shortDescription, $description, $effects,
$isCumulative, $isRemovingPostage, $isAvailableOnSpecialOffers, $isEnabled, $maxUsage, $expirationDate,
$freeShippingForCountries,
$freeShippingForModules,
$perCustomerUsageCount
);
$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);
$this->category_id = isset($effects[self::CATEGORY_ID]) ? $effects[self::CATEGORY_ID] : 0;
$this->setFieldsValue($effects);
return $this;
}
/**
* @inheritdoc
*/
public function exec()
{
// This coupon subtracts the specified amount from the order total
// for each product of the selected products.
$discount = 0;
$cartItems = $this->facade->getCart()->getCartItems();
/** @var CartItem $cartItem */
foreach ($cartItems as $cartItem) {
if (in_array($cartItem->getProduct()->getId(), $this->product_list)) {
if (! $cartItem->getPromo() || $this->isAvailableOnSpecialOffers()) {
$discount += $this->getCartItemDiscount($cartItem);
}
}
}
return $discount;
}
/**
* @inheritdoc
*/
public function drawBaseBackOfficeInputs($templateName, $otherFields)
{
return $this->facade->getParser()->render($templateName, array_merge($otherFields, [
// The category ID field
'category_id_field_name' => $this->makeCouponFieldName(self::CATEGORY_ID),
'category_id_value' => $this->category_id,
// The products list field
'products_field_name' => $this->makeCouponFieldName(self::PRODUCTS_LIST),
'products_values' => $this->product_list,
'products_values_csv' => implode(', ', $this->product_list)
]));
}
/**
* @inheritdoc
*/
public function getBaseFieldList($otherFields)
{
return array_merge($otherFields, [self::CATEGORY_ID, self::PRODUCTS_LIST]);
}
/**
* @inheritdoc
*/
public function checkBaseCouponFieldValue($fieldName, $fieldValue)
{
if ($fieldName === self::CATEGORY_ID) {
if (empty($fieldValue)) {
throw new \InvalidArgumentException(
Translator::getInstance()->trans(
'Please select a category'
)
);
}
} elseif ($fieldName === self::PRODUCTS_LIST) {
if (empty($fieldValue)) {
throw new \InvalidArgumentException(
Translator::getInstance()->trans(
'Please select at least one product'
)
);
}
}
return $fieldValue;
}
}

View File

@@ -0,0 +1,59 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\Coupon\Type;
/**
* Represents a Coupon ready to be processed in a Checkout process
*
* @package Coupon
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
interface AmountAndPercentageCouponInterface
{
/**
* Set the value of specific coupon fields.
* @param Array $effects the Coupon effects params
*/
public function setFieldsValue($effects);
/**
* Get the discount for a specific cart item.
*
* @param CartItem $cartItem the cart item
* @return float the discount value
*/
public function getCartItemDiscount($cartItem);
/**
* Renders the template which implements coupon specific user-input,
* using the provided template file, and a list of specific input fields.
*
* @param string $templateName the path to the template
* @param array $otherFields the list of additional fields fields
*
* @return string the rendered template.
*/
public function drawBaseBackOfficeInputs($templateName, $otherFields);
/**
* @inheritdoc
*/
public function getBaseFieldList($otherFields);
/**
*
*/
public function checkBaseCouponFieldValue($fieldName, $fieldValue);
}

View File

@@ -0,0 +1,93 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\Coupon\Type;
use Thelia\Core\Translation\Translator;
/**
* A trait to manage a coupon which removes a constant amount from the order total.
* Should be used on coupons classes which implements AmountAndPercentageCouponInterface
*
* Class AmountCouponTrait
* @author Franck Allimant <franck@cqfdev.fr>
* @package Thelia\Coupon\Type
*/
Trait AmountCouponTrait {
// The amount is already defined in CouponAbstract, and should not be redefined here.
// protected $amount = 0;
/**
* Should return the amount field name, defined in the parent class.
*
* @return string the percentage field name
*/
abstract protected function getAmountFieldName();
/**
* @inheritdoc
*/
protected function setFieldsValue($effects)
{
$this->amount = $effects[$this->getAmountFieldName()];
}
/**
* @inheritdoc
*/
public function getCartItemDiscount($cartItem)
{
return $cartItem->getQuantity() * $this->amount;
}
/**
* @inheritdoc
*/
public function callDrawBackOfficeInputs($templateName)
{
return $this->drawBaseBackOfficeInputs($templateName, [
'amount_field_name' => $this->makeCouponFieldName($this->getAmountFieldName()),
'amount_value' => $this->amount
]);
}
/**
* @inheritdoc
*/
protected function getFieldList()
{
return $this->getBaseFieldList([$this->getAmountFieldName()]);
}
/**
* @inheritdoc
*/
protected function checkCouponFieldValue($fieldName, $fieldValue)
{
$this->checkBaseCouponFieldValue($fieldName, $fieldValue);
if ($fieldName === $this->getAmountFieldName()) {
if (floatval($fieldValue) < 0) {
throw new \InvalidArgumentException(
Translator::getInstance()->trans(
'Value %val for Discount Amount is invalid. Please enter a positive value.',
[ '%val' => $fieldValue]
)
);
}
}
return $fieldValue;
}
}

View File

@@ -499,4 +499,12 @@ abstract class CouponAbstract implements CouponInterface
return $effects;
}
/**
* @inheritdoc
*/
public function clear()
{
// Does nothing. Override this function as needed.
}
}

View File

@@ -239,4 +239,9 @@ interface CouponInterface
*/
public function getEffects($data);
/**
* Clear all the data the coupon may have stored, called after an order is completed.
*/
public function clear();
}

View File

@@ -0,0 +1,345 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\Coupon\Type;
use Thelia\Core\Event\Cart\CartEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Core\Translation\Translator;
use Thelia\Model\CartItem;
use Thelia\Model\CartItemQuery;
use Thelia\Model\Product;
use Thelia\Model\ProductQuery;
/**
* Allow to remove an amount from the checkout total
*
* @package Coupon
* @author Franck Allimant <franck@cqfdev.fr>
*/
class FreeProduct extends AbstractRemoveOnProducts
{
const OFFERED_PRODUCT_ID = 'offered_product_id';
const OFFERED_CATEGORY_ID = 'offered_category_id';
/** @var string Service Id */
protected $serviceId = 'thelia.coupon.type.free_product';
protected $offeredProductId;
protected $offeredCategoryId;
/**
* This constant is user to mark a free product as in the process of being added to the cart,
* but the CartItem ID is not yet been defined.
*/
const ADD_TO_CART_IN_PROCESS = -1;
/**
* @inheritdoc
*/
public function setFieldsValue($effects)
{
$this->offeredProductId = $effects[self::OFFERED_PRODUCT_ID];
$this->offeredCategoryId = $effects[self::OFFERED_CATEGORY_ID];
}
/**
* @inheritdoc
*/
public function getCartItemDiscount($cartItem)
{
// This method is not used, we use our own implementation of exec();
return 0;
}
/**
* @return string The session variable where the cart item IDs for the free products are stored
*/
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
*
* @param Product $product the product in the cart which triggered the discount
*
* @return bool|int|CartItem the cart item which contains the free product, or false if the product is no longer in the cart, or ADD_TO_CART_IN_PROCESS if the adding process is not finished
*/
protected function getRelatedCartItem($product)
{
$cartItemIdList = $this->facade->getRequest()->getSession()->get(
$this->getSessionVarName(),
array()
);
if (isset($cartItemIdList[$product->getId()])) {
$cartItemId = $cartItemIdList[$product->getId()];
if ($cartItemId == self::ADD_TO_CART_IN_PROCESS) {
return self::ADD_TO_CART_IN_PROCESS;
} elseif (null !== $cartItem = CartItemQuery::create()->findPk($cartItemId)) {
return $cartItem;
}
} else {
// Maybe the product we're offering is already in the cart ? Search it.
$cartItems = $this->facade->getCart()->getCartItems();
/** @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;
}
/**
* Set the cart item id which contains the free product related to a given product
*
* @param Product $product the product in the cart which triggered the discount
* @param bool|int $cartItemId the cart item ID which contains the free product, or just true if the free product is not yet added.
*/
protected function setRelatedCartItem($product, $cartItemId)
{
$cartItemIdList = $this->facade->getRequest()->getSession()->get(
$this->getSessionVarName(),
array()
);
if (! is_array($cartItemIdList)) $cartItemIdList = array();
$cartItemIdList[$product->getId()] = $cartItemId;
$this->facade->getRequest()->getSession()->set(
$this->getSessionVarName(),
$cartItemIdList
);
}
/**
* Get the product id / cart item id list.
*
* @return array an array where the free product ID is the key, and the related cart item id the value.
*/
protected function getFreeProductsCartItemIds()
{
return $this->facade->getRequest()->getSession()->get(
$this->getSessionVarName(),
array()
);
}
/**
* Clear the session variable.
*/
protected function clearFreeProductsCartItemIds()
{
return $this->facade->getRequest()->getSession()->remove($this->getSessionVarName());
}
/**
* We overload this method here to remove the free products when the
* coupons conditions are no longer met.
*
* @inheritdoc
*/
public function isMatching()
{
$match = parent::isMatching();
if (! $match) {
// Cancel coupon effect (but no not remove the product)
$this->clearFreeProductsCartItemIds();
}
return $match;
}
/**
* @inheritdoc
*/
public function exec()
{
$discount = 0;
$cartItems = $this->facade->getCart()->getCartItems();
/** @var Product $eligibleProduct */
$eligibleProduct = null;
/** @var CartItem $cartItem */
foreach ($cartItems as $cartItem) {
if (in_array($cartItem->getProduct()->getId(), $this->product_list)) {
if (! $cartItem->getPromo() || $this->isAvailableOnSpecialOffers()) {
$eligibleProduct = $cartItem;
break;
}
}
}
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 :
//
// 1) exec() adds a product by firing a CART_ADDITEM event,
// 2) the event is processed by Action\Coupon::updateOrderDiscount(),
// 3) Action\Coupon::updateOrderDiscount() calls CouponManager::getDiscount()
// 4) CouponManager::getDiscount() calls exec() -> Infinite loop !!
// Store a marker first, we do not have the cart item id yet.
$this->setRelatedCartItem($eligibleProduct, self::ADD_TO_CART_IN_PROCESS);
$cartEvent = new CartEvent($this->facade->getCart());
$cartEvent->setNewness(true);
$cartEvent->setAppend(false);
$cartEvent->setQuantity(1);
$cartEvent->setProductSaleElementsId($freeProduct->getDefaultSaleElements()->getId());
$cartEvent->setProduct($this->offeredProductId);
$this->facade->getDispatcher()->dispatch(TheliaEvents::CART_ADDITEM, $cartEvent);
// Store the final cart item ID.
$this->setRelatedCartItem($eligibleProduct, $cartEvent->getCartItem()->getId());
$freeProductCartItem = $cartEvent->getCartItem();
// Setting product price is dangerous, as the customer could change the ordered quantity of this product.
// We will instead add the product price to the order discount.
// $cartEvent->getCartItem()->setPrice(0)->save();
}
}
if ($freeProductCartItem instanceof CartItem) {
$taxCountry = $this->facade->getDeliveryCountry();
// The discount is the product price.
$discount = $freeProductCartItem->getPromo() ?
$freeProductCartItem->getPromoPrice() : $freeProductCartItem->getPrice();
}
}
// No eligible product was found !
else {
// Remove all free products for this coupon, but no not remove the product from the cart.
$this->clearFreeProductsCartItemIds();
}
return $discount;
}
/**
* @inheritdoc
*/
protected function getFieldList()
{
return $this->getBaseFieldList([self::OFFERED_CATEGORY_ID, self::OFFERED_PRODUCT_ID]);
}
/**
* @inheritdoc
*/
protected function checkCouponFieldValue($fieldName, $fieldValue)
{
$this->checkBaseCouponFieldValue($fieldName, $fieldValue);
if ($fieldName === self::OFFERED_PRODUCT_ID) {
if (floatval($fieldValue) < 0) {
throw new \InvalidArgumentException(
Translator::getInstance()->trans(
'Please select the offered product'
)
);
}
} elseif ($fieldName === self::OFFERED_CATEGORY_ID) {
if (empty($fieldValue)) {
throw new \InvalidArgumentException(
Translator::getInstance()->trans(
'Please select the category of the offred product'
)
);
}
}
return $fieldValue;
}
/**
* Get I18n name
*
* @return string
*/
public function getName()
{
return $this->facade
->getTranslator()
->trans('Free product when buying one or more selected products', array(), 'coupon');
}
/**
* @inheritdoc
*/
public function getToolTip()
{
$toolTip = $this->facade
->getTranslator()
->trans(
'This coupon adds a free product to the cart if one of the selected products is in the cart.',
array(),
'coupon'
);
return $toolTip;
}
/**
* @inheritdoc
*/
public function drawBackOfficeInputs()
{
return $this->drawBaseBackOfficeInputs("coupon/type-fragments/free-product.html", [
'offered_category_field_name' => $this->makeCouponFieldName(self::OFFERED_CATEGORY_ID),
'offered_category_value' => $this->offeredCategoryId,
'offered_product_field_name' => $this->makeCouponFieldName(self::OFFERED_PRODUCT_ID),
'offered_product_value' => $this->offeredProductId
]);
}
/**
* @inheritdoc
*/
public function clear()
{
// Clear the session variable when the coupon is cleared.
$this->clearFreeProductsCartItemIds();
}
}

View File

@@ -0,0 +1,92 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\Coupon\Type;
/**
* A trait to manage a coupon which removes a percentage of cart items from the order total.
* Should be used on coupons classes which implements AmountAndPercentageCouponInterface
*
* Class PercentageCouponTrait
* @author Franck Allimant <franck@cqfdev.fr>
* @package Thelia\Coupon\Type
*/
Trait PercentageCouponTrait {
public $percentage = 0;
/**
* Should return the percentage field name, defined in the parent class.
*
* @return string the percentage field name
*/
abstract protected function getPercentageFieldName();
/**
* @inheritdoc
*/
protected function setFieldsValue($effects)
{
$this->percentage = $effects[$this->getPercentageFieldName()];
}
/**
* @inheritdoc
*/
public function getCartItemDiscount($cartItem)
{
return $cartItem->getQuantity() * $cartItem->getPrice() * ($this->percentage / 100);
}
/**
* @inheritdoc
*/
public function callDrawBackOfficeInputs($templateName)
{
return $this->drawBaseBackOfficeInputs($templateName, [
'percentage_field_name' => $this->makeCouponFieldName($this->getPercentageFieldName()),
'percentage_value' => $this->percentage,
]);
}
/**
* @inheritdoc
*/
protected function getFieldList()
{
return $this->getBaseFieldList([$this->getPercentageFieldName()]);
}
/**
* @inheritdoc
*/
protected function checkCouponFieldValue($fieldName, $fieldValue)
{
$this->checkBaseCouponFieldValue($fieldName, $fieldValue);
if ($fieldName === $this->getPercentageFieldName()) {
$pcent = floatval($fieldValue);
if ($pcent <= 0 || $pcent > 100) {
throw new \InvalidArgumentException(
Translator::getInstance()->trans(
'Value %val for Percent Discount is invalid. Please enter a positive value between 1 and 100.',
[ '%val' => $fieldValue]
)
);
}
}
return $fieldValue;
}
}

View File

@@ -0,0 +1,65 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\Coupon\Type;
/**
* Allow to remove an amount from the checkout total
*
* @package Coupon
* @author Franck Allimant <franck@cqfdev.fr>
*/
class RemoveAmountOnAttributeValues extends AbstractRemoveOnAttributeValues
{
use AmountCouponTrait;
/** @var string Service Id */
protected $serviceId = 'thelia.coupon.type.remove_amount_on_attribute_av';
protected function getAmountFieldName()
{
return self::AMOUNT_FIELD_NAME;
}
/**
* @inheritdoc
*/
public function getName()
{
return $this->facade
->getTranslator()
->trans('Fixed amount discount for selected attribute values', array(), 'coupon');
}
/**
* @inheritdoc
*/
public function getToolTip()
{
$toolTip = $this->facade
->getTranslator()
->trans(
'This coupon subtracts the specified amount from the order total for each product which uses the selected attribute values. If the discount is greater than the total order, the customer will only pay the shipping, or nothing if the coupon also provides free shipping.',
array(),
'coupon'
);
return $toolTip;
}
/**
* @inheritdoc
*/
public function drawBackOfficeInputs()
{
return $this->callDrawBackOfficeInputs('coupon/type-fragments/remove-amount-on-attributes.html');
}
}

View File

@@ -12,63 +12,25 @@
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
*
* @package Coupon
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
* @author Franck Allimant <franck@cqfdev.fr>
*/
class RemoveAmountOnCategories extends CouponAbstract
class RemoveAmountOnCategories extends AbstractRemoveOnCategories
{
const CATEGORIES_LIST = 'categories';
use AmountCouponTrait;
/** @var string Service Id */
protected $serviceId = 'thelia.coupon.type.remove_amount_on_categories';
public $category_list = array();
/**
* @inheritdoc
*/
public function set(
FacadeInterface $facade,
$code,
$title,
$shortDescription,
$description,
array $effects,
$isCumulative,
$isRemovingPostage,
$isAvailableOnSpecialOffers,
$isEnabled,
$maxUsage,
\DateTime $expirationDate,
$freeShippingForCountries,
$freeShippingForModules,
$perCustomerUsageCount
)
protected function getAmountFieldName()
{
parent::set(
$facade, $code, $title, $shortDescription, $description, $effects,
$isCumulative, $isRemovingPostage, $isAvailableOnSpecialOffers, $isEnabled, $maxUsage, $expirationDate,
$freeShippingForCountries,
$freeShippingForModules,
$perCustomerUsageCount
);
$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);
return $this;
return self::AMOUNT_FIELD_NAME;
}
/**
/**
* @inheritdoc
*/
public function getName()
@@ -94,89 +56,11 @@ class RemoveAmountOnCategories extends CouponAbstract
return $toolTip;
}
/**
* @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 += $cartItem->getQuantity() * $this->amount;
break;
}
}
}
}
return $discount;
}
/**
* @inheritdoc
*/
public function drawBackOfficeInputs()
{
return $this->facade->getParser()->render('coupon/type-fragments/remove-amount-on-categories.html', [
// The standard "Amount" field
'amount_field_name' => $this->makeCouponFieldName(self::AMOUNT_FIELD_NAME),
'amount_value' => $this->amount,
// The categories list field
'categories_field_name' => $this->makeCouponFieldName(self::CATEGORIES_LIST),
'categories_values' => $this->category_list
]);
return $this->callDrawBackOfficeInputs('coupon/type-fragments/remove-amount-on-categories.html');
}
/**
* @inheritdoc
*/
protected function getFieldList()
{
return [self::AMOUNT_FIELD_NAME, self::CATEGORIES_LIST];
}
/**
* @inheritdoc
*/
protected function checkCouponFieldValue($fieldName, $fieldValue)
{
if ($fieldName === self::AMOUNT_FIELD_NAME) {
if (floatval($fieldValue) < 0) {
throw new \InvalidArgumentException(
Translator::getInstance()->trans(
'Value %val for Discount Amount is invalid. Please enter a positive value.',
[ '%val' => $fieldValue]
)
);
}
} elseif ($fieldName === self::CATEGORIES_LIST) {
if (empty($fieldValue)) {
throw new \InvalidArgumentException(
Translator::getInstance()->trans(
'Please select at least one category'
)
);
}
}
return $fieldValue;
}
}

View File

@@ -12,65 +12,24 @@
namespace Thelia\Coupon\Type;
use Thelia\Core\Translation\Translator;
use Thelia\Coupon\FacadeInterface;
use Thelia\Model\CartItem;
use Thelia\Model\Product;
/**
* Allow to remove an amount from the checkout total
*
* @package Coupon
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
* @author Franck Allimant <franck@cqfdev.fr>
*/
class RemoveAmountOnProducts extends CouponAbstract
class RemoveAmountOnProducts extends AbstractRemoveOnProducts
{
const CATEGORY_ID = 'category_id';
const PRODUCTS_LIST = 'products';
use AmountCouponTrait;
/** @var string Service Id */
protected $serviceId = 'thelia.coupon.type.remove_amount_on_products';
public $category_id = 0;
public $product_list = array();
/**
* @inheritdoc
*/
public function set(
FacadeInterface $facade,
$code,
$title,
$shortDescription,
$description,
array $effects,
$isCumulative,
$isRemovingPostage,
$isAvailableOnSpecialOffers,
$isEnabled,
$maxUsage,
\DateTime $expirationDate,
$freeShippingForCountries,
$freeShippingForModules,
$perCustomerUsageCount
)
protected function getAmountFieldName()
{
parent::set(
$facade, $code, $title, $shortDescription, $description, $effects,
$isCumulative, $isRemovingPostage, $isAvailableOnSpecialOffers, $isEnabled, $maxUsage, $expirationDate,
$freeShippingForCountries,
$freeShippingForModules,
$perCustomerUsageCount
);
$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);
$this->category_id = isset($effects[self::CATEGORY_ID]) ? $effects[self::CATEGORY_ID] : 0;
return $this;
return self::AMOUNT_FIELD_NAME;
}
/**
@@ -101,93 +60,11 @@ class RemoveAmountOnProducts extends CouponAbstract
return $toolTip;
}
/**
* @inheritdoc
*/
public function exec()
{
// This coupon subtracts the specified amount from the order total
// for each product of the selected products.
$discount = 0;
$cartItems = $this->facade->getCart()->getCartItems();
/** @var CartItem $cartItem */
foreach ($cartItems as $cartItem) {
if (in_array($cartItem->getProduct()->getId(), $this->product_list)) {
if (! $cartItem->getPromo() || $this->isAvailableOnSpecialOffers()) {
$discount += $cartItem->getQuantity() * $this->amount;
}
}
}
return $discount;
}
/**
* @inheritdoc
*/
public function drawBackOfficeInputs()
{
return $this->facade->getParser()->render('coupon/type-fragments/remove-amount-on-products.html', [
// The standard "Amount" field
'amount_field_name' => $this->makeCouponFieldName(self::AMOUNT_FIELD_NAME),
'amount_value' => $this->amount,
// The category ID field
'category_id_field_name' => $this->makeCouponFieldName(self::CATEGORY_ID),
'category_id_value' => $this->category_id,
// The products list field
'products_field_name' => $this->makeCouponFieldName(self::PRODUCTS_LIST),
'products_values' => $this->product_list,
'products_values_csv' => implode(', ', $this->product_list)
]);
}
/**
* @inheritdoc
*/
protected function getFieldList()
{
return [self::AMOUNT_FIELD_NAME, self::CATEGORY_ID, self::PRODUCTS_LIST];
}
/**
* @inheritdoc
*/
protected function checkCouponFieldValue($fieldName, $fieldValue)
{
if ($fieldName === self::AMOUNT_FIELD_NAME) {
if (floatval($fieldValue) < 0) {
throw new \InvalidArgumentException(
Translator::getInstance()->trans(
'Value %val for Discount Amount is invalid. Please enter a positive value.',
[ '%val' => $fieldValue]
)
);
}
} elseif ($fieldName === self::CATEGORY_ID) {
if (empty($fieldValue)) {
throw new \InvalidArgumentException(
Translator::getInstance()->trans(
'Please select a category'
)
);
}
} elseif ($fieldName === self::PRODUCTS_LIST) {
if (empty($fieldValue)) {
throw new \InvalidArgumentException(
Translator::getInstance()->trans(
'Please select at least one product'
)
);
}
}
return $fieldValue;
return $this->callDrawBackOfficeInputs('coupon/type-fragments/remove-amount-on-products.html');
}
}

View File

@@ -0,0 +1,71 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\Coupon\Type;
/**
* Allow to remove an amount from the checkout total
*
* @package Coupon
* @author Franck Allimant <franck@cqfdev.fr>
*/
class RemovePercentageOnAttributeValues extends AbstractRemoveOnAttributeValues
{
const PERCENTAGE = 'percentage';
use PercentageCouponTrait;
/** @var string Service Id */
protected $serviceId = 'thelia.coupon.type.remove_percentage_on_attribute_av';
/**
* @inheritdoc
*/
protected function getPercentageFieldName()
{
return self::PERCENTAGE;
}
/**
* @inheritdoc
*/
public function getName()
{
return $this->facade
->getTranslator()
->trans('Percentage discount for selected attribute values', array(), 'coupon');
}
/**
* @inheritdoc
*/
public function getToolTip()
{
$toolTip = $this->facade
->getTranslator()
->trans(
'This coupon subtracts from the order total the specified percentage of each product price which uses the selected attribute values. If the discount is greater than the total order, the customer will only pay the shipping, or nothing if the coupon also provides free shipping.',
array(),
'coupon'
);
return $toolTip;
}
/**
* @inheritdoc
*/
public function drawBackOfficeInputs()
{
return $this->callDrawBackOfficeInputs('coupon/type-fragments/remove-percentage-on-attributes.html');
}
}

View File

@@ -12,61 +12,24 @@
namespace Thelia\Coupon\Type;
use Thelia\Core\Translation\Translator;
use Thelia\Coupon\FacadeInterface;
use Thelia\Model\CartItem;
use Thelia\Model\Category;
/**
* @author Franck Allimant <franck@cqfdev.fr>
*
*/
class RemovePercentageOnCategories extends CouponAbstract
class RemovePercentageOnCategories extends AbstractRemoveOnCategories
{
const CATEGORIES_LIST = 'categories';
const PERCENTAGE = 'percentage';
const PERCENTAGE = 'percentage';
use PercentageCouponTrait;
/** @var string Service Id */
protected $serviceId = 'thelia.coupon.type.remove_percentage_on_categories';
protected $category_list = array();
protected $percentage = 0;
/**
* @inheritdoc
*/
public function set(
FacadeInterface $facade,
$code,
$title,
$shortDescription,
$description,
array $effects,
$isCumulative,
$isRemovingPostage,
$isAvailableOnSpecialOffers,
$isEnabled,
$maxUsage,
\DateTime $expirationDate,
$freeShippingForCountries,
$freeShippingForModules,
$perCustomerUsageCount
)
protected function getPercentageFieldName()
{
parent::set(
$facade, $code, $title, $shortDescription, $description, $effects,
$isCumulative, $isRemovingPostage, $isAvailableOnSpecialOffers, $isEnabled, $maxUsage, $expirationDate,
$freeShippingForCountries,
$freeShippingForModules,
$perCustomerUsageCount
);
$this->category_list = isset($effects[self::CATEGORIES_LIST]) ? $effects[self::CATEGORIES_LIST] : array();
$this->percentage = isset($effects[self::PERCENTAGE]) ? $effects[self::PERCENTAGE] : 0;
if (! is_array($this->category_list)) $this->category_list = array($this->category_list);
return $this;
return self::PERCENTAGE;
}
/**
@@ -95,90 +58,11 @@ class RemovePercentageOnCategories extends CouponAbstract
return $toolTip;
}
/**
* @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 += $cartItem->getPrice() * $this->percentage;
break;
}
}
}
}
return $discount;
}
/**
* @inheritdoc
*/
public function drawBackOfficeInputs()
{
return $this->facade->getParser()->render('coupon/type-fragments/remove-percentage-on-categories.html', [
// The standard "Amount" field
'percentage_field_name' => $this->makeCouponFieldName(self::PERCENTAGE),
'percentage_value' => $this->percentage,
// The categories list field
'categories_field_name' => $this->makeCouponFieldName(self::CATEGORIES_LIST),
'categories_values' => $this->category_list
]);
return $this->callDrawBackOfficeInputs('coupon/type-fragments/remove-percentage-on-categories.html');
}
/**
* @inheritdoc
*/
protected function getFieldList()
{
return [self::PERCENTAGE, self::CATEGORIES_LIST];
}
/**
* @inheritdoc
*/
protected function checkCouponFieldValue($fieldName, $fieldValue)
{
if ($fieldName === self::PERCENTAGE) {
$pcent = floatval($fieldValue);
if ($pcent <= 0 || $pcent > 100) {
throw new \InvalidArgumentException(
Translator::getInstance()->trans(
'Value %val for Percent Discount is invalid. Please enter a positive value between 1 and 100.',
[ '%val' => $fieldValue]
)
);
}
} elseif ($fieldName === self::CATEGORIES_LIST) {
if (empty($fieldValue)) {
throw new \InvalidArgumentException(
Translator::getInstance()->trans(
'Please select at least one category'
)
);
}
}
return $fieldValue;
}
}

View File

@@ -12,69 +12,29 @@
namespace Thelia\Coupon\Type;
use Thelia\Core\Translation\Translator;
use Thelia\Coupon\FacadeInterface;
use Thelia\Model\CartItem;
use Thelia\Model\Product;
/**
* Allow to remove an amount from the checkout total
*
* @package Coupon
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
* @author Franck Allimant <franck@cqfdev.fr>
*/
class RemovePercentageOnProducts extends CouponAbstract
class RemovePercentageOnProducts extends AbstractRemoveOnProducts
{
const CATEGORY_ID = 'category_id';
const PRODUCTS_LIST = 'products';
const PERCENTAGE = 'percentage';
const PERCENTAGE = 'percentage';
use PercentageCouponTrait;
/** @var string Service Id */
protected $serviceId = 'thelia.coupon.type.remove_percentage_on_products';
public $category_id = 0;
public $product_list = array();
public $percentage = 0;
/**
* @inheritdoc
*/
public function set(
FacadeInterface $facade,
$code,
$title,
$shortDescription,
$description,
array $effects,
$isCumulative,
$isRemovingPostage,
$isAvailableOnSpecialOffers,
$isEnabled,
$maxUsage,
\DateTime $expirationDate,
$freeShippingForCountries,
$freeShippingForModules,
$perCustomerUsageCount
)
protected function getPercentageFieldName()
{
parent::set(
$facade, $code, $title, $shortDescription, $description, $effects,
$isCumulative, $isRemovingPostage, $isAvailableOnSpecialOffers, $isEnabled, $maxUsage, $expirationDate,
$freeShippingForCountries,
$freeShippingForModules,
$perCustomerUsageCount
);
$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);
$this->category_id = isset($effects[self::CATEGORY_ID]) ? $effects[self::CATEGORY_ID] : 0;
$this->percentage = $effects[self::PERCENTAGE];
return $this;
return self::PERCENTAGE;
}
/**
@@ -105,94 +65,11 @@ class RemovePercentageOnProducts extends CouponAbstract
return $toolTip;
}
/**
* @inheritdoc
*/
public function exec()
{
// This coupon subtracts the specified amount from the order total
// for each product of the selected products.
$discount = 0;
$cartItems = $this->facade->getCart()->getCartItems();
/** @var CartItem $cartItem */
foreach ($cartItems as $cartItem) {
if (in_array($cartItem->getProduct()->getId(), $this->product_list)) {
if (! $cartItem->getPromo() || $this->isAvailableOnSpecialOffers()) {
$discount += $cartItem->getQuantity() * $cartItem->getPrice() * $this->percentage;
}
}
}
return $discount;
}
/**
* @inheritdoc
*/
public function drawBackOfficeInputs()
{
return $this->facade->getParser()->render('coupon/type-fragments/remove-percentage-on-products.html', [
// The standard "Amount" field
'percentage_field_name' => $this->makeCouponFieldName(self::PERCENTAGE),
'percentage_value' => $this->percentage,
// The category ID field
'category_id_field_name' => $this->makeCouponFieldName(self::CATEGORY_ID),
'category_id_value' => $this->category_id,
// The products list field
'products_field_name' => $this->makeCouponFieldName(self::PRODUCTS_LIST),
'products_values' => $this->product_list,
'products_values_csv' => implode(', ', $this->product_list)
]);
}
/**
* @inheritdoc
*/
protected function getFieldList()
{
return [self::PERCENTAGE, self::CATEGORY_ID, self::PRODUCTS_LIST];
}
/**
* @inheritdoc
*/
protected function checkCouponFieldValue($fieldName, $fieldValue)
{
if ($fieldName === self::PERCENTAGE) {
$pcent = floatval($fieldValue);
if ($pcent <= 0 || $pcent > 100) {
throw new \InvalidArgumentException(
Translator::getInstance()->trans(
'Value %val for Percent Discount is invalid. Please enter a positive value between 1 and 100.',
[ '%val' => $fieldValue]
)
);
}
} elseif ($fieldName === self::CATEGORY_ID) {
if (empty($fieldValue)) {
throw new \InvalidArgumentException(
Translator::getInstance()->trans(
'Please select a category'
)
);
}
} elseif ($fieldName === self::PRODUCTS_LIST) {
if (empty($fieldValue)) {
throw new \InvalidArgumentException(
Translator::getInstance()->trans(
'Please select at least one product'
)
);
}
}
return $fieldValue;
return $this->callDrawBackOfficeInputs('coupon/type-fragments/remove-percentage-on-products.html');
}
}

View File

@@ -12,20 +12,25 @@
namespace Thelia\Coupon\Type;
use Thelia\Core\Translation\Translator;
/**
* Allow to remove an amount from the checkout total
*
* @package Coupon
* @author Guillaume MOREL <gmorel@openstudio.fr>
* @author Guillaume MOREL <gmorel@openstudio.fr>, Franck Allimant <franck@cqfdev.fr>
*
*/
class RemoveXAmount extends CouponAbstract
class RemoveXAmount extends AbstractRemove
{
use AmountCouponTrait;
/** @var string Service Id */
protected $serviceId = 'thelia.coupon.type.remove_x_amount';
protected function getAmountFieldName()
{
return self::AMOUNT_FIELD_NAME;
}
/**
* @inheritdoc
*/
@@ -52,43 +57,19 @@ class RemoveXAmount extends CouponAbstract
return $toolTip;
}
/**
* @inheritdoc
*/
public function exec()
{
return $this->amount;
}
/**
* @inheritdoc
*/
public function drawBackOfficeInputs()
{
return $this->facade->getParser()->render('coupon/type-fragments/remove-x-amount.html', [
'fieldName' => $this->makeCouponFieldName(self::AMOUNT_FIELD_NAME),
'value' => $this->amount
]);
return $this->callDrawBackOfficeInputs('coupon/type-fragments/remove-x-amount.html');
}
/**
* @inheritdoc
*/
protected function getFieldList()
{
return [self::AMOUNT_FIELD_NAME];
}
/**
* @inheritdoc
*/
protected function checkCouponFieldValue($fieldName, $fieldValue)
{
if ($fieldName === self::AMOUNT_FIELD_NAME) {
if (floatval($fieldValue) < 0) {
throw new \InvalidArgumentException(
Translator::getInstance()->trans(
'Value %val for Disount Amount is invalid. Please enter a positive value.',
[ '%val' => $fieldValue]
)
);
}
}
return $fieldValue;
}
}

View File

@@ -12,86 +12,26 @@
namespace Thelia\Coupon\Type;
use Thelia\Core\Translation\Translator;
use Thelia\Coupon\FacadeInterface;
/**
* @package Coupon
* @author Guillaume MOREL <gmorel@openstudio.fr>
* @author Guillaume MOREL <gmorel@openstudio.fr>, Franck Allimant <franck@cqfdev.fr>
*
*/
class RemoveXPercent extends CouponAbstract
class RemoveXPercent extends AbstractRemove
{
const INPUT_PERCENTAGE_NAME = 'percentage';
use PercentageCouponTrait;
/** @var string Service Id */
protected $serviceId = 'thelia.coupon.type.remove_x_percent';
/** @var float Percentage removed from the Cart */
protected $percentage = 0;
/**
* @inheritdoc
*/
public function set(
FacadeInterface $facade,
$code,
$title,
$shortDescription,
$description,
array $effects,
$isCumulative,
$isRemovingPostage,
$isAvailableOnSpecialOffers,
$isEnabled,
$maxUsage,
\DateTime $expirationDate,
$freeShippingForCountries,
$freeShippingForModules,
$perCustomerUsageCount
)
protected function getPercentageFieldName()
{
parent::set(
$facade, $code, $title, $shortDescription, $description, $effects,
$isCumulative, $isRemovingPostage, $isAvailableOnSpecialOffers, $isEnabled, $maxUsage, $expirationDate,
$freeShippingForCountries,
$freeShippingForModules,
$perCustomerUsageCount
);
$this->percentage = $effects[self::INPUT_PERCENTAGE_NAME];
return $this;
}
/**
* @inheritdoc
*/
public function exec()
{
return round($this->facade->getCartTotalTaxPrice($this->isAvailableOnSpecialOffers()) * $this->percentage/100, 2);
}
/**
* @inheritdoc
*/
protected function checkCouponFieldValue($fieldName, $fieldValue)
{
if ($fieldName === self::INPUT_PERCENTAGE_NAME) {
$pcent = floatval($fieldValue);
if ($pcent <= 0 || $pcent > 100) {
throw new \InvalidArgumentException(
Translator::getInstance()->trans(
'Value %val for Percent Discount is invalid. Please enter a positive value between 1 and 100.',
[ '%val' => $fieldValue]
)
);
}
}
return $fieldValue;
return self::INPUT_PERCENTAGE_NAME;
}
/**
@@ -123,19 +63,16 @@ class RemoveXPercent extends CouponAbstract
/**
* @inheritdoc
*/
public function drawBackOfficeInputs()
public function exec()
{
return $this->facade->getParser()->render('coupon/type-fragments/remove-x-percent.html', [
'fieldName' => $this->makeCouponFieldName(self::INPUT_PERCENTAGE_NAME),
'value' => $this->percentage
]);
return round($this->facade->getCartTotalTaxPrice($this->isAvailableOnSpecialOffers()) * $this->percentage/100, 2);
}
/**
* @inheritdoc
*/
protected function getFieldList()
public function drawBackOfficeInputs()
{
return [self::INPUT_PERCENTAGE_NAME];
return $this->callDrawBackOfficeInputs('coupon/type-fragments/remove-x-percent.html');
}
}

View File

@@ -41,6 +41,9 @@ use Thelia\Model\Tools\ModelEventDispatcherTrait;
class Coupon extends BaseCoupon
{
// Define the value of an unlimited coupon usage.
const UNLIMITED_COUPON_USE = -1;
use ModelEventDispatcherTrait;
/**
@@ -265,6 +268,10 @@ class Coupon extends BaseCoupon
return CouponModuleQuery::create()->filterByCouponId($this->getId())->find();
}
public function isUsageUnlimited()
{
return $this->getMaxUsage() == self::UNLIMITED_COUPON_USE;
}
/**
* Get coupon usage left, either overall, or per customer.
*

View File

@@ -61,7 +61,7 @@ class Product extends BaseProduct
*/
public function getDefaultSaleElements()
{
return ProductSaleElementsQuery::create()->filterByProductId($this->id)->filterByIsDefault(true)->find();
return ProductSaleElementsQuery::create()->filterByProductId($this->id)->filterByIsDefault(true)->findOne();
}
/**

View File

@@ -0,0 +1,365 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\Condition\Implementation;
use Thelia\Condition\ConditionEvaluator;
use Thelia\Condition\Operators;
use Thelia\Condition\SerializableCondition;
use Thelia\Coupon\FacadeInterface;
use Thelia\Model\Category;
use Thelia\Model\Product;
/**
* @package Coupon
* @author Franck Allimant <franck@cqfdev.fr>
*/
class CartContainsCategoriesTest extends \PHPUnit_Framework_TestCase
{
/**
* Sets up the fixture, for example, opens a network connection.
* This method is called before a test is executed.
*/
protected function setUp()
{
}
/**
* Generate adapter stub
*
* @param int $cartTotalPrice Cart total price
* @param string $checkoutCurrency Checkout currency
* @param string $i18nOutput Output from each translation
*
* @return \PHPUnit_Framework_MockObject_MockObject
*/
public function generateFacadeStub($cartTotalPrice = 400, $checkoutCurrency = 'EUR', $i18nOutput = '')
{
$stubFacade = $this->getMockBuilder('\Thelia\Coupon\BaseFacade')
->disableOriginalConstructor()
->getMock();
$stubFacade->expects($this->any())
->method('getCartTotalPrice')
->will($this->returnValue($cartTotalPrice));
$stubFacade->expects($this->any())
->method('getCheckoutCurrency')
->will($this->returnValue($checkoutCurrency));
$stubFacade->expects($this->any())
->method('getConditionEvaluator')
->will($this->returnValue(new ConditionEvaluator()));
$stubTranslator = $this->getMockBuilder('\Thelia\Core\Translation\Translator')
->disableOriginalConstructor()
->getMock();
$stubTranslator->expects($this->any())
->method('trans')
->will($this->returnValue($i18nOutput));
$stubFacade->expects($this->any())
->method('getTranslator')
->will($this->returnValue($stubTranslator));
$category1 = new Category();
$category1->setId(10);
$category2 = new Category();
$category2->setId(20);
$category3 = new Category();
$category3->setId(30);
$product1 = new Product();
$product1->addCategory($category1)->addCategory($category2);
$product2 = new Product();
$product2->addCategory($category3);
$cartItem1Stub = $this->getMockBuilder('\Thelia\Model\CartItem')
->disableOriginalConstructor()
->getMock();
$cartItem1Stub
->expects($this->any())
->method('getProduct')
->will($this->returnValue($product1))
;
$cartItem1Stub
->expects($this->any())
->method('getQuantity')
->will($this->returnValue(1))
;
$cartItem2Stub = $this->getMockBuilder('\Thelia\Model\CartItem')
->disableOriginalConstructor()
->getMock();
$cartItem2Stub
->expects($this->any())
->method('getProduct')
->will($this->returnValue($product2));
$cartItem2Stub
->expects($this->any())
->method('getQuantity')
->will($this->returnValue(2))
;
$cartStub = $this->getMockBuilder('\Thelia\Model\Cart')
->disableOriginalConstructor()
->getMock();
$cartStub
->expects($this->any())
->method('getCartItems')
->will($this->returnValue([$cartItem1Stub, $cartItem2Stub]));
$stubFacade->expects($this->any())
->method('getCart')
->will($this->returnValue($cartStub));
return $stubFacade;
}
/**
* Check if validity test on BackOffice inputs are working
*
* @covers Thelia\Condition\Implementation\CartContainsCategories::setValidators
* @expectedException \Thelia\Exception\InvalidConditionOperatorException
*/
public function testInValidBackOfficeInputOperator()
{
/** @var FacadeInterface $stubFacade */
$stubFacade = $this->generateFacadeStub();
$condition1 = new CartContainsCategories($stubFacade);
$operators = array(
CartContainsCategories::CATEGORIES_LIST => Operators::INFERIOR_OR_EQUAL
);
$values = array(
CartContainsCategories::CATEGORIES_LIST => array()
);
$condition1->setValidatorsFromForm($operators, $values);
$isValid = $condition1->isMatching();
$expected = true;
$actual =$isValid;
$this->assertEquals($expected, $actual);
}
/**
* Check if validity test on BackOffice inputs are working
*
* @covers Thelia\Condition\Implementation\CartContainsCategories::setValidators
* @expectedException \Thelia\Exception\InvalidConditionValueException
*/
public function testInValidBackOfficeInputValue()
{
/** @var FacadeInterface $stubFacade */
$stubFacade = $this->generateFacadeStub();
$condition1 = new CartContainsCategories($stubFacade);
$operators = array(
CartContainsCategories::CATEGORIES_LIST => Operators::IN
);
$values = array(
CartContainsCategories::CATEGORIES_LIST => array()
);
$condition1->setValidatorsFromForm($operators, $values);
}
/**
* Check if test inferior operator is working
*
* @covers Thelia\Condition\Implementation\CartContainsCategories::isMatching
*
*/
public function testMatchingRule()
{
/** @var FacadeInterface $stubFacade */
$stubFacade = $this->generateFacadeStub();
$condition1 = new CartContainsCategories($stubFacade);
$operators = array(
CartContainsCategories::CATEGORIES_LIST => Operators::IN
);
$values = array(
CartContainsCategories::CATEGORIES_LIST => array(10, 20)
);
$condition1->setValidatorsFromForm($operators, $values);
$isValid = $condition1->isMatching();
$expected = true;
$actual =$isValid;
$this->assertEquals($expected, $actual);
}
/**
* Check if test inferior operator is working
*
* @covers Thelia\Condition\Implementation\CartContainsCategories::isMatching
*
*/
public function testNotMatching()
{
/** @var FacadeInterface $stubFacade */
$stubFacade = $this->generateFacadeStub();
$condition1 = new CartContainsCategories($stubFacade);
$operators = array(
CartContainsCategories::CATEGORIES_LIST => Operators::IN
);
$values = array(
CartContainsCategories::CATEGORIES_LIST => array(50, 60)
);
$condition1->setValidatorsFromForm($operators, $values);
$isValid = $condition1->isMatching();
$expected = false;
$actual =$isValid;
$this->assertEquals($expected, $actual);
}
public function testGetSerializableRule()
{
/** @var FacadeInterface $stubFacade */
$stubFacade = $this->generateFacadeStub();
$condition1 = new CartContainsCategories($stubFacade);
$operators = array(
CartContainsCategories::CATEGORIES_LIST => Operators::IN
);
$values = array(
CartContainsCategories::CATEGORIES_LIST => array(50, 60)
);
$condition1->setValidatorsFromForm($operators, $values);
$serializableRule = $condition1->getSerializableCondition();
$expected = new SerializableCondition();
$expected->conditionServiceId = $condition1->getServiceId();
$expected->operators = $operators;
$expected->values = $values;
$actual = $serializableRule;
$this->assertEquals($expected, $actual);
}
/**
* Check getName i18n
*
* @covers Thelia\Condition\Implementation\CartContainsCategories::getName
*
*/
public function testGetName()
{
$stubFacade = $this->generateFacadeStub(399, 'EUR', 'Number of articles in cart');
/** @var FacadeInterface $stubFacade */
$condition1 = new CartContainsCategories($stubFacade);
$actual = $condition1->getName();
$expected = 'Number of articles in cart';
$this->assertEquals($expected, $actual);
}
/**
* Check tooltip i18n
*
* @covers Thelia\Condition\Implementation\CartContainsCategories::getToolTip
*
*/
public function testGetToolTip()
{
$stubFacade = $this->generateFacadeStub(399, 'EUR', 'Sample coupon condition');
/** @var FacadeInterface $stubFacade */
$condition1 = new CartContainsCategories($stubFacade);
$actual = $condition1->getToolTip();
$expected = 'Sample coupon condition';
$this->assertEquals($expected, $actual);
}
/**
* Check validator
*
* @covers Thelia\Condition\Implementation\CartContainsCategories::generateInputs
*
*/
public function testGetValidator()
{
$stubFacade = $this->generateFacadeStub(399, 'EUR', 'Price');
/** @var FacadeInterface $stubFacade */
$condition1 = new CartContainsCategories($stubFacade);
$operators = array(
CartContainsCategories::CATEGORIES_LIST => Operators::IN
);
$values = array(
CartContainsCategories::CATEGORIES_LIST => array(50, 60)
);
$condition1->setValidatorsFromForm($operators, $values);
$actual = $condition1->getValidators();
$validators = array(
'inputs' => array(
CartContainsCategories::CATEGORIES_LIST => array(
'availableOperators' => array(
'in' => 'Price',
'out' => 'Price',
),
'value' => '',
'selectedOperator' => 'in'
)
),
'setOperators' => array(
'categories' => 'in'
),
'setValues' => array(
'categories' => array(50, 60)
)
);
$expected = $validators;
$this->assertEquals($expected, $actual);
}
/**
* Tears down the fixture, for example, closes a network connection.
* This method is called after a test is executed.
*/
protected function tearDown()
{
}
}

View File

@@ -0,0 +1,365 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\Condition\Implementation;
use Thelia\Condition\ConditionEvaluator;
use Thelia\Condition\Operators;
use Thelia\Condition\SerializableCondition;
use Thelia\Coupon\FacadeInterface;
use Thelia\Model\Category;
use Thelia\Model\Product;
/**
* @package Coupon
* @author Franck Allimant <franck@cqfdev.fr>
*/
class CartContainsProductsTest extends \PHPUnit_Framework_TestCase
{
/**
* Sets up the fixture, for example, opens a network connection.
* This method is called before a test is executed.
*/
protected function setUp()
{
}
/**
* Generate adapter stub
*
* @param int $cartTotalPrice Cart total price
* @param string $checkoutCurrency Checkout currency
* @param string $i18nOutput Output from each translation
*
* @return \PHPUnit_Framework_MockObject_MockObject
*/
public function generateFacadeStub($cartTotalPrice = 400, $checkoutCurrency = 'EUR', $i18nOutput = '')
{
$stubFacade = $this->getMockBuilder('\Thelia\Coupon\BaseFacade')
->disableOriginalConstructor()
->getMock();
$stubFacade->expects($this->any())
->method('getCartTotalPrice')
->will($this->returnValue($cartTotalPrice));
$stubFacade->expects($this->any())
->method('getCheckoutCurrency')
->will($this->returnValue($checkoutCurrency));
$stubFacade->expects($this->any())
->method('getConditionEvaluator')
->will($this->returnValue(new ConditionEvaluator()));
$stubTranslator = $this->getMockBuilder('\Thelia\Core\Translation\Translator')
->disableOriginalConstructor()
->getMock();
$stubTranslator->expects($this->any())
->method('trans')
->will($this->returnValue($i18nOutput));
$stubFacade->expects($this->any())
->method('getTranslator')
->will($this->returnValue($stubTranslator));
$category1 = new Category();
$category1->setId(10);
$category2 = new Category();
$category2->setId(20);
$category3 = new Category();
$category3->setId(30);
$product1 = new Product();
$product1->setId(10)->addCategory($category1)->addCategory($category2);
$product2 = new Product();
$product2->setId(20)->addCategory($category3);
$cartItem1Stub = $this->getMockBuilder('\Thelia\Model\CartItem')
->disableOriginalConstructor()
->getMock();
$cartItem1Stub
->expects($this->any())
->method('getProduct')
->will($this->returnValue($product1))
;
$cartItem1Stub
->expects($this->any())
->method('getQuantity')
->will($this->returnValue(1))
;
$cartItem2Stub = $this->getMockBuilder('\Thelia\Model\CartItem')
->disableOriginalConstructor()
->getMock();
$cartItem2Stub
->expects($this->any())
->method('getProduct')
->will($this->returnValue($product2));
$cartItem2Stub
->expects($this->any())
->method('getQuantity')
->will($this->returnValue(2))
;
$cartStub = $this->getMockBuilder('\Thelia\Model\Cart')
->disableOriginalConstructor()
->getMock();
$cartStub
->expects($this->any())
->method('getCartItems')
->will($this->returnValue([$cartItem1Stub, $cartItem2Stub]));
$stubFacade->expects($this->any())
->method('getCart')
->will($this->returnValue($cartStub));
return $stubFacade;
}
/**
* Check if validity test on BackOffice inputs are working
*
* @covers Thelia\Condition\Implementation\CartContainsProducts::setValidators
* @expectedException \Thelia\Exception\InvalidConditionOperatorException
*/
public function testInValidBackOfficeInputOperator()
{
/** @var FacadeInterface $stubFacade */
$stubFacade = $this->generateFacadeStub();
$condition1 = new CartContainsProducts($stubFacade);
$operators = array(
CartContainsProducts::PRODUCTS_LIST => Operators::INFERIOR_OR_EQUAL
);
$values = array(
CartContainsProducts::PRODUCTS_LIST => array()
);
$condition1->setValidatorsFromForm($operators, $values);
$isValid = $condition1->isMatching();
$expected = true;
$actual =$isValid;
$this->assertEquals($expected, $actual);
}
/**
* Check if validity test on BackOffice inputs are working
*
* @covers Thelia\Condition\Implementation\CartContainsProducts::setValidators
* @expectedException \Thelia\Exception\InvalidConditionValueException
*/
public function testInValidBackOfficeInputValue()
{
/** @var FacadeInterface $stubFacade */
$stubFacade = $this->generateFacadeStub();
$condition1 = new CartContainsProducts($stubFacade);
$operators = array(
CartContainsProducts::PRODUCTS_LIST => Operators::IN
);
$values = array(
CartContainsProducts::PRODUCTS_LIST => array()
);
$condition1->setValidatorsFromForm($operators, $values);
}
/**
* Check if test inferior operator is working
*
* @covers Thelia\Condition\Implementation\CartContainsProducts::isMatching
*
*/
public function testMatchingRule()
{
/** @var FacadeInterface $stubFacade */
$stubFacade = $this->generateFacadeStub();
$condition1 = new CartContainsProducts($stubFacade);
$operators = array(
CartContainsProducts::PRODUCTS_LIST => Operators::IN
);
$values = array(
CartContainsProducts::PRODUCTS_LIST => array(10, 20)
);
$condition1->setValidatorsFromForm($operators, $values);
$isValid = $condition1->isMatching();
$expected = true;
$actual =$isValid;
$this->assertEquals($expected, $actual);
}
/**
* Check if test inferior operator is working
*
* @covers Thelia\Condition\Implementation\CartContainsProducts::isMatching
*
*/
public function testNotMatching()
{
/** @var FacadeInterface $stubFacade */
$stubFacade = $this->generateFacadeStub();
$condition1 = new CartContainsProducts($stubFacade);
$operators = array(
CartContainsProducts::PRODUCTS_LIST => Operators::IN
);
$values = array(
CartContainsProducts::PRODUCTS_LIST => array(50, 60)
);
$condition1->setValidatorsFromForm($operators, $values);
$isValid = $condition1->isMatching();
$expected = false;
$actual =$isValid;
$this->assertEquals($expected, $actual);
}
public function testGetSerializableRule()
{
/** @var FacadeInterface $stubFacade */
$stubFacade = $this->generateFacadeStub();
$condition1 = new CartContainsProducts($stubFacade);
$operators = array(
CartContainsProducts::PRODUCTS_LIST => Operators::IN
);
$values = array(
CartContainsProducts::PRODUCTS_LIST => array(50, 60)
);
$condition1->setValidatorsFromForm($operators, $values);
$serializableRule = $condition1->getSerializableCondition();
$expected = new SerializableCondition();
$expected->conditionServiceId = $condition1->getServiceId();
$expected->operators = $operators;
$expected->values = $values;
$actual = $serializableRule;
$this->assertEquals($expected, $actual);
}
/**
* Check getName i18n
*
* @covers Thelia\Condition\Implementation\CartContainsProducts::getName
*
*/
public function testGetName()
{
$stubFacade = $this->generateFacadeStub(399, 'EUR', 'Number of articles in cart');
/** @var FacadeInterface $stubFacade */
$condition1 = new CartContainsProducts($stubFacade);
$actual = $condition1->getName();
$expected = 'Number of articles in cart';
$this->assertEquals($expected, $actual);
}
/**
* Check tooltip i18n
*
* @covers Thelia\Condition\Implementation\CartContainsProducts::getToolTip
*
*/
public function testGetToolTip()
{
$stubFacade = $this->generateFacadeStub(399, 'EUR', 'Sample coupon condition');
/** @var FacadeInterface $stubFacade */
$condition1 = new CartContainsProducts($stubFacade);
$actual = $condition1->getToolTip();
$expected = 'Sample coupon condition';
$this->assertEquals($expected, $actual);
}
/**
* Check validator
*
* @covers Thelia\Condition\Implementation\CartContainsProducts::generateInputs
*
*/
public function testGetValidator()
{
$stubFacade = $this->generateFacadeStub(399, 'EUR', 'Price');
/** @var FacadeInterface $stubFacade */
$condition1 = new CartContainsProducts($stubFacade);
$operators = array(
CartContainsProducts::PRODUCTS_LIST => Operators::IN
);
$values = array(
CartContainsProducts::PRODUCTS_LIST => array(50, 60)
);
$condition1->setValidatorsFromForm($operators, $values);
$actual = $condition1->getValidators();
$validators = array(
'inputs' => array(
CartContainsProducts::PRODUCTS_LIST => array(
'availableOperators' => array(
'in' => 'Price',
'out' => 'Price',
),
'value' => '',
'selectedOperator' => 'in'
)
),
'setOperators' => array(
'products' => 'in'
),
'setValues' => array(
'products' => array(50, 60)
)
);
$expected = $validators;
$this->assertEquals($expected, $actual);
}
/**
* Tears down the fixture, for example, closes a network connection.
* This method is called after a test is executed.
*/
protected function tearDown()
{
}
}

View File

@@ -0,0 +1,304 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\Condition\Implementation;
use Thelia\Condition\ConditionEvaluator;
use Thelia\Condition\Operators;
use Thelia\Condition\SerializableCondition;
use Thelia\Coupon\FacadeInterface;
use Thelia\Model\Customer;
/**
* @package Coupon
* @author Franck Allimant <franck@cqfdev.fr>
*/
class ForSomeCustomersTest extends \PHPUnit_Framework_TestCase
{
/**
* Sets up the fixture, for example, opens a network connection.
* This method is called before a test is executed.
*/
protected function setUp()
{
}
/**
* Generate adapter stub
*
* @param int $cartTotalPrice Cart total price
* @param string $checkoutCurrency Checkout currency
* @param string $i18nOutput Output from each translation
*
* @return \PHPUnit_Framework_MockObject_MockObject
*/
public function generateFacadeStub($cartTotalPrice = 400, $checkoutCurrency = 'EUR', $i18nOutput = '')
{
$stubFacade = $this->getMockBuilder('\Thelia\Coupon\BaseFacade')
->disableOriginalConstructor()
->getMock();
$customer = new Customer();
$customer->setId(10);
$stubFacade->expects($this->any())
->method('getCustomer')
->will($this->returnValue($customer));
$stubFacade->expects($this->any())
->method('getConditionEvaluator')
->will($this->returnValue(new ConditionEvaluator()));
$stubTranslator = $this->getMockBuilder('\Thelia\Core\Translation\Translator')
->disableOriginalConstructor()
->getMock();
$stubTranslator->expects($this->any())
->method('trans')
->will($this->returnValue($i18nOutput));
$stubFacade->expects($this->any())
->method('getTranslator')
->will($this->returnValue($stubTranslator));
return $stubFacade;
}
/**
* Check if validity test on BackOffice inputs are working
*
* @covers Thelia\Condition\Implementation\ForSomeCustomers::setValidators
* @expectedException \Thelia\Exception\InvalidConditionOperatorException
*/
public function testInValidBackOfficeInputOperator()
{
/** @var FacadeInterface $stubFacade */
$stubFacade = $this->generateFacadeStub();
$condition1 = new ForSomeCustomers($stubFacade);
$operators = array(
ForSomeCustomers::CUSTOMERS_LIST => Operators::INFERIOR_OR_EQUAL
);
$values = array(
ForSomeCustomers::CUSTOMERS_LIST => array()
);
$condition1->setValidatorsFromForm($operators, $values);
$isValid = $condition1->isMatching();
$expected = true;
$actual =$isValid;
$this->assertEquals($expected, $actual);
}
/**
* Check if validity test on BackOffice inputs are working
*
* @covers Thelia\Condition\Implementation\ForSomeCustomers::setValidators
* @expectedException \Thelia\Exception\InvalidConditionValueException
*/
public function testInValidBackOfficeInputValue()
{
/** @var FacadeInterface $stubFacade */
$stubFacade = $this->generateFacadeStub();
$condition1 = new ForSomeCustomers($stubFacade);
$operators = array(
ForSomeCustomers::CUSTOMERS_LIST => Operators::IN
);
$values = array(
ForSomeCustomers::CUSTOMERS_LIST => array()
);
$condition1->setValidatorsFromForm($operators, $values);
}
/**
* Check if test inferior operator is working
*
* @covers Thelia\Condition\Implementation\ForSomeCustomers::isMatching
*
*/
public function testMatchingRule()
{
/** @var FacadeInterface $stubFacade */
$stubFacade = $this->generateFacadeStub();
$condition1 = new ForSomeCustomers($stubFacade);
$operators = array(
ForSomeCustomers::CUSTOMERS_LIST => Operators::IN
);
$values = array(
ForSomeCustomers::CUSTOMERS_LIST => array(10, 20)
);
$condition1->setValidatorsFromForm($operators, $values);
$isValid = $condition1->isMatching();
$expected = true;
$actual =$isValid;
$this->assertEquals($expected, $actual);
}
/**
* Check if test inferior operator is working
*
* @covers Thelia\Condition\Implementation\ForSomeCustomers::isMatching
*
*/
public function testNotMatching()
{
/** @var FacadeInterface $stubFacade */
$stubFacade = $this->generateFacadeStub();
$condition1 = new ForSomeCustomers($stubFacade);
$operators = array(
ForSomeCustomers::CUSTOMERS_LIST => Operators::IN
);
$values = array(
ForSomeCustomers::CUSTOMERS_LIST => array(50, 60)
);
$condition1->setValidatorsFromForm($operators, $values);
$isValid = $condition1->isMatching();
$expected = false;
$actual =$isValid;
$this->assertEquals($expected, $actual);
}
public function testGetSerializableRule()
{
/** @var FacadeInterface $stubFacade */
$stubFacade = $this->generateFacadeStub();
$condition1 = new ForSomeCustomers($stubFacade);
$operators = array(
ForSomeCustomers::CUSTOMERS_LIST => Operators::IN
);
$values = array(
ForSomeCustomers::CUSTOMERS_LIST => array(50, 60)
);
$condition1->setValidatorsFromForm($operators, $values);
$serializableRule = $condition1->getSerializableCondition();
$expected = new SerializableCondition();
$expected->conditionServiceId = $condition1->getServiceId();
$expected->operators = $operators;
$expected->values = $values;
$actual = $serializableRule;
$this->assertEquals($expected, $actual);
}
/**
* Check getName i18n
*
* @covers Thelia\Condition\Implementation\ForSomeCustomers::getName
*
*/
public function testGetName()
{
$stubFacade = $this->generateFacadeStub(399, 'EUR', 'Number of articles in cart');
/** @var FacadeInterface $stubFacade */
$condition1 = new ForSomeCustomers($stubFacade);
$actual = $condition1->getName();
$expected = 'Number of articles in cart';
$this->assertEquals($expected, $actual);
}
/**
* Check tooltip i18n
*
* @covers Thelia\Condition\Implementation\ForSomeCustomers::getToolTip
*
*/
public function testGetToolTip()
{
$stubFacade = $this->generateFacadeStub(399, 'EUR', 'Sample coupon condition');
/** @var FacadeInterface $stubFacade */
$condition1 = new ForSomeCustomers($stubFacade);
$actual = $condition1->getToolTip();
$expected = 'Sample coupon condition';
$this->assertEquals($expected, $actual);
}
/**
* Check validator
*
* @covers Thelia\Condition\Implementation\ForSomeCustomers::generateInputs
*
*/
public function testGetValidator()
{
$stubFacade = $this->generateFacadeStub(399, 'EUR', 'Price');
/** @var FacadeInterface $stubFacade */
$condition1 = new ForSomeCustomers($stubFacade);
$operators = array(
ForSomeCustomers::CUSTOMERS_LIST => Operators::IN
);
$values = array(
ForSomeCustomers::CUSTOMERS_LIST => array(50, 60)
);
$condition1->setValidatorsFromForm($operators, $values);
$actual = $condition1->getValidators();
$validators = array(
'inputs' => array(
ForSomeCustomers::CUSTOMERS_LIST => array(
'availableOperators' => array(
'in' => 'Price',
'out' => 'Price',
),
'value' => '',
'selectedOperator' => 'in'
)
),
'setOperators' => array(
'customers' => 'in'
),
'setValues' => array(
'customers' => array(50, 60)
)
);
$expected = $validators;
$this->assertEquals($expected, $actual);
}
/**
* Tears down the fixture, for example, closes a network connection.
* This method is called after a test is executed.
*/
protected function tearDown()
{
}
}

View File

@@ -0,0 +1,312 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\Condition\Implementation;
use Thelia\Condition\ConditionEvaluator;
use Thelia\Condition\Operators;
use Thelia\Condition\SerializableCondition;
use Thelia\Coupon\FacadeInterface;
use Thelia\Model\Address;
/**
* @package Coupon
* @author Franck Allimant <franck@cqfdev.fr>
*/
class MatchBillingCountriesTest extends \PHPUnit_Framework_TestCase
{
/**
* Sets up the fixture, for example, opens a network connection.
* This method is called before a test is executed.
*/
protected function setUp()
{
}
/**
* Generate adapter stub
*
* @param int $cartTotalPrice Cart total price
* @param string $checkoutCurrency Checkout currency
* @param string $i18nOutput Output from each translation
*
* @return \PHPUnit_Framework_MockObject_MockObject
*/
public function generateFacadeStub($cartTotalPrice = 400, $checkoutCurrency = 'EUR', $i18nOutput = '')
{
$stubFacade = $this->getMockBuilder('\Thelia\Coupon\BaseFacade')
->disableOriginalConstructor()
->getMock();
$address = new Address();
$address->setCountryId(10);
$stubCustomer = $this->getMockBuilder('\Thelia\Model\Customer')
->disableOriginalConstructor()
->getMock();
$stubCustomer->expects($this->any())
->method('getDefaultAddress')
->will($this->returnValue($address));
$stubFacade->expects($this->any())
->method('getCustomer')
->will($this->returnValue($stubCustomer));
$stubFacade->expects($this->any())
->method('getConditionEvaluator')
->will($this->returnValue(new ConditionEvaluator()));
$stubTranslator = $this->getMockBuilder('\Thelia\Core\Translation\Translator')
->disableOriginalConstructor()
->getMock();
$stubTranslator->expects($this->any())
->method('trans')
->will($this->returnValue($i18nOutput));
$stubFacade->expects($this->any())
->method('getTranslator')
->will($this->returnValue($stubTranslator));
return $stubFacade;
}
/**
* Check if validity test on BackOffice inputs are working
*
* @covers Thelia\Condition\Implementation\MatchBillingCountries::setValidators
* @expectedException \Thelia\Exception\InvalidConditionOperatorException
*/
public function testInValidBackOfficeInputOperator()
{
/** @var FacadeInterface $stubFacade */
$stubFacade = $this->generateFacadeStub();
$condition1 = new MatchBillingCountries($stubFacade);
$operators = array(
MatchBillingCountries::COUNTRIES_LIST => Operators::INFERIOR_OR_EQUAL
);
$values = array(
MatchBillingCountries::COUNTRIES_LIST => array()
);
$condition1->setValidatorsFromForm($operators, $values);
$isValid = $condition1->isMatching();
$expected = true;
$actual =$isValid;
$this->assertEquals($expected, $actual);
}
/**
* Check if validity test on BackOffice inputs are working
*
* @covers Thelia\Condition\Implementation\MatchBillingCountries::setValidators
* @expectedException \Thelia\Exception\InvalidConditionValueException
*/
public function testInValidBackOfficeInputValue()
{
/** @var FacadeInterface $stubFacade */
$stubFacade = $this->generateFacadeStub();
$condition1 = new MatchBillingCountries($stubFacade);
$operators = array(
MatchBillingCountries::COUNTRIES_LIST => Operators::IN
);
$values = array(
MatchBillingCountries::COUNTRIES_LIST => array()
);
$condition1->setValidatorsFromForm($operators, $values);
}
/**
* Check if test inferior operator is working
*
* @covers Thelia\Condition\Implementation\MatchBillingCountries::isMatching
*
*/
public function testMatchingRule()
{
/** @var FacadeInterface $stubFacade */
$stubFacade = $this->generateFacadeStub();
$condition1 = new MatchBillingCountries($stubFacade);
$operators = array(
MatchBillingCountries::COUNTRIES_LIST => Operators::IN
);
$values = array(
MatchBillingCountries::COUNTRIES_LIST => array(10, 20)
);
$condition1->setValidatorsFromForm($operators, $values);
$isValid = $condition1->isMatching();
$expected = true;
$actual =$isValid;
$this->assertEquals($expected, $actual);
}
/**
* Check if test inferior operator is working
*
* @covers Thelia\Condition\Implementation\MatchBillingCountries::isMatching
*
*/
public function testNotMatching()
{
/** @var FacadeInterface $stubFacade */
$stubFacade = $this->generateFacadeStub();
$condition1 = new MatchBillingCountries($stubFacade);
$operators = array(
MatchBillingCountries::COUNTRIES_LIST => Operators::IN
);
$values = array(
MatchBillingCountries::COUNTRIES_LIST => array(50, 60)
);
$condition1->setValidatorsFromForm($operators, $values);
$isValid = $condition1->isMatching();
$expected = false;
$actual =$isValid;
$this->assertEquals($expected, $actual);
}
public function testGetSerializableRule()
{
/** @var FacadeInterface $stubFacade */
$stubFacade = $this->generateFacadeStub();
$condition1 = new MatchBillingCountries($stubFacade);
$operators = array(
MatchBillingCountries::COUNTRIES_LIST => Operators::IN
);
$values = array(
MatchBillingCountries::COUNTRIES_LIST => array(50, 60)
);
$condition1->setValidatorsFromForm($operators, $values);
$serializableRule = $condition1->getSerializableCondition();
$expected = new SerializableCondition();
$expected->conditionServiceId = $condition1->getServiceId();
$expected->operators = $operators;
$expected->values = $values;
$actual = $serializableRule;
$this->assertEquals($expected, $actual);
}
/**
* Check getName i18n
*
* @covers Thelia\Condition\Implementation\MatchBillingCountries::getName
*
*/
public function testGetName()
{
$stubFacade = $this->generateFacadeStub(399, 'EUR', 'Number of articles in cart');
/** @var FacadeInterface $stubFacade */
$condition1 = new MatchBillingCountries($stubFacade);
$actual = $condition1->getName();
$expected = 'Number of articles in cart';
$this->assertEquals($expected, $actual);
}
/**
* Check tooltip i18n
*
* @covers Thelia\Condition\Implementation\MatchBillingCountries::getToolTip
*
*/
public function testGetToolTip()
{
$stubFacade = $this->generateFacadeStub(399, 'EUR', 'Sample coupon condition');
/** @var FacadeInterface $stubFacade */
$condition1 = new MatchBillingCountries($stubFacade);
$actual = $condition1->getToolTip();
$expected = 'Sample coupon condition';
$this->assertEquals($expected, $actual);
}
/**
* Check validator
*
* @covers Thelia\Condition\Implementation\MatchBillingCountries::generateInputs
*
*/
public function testGetValidator()
{
$stubFacade = $this->generateFacadeStub(399, 'EUR', 'Price');
/** @var FacadeInterface $stubFacade */
$condition1 = new MatchBillingCountries($stubFacade);
$operators = array(
MatchBillingCountries::COUNTRIES_LIST => Operators::IN
);
$values = array(
MatchBillingCountries::COUNTRIES_LIST => array(50, 60)
);
$condition1->setValidatorsFromForm($operators, $values);
$actual = $condition1->getValidators();
$validators = array(
'inputs' => array(
MatchBillingCountries::COUNTRIES_LIST => array(
'availableOperators' => array(
'in' => 'Price',
'out' => 'Price',
),
'value' => '',
'selectedOperator' => 'in'
)
),
'setOperators' => array(
'countries' => 'in'
),
'setValues' => array(
'countries' => array(50, 60)
)
);
$expected = $validators;
$this->assertEquals($expected, $actual);
}
/**
* Tears down the fixture, for example, closes a network connection.
* This method is called after a test is executed.
*/
protected function tearDown()
{
}
}

View File

@@ -0,0 +1,304 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\Condition\Implementation;
use Thelia\Condition\ConditionEvaluator;
use Thelia\Condition\Operators;
use Thelia\Condition\SerializableCondition;
use Thelia\Coupon\FacadeInterface;
use Thelia\Model\Address;
/**
* @package Coupon
* @author Franck Allimant <franck@cqfdev.fr>
*/
class MatchDeliveryCountriesTest extends \PHPUnit_Framework_TestCase
{
/**
* Sets up the fixture, for example, opens a network connection.
* This method is called before a test is executed.
*/
protected function setUp()
{
}
/**
* Generate adapter stub
*
* @param int $cartTotalPrice Cart total price
* @param string $checkoutCurrency Checkout currency
* @param string $i18nOutput Output from each translation
*
* @return \PHPUnit_Framework_MockObject_MockObject
*/
public function generateFacadeStub($cartTotalPrice = 400, $checkoutCurrency = 'EUR', $i18nOutput = '')
{
$stubFacade = $this->getMockBuilder('\Thelia\Coupon\BaseFacade')
->disableOriginalConstructor()
->getMock();
$address = new Address();
$address->setCountryId(10);
$stubFacade->expects($this->any())
->method('getDeliveryAddress')
->will($this->returnValue($address));
$stubFacade->expects($this->any())
->method('getConditionEvaluator')
->will($this->returnValue(new ConditionEvaluator()));
$stubTranslator = $this->getMockBuilder('\Thelia\Core\Translation\Translator')
->disableOriginalConstructor()
->getMock();
$stubTranslator->expects($this->any())
->method('trans')
->will($this->returnValue($i18nOutput));
$stubFacade->expects($this->any())
->method('getTranslator')
->will($this->returnValue($stubTranslator));
return $stubFacade;
}
/**
* Check if validity test on BackOffice inputs are working
*
* @covers Thelia\Condition\Implementation\MatchDeliveryCountries::setValidators
* @expectedException \Thelia\Exception\InvalidConditionOperatorException
*/
public function testInValidBackOfficeInputOperator()
{
/** @var FacadeInterface $stubFacade */
$stubFacade = $this->generateFacadeStub();
$condition1 = new MatchDeliveryCountries($stubFacade);
$operators = array(
MatchDeliveryCountries::COUNTRIES_LIST => Operators::INFERIOR_OR_EQUAL
);
$values = array(
MatchDeliveryCountries::COUNTRIES_LIST => array()
);
$condition1->setValidatorsFromForm($operators, $values);
$isValid = $condition1->isMatching();
$expected = true;
$actual =$isValid;
$this->assertEquals($expected, $actual);
}
/**
* Check if validity test on BackOffice inputs are working
*
* @covers Thelia\Condition\Implementation\MatchDeliveryCountries::setValidators
* @expectedException \Thelia\Exception\InvalidConditionValueException
*/
public function testInValidBackOfficeInputValue()
{
/** @var FacadeInterface $stubFacade */
$stubFacade = $this->generateFacadeStub();
$condition1 = new MatchDeliveryCountries($stubFacade);
$operators = array(
MatchDeliveryCountries::COUNTRIES_LIST => Operators::IN
);
$values = array(
MatchDeliveryCountries::COUNTRIES_LIST => array()
);
$condition1->setValidatorsFromForm($operators, $values);
}
/**
* Check if test inferior operator is working
*
* @covers Thelia\Condition\Implementation\MatchDeliveryCountries::isMatching
*
*/
public function testMatchingRule()
{
/** @var FacadeInterface $stubFacade */
$stubFacade = $this->generateFacadeStub();
$condition1 = new MatchDeliveryCountries($stubFacade);
$operators = array(
MatchDeliveryCountries::COUNTRIES_LIST => Operators::IN
);
$values = array(
MatchDeliveryCountries::COUNTRIES_LIST => array(10, 20)
);
$condition1->setValidatorsFromForm($operators, $values);
$isValid = $condition1->isMatching();
$expected = true;
$actual =$isValid;
$this->assertEquals($expected, $actual);
}
/**
* Check if test inferior operator is working
*
* @covers Thelia\Condition\Implementation\MatchDeliveryCountries::isMatching
*
*/
public function testNotMatching()
{
/** @var FacadeInterface $stubFacade */
$stubFacade = $this->generateFacadeStub();
$condition1 = new MatchDeliveryCountries($stubFacade);
$operators = array(
MatchDeliveryCountries::COUNTRIES_LIST => Operators::IN
);
$values = array(
MatchDeliveryCountries::COUNTRIES_LIST => array(50, 60)
);
$condition1->setValidatorsFromForm($operators, $values);
$isValid = $condition1->isMatching();
$expected = false;
$actual =$isValid;
$this->assertEquals($expected, $actual);
}
public function testGetSerializableRule()
{
/** @var FacadeInterface $stubFacade */
$stubFacade = $this->generateFacadeStub();
$condition1 = new MatchDeliveryCountries($stubFacade);
$operators = array(
MatchDeliveryCountries::COUNTRIES_LIST => Operators::IN
);
$values = array(
MatchDeliveryCountries::COUNTRIES_LIST => array(50, 60)
);
$condition1->setValidatorsFromForm($operators, $values);
$serializableRule = $condition1->getSerializableCondition();
$expected = new SerializableCondition();
$expected->conditionServiceId = $condition1->getServiceId();
$expected->operators = $operators;
$expected->values = $values;
$actual = $serializableRule;
$this->assertEquals($expected, $actual);
}
/**
* Check getName i18n
*
* @covers Thelia\Condition\Implementation\MatchDeliveryCountries::getName
*
*/
public function testGetName()
{
$stubFacade = $this->generateFacadeStub(399, 'EUR', 'Number of articles in cart');
/** @var FacadeInterface $stubFacade */
$condition1 = new MatchDeliveryCountries($stubFacade);
$actual = $condition1->getName();
$expected = 'Number of articles in cart';
$this->assertEquals($expected, $actual);
}
/**
* Check tooltip i18n
*
* @covers Thelia\Condition\Implementation\MatchDeliveryCountries::getToolTip
*
*/
public function testGetToolTip()
{
$stubFacade = $this->generateFacadeStub(399, 'EUR', 'Sample coupon condition');
/** @var FacadeInterface $stubFacade */
$condition1 = new MatchDeliveryCountries($stubFacade);
$actual = $condition1->getToolTip();
$expected = 'Sample coupon condition';
$this->assertEquals($expected, $actual);
}
/**
* Check validator
*
* @covers Thelia\Condition\Implementation\MatchDeliveryCountries::generateInputs
*
*/
public function testGetValidator()
{
$stubFacade = $this->generateFacadeStub(399, 'EUR', 'Price');
/** @var FacadeInterface $stubFacade */
$condition1 = new MatchDeliveryCountries($stubFacade);
$operators = array(
MatchDeliveryCountries::COUNTRIES_LIST => Operators::IN
);
$values = array(
MatchDeliveryCountries::COUNTRIES_LIST => array(50, 60)
);
$condition1->setValidatorsFromForm($operators, $values);
$actual = $condition1->getValidators();
$validators = array(
'inputs' => array(
MatchDeliveryCountries::COUNTRIES_LIST => array(
'availableOperators' => array(
'in' => 'Price',
'out' => 'Price',
),
'value' => '',
'selectedOperator' => 'in'
)
),
'setOperators' => array(
'countries' => 'in'
),
'setValues' => array(
'countries' => array(50, 60)
)
);
$expected = $validators;
$this->assertEquals($expected, $actual);
}
/**
* Tears down the fixture, for example, closes a network connection.
* This method is called after a test is executed.
*/
protected function tearDown()
{
}
}

View File

@@ -13,7 +13,6 @@
namespace Thelia\Condition\Implementation;
use Thelia\Condition\ConditionEvaluator;
use Thelia\Coupon\FacadeInterface;
use Thelia\Model\Currency;

View File

@@ -12,13 +12,12 @@
namespace Thelia\Tests\Condition\Implementation;
use Thelia\Condition\ConditionCollection;
use Thelia\Condition\ConditionEvaluator;
use Thelia\Condition\ConditionFactory;
use Thelia\Condition\Implementation\MatchForTotalAmount;
use Thelia\Condition\Operators;
use Thelia\Condition\ConditionCollection;
use Thelia\Coupon\FacadeInterface;
use Thelia\Model\Currency;
use Thelia\Model\CurrencyQuery;

View File

@@ -0,0 +1,329 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\Condition\Implementation;
use Thelia\Condition\ConditionEvaluator;
use Thelia\Condition\Operators;
use Thelia\Condition\SerializableCondition;
use Thelia\Coupon\FacadeInterface;
use Thelia\Model\Address;
use Thelia\Model\Lang;
/**
* @package Coupon
* @author Franck Allimant <franck@cqfdev.fr>
*/
class StartDateTest extends \PHPUnit_Framework_TestCase
{
var $startDate;
/**
* Sets up the fixture, for example, opens a network connection.
* This method is called before a test is executed.
*/
protected function setUp()
{
$this->startDate = time() - 2000;
}
/**
* Generate adapter stub
*
* @param int $cartTotalPrice Cart total price
* @param string $checkoutCurrency Checkout currency
* @param string $i18nOutput Output from each translation
*
* @return \PHPUnit_Framework_MockObject_MockObject
*/
public function generateFacadeStub($cartTotalPrice = 400, $checkoutCurrency = 'EUR', $i18nOutput = '')
{
$stubFacade = $this->getMockBuilder('\Thelia\Coupon\BaseFacade')
->disableOriginalConstructor()
->getMock();
$address = new Address();
$address->setCountryId(10);
$stubFacade->expects($this->any())
->method('getDeliveryAddress')
->will($this->returnValue($address));
$stubFacade->expects($this->any())
->method('getConditionEvaluator')
->will($this->returnValue(new ConditionEvaluator()));
$stubTranslator = $this->getMockBuilder('\Thelia\Core\Translation\Translator')
->disableOriginalConstructor()
->getMock();
$stubTranslator->expects($this->any())
->method('trans')
->will($this->returnValue($i18nOutput));
$stubFacade->expects($this->any())
->method('getTranslator')
->will($this->returnValue($stubTranslator));
$lang = new Lang();
$lang->setDateFormat("d/m/Y");
$stubSession = $this->getMockBuilder('\Thelia\Core\HttpFoundation\Session\Session')
->disableOriginalConstructor()
->getMock();
$stubSession->expects($this->any())
->method('getLang')
->will($this->returnValue($lang));
$stubRequest = $this->getMockBuilder('\Thelia\Core\HttpFoundation\Request')
->disableOriginalConstructor()
->getMock();
$stubRequest->expects($this->any())
->method('getSession')
->will($this->returnValue($stubSession));
$stubFacade->expects($this->any())
->method('getRequest')
->will($this->returnValue($stubRequest));
return $stubFacade;
}
/**
* Check if validity test on BackOffice inputs are working
*
* @covers Thelia\Condition\Implementation\StartDate::setValidators
* @expectedException \Thelia\Exception\InvalidConditionOperatorException
*/
public function testInValidBackOfficeInputOperator()
{
/** @var FacadeInterface $stubFacade */
$stubFacade = $this->generateFacadeStub();
$condition1 = new StartDate($stubFacade);
$operators = array(
StartDate::START_DATE => 'petite licorne'
);
$values = array(
StartDate::START_DATE => $this->startDate
);
$condition1->setValidatorsFromForm($operators, $values);
$isValid = $condition1->isMatching();
$expected = true;
$actual =$isValid;
$this->assertEquals($expected, $actual);
}
/**
* Check if validity test on BackOffice inputs are working
*
* @covers Thelia\Condition\Implementation\StartDate::setValidators
* @expectedException \Thelia\Exception\InvalidConditionValueException
*/
public function testInValidBackOfficeInputValue()
{
/** @var FacadeInterface $stubFacade */
$stubFacade = $this->generateFacadeStub();
$condition1 = new StartDate($stubFacade);
$operators = array(
StartDate::START_DATE => Operators::SUPERIOR_OR_EQUAL
);
$values = array(
StartDate::START_DATE => 'petit poney'
);
$condition1->setValidatorsFromForm($operators, $values);
}
/**
* Check if test inferior operator is working
*
* @covers Thelia\Condition\Implementation\StartDate::isMatching
*
*/
public function testMatchingRule()
{
/** @var FacadeInterface $stubFacade */
$stubFacade = $this->generateFacadeStub();
$condition1 = new StartDate($stubFacade);
$operators = array(
StartDate::START_DATE => Operators::SUPERIOR_OR_EQUAL
);
$values = array(
StartDate::START_DATE => $this->startDate
);
$condition1->setValidatorsFromForm($operators, $values);
$isValid = $condition1->isMatching();
$expected = true;
$actual =$isValid;
$this->assertEquals($expected, $actual);
}
/**
* Check if test inferior operator is working
*
* @covers Thelia\Condition\Implementation\StartDate::isMatching
*
*/
public function testNotMatching()
{
/** @var FacadeInterface $stubFacade */
$stubFacade = $this->generateFacadeStub();
$condition1 = new StartDate($stubFacade);
$operators = array(
StartDate::START_DATE => Operators::SUPERIOR_OR_EQUAL
);
$values = array(
StartDate::START_DATE => time() + 2000
);
$condition1->setValidatorsFromForm($operators, $values);
$isValid = $condition1->isMatching();
$expected = false;
$actual =$isValid;
$this->assertEquals($expected, $actual);
}
public function testGetSerializableRule()
{
/** @var FacadeInterface $stubFacade */
$stubFacade = $this->generateFacadeStub();
$condition1 = new StartDate($stubFacade);
$operators = array(
StartDate::START_DATE => Operators::SUPERIOR_OR_EQUAL
);
$values = array(
StartDate::START_DATE => $this->startDate
);
$condition1->setValidatorsFromForm($operators, $values);
$serializableRule = $condition1->getSerializableCondition();
$expected = new SerializableCondition();
$expected->conditionServiceId = $condition1->getServiceId();
$expected->operators = $operators;
$expected->values = $values;
$actual = $serializableRule;
$this->assertEquals($expected, $actual);
}
/**
* Check getName i18n
*
* @covers Thelia\Condition\Implementation\StartDate::getName
*
*/
public function testGetName()
{
$stubFacade = $this->generateFacadeStub(399, 'EUR', 'Number of articles in cart');
/** @var FacadeInterface $stubFacade */
$condition1 = new StartDate($stubFacade);
$actual = $condition1->getName();
$expected = 'Number of articles in cart';
$this->assertEquals($expected, $actual);
}
/**
* Check tooltip i18n
*
* @covers Thelia\Condition\Implementation\StartDate::getToolTip
*
*/
public function testGetToolTip()
{
$stubFacade = $this->generateFacadeStub(399, 'EUR', 'Sample coupon condition');
/** @var FacadeInterface $stubFacade */
$condition1 = new StartDate($stubFacade);
$actual = $condition1->getToolTip();
$expected = 'Sample coupon condition';
$this->assertEquals($expected, $actual);
}
/**
* Check validator
*
* @covers Thelia\Condition\Implementation\StartDate::generateInputs
*
*/
public function testGetValidator()
{
$stubFacade = $this->generateFacadeStub(399, 'EUR', 'Price');
/** @var FacadeInterface $stubFacade */
$condition1 = new StartDate($stubFacade);
$operators = array(
StartDate::START_DATE => Operators::SUPERIOR_OR_EQUAL
);
$values = array(
StartDate::START_DATE => $this->startDate
);
$condition1->setValidatorsFromForm($operators, $values);
$actual = $condition1->getValidators();
$validators = array(
'inputs' => array(
StartDate::START_DATE => array(
'availableOperators' => array(
'>=' => 'Price',
),
'value' => '',
'selectedOperator' => '>='
)
),
'setOperators' => array(
'start_date' => '>='
),
'setValues' => array(
'start_date' => $this->startDate
)
);
$expected = $validators;
$this->assertEquals($expected, $actual);
}
/**
* Tears down the fixture, for example, closes a network connection.
* This method is called after a test is executed.
*/
protected function tearDown()
{
}
}

View File

@@ -0,0 +1,412 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\Coupon\Type;
use Propel\Runtime\Collection\ObjectCollection;
use Thelia\Condition\ConditionCollection;
use Thelia\Condition\ConditionEvaluator;
use Thelia\Condition\Implementation\MatchForTotalAmount;
use Thelia\Condition\Operators;
use Thelia\Coupon\FacadeInterface;
use Thelia\Model\CartItem;
use Thelia\Model\CurrencyQuery;
use Thelia\Model\Product;
use Thelia\Model\ProductQuery;
/**
* @package Coupon
* @author Franck Allimant <franck@cqfdev.fr>
*/
class FreeProductTest extends \PHPUnit_Framework_TestCase
{
/** @var Product $freeProduct */
var $freeProduct;
var $originalPrice;
var $originalPromo;
/**
* Sets up the fixture, for example, opens a network connection.
* This method is called before a test is executed.
*/
protected function setUp()
{
$currency = CurrencyQuery::create()->filterByCode('EUR')->findOne();
// Find a product
$this->freeProduct = ProductQuery::create()->findOne();
$this->originalPrice = $this->freeProduct->getDefaultSaleElements()->getPricesByCurrency($currency)->getPrice();
$this->originalPromo = $this->freeProduct->getDefaultSaleElements()->getPromo();
$this->freeProduct->getDefaultSaleElements()->setPromo(false)->save();
}
/**
* Generate adapter stub
*
* @param int $cartTotalPrice Cart total price
* @param string $checkoutCurrency Checkout currency
* @param string $i18nOutput Output from each translation
*
* @return \PHPUnit_Framework_MockObject_MockObject
*/
public function generateFacadeStub($cartTotalPrice = 400, $checkoutCurrency = 'EUR', $i18nOutput = '')
{
$stubFacade = $this->getMockBuilder('\Thelia\Coupon\BaseFacade')
->disableOriginalConstructor()
->getMock();
$currencies = CurrencyQuery::create();
$currencies = $currencies->find();
$stubFacade->expects($this->any())
->method('getAvailableCurrencies')
->will($this->returnValue($currencies));
$stubFacade->expects($this->any())
->method('getCartTotalPrice')
->will($this->returnValue($cartTotalPrice));
$stubFacade->expects($this->any())
->method('getCheckoutCurrency')
->will($this->returnValue($checkoutCurrency));
$stubFacade->expects($this->any())
->method('getConditionEvaluator')
->will($this->returnValue(new ConditionEvaluator()));
$stubTranslator = $this->getMockBuilder('\Thelia\Core\Translation\Translator')
->disableOriginalConstructor()
->getMock();
$stubTranslator->expects($this->any())
->method('trans')
->will($this->returnValue($i18nOutput));
$stubFacade->expects($this->any())
->method('getTranslator')
->will($this->returnValue($stubTranslator));
$stubDispatcher = $this->getMockBuilder('\Symfony\Component\EventDispatcher\EventDispatcher')
->disableOriginalConstructor()
->getMock();
$stubDispatcher->expects($this->any())
->method('dispatch')
->will($this->returnCallback(function($dummy, $cartEvent) {
$ci = new CartItem();
$ci->setId(3)->setPrice(123)->setPromo(0);
$cartEvent->setCartItem($ci);
}));
$stubFacade->expects($this->any())
->method('getDispatcher')
->will($this->returnValue($stubDispatcher));
$stubSession = $this->getMockBuilder('\Thelia\Core\HttpFoundation\Session\Session')
->disableOriginalConstructor()
->getMock();
$stubSession->expects($this->any())
->method('get')
->will($this->onConsecutiveCalls(-1, 3));
$stubRequest = $this->getMockBuilder('\Thelia\Core\HttpFoundation\Request')
->disableOriginalConstructor()
->getMock();
$stubRequest->expects($this->any())
->method('getSession')
->will($this->returnValue($stubSession));
$stubFacade->expects($this->any())
->method('getRequest')
->will($this->returnValue($stubRequest));
return $stubFacade;
}
public function generateMatchingCart(\PHPUnit_Framework_MockObject_MockObject $stubFacade, $count) {
$product1 = new Product();
$product1->setId(10);
$product2 = new Product();
$product2->setId(20);
$cartItem1Stub = $this->getMockBuilder('\Thelia\Model\CartItem')
->disableOriginalConstructor()
->getMock();
$cartItem1Stub
->expects($this->any())
->method('getProduct')
->will($this->returnValue($product1))
;
$cartItem1Stub
->expects($this->any())
->method('getQuantity')
->will($this->returnValue(1))
;
$cartItem1Stub
->expects($this->any())
->method('getPrice')
->will($this->returnValue(100))
;
$cartItem2Stub = $this->getMockBuilder('\Thelia\Model\CartItem')
->disableOriginalConstructor()
->getMock();
$cartItem2Stub
->expects($this->any())
->method('getProduct')
->will($this->returnValue($product2));
$cartItem2Stub
->expects($this->any())
->method('getQuantity')
->will($this->returnValue(2))
;
$cartItem2Stub
->expects($this->any())
->method('getPrice')
->will($this->returnValue(150))
;
$cartStub = $this->getMockBuilder('\Thelia\Model\Cart')
->disableOriginalConstructor()
->getMock();
if ($count == 1)
$ret = [$cartItem1Stub];
else
$ret = [$cartItem1Stub, $cartItem2Stub];
$cartStub
->expects($this->any())
->method('getCartItems')
->will($this->returnValue($ret));
$stubFacade->expects($this->any())
->method('getCart')
->will($this->returnValue($cartStub));
}
public function generateNoMatchingCart(\PHPUnit_Framework_MockObject_MockObject $stubFacade) {
$product2 = new Product();
$product2->setId(30);
$cartItem2Stub = $this->getMockBuilder('\Thelia\Model\CartItem')
->disableOriginalConstructor()
->getMock();
$cartItem2Stub->expects($this->any())
->method('getProduct')
->will($this->returnValue($product2))
;
$cartItem2Stub->expects($this->any())
->method('getQuantity')
->will($this->returnValue(2))
;
$cartItem2Stub
->expects($this->any())
->method('getPrice')
->will($this->returnValue(11000))
;
$cartStub = $this->getMockBuilder('\Thelia\Model\Cart')
->disableOriginalConstructor()
->getMock();
$cartStub
->expects($this->any())
->method('getCartItems')
->will($this->returnValue([$cartItem2Stub]));
$stubFacade->expects($this->any())
->method('getCart')
->will($this->returnValue($cartStub));
}
public function testSet()
{
$stubFacade = $this->generateFacadeStub();
$coupon = new FreeProduct($stubFacade);
$date = new \DateTime();
$coupon->set(
$stubFacade,
'TEST', 'TEST Coupon', 'This is a test coupon title', 'This is a test coupon description',
array('percentage' => 10.00, 'products' => [10, 20], 'offered_product_id' => $this->freeProduct->getId(), 'offered_category_id' => 1),
true, true, true, true,
254,
$date->setTimestamp(strtotime("today + 3 months")),
new ObjectCollection(),
new ObjectCollection(),
false
);
$condition1 = new MatchForTotalAmount($stubFacade);
$operators = array(
MatchForTotalAmount::CART_TOTAL => Operators::SUPERIOR,
MatchForTotalAmount::CART_CURRENCY => Operators::EQUAL
);
$values = array(
MatchForTotalAmount::CART_TOTAL => 40.00,
MatchForTotalAmount::CART_CURRENCY => 'EUR'
);
$condition1->setValidatorsFromForm($operators, $values);
$condition2 = new MatchForTotalAmount($stubFacade);
$operators = array(
MatchForTotalAmount::CART_TOTAL => Operators::INFERIOR,
MatchForTotalAmount::CART_CURRENCY => Operators::EQUAL
);
$values = array(
MatchForTotalAmount::CART_TOTAL => 400.00,
MatchForTotalAmount::CART_CURRENCY => 'EUR'
);
$condition2->setValidatorsFromForm($operators, $values);
$conditions = new ConditionCollection();
$conditions[] = $condition1;
$conditions[] = $condition2;
$coupon->setConditions($conditions);
$this->assertEquals('TEST', $coupon->getCode());
$this->assertEquals('TEST Coupon', $coupon->getTitle());
$this->assertEquals('This is a test coupon title', $coupon->getShortDescription());
$this->assertEquals('This is a test coupon description', $coupon->getDescription());
$this->assertEquals(true, $coupon->isCumulative());
$this->assertEquals(true, $coupon->isRemovingPostage());
$this->assertEquals(true, $coupon->isAvailableOnSpecialOffers());
$this->assertEquals(true, $coupon->isEnabled());
$this->assertEquals(254, $coupon->getMaxUsage());
$this->assertEquals($date, $coupon->getExpirationDate());
}
public function testMatchOne()
{
$stubFacade = $this->generateFacadeStub();
$coupon = new FreeProduct($stubFacade);
$date = new \DateTime();
$coupon->set(
$stubFacade,
'TEST', 'TEST Coupon', 'This is a test coupon title', 'This is a test coupon description',
array('percentage' => 10.00, 'products' => [10, 20], 'offered_product_id' => $this->freeProduct->getId(), 'offered_category_id' => 1),
true, true, true, true,
254,
$date->setTimestamp(strtotime("today + 3 months")),
new ObjectCollection(),
new ObjectCollection(),
false
);
$this->generateMatchingCart($stubFacade, 1);
$this->assertEquals(123.00, $coupon->exec());
}
public function testMatchSeveral()
{
$stubFacade = $this->generateFacadeStub();
$coupon = new FreeProduct($stubFacade);
$date = new \DateTime();
$coupon->set(
$stubFacade,
'TEST', 'TEST Coupon', 'This is a test coupon title', 'This is a test coupon description',
array('percentage' => 10.00, 'products' => [10, 20], 'offered_product_id' => $this->freeProduct->getId(), 'offered_category_id' => 1),
true, true, true, true,
254,
$date->setTimestamp(strtotime("today + 3 months")),
new ObjectCollection(),
new ObjectCollection(),
false
);
$this->generateMatchingCart($stubFacade, 2);
$this->assertEquals(123.00, $coupon->exec());
}
public function testNoMatch()
{
$stubFacade = $this->generateFacadeStub();
$coupon = new FreeProduct($stubFacade);
$date = new \DateTime();
$coupon->set(
$stubFacade,
'TEST', 'TEST Coupon', 'This is a test coupon title', 'This is a test coupon description',
array('percentage' => 10.00, 'products' => [10, 20], 'offered_product_id' => $this->freeProduct->getId(), 'offered_category_id' => 1),
true, true, true, true,
254,
$date->setTimestamp(strtotime("today + 3 months")),
new ObjectCollection(),
new ObjectCollection(),
false
);
$this->generateNoMatchingCart($stubFacade);
$this->assertEquals(0.00, $coupon->exec());
}
public function testGetName()
{
$stubFacade = $this->generateFacadeStub(399, 'EUR', 'Coupon test name');
/** @var FacadeInterface $stubFacade */
$coupon = new FreeProduct($stubFacade);
$actual = $coupon->getName();
$expected = 'Coupon test name';
$this->assertEquals($expected, $actual);
}
public function testGetToolTip()
{
$tooltip = 'Coupon test tooltip';
$stubFacade = $this->generateFacadeStub(399, 'EUR', $tooltip);
/** @var FacadeInterface $stubFacade */
$coupon = new FreeProduct($stubFacade);
$actual = $coupon->getToolTip();
$expected = $tooltip;
$this->assertEquals($expected, $actual);
}
/**
* Tears down the fixture, for example, closes a network connection.
* This method is called after a test is executed.
*/
protected function tearDown()
{
$this->freeProduct->getDefaultSaleElements()->setPromo($this->originalPromo)->save();
}
}

View File

@@ -0,0 +1,398 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\Coupon\Type;
use Propel\Runtime\Collection\ObjectCollection;
use Thelia\Condition\ConditionCollection;
use Thelia\Condition\ConditionEvaluator;
use Thelia\Condition\Implementation\MatchForTotalAmount;
use Thelia\Condition\Operators;
use Thelia\Coupon\FacadeInterface;
use Thelia\Model\CurrencyQuery;
/**
* @package Coupon
* @author Franck Allimant <franck@cqfdev.fr>
*/
class RemoveAmountOnAttributeValuesTest extends \PHPUnit_Framework_TestCase
{
/**
* Sets up the fixture, for example, opens a network connection.
* This method is called before a test is executed.
*/
protected function setUp()
{
}
/**
* Generate adapter stub
*
* @param int $cartTotalPrice Cart total price
* @param string $checkoutCurrency Checkout currency
* @param string $i18nOutput Output from each translation
*
* @return \PHPUnit_Framework_MockObject_MockObject
*/
public function generateFacadeStub($cartTotalPrice = 400, $checkoutCurrency = 'EUR', $i18nOutput = '')
{
$stubFacade = $this->getMockBuilder('\Thelia\Coupon\BaseFacade')
->disableOriginalConstructor()
->getMock();
$currencies = CurrencyQuery::create();
$currencies = $currencies->find();
$stubFacade->expects($this->any())
->method('getAvailableCurrencies')
->will($this->returnValue($currencies));
$stubFacade->expects($this->any())
->method('getCartTotalPrice')
->will($this->returnValue($cartTotalPrice));
$stubFacade->expects($this->any())
->method('getCheckoutCurrency')
->will($this->returnValue($checkoutCurrency));
$stubFacade->expects($this->any())
->method('getConditionEvaluator')
->will($this->returnValue(new ConditionEvaluator()));
$stubTranslator = $this->getMockBuilder('\Thelia\Core\Translation\Translator')
->disableOriginalConstructor()
->getMock();
$stubTranslator->expects($this->any())
->method('trans')
->will($this->returnValue($i18nOutput));
$stubFacade->expects($this->any())
->method('getTranslator')
->will($this->returnValue($stubTranslator));
return $stubFacade;
}
public function generateMatchingCart(\PHPUnit_Framework_MockObject_MockObject $stubFacade, $count) {
$attrCombination1 = $this->getMockBuilder('\Thelia\Model\AttributeCombination')
->disableOriginalConstructor()
->getMock()
;
$attrCombination1
->expects($this->any())
->method('getAttributeAvId')
->will($this->returnValue(10))
;
$attrCombination2 = $this->getMockBuilder('\Thelia\Model\AttributeCombination')
->disableOriginalConstructor()
->getMock()
;
$attrCombination2
->expects($this->any())
->method('getAttributeAvId')
->will($this->returnValue(20))
;
$pse1 = $this->getMockBuilder('\Thelia\Model\ProductSaleElements')
->disableOriginalConstructor()
->getMock()
;
$pse1
->expects($this->any())
->method('getAttributeCombinations')
->will($this->returnValue([$attrCombination1]))
;
$pse2 = $this->getMockBuilder('\Thelia\Model\ProductSaleElements')
->disableOriginalConstructor()
->getMock();
;
$pse2
->expects($this->any())
->method('getAttributeCombinations')
->will($this->returnValue([$attrCombination1, $attrCombination2]))
;
$cartItem1Stub = $this->getMockBuilder('\Thelia\Model\CartItem')
->disableOriginalConstructor()
->getMock()
;
$cartItem1Stub
->expects($this->any())
->method('getProductSaleElements')
->will($this->returnValue($pse1))
;
$cartItem1Stub
->expects($this->any())
->method('getQuantity')
->will($this->returnValue(1))
;
$cartItem2Stub = $this->getMockBuilder('\Thelia\Model\CartItem')
->disableOriginalConstructor()
->getMock()
;
$cartItem2Stub
->expects($this->any())
->method('getProductSaleElements')
->will($this->returnValue($pse2))
;
$cartItem2Stub
->expects($this->any())
->method('getQuantity')
->will($this->returnValue(2))
;
$cartStub = $this->getMockBuilder('\Thelia\Model\Cart')
->disableOriginalConstructor()
->getMock();
if ($count == 1)
$ret = [$cartItem1Stub];
else
$ret = [$cartItem1Stub, $cartItem2Stub];
$cartStub
->expects($this->any())
->method('getCartItems')
->will($this->returnValue($ret));
$stubFacade->expects($this->any())
->method('getCart')
->will($this->returnValue($cartStub));
}
public function generateNoMatchingCart(\PHPUnit_Framework_MockObject_MockObject $stubFacade) {
$attrCombination1 = $this->getMockBuilder('\Thelia\Model\AttributeCombination')
->disableOriginalConstructor()
->getMock()
;
$attrCombination1
->expects($this->any())
->method('getAttributeAvId')
->will($this->returnValue(30))
;
$pse1 = $this->getMockBuilder('\Thelia\Model\ProductSaleElements')
->disableOriginalConstructor()
->getMock()
;
$pse1
->expects($this->any())
->method('getAttributeCombinations')
->will($this->returnValue([$attrCombination1]))
;
$cartItem1Stub = $this->getMockBuilder('\Thelia\Model\CartItem')
->disableOriginalConstructor()
->getMock()
;
$cartItem1Stub
->expects($this->any())
->method('getProductSaleElements')
->will($this->returnValue($pse1))
;
$cartItem1Stub
->expects($this->any())
->method('getQuantity')
->will($this->returnValue(1))
;
$cartStub = $this->getMockBuilder('\Thelia\Model\Cart')
->disableOriginalConstructor()
->getMock();
$cartStub
->expects($this->any())
->method('getCartItems')
->will($this->returnValue([$cartItem1Stub]));
$stubFacade->expects($this->any())
->method('getCart')
->will($this->returnValue($cartStub));
}
public function testSet()
{
$stubFacade = $this->generateFacadeStub();
$coupon = new RemoveAmountOnAttributeValues($stubFacade);
$date = new \DateTime();
$coupon->set(
$stubFacade,
'TEST', 'TEST Coupon', 'This is a test coupon title', 'This is a test coupon description',
array('amount' => 10.00, 'attribute_avs' => [10, 20]),
true, true, true, true,
254,
$date->setTimestamp(strtotime("today + 3 months")),
new ObjectCollection(),
new ObjectCollection(),
false
);
$condition1 = new MatchForTotalAmount($stubFacade);
$operators = array(
MatchForTotalAmount::CART_TOTAL => Operators::SUPERIOR,
MatchForTotalAmount::CART_CURRENCY => Operators::EQUAL
);
$values = array(
MatchForTotalAmount::CART_TOTAL => 40.00,
MatchForTotalAmount::CART_CURRENCY => 'EUR'
);
$condition1->setValidatorsFromForm($operators, $values);
$condition2 = new MatchForTotalAmount($stubFacade);
$operators = array(
MatchForTotalAmount::CART_TOTAL => Operators::INFERIOR,
MatchForTotalAmount::CART_CURRENCY => Operators::EQUAL
);
$values = array(
MatchForTotalAmount::CART_TOTAL => 400.00,
MatchForTotalAmount::CART_CURRENCY => 'EUR'
);
$condition2->setValidatorsFromForm($operators, $values);
$conditions = new ConditionCollection();
$conditions[] = $condition1;
$conditions[] = $condition2;
$coupon->setConditions($conditions);
$this->assertEquals('TEST', $coupon->getCode());
$this->assertEquals('TEST Coupon', $coupon->getTitle());
$this->assertEquals('This is a test coupon title', $coupon->getShortDescription());
$this->assertEquals('This is a test coupon description', $coupon->getDescription());
$this->assertEquals(true, $coupon->isCumulative());
$this->assertEquals(true, $coupon->isRemovingPostage());
$this->assertEquals(true, $coupon->isAvailableOnSpecialOffers());
$this->assertEquals(true, $coupon->isEnabled());
$this->assertEquals(254, $coupon->getMaxUsage());
$this->assertEquals($date, $coupon->getExpirationDate());
}
public function testMatchOne()
{
$stubFacade = $this->generateFacadeStub();
$coupon = new RemoveAmountOnAttributeValues($stubFacade);
$date = new \DateTime();
$coupon->set(
$stubFacade,
'TEST', 'TEST Coupon', 'This is a test coupon title', 'This is a test coupon description',
array('amount' => 10.00, 'attribute_avs' => [10, 20]),
true, true, true, true,
254,
$date->setTimestamp(strtotime("today + 3 months")),
new ObjectCollection(),
new ObjectCollection(),
false
);
$this->generateMatchingCart($stubFacade, 1);
$this->assertEquals(10.00, $coupon->exec());
}
public function testMatchSeveral()
{
$stubFacade = $this->generateFacadeStub();
$coupon = new RemoveAmountOnAttributeValues($stubFacade);
$date = new \DateTime();
$coupon->set(
$stubFacade,
'TEST', 'TEST Coupon', 'This is a test coupon title', 'This is a test coupon description',
array('amount' => 10.00, 'attribute_avs' => [10, 20]),
true, true, true, true,
254,
$date->setTimestamp(strtotime("today + 3 months")),
new ObjectCollection(),
new ObjectCollection(),
false
);
$this->generateMatchingCart($stubFacade, 2);
$this->assertEquals(30.00, $coupon->exec());
}
public function testNoMatch()
{
$stubFacade = $this->generateFacadeStub();
$coupon = new RemoveAmountOnAttributeValues($stubFacade);
$date = new \DateTime();
$coupon->set(
$stubFacade,
'TEST', 'TEST Coupon', 'This is a test coupon title', 'This is a test coupon description',
array('amount' => 10.00, 'attribute_avs' => [10, 20]),
true, true, true, true,
254,
$date->setTimestamp(strtotime("today + 3 months")),
new ObjectCollection(),
new ObjectCollection(),
false
);
$this->generateNoMatchingCart($stubFacade);
$this->assertEquals(0.00, $coupon->exec());
}
public function testGetName()
{
$stubFacade = $this->generateFacadeStub(399, 'EUR', 'Coupon test name');
/** @var FacadeInterface $stubFacade */
$coupon = new RemoveAmountOnAttributeValues($stubFacade);
$actual = $coupon->getName();
$expected = 'Coupon test name';
$this->assertEquals($expected, $actual);
}
public function testGetToolTip()
{
$tooltip = 'Coupon test tooltip';
$stubFacade = $this->generateFacadeStub(399, 'EUR', $tooltip);
/** @var FacadeInterface $stubFacade */
$coupon = new RemoveAmountOnAttributeValues($stubFacade);
$actual = $coupon->getToolTip();
$expected = $tooltip;
$this->assertEquals($expected, $actual);
}
/**
* Tears down the fixture, for example, closes a network connection.
* This method is called after a test is executed.
*/
protected function tearDown()
{
}
}

View File

@@ -0,0 +1,330 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\Coupon\Type;
use Propel\Runtime\Collection\ObjectCollection;
use Thelia\Condition\ConditionCollection;
use Thelia\Condition\ConditionEvaluator;
use Thelia\Condition\Implementation\MatchForTotalAmount;
use Thelia\Condition\Operators;
use Thelia\Coupon\FacadeInterface;
use Thelia\Model\Category;
use Thelia\Model\CurrencyQuery;
use Thelia\Model\Product;
/**
* @package Coupon
* @author Franck Allimant <franck@cqfdev.fr>
*/
class RemoveAmountOnCategoriesTest extends \PHPUnit_Framework_TestCase
{
/**
* Sets up the fixture, for example, opens a network connection.
* This method is called before a test is executed.
*/
protected function setUp()
{
}
/**
* Generate adapter stub
*
* @param int $cartTotalPrice Cart total price
* @param string $checkoutCurrency Checkout currency
* @param string $i18nOutput Output from each translation
*
* @return \PHPUnit_Framework_MockObject_MockObject
*/
public function generateFacadeStub($cartTotalPrice = 400, $checkoutCurrency = 'EUR', $i18nOutput = '')
{
$stubFacade = $this->getMockBuilder('\Thelia\Coupon\BaseFacade')
->disableOriginalConstructor()
->getMock();
$currencies = CurrencyQuery::create();
$currencies = $currencies->find();
$stubFacade->expects($this->any())
->method('getAvailableCurrencies')
->will($this->returnValue($currencies));
$stubFacade->expects($this->any())
->method('getCartTotalPrice')
->will($this->returnValue($cartTotalPrice));
$stubFacade->expects($this->any())
->method('getCheckoutCurrency')
->will($this->returnValue($checkoutCurrency));
$stubFacade->expects($this->any())
->method('getConditionEvaluator')
->will($this->returnValue(new ConditionEvaluator()));
$stubTranslator = $this->getMockBuilder('\Thelia\Core\Translation\Translator')
->disableOriginalConstructor()
->getMock();
$stubTranslator->expects($this->any())
->method('trans')
->will($this->returnValue($i18nOutput));
$stubFacade->expects($this->any())
->method('getTranslator')
->will($this->returnValue($stubTranslator));
return $stubFacade;
}
public function generateMatchingCart(\PHPUnit_Framework_MockObject_MockObject $stubFacade) {
$category1 = new Category();
$category1->setId(10);
$category2 = new Category();
$category2->setId(20);
$category3 = new Category();
$category3->setId(30);
$product1 = new Product();
$product1->addCategory($category1)->addCategory($category2);
$product2 = new Product();
$product2->addCategory($category3);
$cartItem1Stub = $this->getMockBuilder('\Thelia\Model\CartItem')
->disableOriginalConstructor()
->getMock();
$cartItem1Stub
->expects($this->any())
->method('getProduct')
->will($this->returnValue($product1))
;
$cartItem1Stub
->expects($this->any())
->method('getQuantity')
->will($this->returnValue(1))
;
$cartItem2Stub = $this->getMockBuilder('\Thelia\Model\CartItem')
->disableOriginalConstructor()
->getMock();
$cartItem2Stub
->expects($this->any())
->method('getProduct')
->will($this->returnValue($product2));
$cartItem2Stub
->expects($this->any())
->method('getQuantity')
->will($this->returnValue(2))
;
$cartStub = $this->getMockBuilder('\Thelia\Model\Cart')
->disableOriginalConstructor()
->getMock();
$cartStub
->expects($this->any())
->method('getCartItems')
->will($this->returnValue([$cartItem1Stub, $cartItem2Stub]));
$stubFacade->expects($this->any())
->method('getCart')
->will($this->returnValue($cartStub));
}
public function generateNoMatchingCart(\PHPUnit_Framework_MockObject_MockObject $stubFacade) {
$category3 = new Category();
$category3->setId(30);
$product2 = new Product();
$product2->addCategory($category3);
$cartItem2Stub = $this->getMockBuilder('\Thelia\Model\CartItem')
->disableOriginalConstructor()
->getMock();
$cartItem2Stub->expects($this->any())
->method('getProduct')
->will($this->returnValue($product2));
$cartItem2Stub->expects($this->any())
->method('getQuantity')
->will($this->returnValue(2));
$cartStub = $this->getMockBuilder('\Thelia\Model\Cart')
->disableOriginalConstructor()
->getMock();
$cartStub
->expects($this->any())
->method('getCartItems')
->will($this->returnValue([$cartItem2Stub]));
$stubFacade->expects($this->any())
->method('getCart')
->will($this->returnValue($cartStub));
}
public function testSet()
{
$stubFacade = $this->generateFacadeStub();
$coupon = new RemoveAmountOnCategories($stubFacade);
$date = new \DateTime();
$coupon->set(
$stubFacade,
'TEST', 'TEST Coupon', 'This is a test coupon title', 'This is a test coupon description',
array('amount' => 10.00, 'categories' => [10, 20]),
true, true, true, true,
254,
$date->setTimestamp(strtotime("today + 3 months")),
new ObjectCollection(),
new ObjectCollection(),
false
);
$condition1 = new MatchForTotalAmount($stubFacade);
$operators = array(
MatchForTotalAmount::CART_TOTAL => Operators::SUPERIOR,
MatchForTotalAmount::CART_CURRENCY => Operators::EQUAL
);
$values = array(
MatchForTotalAmount::CART_TOTAL => 40.00,
MatchForTotalAmount::CART_CURRENCY => 'EUR'
);
$condition1->setValidatorsFromForm($operators, $values);
$condition2 = new MatchForTotalAmount($stubFacade);
$operators = array(
MatchForTotalAmount::CART_TOTAL => Operators::INFERIOR,
MatchForTotalAmount::CART_CURRENCY => Operators::EQUAL
);
$values = array(
MatchForTotalAmount::CART_TOTAL => 400.00,
MatchForTotalAmount::CART_CURRENCY => 'EUR'
);
$condition2->setValidatorsFromForm($operators, $values);
$conditions = new ConditionCollection();
$conditions[] = $condition1;
$conditions[] = $condition2;
$coupon->setConditions($conditions);
$this->assertEquals('TEST', $coupon->getCode());
$this->assertEquals('TEST Coupon', $coupon->getTitle());
$this->assertEquals('This is a test coupon title', $coupon->getShortDescription());
$this->assertEquals('This is a test coupon description', $coupon->getDescription());
$this->assertEquals(true, $coupon->isCumulative());
$this->assertEquals(true, $coupon->isRemovingPostage());
$this->assertEquals(true, $coupon->isAvailableOnSpecialOffers());
$this->assertEquals(true, $coupon->isEnabled());
$this->assertEquals(254, $coupon->getMaxUsage());
$this->assertEquals($date, $coupon->getExpirationDate());
$this->generateMatchingCart($stubFacade);
$this->assertEquals(10.00, $coupon->exec());
}
public function testMatch()
{
$stubFacade = $this->generateFacadeStub();
$coupon = new RemoveAmountOnCategories($stubFacade);
$date = new \DateTime();
$coupon->set(
$stubFacade,
'TEST', 'TEST Coupon', 'This is a test coupon title', 'This is a test coupon description',
array('amount' => 10.00, 'categories' => [10, 20]),
true, true, true, true,
254,
$date->setTimestamp(strtotime("today + 3 months")),
new ObjectCollection(),
new ObjectCollection(),
false
);
$this->generateMatchingCart($stubFacade);
$this->assertEquals(10.00, $coupon->exec());
}
public function testNoMatch()
{
$stubFacade = $this->generateFacadeStub();
$coupon = new RemoveAmountOnCategories($stubFacade);
$date = new \DateTime();
$coupon->set(
$stubFacade,
'TEST', 'TEST Coupon', 'This is a test coupon title', 'This is a test coupon description',
array('amount' => 10.00, 'categories' => [10, 20]),
true, true, true, true,
254,
$date->setTimestamp(strtotime("today + 3 months")),
new ObjectCollection(),
new ObjectCollection(),
false
);
$this->generateNoMatchingCart($stubFacade);
$this->assertEquals(0.00, $coupon->exec());
}
public function testGetName()
{
$stubFacade = $this->generateFacadeStub(399, 'EUR', 'Coupon test name');
/** @var FacadeInterface $stubFacade */
$coupon = new RemoveAmountOnCategories($stubFacade);
$actual = $coupon->getName();
$expected = 'Coupon test name';
$this->assertEquals($expected, $actual);
}
public function testGetToolTip()
{
$tooltip = 'Coupon test tooltip';
$stubFacade = $this->generateFacadeStub(399, 'EUR', $tooltip);
/** @var FacadeInterface $stubFacade */
$coupon = new RemoveAmountOnCategories($stubFacade);
$actual = $coupon->getToolTip();
$expected = $tooltip;
$this->assertEquals($expected, $actual);
}
/**
* Tears down the fixture, for example, closes a network connection.
* This method is called after a test is executed.
*/
protected function tearDown()
{
}
}

View File

@@ -0,0 +1,343 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\Coupon\Type;
use Propel\Runtime\Collection\ObjectCollection;
use Thelia\Condition\ConditionCollection;
use Thelia\Condition\ConditionEvaluator;
use Thelia\Condition\Implementation\MatchForTotalAmount;
use Thelia\Condition\Operators;
use Thelia\Coupon\FacadeInterface;
use Thelia\Model\CurrencyQuery;
use Thelia\Model\Product;
/**
* @package Coupon
* @author Franck Allimant <franck@cqfdev.fr>
*/
class RemoveAmountOnProductsTest extends \PHPUnit_Framework_TestCase
{
/**
* Sets up the fixture, for example, opens a network connection.
* This method is called before a test is executed.
*/
protected function setUp()
{
}
/**
* Generate adapter stub
*
* @param int $cartTotalPrice Cart total price
* @param string $checkoutCurrency Checkout currency
* @param string $i18nOutput Output from each translation
*
* @return \PHPUnit_Framework_MockObject_MockObject
*/
public function generateFacadeStub($cartTotalPrice = 400, $checkoutCurrency = 'EUR', $i18nOutput = '')
{
$stubFacade = $this->getMockBuilder('\Thelia\Coupon\BaseFacade')
->disableOriginalConstructor()
->getMock();
$currencies = CurrencyQuery::create();
$currencies = $currencies->find();
$stubFacade->expects($this->any())
->method('getAvailableCurrencies')
->will($this->returnValue($currencies));
$stubFacade->expects($this->any())
->method('getCartTotalPrice')
->will($this->returnValue($cartTotalPrice));
$stubFacade->expects($this->any())
->method('getCheckoutCurrency')
->will($this->returnValue($checkoutCurrency));
$stubFacade->expects($this->any())
->method('getConditionEvaluator')
->will($this->returnValue(new ConditionEvaluator()));
$stubTranslator = $this->getMockBuilder('\Thelia\Core\Translation\Translator')
->disableOriginalConstructor()
->getMock();
$stubTranslator->expects($this->any())
->method('trans')
->will($this->returnValue($i18nOutput));
$stubFacade->expects($this->any())
->method('getTranslator')
->will($this->returnValue($stubTranslator));
return $stubFacade;
}
public function generateMatchingCart(\PHPUnit_Framework_MockObject_MockObject $stubFacade, $count) {
$product1 = new Product();
$product1->setId(10);
$product2 = new Product();
$product2->setId(20);
$cartItem1Stub = $this->getMockBuilder('\Thelia\Model\CartItem')
->disableOriginalConstructor()
->getMock();
$cartItem1Stub
->expects($this->any())
->method('getProduct')
->will($this->returnValue($product1))
;
$cartItem1Stub
->expects($this->any())
->method('getQuantity')
->will($this->returnValue(1))
;
$cartItem2Stub = $this->getMockBuilder('\Thelia\Model\CartItem')
->disableOriginalConstructor()
->getMock();
$cartItem2Stub
->expects($this->any())
->method('getProduct')
->will($this->returnValue($product2));
$cartItem2Stub
->expects($this->any())
->method('getQuantity')
->will($this->returnValue(2))
;
$cartStub = $this->getMockBuilder('\Thelia\Model\Cart')
->disableOriginalConstructor()
->getMock();
if ($count == 1)
$ret = [$cartItem1Stub];
else
$ret = [$cartItem1Stub, $cartItem2Stub];
$cartStub
->expects($this->any())
->method('getCartItems')
->will($this->returnValue($ret));
$stubFacade->expects($this->any())
->method('getCart')
->will($this->returnValue($cartStub));
}
public function generateNoMatchingCart(\PHPUnit_Framework_MockObject_MockObject $stubFacade) {
$product2 = new Product();
$product2->setId(30);
$cartItem2Stub = $this->getMockBuilder('\Thelia\Model\CartItem')
->disableOriginalConstructor()
->getMock();
$cartItem2Stub->expects($this->any())
->method('getProduct')
->will($this->returnValue($product2));
$cartItem2Stub->expects($this->any())
->method('getQuantity')
->will($this->returnValue(2));
$cartStub = $this->getMockBuilder('\Thelia\Model\Cart')
->disableOriginalConstructor()
->getMock();
$cartStub
->expects($this->any())
->method('getCartItems')
->will($this->returnValue([$cartItem2Stub]));
$stubFacade->expects($this->any())
->method('getCart')
->will($this->returnValue($cartStub));
}
public function testSet()
{
$stubFacade = $this->generateFacadeStub();
$coupon = new RemoveAmountOnProducts($stubFacade);
$date = new \DateTime();
$coupon->set(
$stubFacade,
'TEST', 'TEST Coupon', 'This is a test coupon title', 'This is a test coupon description',
array('amount' => 10.00, 'products' => [10, 20]),
true, true, true, true,
254,
$date->setTimestamp(strtotime("today + 3 months")),
new ObjectCollection(),
new ObjectCollection(),
false
);
$condition1 = new MatchForTotalAmount($stubFacade);
$operators = array(
MatchForTotalAmount::CART_TOTAL => Operators::SUPERIOR,
MatchForTotalAmount::CART_CURRENCY => Operators::EQUAL
);
$values = array(
MatchForTotalAmount::CART_TOTAL => 40.00,
MatchForTotalAmount::CART_CURRENCY => 'EUR'
);
$condition1->setValidatorsFromForm($operators, $values);
$condition2 = new MatchForTotalAmount($stubFacade);
$operators = array(
MatchForTotalAmount::CART_TOTAL => Operators::INFERIOR,
MatchForTotalAmount::CART_CURRENCY => Operators::EQUAL
);
$values = array(
MatchForTotalAmount::CART_TOTAL => 400.00,
MatchForTotalAmount::CART_CURRENCY => 'EUR'
);
$condition2->setValidatorsFromForm($operators, $values);
$conditions = new ConditionCollection();
$conditions[] = $condition1;
$conditions[] = $condition2;
$coupon->setConditions($conditions);
$this->assertEquals('TEST', $coupon->getCode());
$this->assertEquals('TEST Coupon', $coupon->getTitle());
$this->assertEquals('This is a test coupon title', $coupon->getShortDescription());
$this->assertEquals('This is a test coupon description', $coupon->getDescription());
$this->assertEquals(true, $coupon->isCumulative());
$this->assertEquals(true, $coupon->isRemovingPostage());
$this->assertEquals(true, $coupon->isAvailableOnSpecialOffers());
$this->assertEquals(true, $coupon->isEnabled());
$this->assertEquals(254, $coupon->getMaxUsage());
$this->assertEquals($date, $coupon->getExpirationDate());
}
public function testMatchOne()
{
$stubFacade = $this->generateFacadeStub();
$coupon = new RemoveAmountOnProducts($stubFacade);
$date = new \DateTime();
$coupon->set(
$stubFacade,
'TEST', 'TEST Coupon', 'This is a test coupon title', 'This is a test coupon description',
array('amount' => 10.00, 'products' => [10, 20]),
true, true, true, true,
254,
$date->setTimestamp(strtotime("today + 3 months")),
new ObjectCollection(),
new ObjectCollection(),
false
);
$this->generateMatchingCart($stubFacade, 1);
$this->assertEquals(10.00, $coupon->exec());
}
public function testMatchSeveral()
{
$stubFacade = $this->generateFacadeStub();
$coupon = new RemoveAmountOnProducts($stubFacade);
$date = new \DateTime();
$coupon->set(
$stubFacade,
'TEST', 'TEST Coupon', 'This is a test coupon title', 'This is a test coupon description',
array('amount' => 10.00, 'products' => [10, 20]),
true, true, true, true,
254,
$date->setTimestamp(strtotime("today + 3 months")),
new ObjectCollection(),
new ObjectCollection(),
false
);
$this->generateMatchingCart($stubFacade, 2);
$this->assertEquals(30.00, $coupon->exec());
}
public function testNoMatch()
{
$stubFacade = $this->generateFacadeStub();
$coupon = new RemoveAmountOnProducts($stubFacade);
$date = new \DateTime();
$coupon->set(
$stubFacade,
'TEST', 'TEST Coupon', 'This is a test coupon title', 'This is a test coupon description',
array('amount' => 10.00, 'products' => [10, 20]),
true, true, true, true,
254,
$date->setTimestamp(strtotime("today + 3 months")),
new ObjectCollection(),
new ObjectCollection(),
false
);
$this->generateNoMatchingCart($stubFacade);
$this->assertEquals(0.00, $coupon->exec());
}
public function testGetName()
{
$stubFacade = $this->generateFacadeStub(399, 'EUR', 'Coupon test name');
/** @var FacadeInterface $stubFacade */
$coupon = new RemoveAmountOnProducts($stubFacade);
$actual = $coupon->getName();
$expected = 'Coupon test name';
$this->assertEquals($expected, $actual);
}
public function testGetToolTip()
{
$tooltip = 'Coupon test tooltip';
$stubFacade = $this->generateFacadeStub(399, 'EUR', $tooltip);
/** @var FacadeInterface $stubFacade */
$coupon = new RemoveAmountOnProducts($stubFacade);
$actual = $coupon->getToolTip();
$expected = $tooltip;
$this->assertEquals($expected, $actual);
}
/**
* Tears down the fixture, for example, closes a network connection.
* This method is called after a test is executed.
*/
protected function tearDown()
{
}
}

View File

@@ -0,0 +1,412 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\Coupon\Type;
use Propel\Runtime\Collection\ObjectCollection;
use Thelia\Condition\ConditionCollection;
use Thelia\Condition\ConditionEvaluator;
use Thelia\Condition\Implementation\MatchForTotalAmount;
use Thelia\Condition\Operators;
use Thelia\Coupon\FacadeInterface;
use Thelia\Model\CurrencyQuery;
/**
* @package Coupon
* @author Franck Allimant <franck@cqfdev.fr>
*/
class RemovePercentageOnAttributeValuesTest extends \PHPUnit_Framework_TestCase
{
/**
* Sets up the fixture, for example, opens a network connection.
* This method is called before a test is executed.
*/
protected function setUp()
{
}
/**
* Generate adapter stub
*
* @param int $cartTotalPrice Cart total price
* @param string $checkoutCurrency Checkout currency
* @param string $i18nOutput Output from each translation
*
* @return \PHPUnit_Framework_MockObject_MockObject
*/
public function generateFacadeStub($cartTotalPrice = 400, $checkoutCurrency = 'EUR', $i18nOutput = '')
{
$stubFacade = $this->getMockBuilder('\Thelia\Coupon\BaseFacade')
->disableOriginalConstructor()
->getMock();
$currencies = CurrencyQuery::create();
$currencies = $currencies->find();
$stubFacade->expects($this->any())
->method('getAvailableCurrencies')
->will($this->returnValue($currencies));
$stubFacade->expects($this->any())
->method('getCartTotalPrice')
->will($this->returnValue($cartTotalPrice));
$stubFacade->expects($this->any())
->method('getCheckoutCurrency')
->will($this->returnValue($checkoutCurrency));
$stubFacade->expects($this->any())
->method('getConditionEvaluator')
->will($this->returnValue(new ConditionEvaluator()));
$stubTranslator = $this->getMockBuilder('\Thelia\Core\Translation\Translator')
->disableOriginalConstructor()
->getMock();
$stubTranslator->expects($this->any())
->method('trans')
->will($this->returnValue($i18nOutput));
$stubFacade->expects($this->any())
->method('getTranslator')
->will($this->returnValue($stubTranslator));
return $stubFacade;
}
public function generateMatchingCart(\PHPUnit_Framework_MockObject_MockObject $stubFacade, $count) {
$attrCombination1 = $this->getMockBuilder('\Thelia\Model\AttributeCombination')
->disableOriginalConstructor()
->getMock()
;
$attrCombination1
->expects($this->any())
->method('getAttributeAvId')
->will($this->returnValue(10))
;
$attrCombination2 = $this->getMockBuilder('\Thelia\Model\AttributeCombination')
->disableOriginalConstructor()
->getMock()
;
$attrCombination2
->expects($this->any())
->method('getAttributeAvId')
->will($this->returnValue(20))
;
$pse1 = $this->getMockBuilder('\Thelia\Model\ProductSaleElements')
->disableOriginalConstructor()
->getMock()
;
$pse1
->expects($this->any())
->method('getAttributeCombinations')
->will($this->returnValue([$attrCombination1]))
;
$pse2 = $this->getMockBuilder('\Thelia\Model\ProductSaleElements')
->disableOriginalConstructor()
->getMock();
;
$pse2
->expects($this->any())
->method('getAttributeCombinations')
->will($this->returnValue([$attrCombination1, $attrCombination2]))
;
$cartItem1Stub = $this->getMockBuilder('\Thelia\Model\CartItem')
->disableOriginalConstructor()
->getMock()
;
$cartItem1Stub
->expects($this->any())
->method('getProductSaleElements')
->will($this->returnValue($pse1))
;
$cartItem1Stub
->expects($this->any())
->method('getQuantity')
->will($this->returnValue(1))
;
$cartItem1Stub
->expects($this->any())
->method('getPrice')
->will($this->returnValue(100))
;
$cartItem2Stub = $this->getMockBuilder('\Thelia\Model\CartItem')
->disableOriginalConstructor()
->getMock()
;
$cartItem2Stub
->expects($this->any())
->method('getProductSaleElements')
->will($this->returnValue($pse2))
;
$cartItem2Stub
->expects($this->any())
->method('getQuantity')
->will($this->returnValue(2))
;
$cartItem2Stub
->expects($this->any())
->method('getPrice')
->will($this->returnValue(150))
;
$cartStub = $this->getMockBuilder('\Thelia\Model\Cart')
->disableOriginalConstructor()
->getMock();
if ($count == 1)
$ret = [$cartItem1Stub];
else
$ret = [$cartItem1Stub, $cartItem2Stub];
$cartStub
->expects($this->any())
->method('getCartItems')
->will($this->returnValue($ret));
$stubFacade->expects($this->any())
->method('getCart')
->will($this->returnValue($cartStub));
}
public function generateNoMatchingCart(\PHPUnit_Framework_MockObject_MockObject $stubFacade) {
$attrCombination1 = $this->getMockBuilder('\Thelia\Model\AttributeCombination')
->disableOriginalConstructor()
->getMock()
;
$attrCombination1
->expects($this->any())
->method('getAttributeAvId')
->will($this->returnValue(30))
;
$pse1 = $this->getMockBuilder('\Thelia\Model\ProductSaleElements')
->disableOriginalConstructor()
->getMock()
;
$pse1
->expects($this->any())
->method('getAttributeCombinations')
->will($this->returnValue([$attrCombination1]))
;
$cartItem1Stub = $this->getMockBuilder('\Thelia\Model\CartItem')
->disableOriginalConstructor()
->getMock()
;
$cartItem1Stub
->expects($this->any())
->method('getProductSaleElements')
->will($this->returnValue($pse1))
;
$cartItem1Stub
->expects($this->any())
->method('getQuantity')
->will($this->returnValue(1))
;
$cartItem1Stub
->expects($this->any())
->method('getPrice')
->will($this->returnValue(100))
;
$cartStub = $this->getMockBuilder('\Thelia\Model\Cart')
->disableOriginalConstructor()
->getMock();
$cartStub
->expects($this->any())
->method('getCartItems')
->will($this->returnValue([$cartItem1Stub]));
$stubFacade->expects($this->any())
->method('getCart')
->will($this->returnValue($cartStub));
}
public function testSet()
{
$stubFacade = $this->generateFacadeStub();
$coupon = new RemovePercentageOnAttributeValues($stubFacade);
$date = new \DateTime();
$coupon->set(
$stubFacade,
'TEST', 'TEST Coupon', 'This is a test coupon title', 'This is a test coupon description',
array('percentage' => 10.00, 'attribute_avs' => [10, 20]),
true, true, true, true,
254,
$date->setTimestamp(strtotime("today + 3 months")),
new ObjectCollection(),
new ObjectCollection(),
false
);
$condition1 = new MatchForTotalAmount($stubFacade);
$operators = array(
MatchForTotalAmount::CART_TOTAL => Operators::SUPERIOR,
MatchForTotalAmount::CART_CURRENCY => Operators::EQUAL
);
$values = array(
MatchForTotalAmount::CART_TOTAL => 40.00,
MatchForTotalAmount::CART_CURRENCY => 'EUR'
);
$condition1->setValidatorsFromForm($operators, $values);
$condition2 = new MatchForTotalAmount($stubFacade);
$operators = array(
MatchForTotalAmount::CART_TOTAL => Operators::INFERIOR,
MatchForTotalAmount::CART_CURRENCY => Operators::EQUAL
);
$values = array(
MatchForTotalAmount::CART_TOTAL => 400.00,
MatchForTotalAmount::CART_CURRENCY => 'EUR'
);
$condition2->setValidatorsFromForm($operators, $values);
$conditions = new ConditionCollection();
$conditions[] = $condition1;
$conditions[] = $condition2;
$coupon->setConditions($conditions);
$this->assertEquals('TEST', $coupon->getCode());
$this->assertEquals('TEST Coupon', $coupon->getTitle());
$this->assertEquals('This is a test coupon title', $coupon->getShortDescription());
$this->assertEquals('This is a test coupon description', $coupon->getDescription());
$this->assertEquals(true, $coupon->isCumulative());
$this->assertEquals(true, $coupon->isRemovingPostage());
$this->assertEquals(true, $coupon->isAvailableOnSpecialOffers());
$this->assertEquals(true, $coupon->isEnabled());
$this->assertEquals(254, $coupon->getMaxUsage());
$this->assertEquals($date, $coupon->getExpirationDate());
}
public function testMatchOne()
{
$stubFacade = $this->generateFacadeStub();
$coupon = new RemovePercentageOnAttributeValues($stubFacade);
$date = new \DateTime();
$coupon->set(
$stubFacade,
'TEST', 'TEST Coupon', 'This is a test coupon title', 'This is a test coupon description',
array('percentage' => 10.00, 'attribute_avs' => [10, 20]),
true, true, true, true,
254,
$date->setTimestamp(strtotime("today + 3 months")),
new ObjectCollection(),
new ObjectCollection(),
false
);
$this->generateMatchingCart($stubFacade, 1);
$this->assertEquals(10.00, $coupon->exec());
}
public function testMatchSeveral()
{
$stubFacade = $this->generateFacadeStub();
$coupon = new RemovePercentageOnAttributeValues($stubFacade);
$date = new \DateTime();
$coupon->set(
$stubFacade,
'TEST', 'TEST Coupon', 'This is a test coupon title', 'This is a test coupon description',
array('percentage' => 10.00, 'attribute_avs' => [10, 20]),
true, true, true, true,
254,
$date->setTimestamp(strtotime("today + 3 months")),
new ObjectCollection(),
new ObjectCollection(),
false
);
$this->generateMatchingCart($stubFacade, 2);
$this->assertEquals(40.00, $coupon->exec());
}
public function testNoMatch()
{
$stubFacade = $this->generateFacadeStub();
$coupon = new RemovePercentageOnAttributeValues($stubFacade);
$date = new \DateTime();
$coupon->set(
$stubFacade,
'TEST', 'TEST Coupon', 'This is a test coupon title', 'This is a test coupon description',
array('percentage' => 10.00, 'attribute_avs' => [10, 20]),
true, true, true, true,
254,
$date->setTimestamp(strtotime("today + 3 months")),
new ObjectCollection(),
new ObjectCollection(),
false
);
$this->generateNoMatchingCart($stubFacade);
$this->assertEquals(0.00, $coupon->exec());
}
public function testGetName()
{
$stubFacade = $this->generateFacadeStub(399, 'EUR', 'Coupon test name');
/** @var FacadeInterface $stubFacade */
$coupon = new RemovePercentageOnAttributeValues($stubFacade);
$actual = $coupon->getName();
$expected = 'Coupon test name';
$this->assertEquals($expected, $actual);
}
public function testGetToolTip()
{
$tooltip = 'Coupon test tooltip';
$stubFacade = $this->generateFacadeStub(399, 'EUR', $tooltip);
/** @var FacadeInterface $stubFacade */
$coupon = new RemovePercentageOnAttributeValues($stubFacade);
$actual = $coupon->getToolTip();
$expected = $tooltip;
$this->assertEquals($expected, $actual);
}
/**
* Tears down the fixture, for example, closes a network connection.
* This method is called after a test is executed.
*/
protected function tearDown()
{
}
}

View File

@@ -0,0 +1,346 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\Coupon\Type;
use Propel\Runtime\Collection\ObjectCollection;
use Thelia\Condition\ConditionCollection;
use Thelia\Condition\ConditionEvaluator;
use Thelia\Condition\Implementation\MatchForTotalAmount;
use Thelia\Condition\Operators;
use Thelia\Coupon\FacadeInterface;
use Thelia\Model\Category;
use Thelia\Model\CurrencyQuery;
use Thelia\Model\Product;
/**
* @package Coupon
* @author Franck Allimant <franck@cqfdev.fr>
*/
class RemovePercentageOnCategoriesTest extends \PHPUnit_Framework_TestCase
{
/**
* Sets up the fixture, for example, opens a network connection.
* This method is called before a test is executed.
*/
protected function setUp()
{
}
/**
* Generate adapter stub
*
* @param int $cartTotalPrice Cart total price
* @param string $checkoutCurrency Checkout currency
* @param string $i18nOutput Output from each translation
*
* @return \PHPUnit_Framework_MockObject_MockObject
*/
public function generateFacadeStub($cartTotalPrice = 400, $checkoutCurrency = 'EUR', $i18nOutput = '')
{
$stubFacade = $this->getMockBuilder('\Thelia\Coupon\BaseFacade')
->disableOriginalConstructor()
->getMock();
$currencies = CurrencyQuery::create();
$currencies = $currencies->find();
$stubFacade->expects($this->any())
->method('getAvailableCurrencies')
->will($this->returnValue($currencies));
$stubFacade->expects($this->any())
->method('getCartTotalPrice')
->will($this->returnValue($cartTotalPrice));
$stubFacade->expects($this->any())
->method('getCheckoutCurrency')
->will($this->returnValue($checkoutCurrency));
$stubFacade->expects($this->any())
->method('getConditionEvaluator')
->will($this->returnValue(new ConditionEvaluator()));
$stubTranslator = $this->getMockBuilder('\Thelia\Core\Translation\Translator')
->disableOriginalConstructor()
->getMock();
$stubTranslator->expects($this->any())
->method('trans')
->will($this->returnValue($i18nOutput));
$stubFacade->expects($this->any())
->method('getTranslator')
->will($this->returnValue($stubTranslator));
return $stubFacade;
}
public function generateMatchingCart(\PHPUnit_Framework_MockObject_MockObject $stubFacade) {
$category1 = new Category();
$category1->setId(10);
$category2 = new Category();
$category2->setId(20);
$category3 = new Category();
$category3->setId(30);
$product1 = new Product();
$product1->addCategory($category1)->addCategory($category2);
$product2 = new Product();
$product2->addCategory($category3);
$cartItem1Stub = $this->getMockBuilder('\Thelia\Model\CartItem')
->disableOriginalConstructor()
->getMock();
$cartItem1Stub
->expects($this->any())
->method('getProduct')
->will($this->returnValue($product1))
;
$cartItem1Stub
->expects($this->any())
->method('getQuantity')
->will($this->returnValue(1))
;
$cartItem1Stub
->expects($this->any())
->method('getPrice')
->will($this->returnValue(100))
;
$cartItem2Stub = $this->getMockBuilder('\Thelia\Model\CartItem')
->disableOriginalConstructor()
->getMock();
$cartItem2Stub
->expects($this->any())
->method('getProduct')
->will($this->returnValue($product2))
;
$cartItem2Stub
->expects($this->any())
->method('getQuantity')
->will($this->returnValue(2))
;
$cartItem2Stub
->expects($this->any())
->method('getPrice')
->will($this->returnValue(200))
;
$cartStub = $this->getMockBuilder('\Thelia\Model\Cart')
->disableOriginalConstructor()
->getMock();
$cartStub
->expects($this->any())
->method('getCartItems')
->will($this->returnValue([$cartItem1Stub, $cartItem2Stub]));
$stubFacade->expects($this->any())
->method('getCart')
->will($this->returnValue($cartStub));
}
public function generateNoMatchingCart(\PHPUnit_Framework_MockObject_MockObject $stubFacade) {
$category3 = new Category();
$category3->setId(30);
$product2 = new Product();
$product2->addCategory($category3);
$cartItem2Stub = $this->getMockBuilder('\Thelia\Model\CartItem')
->disableOriginalConstructor()
->getMock();
$cartItem2Stub->expects($this->any())
->method('getProduct')
->will($this->returnValue($product2));
$cartItem2Stub->expects($this->any())
->method('getQuantity')
->will($this->returnValue(2));
$cartItem2Stub
->expects($this->any())
->method('getPrice')
->will($this->returnValue(200000))
;
$cartStub = $this->getMockBuilder('\Thelia\Model\Cart')
->disableOriginalConstructor()
->getMock();
$cartStub
->expects($this->any())
->method('getCartItems')
->will($this->returnValue([$cartItem2Stub]));
$stubFacade->expects($this->any())
->method('getCart')
->will($this->returnValue($cartStub));
}
public function testSet()
{
$stubFacade = $this->generateFacadeStub();
$coupon = new RemovePercentageOnCategories($stubFacade);
$date = new \DateTime();
$coupon->set(
$stubFacade,
'TEST', 'TEST Coupon', 'This is a test coupon title', 'This is a test coupon description',
array('percentage' => 10, 'categories' => [10, 20]),
true, true, true, true,
254,
$date->setTimestamp(strtotime("today + 3 months")),
new ObjectCollection(),
new ObjectCollection(),
false
);
$condition1 = new MatchForTotalAmount($stubFacade);
$operators = array(
MatchForTotalAmount::CART_TOTAL => Operators::SUPERIOR,
MatchForTotalAmount::CART_CURRENCY => Operators::EQUAL
);
$values = array(
MatchForTotalAmount::CART_TOTAL => 40.00,
MatchForTotalAmount::CART_CURRENCY => 'EUR'
);
$condition1->setValidatorsFromForm($operators, $values);
$condition2 = new MatchForTotalAmount($stubFacade);
$operators = array(
MatchForTotalAmount::CART_TOTAL => Operators::INFERIOR,
MatchForTotalAmount::CART_CURRENCY => Operators::EQUAL
);
$values = array(
MatchForTotalAmount::CART_TOTAL => 400.00,
MatchForTotalAmount::CART_CURRENCY => 'EUR'
);
$condition2->setValidatorsFromForm($operators, $values);
$conditions = new ConditionCollection();
$conditions[] = $condition1;
$conditions[] = $condition2;
$coupon->setConditions($conditions);
$this->assertEquals('TEST', $coupon->getCode());
$this->assertEquals('TEST Coupon', $coupon->getTitle());
$this->assertEquals('This is a test coupon title', $coupon->getShortDescription());
$this->assertEquals('This is a test coupon description', $coupon->getDescription());
$this->assertEquals(true, $coupon->isCumulative());
$this->assertEquals(true, $coupon->isRemovingPostage());
$this->assertEquals(true, $coupon->isAvailableOnSpecialOffers());
$this->assertEquals(true, $coupon->isEnabled());
$this->assertEquals(254, $coupon->getMaxUsage());
$this->assertEquals($date, $coupon->getExpirationDate());
}
public function testMatch()
{
$stubFacade = $this->generateFacadeStub();
$coupon = new RemovePercentageOnCategories($stubFacade);
$date = new \DateTime();
$coupon->set(
$stubFacade,
'TEST', 'TEST Coupon', 'This is a test coupon title', 'This is a test coupon description',
array('percentage' => 10, 'categories' => [10, 20]),
true, true, true, true,
254,
$date->setTimestamp(strtotime("today + 3 months")),
new ObjectCollection(),
new ObjectCollection(),
false
);
$this->generateMatchingCart($stubFacade);
$this->assertEquals(10.00, $coupon->exec());
}
public function testNoMatch()
{
$stubFacade = $this->generateFacadeStub();
$coupon = new RemovePercentageOnCategories($stubFacade);
$date = new \DateTime();
$coupon->set(
$stubFacade,
'TEST', 'TEST Coupon', 'This is a test coupon title', 'This is a test coupon description',
array('percentage' => 10, 'categories' => [10, 20]),
true, true, true, true,
254,
$date->setTimestamp(strtotime("today + 3 months")),
new ObjectCollection(),
new ObjectCollection(),
false
);
$this->generateNoMatchingCart($stubFacade);
$this->assertEquals(0.00, $coupon->exec());
}
/**
* @covers Thelia\Coupon\Type\RemoveXAmount::getName
*/
public function testGetName()
{
$stubFacade = $this->generateFacadeStub(399, 'EUR', 'Coupon test name');
/** @var FacadeInterface $stubFacade */
$coupon = new RemovePercentageOnCategories($stubFacade);
$actual = $coupon->getName();
$expected = 'Coupon test name';
$this->assertEquals($expected, $actual);
}
/**
* @covers Thelia\Coupon\Type\RemoveXAmount::getToolTip
*/
public function testGetToolTip()
{
$tooltip = 'Coupon test tooltip';
$stubFacade = $this->generateFacadeStub(399, 'EUR', $tooltip);
/** @var FacadeInterface $stubFacade */
$coupon = new RemovePercentageOnCategories($stubFacade);
$actual = $coupon->getToolTip();
$expected = $tooltip;
$this->assertEquals($expected, $actual);
}
/**
* Tears down the fixture, for example, closes a network connection.
* This method is called after a test is executed.
*/
protected function tearDown()
{
}
}

View File

@@ -0,0 +1,360 @@
<?php
/*************************************************************************************/
/* This file is part of the Thelia package. */
/* */
/* Copyright (c) OpenStudio */
/* email : dev@thelia.net */
/* web : http://www.thelia.net */
/* */
/* For the full copyright and license information, please view the LICENSE.txt */
/* file that was distributed with this source code. */
/*************************************************************************************/
namespace Thelia\Coupon\Type;
use Propel\Runtime\Collection\ObjectCollection;
use Thelia\Condition\ConditionCollection;
use Thelia\Condition\ConditionEvaluator;
use Thelia\Condition\Implementation\MatchForTotalAmount;
use Thelia\Condition\Operators;
use Thelia\Coupon\FacadeInterface;
use Thelia\Model\CurrencyQuery;
use Thelia\Model\Product;
/**
* @package Coupon
* @author Franck Allimant <franck@cqfdev.fr>
*/
class RemovePercentageOnProductsTest extends \PHPUnit_Framework_TestCase
{
/**
* Sets up the fixture, for example, opens a network connection.
* This method is called before a test is executed.
*/
protected function setUp()
{
}
/**
* Generate adapter stub
*
* @param int $cartTotalPrice Cart total price
* @param string $checkoutCurrency Checkout currency
* @param string $i18nOutput Output from each translation
*
* @return \PHPUnit_Framework_MockObject_MockObject
*/
public function generateFacadeStub($cartTotalPrice = 400, $checkoutCurrency = 'EUR', $i18nOutput = '')
{
$stubFacade = $this->getMockBuilder('\Thelia\Coupon\BaseFacade')
->disableOriginalConstructor()
->getMock();
$currencies = CurrencyQuery::create();
$currencies = $currencies->find();
$stubFacade->expects($this->any())
->method('getAvailableCurrencies')
->will($this->returnValue($currencies));
$stubFacade->expects($this->any())
->method('getCartTotalPrice')
->will($this->returnValue($cartTotalPrice));
$stubFacade->expects($this->any())
->method('getCheckoutCurrency')
->will($this->returnValue($checkoutCurrency));
$stubFacade->expects($this->any())
->method('getConditionEvaluator')
->will($this->returnValue(new ConditionEvaluator()));
$stubTranslator = $this->getMockBuilder('\Thelia\Core\Translation\Translator')
->disableOriginalConstructor()
->getMock();
$stubTranslator->expects($this->any())
->method('trans')
->will($this->returnValue($i18nOutput));
$stubFacade->expects($this->any())
->method('getTranslator')
->will($this->returnValue($stubTranslator));
return $stubFacade;
}
public function generateMatchingCart(\PHPUnit_Framework_MockObject_MockObject $stubFacade, $count) {
$product1 = new Product();
$product1->setId(10);
$product2 = new Product();
$product2->setId(20);
$cartItem1Stub = $this->getMockBuilder('\Thelia\Model\CartItem')
->disableOriginalConstructor()
->getMock();
$cartItem1Stub
->expects($this->any())
->method('getProduct')
->will($this->returnValue($product1))
;
$cartItem1Stub
->expects($this->any())
->method('getQuantity')
->will($this->returnValue(1))
;
$cartItem1Stub
->expects($this->any())
->method('getPrice')
->will($this->returnValue(100))
;
$cartItem2Stub = $this->getMockBuilder('\Thelia\Model\CartItem')
->disableOriginalConstructor()
->getMock();
$cartItem2Stub
->expects($this->any())
->method('getProduct')
->will($this->returnValue($product2));
$cartItem2Stub
->expects($this->any())
->method('getQuantity')
->will($this->returnValue(2))
;
$cartItem2Stub
->expects($this->any())
->method('getPrice')
->will($this->returnValue(150))
;
$cartStub = $this->getMockBuilder('\Thelia\Model\Cart')
->disableOriginalConstructor()
->getMock();
if ($count == 1)
$ret = [$cartItem1Stub];
else
$ret = [$cartItem1Stub, $cartItem2Stub];
$cartStub
->expects($this->any())
->method('getCartItems')
->will($this->returnValue($ret));
$stubFacade->expects($this->any())
->method('getCart')
->will($this->returnValue($cartStub));
}
public function generateNoMatchingCart(\PHPUnit_Framework_MockObject_MockObject $stubFacade) {
$product2 = new Product();
$product2->setId(30);
$cartItem2Stub = $this->getMockBuilder('\Thelia\Model\CartItem')
->disableOriginalConstructor()
->getMock();
$cartItem2Stub->expects($this->any())
->method('getProduct')
->will($this->returnValue($product2))
;
$cartItem2Stub->expects($this->any())
->method('getQuantity')
->will($this->returnValue(2))
;
$cartItem2Stub
->expects($this->any())
->method('getPrice')
->will($this->returnValue(11000))
;
$cartStub = $this->getMockBuilder('\Thelia\Model\Cart')
->disableOriginalConstructor()
->getMock();
$cartStub
->expects($this->any())
->method('getCartItems')
->will($this->returnValue([$cartItem2Stub]));
$stubFacade->expects($this->any())
->method('getCart')
->will($this->returnValue($cartStub));
}
public function testSet()
{
$stubFacade = $this->generateFacadeStub();
$coupon = new RemovePercentageOnProducts($stubFacade);
$date = new \DateTime();
$coupon->set(
$stubFacade,
'TEST', 'TEST Coupon', 'This is a test coupon title', 'This is a test coupon description',
array('percentage' => 10.00, 'products' => [10, 20]),
true, true, true, true,
254,
$date->setTimestamp(strtotime("today + 3 months")),
new ObjectCollection(),
new ObjectCollection(),
false
);
$condition1 = new MatchForTotalAmount($stubFacade);
$operators = array(
MatchForTotalAmount::CART_TOTAL => Operators::SUPERIOR,
MatchForTotalAmount::CART_CURRENCY => Operators::EQUAL
);
$values = array(
MatchForTotalAmount::CART_TOTAL => 40.00,
MatchForTotalAmount::CART_CURRENCY => 'EUR'
);
$condition1->setValidatorsFromForm($operators, $values);
$condition2 = new MatchForTotalAmount($stubFacade);
$operators = array(
MatchForTotalAmount::CART_TOTAL => Operators::INFERIOR,
MatchForTotalAmount::CART_CURRENCY => Operators::EQUAL
);
$values = array(
MatchForTotalAmount::CART_TOTAL => 400.00,
MatchForTotalAmount::CART_CURRENCY => 'EUR'
);
$condition2->setValidatorsFromForm($operators, $values);
$conditions = new ConditionCollection();
$conditions[] = $condition1;
$conditions[] = $condition2;
$coupon->setConditions($conditions);
$this->assertEquals('TEST', $coupon->getCode());
$this->assertEquals('TEST Coupon', $coupon->getTitle());
$this->assertEquals('This is a test coupon title', $coupon->getShortDescription());
$this->assertEquals('This is a test coupon description', $coupon->getDescription());
$this->assertEquals(true, $coupon->isCumulative());
$this->assertEquals(true, $coupon->isRemovingPostage());
$this->assertEquals(true, $coupon->isAvailableOnSpecialOffers());
$this->assertEquals(true, $coupon->isEnabled());
$this->assertEquals(254, $coupon->getMaxUsage());
$this->assertEquals($date, $coupon->getExpirationDate());
}
public function testMatchOne()
{
$stubFacade = $this->generateFacadeStub();
$coupon = new RemovePercentageOnProducts($stubFacade);
$date = new \DateTime();
$coupon->set(
$stubFacade,
'TEST', 'TEST Coupon', 'This is a test coupon title', 'This is a test coupon description',
array('percentage' => 10.00, 'products' => [10, 20]),
true, true, true, true,
254,
$date->setTimestamp(strtotime("today + 3 months")),
new ObjectCollection(),
new ObjectCollection(),
false
);
$this->generateMatchingCart($stubFacade, 1);
$this->assertEquals(10.00, $coupon->exec());
}
public function testMatchSeveral()
{
$stubFacade = $this->generateFacadeStub();
$coupon = new RemovePercentageOnProducts($stubFacade);
$date = new \DateTime();
$coupon->set(
$stubFacade,
'TEST', 'TEST Coupon', 'This is a test coupon title', 'This is a test coupon description',
array('percentage' => 10.00, 'products' => [10, 20]),
true, true, true, true,
254,
$date->setTimestamp(strtotime("today + 3 months")),
new ObjectCollection(),
new ObjectCollection(),
false
);
$this->generateMatchingCart($stubFacade, 2);
$this->assertEquals(40.00, $coupon->exec());
}
public function testNoMatch()
{
$stubFacade = $this->generateFacadeStub();
$coupon = new RemovePercentageOnProducts($stubFacade);
$date = new \DateTime();
$coupon->set(
$stubFacade,
'TEST', 'TEST Coupon', 'This is a test coupon title', 'This is a test coupon description',
array('percentage' => 10.00, 'products' => [10, 20]),
true, true, true, true,
254,
$date->setTimestamp(strtotime("today + 3 months")),
new ObjectCollection(),
new ObjectCollection(),
false
);
$this->generateNoMatchingCart($stubFacade);
$this->assertEquals(0.00, $coupon->exec());
}
public function testGetName()
{
$stubFacade = $this->generateFacadeStub(399, 'EUR', 'Coupon test name');
/** @var FacadeInterface $stubFacade */
$coupon = new RemovePercentageOnProducts($stubFacade);
$actual = $coupon->getName();
$expected = 'Coupon test name';
$this->assertEquals($expected, $actual);
}
public function testGetToolTip()
{
$tooltip = 'Coupon test tooltip';
$stubFacade = $this->generateFacadeStub(399, 'EUR', $tooltip);
/** @var FacadeInterface $stubFacade */
$coupon = new RemovePercentageOnProducts($stubFacade);
$actual = $coupon->getToolTip();
$expected = $tooltip;
$this->assertEquals($expected, $actual);
}
/**
* Tears down the fixture, for example, closes a network connection.
* This method is called after a test is executed.
*/
protected function tearDown()
{
}
}