- Coupon Add/Edit/Delete rule AJAX
This commit is contained in:
gmorel
2013-09-10 20:00:43 +02:00
parent 3ffc948d4b
commit 8be785e9b3
11 changed files with 409 additions and 622 deletions

View File

@@ -24,6 +24,7 @@
namespace Thelia\Action; namespace Thelia\Action;
use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Thelia\Constraint\ConstraintFactory;
use Thelia\Core\Event\Coupon\CouponCreateOrUpdateEvent; use Thelia\Core\Event\Coupon\CouponCreateOrUpdateEvent;
use Thelia\Core\Event\TheliaEvents; use Thelia\Core\Event\TheliaEvents;
use Thelia\Model\Coupon as CouponModel; use Thelia\Model\Coupon as CouponModel;
@@ -68,18 +69,6 @@ class Coupon extends BaseAction implements EventSubscriberInterface
$this->createOrUpdate($coupon, $event); $this->createOrUpdate($coupon, $event);
} }
/**
* Occurring when a Coupon rule is about to be created
*
* @param CouponCreateOrUpdateEvent $event Event creation or update Event
*/
public function createRule(CouponCreateOrUpdateEvent $event)
{
$coupon = $event->getCoupon();
$this->createOrUpdate($coupon, $event);
}
/** /**
* Occurring when a Coupon rule is about to be updated * Occurring when a Coupon rule is about to be updated
* *
@@ -89,19 +78,7 @@ class Coupon extends BaseAction implements EventSubscriberInterface
{ {
$coupon = $event->getCoupon(); $coupon = $event->getCoupon();
$this->createOrUpdate($coupon, $event); $this->createOrUpdateRule($coupon, $event);
}
/**
* Occurring when a Coupon rule is about to be deleted
*
* @param CouponCreateOrUpdateEvent $event Event creation or update Event
*/
public function deleteRule(CouponCreateOrUpdateEvent $event)
{
$coupon = $event->getCoupon();
$this->createOrUpdate($coupon, $event);
} }
/** /**
@@ -130,6 +107,7 @@ class Coupon extends BaseAction implements EventSubscriberInterface
$event->getTitle(), $event->getTitle(),
$event->getAmount(), $event->getAmount(),
$event->getEffect(), $event->getEffect(),
$event->isRemovingPostage(),
$event->getShortDescription(), $event->getShortDescription(),
$event->getDescription(), $event->getDescription(),
$event->isEnabled(), $event->isEnabled(),
@@ -137,7 +115,28 @@ class Coupon extends BaseAction implements EventSubscriberInterface
$event->isAvailableOnSpecialOffers(), $event->isAvailableOnSpecialOffers(),
$event->isCumulative(), $event->isCumulative(),
$event->getMaxUsage(), $event->getMaxUsage(),
$event->getRules(), $event->getLocale()
);
$event->setCoupon($coupon);
}
/**
* Call the Model and delegate the create or delete action
* Feed the Event with the updated model
*
* @param CouponModel $coupon Model to save
* @param CouponCreateOrUpdateEvent $event Event containing data
*/
protected function createOrUpdateRule(CouponModel $coupon, CouponCreateOrUpdateEvent $event)
{
$coupon->setDispatcher($this->getDispatcher());
/** @var ConstraintFactory $constraintFactory */
$constraintFactory = $this->container->get('thelia.constraint.factory');
$coupon->createOrUpdateRules(
$constraintFactory->serializeCouponRuleCollection($event->getRules()),
$event->getLocale() $event->getLocale()
); );
@@ -172,8 +171,7 @@ class Coupon extends BaseAction implements EventSubscriberInterface
TheliaEvents::COUPON_DISABLE => array("disable", 128), TheliaEvents::COUPON_DISABLE => array("disable", 128),
TheliaEvents::COUPON_ENABLE => array("enable", 128), TheliaEvents::COUPON_ENABLE => array("enable", 128),
TheliaEvents::COUPON_CONSUME => array("consume", 128), TheliaEvents::COUPON_CONSUME => array("consume", 128),
TheliaEvents::COUPON_RULE_UPDATE => array("updateRule", 128), TheliaEvents::COUPON_RULE_UPDATE => array("updateRule", 128)
TheliaEvents::COUPON_RULE_DELETE => array("deleteRule", 128)
); );
} }
} }

View File

@@ -73,70 +73,6 @@ class AvailableForTotalAmountManager extends CouponRuleAbstract
) )
); );
// /** @var RuleValidator Price Validator */
// protected $priceValidator = null;
// /**
// * Check if backoffice inputs are relevant or not
// *
// * @throws InvalidRuleOperatorException if Operator is not allowed
// * @throws InvalidRuleValueException if Value is not allowed
// * @return bool
// */
// public function checkBackOfficeInput()
// {
// if (!isset($this->validators)
// || empty($this->validators)
// ||!isset($this->validators[self::PARAM1_PRICE])
// ||!isset($this->validators[self::PARAM1_PRICE])
// ) {
// throw new InvalidRuleValueException(get_class(), self::PARAM1_PRICE);
// }
//
// /** @var RuleValidator $ruleValidator */
// $ruleValidator = $this->validators[self::PARAM1_PRICE];
// /** @var PriceParam $price */
// $price = $ruleValidator->getParam();
//
// if (!$price instanceof PriceParam) {
// throw new InvalidRuleValueException(get_class(), self::PARAM1_PRICE);
// }
//
// $this->checkBackOfficeInputsOperators();
//
// return $this->isPriceValid($price->getPrice(), $price->getCurrency());
// }
// /**
// * Check if Checkout inputs are relevant or not
// *
// * @throws InvalidRuleValueException if Value is not allowed
// * @return bool
// */
// public function checkCheckoutInput()
// {
// $currency = $this->adapter->getCheckoutCurrency();
// if (empty($currency)) {
// throw new InvalidRuleValueException(
// get_class(), self::PARAM1_CURRENCY
// );
// }
//
// $price = $this->adapter->getCartTotalPrice();
// if (empty($price)) {
// throw new InvalidRuleValueException(
// get_class(), self::PARAM1_PRICE
// );
// }
//
// $this->paramsToValidate = array(
// self::PARAM1_PRICE => $this->adapter->getCartTotalPrice(),
// self::PARAM1_CURRENCY => $this->adapter->getCheckoutCurrency()
// );
//
// return $this->isPriceValid($price, $currency);
// }
/** /**
* Check validators relevancy and store them * Check validators relevancy and store them
* *
@@ -249,49 +185,6 @@ class AvailableForTotalAmountManager extends CouponRuleAbstract
return false; return false;
} }
// /**
// * Check if a price is valid
// *
// * @param float $price Price to check
// * @param string $currency Price currency
// *
// * @throws InvalidRuleValueException if Value is not allowed
// * @return bool
// */
// protected function isPriceValid($price, $currency)
// {
// $priceValidator = $this->priceValidator;
//
// /** @var PriceParam $param */
// $param = $priceValidator->getParam();
// if ($currency == $param->getCurrency()) {
// try {
// $priceValidator->getParam()->compareTo($price);
// } catch(\InvalidArgumentException $e) {
// throw new InvalidRuleValueException(get_class(), self::PARAM1_PRICE);
// }
// } else {
// throw new InvalidRuleValueException(get_class(), self::PARAM1_CURRENCY);
// }
//
// return true;
// }
// /**
// * Generate current Rule param to be validated from adapter
// *
// * @return $this
// */
// protected function setParametersToValidate()
// {
// $this->paramsToValidate = array(
// self::PARAM1_PRICE => $this->adapter->getCartTotalPrice(),
// self::PARAM1_CURRENCY => $this->adapter->getCheckoutCurrency()
// );
//
// return $this;
// }
/** /**
* Get I18n name * Get I18n name
* *
@@ -377,41 +270,4 @@ class AvailableForTotalAmountManager extends CouponRuleAbstract
); );
} }
// /**
// * Populate a Rule from a form admin
// *
// * @param array $operators Rule Operator set by the Admin
// * @param array $values Rule Values set by the Admin
// *
// * @throws \InvalidArgumentException
// * @return $this
// */
// public function populateFromForm(array $operators, array $values)
// {
// if ($values[self::PARAM1_PRICE] === null
// || $values[self::PARAM1_CURRENCY] === null
// ) {
// throw new \InvalidArgumentException(
// 'The Rule ' . get_class() . 'needs at least a quantity set (' . self::PARAM1_PRICE . ', ' . self::PARAM1_CURRENCY . ')'
// );
// }
//
// $this->priceValidator = new RuleValidator(
// $operators[self::PARAM1_PRICE],
// new PriceParam(
// $this->translator,
// $values[self::PARAM1_PRICE],
// $values[self::PARAM1_CURRENCY]
// )
// );
//
// $this->validators = array(self::PARAM1_PRICE => $this->priceValidator);
//
// return $this;
// }
} }

View File

@@ -63,77 +63,6 @@ class AvailableForXArticlesManager extends CouponRuleAbstract
) )
); );
// /** @var QuantityParam Quantity Validator */
// protected $quantityValidator = null;
// /**
// * Check if backoffice inputs are relevant or not
// *
// * @throws InvalidRuleOperatorException if Operator is not allowed
// * @throws InvalidRuleValueException if Value is not allowed
// * @return bool
// */
// public function checkBackOfficeInput()
// {
// if (!isset($this->validators)
// || empty($this->validators)
// ||!isset($this->validators[self::PARAM1_QUANTITY])
// ||!isset($this->validators[self::PARAM1_QUANTITY])
// ) {
// throw new InvalidRuleValueException(get_class(), self::PARAM1_QUANTITY);
// }
//
// /** @var RuleValidator $ruleValidator */
// $ruleValidator = $this->validators[self::PARAM1_QUANTITY];
// /** @var QuantityParam $quantity */
// $quantity = $ruleValidator->getParam();
//
// if (!$quantity instanceof QuantityParam) {
// throw new InvalidRuleValueException(get_class(), self::PARAM1_QUANTITY);
// }
//
// $this->checkBackOfficeInputsOperators();
//
// return $this->isQuantityValid($quantity->getInteger());
// }
// /**
// * Generate current Rule param to be validated from adapter
// *
// * @param CouponAdapterInterface $adapter allowing to gather
// * all necessary Thelia variables
// *
// * @return $this
// */
// protected function setParametersToValidate()
// {
// $this->paramsToValidate = array(
// self::PARAM1_QUANTITY => $this->adapter->getNbArticlesInCart()
// );
//
// return $this;
// }
// /**
// * Check if Checkout inputs are relevant or not
// *
// * @throws \Thelia\Exception\InvalidRuleValueException
// * @return bool
// */
// public function checkCheckoutInput()
// {
// if (!isset($this->paramsToValidate)
// || empty($this->paramsToValidate)
// ||!isset($this->paramsToValidate[self::PARAM1_QUANTITY])
// ) {
// throw new InvalidRuleValueException(get_class(), self::PARAM1_QUANTITY);
// }
//
// $price = $this->paramsToValidate[self::PARAM1_QUANTITY];
//
// return $this->isQuantityValid($price);
// }
/** /**
* Check validators relevancy and store them * Check validators relevancy and store them
* *
@@ -174,7 +103,7 @@ class AvailableForXArticlesManager extends CouponRuleAbstract
); );
} }
if (!is_int($quantityValue) || $quantityValue <= 0) { if ((int) $quantityValue <= 0) {
throw new \InvalidArgumentException( throw new \InvalidArgumentException(
'Value for quantity field is not legit' 'Value for quantity field is not legit'
); );
@@ -210,26 +139,6 @@ class AvailableForXArticlesManager extends CouponRuleAbstract
return false; return false;
} }
// /**
// * Check if a quantity is valid
// *
// * @param int $quantity Quantity to check
// *
// * @throws InvalidRuleValueException if Value is not allowed
// * @return bool
// */
// protected function isQuantityValid($quantity)
// {
// $quantityValidator = $this->quantityValidator;
// try {
// $quantityValidator->getParam()->compareTo($quantity);
// } catch(InvalidArgumentException $e) {
// throw new InvalidRuleValueException(get_class(), self::PARAM1_QUANTITY);
// }
//
// return true;
// }
/** /**
* Get I18n name * Get I18n name
* *
@@ -267,36 +176,6 @@ class AvailableForXArticlesManager extends CouponRuleAbstract
return $toolTip; return $toolTip;
} }
// /**
// * Populate a Rule from a form admin
// *
// * @param array $operators Rule Operator set by the Admin
// * @param array $values Rule Values set by the Admin
// *
// * @throws InvalidArgumentException
// * @return $this
// */
// public function populateFromForm(array $operators, array $values)
// {
// if ($values[self::PARAM1_QUANTITY] === null) {
// throw new InvalidArgumentException(
// 'The Rule ' . get_class() . 'needs at least a quantity set (' . self::PARAM1_QUANTITY. ')'
// );
// }
//
// $this->quantityValidator = new RuleValidator(
// $operators[self::PARAM1_QUANTITY],
// new QuantityParam(
// $this->adapter,
// $values[self::PARAM1_QUANTITY]
// )
// );
//
// $this->validators = array(self::PARAM1_QUANTITY => $this->quantityValidator);
//
// return $this;
// }
/** /**
* Generate inputs ready to be drawn * Generate inputs ready to be drawn
* *

View File

@@ -158,6 +158,13 @@ class CouponController extends BaseAdminController
); );
} else { } else {
// Prepare the data that will hydrate the form // Prepare the data that will hydrate the form
/** @var ConstraintFactory $constraintFactory */
$constraintFactory = $this->container->get('thelia.constraint.factory');
$rules = $constraintFactory->unserializeCouponRuleCollection(
$coupon->getSerializedRules()
);
$data = array( $data = array(
'code' => $coupon->getCode(), 'code' => $coupon->getCode(),
'title' => $coupon->getTitle(), 'title' => $coupon->getTitle(),
@@ -171,18 +178,12 @@ class CouponController extends BaseAdminController
'isCumulative' => ($coupon->getIsCumulative() == 1), 'isCumulative' => ($coupon->getIsCumulative() == 1),
'isRemovingPostage' => ($coupon->getIsRemovingPostage() == 1), 'isRemovingPostage' => ($coupon->getIsRemovingPostage() == 1),
'maxUsage' => $coupon->getMaxUsage(), 'maxUsage' => $coupon->getMaxUsage(),
'rules' => new CouponRuleCollection(array()), 'rules' => $rules,
'locale' => $coupon->getLocale(), 'locale' => $coupon->getLocale(),
); );
$args['rulesObject'] = array(); $args['rulesObject'] = array();
/** @var ConstraintFactory $constraintFactory */
$constraintFactory = $this->container->get('thelia.constraint.factory');
$rules = $constraintFactory->unserializeCouponRuleCollection(
$coupon->getSerializedRules()
);
/** @var CouponRuleInterface $rule */ /** @var CouponRuleInterface $rule */
foreach ($rules->getRules() as $rule) { foreach ($rules->getRules() as $rule) {
$args['rulesObject'][] = array( $args['rulesObject'][] = array(
@@ -193,6 +194,8 @@ class CouponController extends BaseAdminController
); );
} }
$args['rules'] = $this->cleanRuleForTemplate($rules);
// Setup the object form // Setup the object form
$changeForm = new CouponCreationForm($this->getRequest(), 'form', $data); $changeForm = new CouponCreationForm($this->getRequest(), 'form', $data);
@@ -216,100 +219,101 @@ class CouponController extends BaseAdminController
$args['formAction'] = 'admin/coupon/update/' . $couponId; $args['formAction'] = 'admin/coupon/update/' . $couponId;
return $this->render( return $this->render('coupon-update', $args);
'coupon-update',
$args
);
} }
/** // /**
* Manage Coupons Rule creation display // * Manage Coupons Rule creation display
* // *
* @param int $couponId Coupon id // * @param int $couponId Coupon id
* // *
* @return \Symfony\Component\HttpFoundation\Response // * @return \Symfony\Component\HttpFoundation\Response
*/ // */
public function createRuleAction($couponId) // public function createRuleAction($couponId)
{ // {
// Check current user authorization // // Check current user authorization
$response = $this->checkAuth('admin.coupon.update'); // $response = $this->checkAuth('admin.coupon.update');
if ($response !== null) { // if ($response !== null) {
return $response; // return $response;
} // }
//
/** @var Coupon $coupon */ // /** @var Coupon $coupon */
$coupon = CouponQuery::create()->findOneById($couponId); // $coupon = CouponQuery::create()->findOneById($couponId);
if (!$coupon) { // if (!$coupon) {
$this->pageNotFound(); // $this->pageNotFound();
} // }
//
// Parameters given to the template // // Parameters given to the template
$args = array(); // $args = array();
//
$i18n = new I18n(); // $i18n = new I18n();
/** @var Lang $lang */ // /** @var Lang $lang */
$lang = $this->getSession()->get('lang'); // $lang = $this->getSession()->get('lang');
$eventToDispatch = TheliaEvents::COUPON_RULE_CREATE; // $eventToDispatch = TheliaEvents::COUPON_RULE_CREATE;
//
if ($this->getRequest()->isMethod('POST')) { // if ($this->getRequest()->isMethod('POST')) {
$this->validateCreateOrUpdateForm( // $this->validateCreateOrUpdateForm(
$i18n, // $i18n,
$lang, // $lang,
$eventToDispatch, // $eventToDispatch,
'updated', // 'updated',
'update' // 'update'
); // );
} else { // } else {
// Prepare the data that will hydrate the form // // Prepare the data that will hydrate the form
$data = array( //
'code' => $coupon->getCode(), // /** @var ConstraintFactory $constraintFactory */
'title' => $coupon->getTitle(), // $constraintFactory = $this->container->get('thelia.constraint.factory');
'amount' => $coupon->getAmount(), //
'effect' => $coupon->getType(), // $data = array(
'shortDescription' => $coupon->getShortDescription(), // 'code' => $coupon->getCode(),
'description' => $coupon->getDescription(), // 'title' => $coupon->getTitle(),
'isEnabled' => ($coupon->getIsEnabled() == 1), // 'amount' => $coupon->getAmount(),
'expirationDate' => $coupon->getExpirationDate($lang->getDateFormat()), // 'effect' => $coupon->getType(),
'isAvailableOnSpecialOffers' => ($coupon->getIsAvailableOnSpecialOffers() == 1), // 'shortDescription' => $coupon->getShortDescription(),
'isCumulative' => ($coupon->getIsCumulative() == 1), // 'description' => $coupon->getDescription(),
'isRemovingPostage' => ($coupon->getIsRemovingPostage() == 1), // 'isEnabled' => ($coupon->getIsEnabled() == 1),
'maxUsage' => $coupon->getMaxUsage(), // 'expirationDate' => $coupon->getExpirationDate($lang->getDateFormat()),
'rules' => new CouponRuleCollection(array()), // 'isAvailableOnSpecialOffers' => ($coupon->getIsAvailableOnSpecialOffers() == 1),
'locale' => $coupon->getLocale(), // 'isCumulative' => ($coupon->getIsCumulative() == 1),
); // 'isRemovingPostage' => ($coupon->getIsRemovingPostage() == 1),
// 'maxUsage' => $coupon->getMaxUsage(),
/** @var CouponAdapterInterface $adapter */ // 'rules' => $constraintFactory->unserializeCouponRuleCollection($coupon->getSerializedRules()),
$adapter = $this->container->get('thelia.adapter'); // 'locale' => $coupon->getLocale(),
/** @var Translator $translator */ // );
$translator = $this->container->get('thelia.translator'); //
// /** @var CouponAdapterInterface $adapter */
$args['rulesObject'] = array(); // $adapter = $this->container->get('thelia.adapter');
/** @var CouponRuleInterface $rule */ // /** @var Translator $translator */
foreach ($coupon->getRules()->getRules() as $rule) { // $translator = $this->container->get('thelia.translator');
$args['rulesObject'][] = array( //
'name' => $rule->getName($translator), // $args['rulesObject'] = array();
'tooltip' => $rule->getToolTip($translator), // /** @var CouponRuleInterface $rule */
'validators' => $rule->getValidators() // foreach ($coupon->getRules()->getRules() as $rule) {
); // $args['rulesObject'][] = array(
} // 'name' => $rule->getName($translator),
// 'tooltip' => $rule->getToolTip($translator),
// 'validators' => $rule->getValidators()
// );
// }
//
// $args['rules'] = $this->cleanRuleForTemplate($coupon->getRules()->getRules()); // $args['rules'] = $this->cleanRuleForTemplate($coupon->getRules()->getRules());
//
// Setup the object form // // Setup the object form
$changeForm = new CouponCreationForm($this->getRequest(), 'form', $data); // $changeForm = new CouponCreationForm($this->getRequest(), 'form', $data);
//
// Pass it to the parser // // Pass it to the parser
$this->getParserContext()->addForm($changeForm); // $this->getParserContext()->addForm($changeForm);
} // }
//
$args['formAction'] = 'admin/coupon/update/' . $couponId; // $args['formAction'] = 'admin/coupon/update/' . $couponId;
//
return $this->render( // return $this->render(
'coupon-update', // 'coupon-update',
$args // $args
); // );
} // }
@@ -413,7 +417,6 @@ class CouponController extends BaseAdminController
$constraintFactory = $this->container->get('thelia.constraint.factory'); $constraintFactory = $this->container->get('thelia.constraint.factory');
$rulesReceived = json_decode($this->getRequest()->get('rules')); $rulesReceived = json_decode($this->getRequest()->get('rules'));
foreach ($rulesReceived as $ruleReceived) { foreach ($rulesReceived as $ruleReceived) {
var_dump('building ', $ruleReceived->values);
$rule = $constraintFactory->build( $rule = $constraintFactory->build(
$ruleReceived->serviceId, $ruleReceived->serviceId,
(array) $ruleReceived->operators, (array) $ruleReceived->operators,
@@ -442,6 +445,7 @@ class CouponController extends BaseAdminController
$rules, $rules,
$coupon->getLocale() $coupon->getLocale()
); );
$couponEvent->setCoupon($coupon);
$eventToDispatch = TheliaEvents::COUPON_RULE_UPDATE; $eventToDispatch = TheliaEvents::COUPON_RULE_UPDATE;
// Dispatch Event to the Action // Dispatch Event to the Action

View File

@@ -296,22 +296,6 @@ final class TheliaEvents
*/ */
const AFTER_COUPON_RULE_UPDATE = "action.after_update_coupon_rule"; const AFTER_COUPON_RULE_UPDATE = "action.after_update_coupon_rule";
/**
* Sent when attempting to delete Coupon Rule
*/
const COUPON_RULE_DELETE = "action.delete_coupon_rule";
/**
* Sent just before an attempt to delete a Coupon Rule
*/
const BEFORE_COUPON_RULE_DELETE = "action.before_delete_coupon_rule";
/**
* Sent just after an attempt to delete a Coupon Rule
*/
const AFTER_COUPON_RULE_DELETE = "action.after_delete_coupon_rule";
// -- Configuration management --------------------------------------------- // -- Configuration management ---------------------------------------------
const CONFIG_CREATE = "action.createConfig"; const CONFIG_CREATE = "action.createConfig";

View File

@@ -49,24 +49,25 @@ class Coupon extends BaseCoupon
/** /**
* Constructor * Create or Update this Coupon
* *
* @param string $code Coupon Code * @param string $code Coupon Code
* @param string $title Coupon title * @param string $title Coupon title
* @param float $amount Amount removed from the Total Checkout * @param float $amount Amount removed from the Total Checkout
* @param string $effect Coupon effect * @param string $effect Coupon effect
* @param string $shortDescription Coupon short description * @param bool $isRemovingPostage Is removing Postage
* @param string $description Coupon description * @param string $shortDescription Coupon short description
* @param boolean $isEnabled Enable/Disable * @param string $description Coupon description
* @param \DateTime $expirationDate Coupon expiration date * @param boolean $isEnabled Enable/Disable
* @param boolean $isAvailableOnSpecialOffers Is available on special offers * @param \DateTime $expirationDate Coupon expiration date
* @param boolean $isCumulative Is cumulative * @param boolean $isAvailableOnSpecialOffers Is available on special offers
* @param boolean $isRemovingPostage Is removing Postage * @param boolean $isCumulative Is cumulative
* @param int $maxUsage Coupon quantity * @param int $maxUsage Coupon quantity
* @param CouponRuleCollection $rules CouponRuleInterface to add * @param string $locale Coupon Language code ISO (ex: fr_FR)
* @param string $locale Coupon Language code ISO (ex: fr_FR) *
* @throws \Exception
*/ */
function createOrUpdate($code, $title, $amount, $effect, $shortDescription, $description, $isEnabled, $expirationDate, $isAvailableOnSpecialOffers, $isCumulative, $maxUsage, $rules, $locale = null) function createOrUpdate($code, $title, $amount, $effect, $isRemovingPostage, $shortDescription, $description, $isEnabled, $expirationDate, $isAvailableOnSpecialOffers, $isCumulative, $maxUsage, $locale = null)
{ {
$this->setCode($code) $this->setCode($code)
->setTitle($title) ->setTitle($title)
@@ -74,13 +75,13 @@ class Coupon extends BaseCoupon
->setDescription($description) ->setDescription($description)
->setType($effect) ->setType($effect)
->setAmount($amount) ->setAmount($amount)
->setIsRemovingPostage($isRemovingPostage)
->setType($amount) ->setType($amount)
->setIsEnabled($isEnabled) ->setIsEnabled($isEnabled)
->setExpirationDate($expirationDate) ->setExpirationDate($expirationDate)
->setIsAvailableOnSpecialOffers($isAvailableOnSpecialOffers) ->setIsAvailableOnSpecialOffers($isAvailableOnSpecialOffers)
->setIsCumulative($isCumulative) ->setIsCumulative($isCumulative)
->setMaxUsage($maxUsage) ->setMaxUsage($maxUsage);
->setRules($rules);
// Set object language (i18n) // Set object language (i18n)
if (!is_null($locale)) { if (!is_null($locale)) {
@@ -99,33 +100,34 @@ class Coupon extends BaseCoupon
} }
} }
// /** /**
// * Set the value of [serialized_rules] column. * Create or Update this coupon rule
// * Convert a CouponRuleCollection into a serialized array of SerializableRule *
// * * @param string $serializableRules Serialized rules ready to be saved
// * @param CouponRuleCollection $rules A set of Rules * @param string $locale Coupon Language code ISO (ex: fr_FR)
// * *
// * @return \Thelia\Model\Coupon The current object (for fluent API support) * @throws \Exception
// */ */
// public function setRules(CouponRuleCollection $rules) function createOrUpdateRules($serializableRules, $locale)
// { {
// $serializedRules = null; $this->setSerializedRules($serializableRules);
// if ($rules !== null) {
// /** @var $rule CouponRuleInterface */ // Set object language (i18n)
// foreach ($rules->getRules() as $rule) { if (!is_null($locale)) {
// $serializedRules[] = $rule->getSerializableRule(); $this->setLocale($locale);
// } }
//
// $serializedRules = (string) base64_encode(serialize($serializedRules)); $con = Propel::getWriteConnection(CouponTableMap::DATABASE_NAME);
// } $con->beginTransaction();
// try {
// if ($this->serialized_rules !== $serializedRules) { $this->save($con);
// $this->serialized_rules = $serializedRules; $con->commit();
// $this->modifiedColumns[] = CouponTableMap::SERIALIZED_RULES;
// } } catch(\Exception $e) {
// $con->rollback();
// return $this; throw $e;
// } }
}

View File

@@ -16,7 +16,7 @@
</div> </div>
{form name="thelia.admin.coupon.creation"} {form name="thelia.admin.coupon.creation"}
{include file='coupon/form.html' formAction={url path={$formAction}}} {include file='coupon/form.html' formAction={url path={$formAction}} noRules=true}
{/form} {/form}
</section> <!-- #wrapper --> </section> <!-- #wrapper -->

View File

@@ -16,7 +16,7 @@
</div> </div>
{form name="thelia.admin.coupon.creation"} {form name="thelia.admin.coupon.creation"}
{include file='coupon/form.html' formAction={url path={$formAction}} form=$form} {include file='coupon/form.html' formAction={url path={$formAction}} form=$form noRules=false}
{/form} {/form}
</section> <!-- #wrapper --> </section> <!-- #wrapper -->
@@ -43,11 +43,19 @@
Array.prototype.clean = function(deleteValue) {
for (var i = 0; i < this.length; i++) {
if (this[i] == deleteValue) {
this.splice(i, 1);
i--;
}
}
return this;
};
// Init Rules // Init Rules
var initRule = function() { var initRules = function() {
var rules = []; var rules = [];
{foreach from=$rulesObject key=k item=rule} {foreach from=$rulesObject key=k item=rule}
var rule = {}; var rule = {};
@@ -67,16 +75,13 @@
// Save Rules AJAX // Save Rules AJAX
var saveRuleAjax = function() { var saveRuleAjax = function() {
console.log('rulesToSave');
console.log(rulesToSave);
var $url = '{$urlAjaxUpdateRules}'; var $url = '{$urlAjaxUpdateRules}';
console.log('save');
console.log('{$urlAjaxUpdateRules}');
console.log(rules);
console.log(JSON.stringify(rules));
$.ajax({ $.ajax({
type: "POST", type: "POST",
url: $url, url: $url,
{*data: {literal}{{/literal}rules:rules{literal}}{/literal},*} data: {literal}{{/literal}rules:JSON.stringify(rulesToSave){literal}}{/literal},
data: {literal}{{/literal}rules:JSON.stringify(rules){literal}}{/literal},
statusCode: { statusCode: {
404: function() { 404: function() {
$('#constraint-add-operators-values').html( $('#constraint-add-operators-values').html(
@@ -91,20 +96,83 @@
} }
// Remove 1 Rule then Save Rules AJAX // Remove 1 Rule then Save Rules AJAX
var removeRuleAjax = function($id) { var removeRuleAjax = function(id) {
rules.slice($id, 1); // Delete rule in temporary array
delete rulesToSave[id];
rulesToSave.clean(undefined);
// Save
saveRuleAjax(); saveRuleAjax();
} }
// Add 1 Rule then Save Rules AJAX // Add 1 Rule / or update the temporary Rules array then Save Rules via AJAX
var addRuleAjax = function() { var addRuleAjax = function(id) {
rules.push(ruleToSave); if(typeof id === 'number' && id % 1 == 0) {
rulesToSave[id] = ruleToSave;
} else {
rulesToSave.push(ruleToSave);
}
saveRuleAjax(); saveRuleAjax();
} }
// Set rule inputs to allow editing
var updateRuleAjax = function(id) {
ruleToSave = rulesToSave[id];
var ruleToUpdate = ruleToSave;
var rules = initRule(); // Deleting this rule, we will reset it
console.log(rules); delete rulesToSave[id];
// Set the rule seletor
$("#category-rule option").filter(function() {
return $(this).val() == ruleToSave.serviceId;
}).prop('selected', true);
// Force rule input refresh
loadRuleInputs(ruleToSave.serviceId, ruleToUpdate, function(ruleToUpdate) {
fillInRuleInputs(ruleToUpdate);
});
}
// Fill in rule inputs
var fillInRuleInputs = function(ruleToUpdate) {
var valueId = null;
var operatorId = null;
for (idName in ruleToUpdate.operators) {
// Setting idName operator input
operatorId = idName + '-operator';
$('#' + operatorId).val(ruleToUpdate.operators[idName]);
// Setting idName value input
valueId = idName + '-value';
$('#' + valueId).val(ruleToUpdate.values[idName]);
}
}
// Reload rule inputs
var loadRuleInputs = function(ruleId, ruleToSave, callBack) {
$('#constraint-add-operators-values').html('<div class="loading" ></div>');
var url = "{$urlAjaxGetRuleInput}";
url = url.replace('ruleId', ruleId)
$.ajax({
url: url,
statusCode: {
404: function() {
$('#constraint-add-operators-values').html(
'{intl l='Please select another rule'}'
);
}
}
}).done(function(data) {
$('#constraint-add-operators-values').html(data);
return callBack(ruleToSave);
});
}
// Save rules on click // Save rules on click
@@ -117,12 +185,24 @@
// Remove rule on click // Remove rule on click
var onClickDeleteRule = function() { var onClickDeleteRule = function() {
$('#constraint-delete-btn').on('click', function (e) { $('.constraint-delete-btn').on('click', function (e) {
// removeRuleAjax(); e.preventDefault();
var $this = $(this);
removeRuleAjax($this.attr('data-int'));
}); });
} }
onClickDeleteRule(); onClickDeleteRule();
// Remove rule on click
var onClickUpdateRule = function() {
$('.constraint-update-btn').on('click', function (e) {
e.preventDefault();
var $this = $(this);
updateRuleAjax($this.attr('data-int'));
});
}
onClickUpdateRule();
// Reload effect inputs when changing effect // Reload effect inputs when changing effect
var onEffectChange = function() { var onEffectChange = function() {
$('#effect').on('change', function (e) { $('#effect').on('change', function (e) {
@@ -135,24 +215,18 @@
// Reload rule inputs when changing effect // Reload rule inputs when changing effect
var onRuleChange = function() { var onRuleChange = function() {
$('#category-rule').on('change', function (e) { $('#category-rule').on('change', function (e) {
$('#constraint-add-operators-values').html('<div class="loading" ></div>'); loadRuleInputs($(this).val(), null, function(ruleToSave) {});
var url = "{$urlAjaxGetRuleInput}";
url = url.replace('ruleId', $(this).val())
$.ajax({
url: url,
statusCode: {
404: function() {
$('#constraint-add-operators-values').html(
'{intl l='Please select another rule'}'
);
}
}
}).done(function(data) {
$('#constraint-add-operators-values').html(data);
});
}); });
} }
onRuleChange(); onRuleChange();
// Rule to save
var ruleToSave = {literal}{}{/literal};
// Rules which will be saved
var rulesToSave = initRules();
}); });

View File

@@ -161,134 +161,122 @@
</div> </div>
</section> </section>
{if $noRules}
<section class="row"> {include file='includes/notifications.html' message={intl l='Please save your Coupon in oder to affect it some application fields'}}
<div class="col-md-12 general-block-decorator"> {else}
<table class="table table-striped"> <section class="row">
<caption class="clearfix"> <div class="col-md-12 general-block-decorator">
{intl l='Rules'} <table class="table table-striped">
</caption> <caption class="clearfix">
<thead> {intl l='Rules'}
<tr> </caption>
<th>{intl l='Conditions'}</th> <thead>
<th>{intl l='Actions'}</th> <tr>
</tr> <th>{intl l='Conditions'}</th>
</thead> <th>{intl l='Actions'}</th>
<tbody id="constraint-list"> </tr>
{include file='coupon/rules.html' rules=$rulesObject} </thead>
{*{foreach from=$rulesObject item=rule name=rulesForeach}*} <tbody id="constraint-list">
{*<tr>*} {include file='coupon/rules.html' rules=$rules}
{*<td>*} </tbody>
{*{if !$smarty.foreach.rulesForeach.first}*} </table>
{*<span class="label label-info">{intl l='And'}</span>*}
{*{/if}*}
{*{$rule.tooltip nofilter}*}
{*</td>*}
{*<td>*}
{*<a href="#url" class="btn btn-default btn-primary btn-medium"><span class="glyphicon glyphicon-edit"></span> {intl l='Edit'}</a>*}
{*<a href="#url" class="btn btn-default btn-danger btn-medium" data-toggle="confirm" data-target="#delete"><span class="glyphicon glyphicon-remove"></span> {intl l='Delete'}</a>*}
{*</td>*}
{*</tr>*}
{*{/foreach}*}
</tbody>
</table>
</div>
</section>
<section class="row">
<div class="col-md-12 general-block-decorator clearfix">
<a id="constraint-save-btn" title="{intl l='Save this rule'}" class="btn btn-default btn-primary pull-right">
<span class="glyphicon glyphicon-plus-sign"></span>
</a>
<div id="rule-add-organizer" class="form-group col-md-2">
<label for="type">{intl l='Condition type :'}</label>
<label class="radio">
<input type="radio" name="type" id="type" value="1" checked> {intl l='And'}
</label>
<label class="radio">
<input type="radio" name="type" value="2"> {intl l='Or'}
</label>
</div> </div>
</section>
<div id="rule-add-type" class="form-group col-md-4"> <section class="row">
<label for="categoryRule">{intl l='Rule\'s category :'}</label> <div class="col-md-12 general-block-decorator clearfix">
<select name="categoryRule" id="category-rule" class="form-control"> <a id="constraint-save-btn" title="{intl l='Save this rule'}" class="btn btn-default btn-primary pull-right">
{foreach from=$availableRules item=availableRule} <span class="glyphicon glyphicon-plus-sign"></span>
<option value="{$availableRule.serviceId}" data-description="{$availableRule.toolTip}">{$availableRule.name}</option> </a>
{/foreach}
</select> <div id="rule-add-organizer" class="form-group col-md-2">
<label for="type">{intl l='Condition type :'}</label>
<label class="radio">
<input type="radio" name="type" id="type" value="1" checked> {intl l='And'}
</label>
<label class="radio">
<input type="radio" name="type" value="2"> {intl l='Or'}
</label>
</div>
<div id="rule-add-type" class="form-group col-md-4">
<label for="categoryRule">{intl l='Rule\'s category :'}</label>
<select name="categoryRule" id="category-rule" class="form-control">
{foreach from=$availableRules item=availableRule}
<option value="{$availableRule.serviceId}" data-description="{$availableRule.toolTip}">{$availableRule.name}</option>
{/foreach}
</select>
</div>
<div id="constraint-add-operators-values" class="form-group col-md-6">
{*<label for="operator">{intl l='Operator :'}</label>*}
{*<div class="row">*}
{*<div class="col-lg-6">*}
{*<select name="operator" id="operator" class="form-control">*}
{*<option value="1">is superior to</option>*}
{*<option value="2">equals to</option>*}
{*<option value="3">is inferior to</option>*}
{*<option value="4">is inferior or equals to</option>*}
{*<option value="5">is superior or equals to</option>*}
{*</select>*}
{*</div>*}
{*<div class="input-group col-lg-6">*}
{*<input type="text" name="value" class="form-control">*}
{*<span class="input-group-addon">&euro;</span>*}
{*</div>*}
{*</div>*}
{**}
{*<label for="operator">Operator :</label>*}
{*<div class="row">*}
{*<div class="col-lg-6">*}
{*<select name="operator" id="operator" class="form-control">*}
{*<option value="1">is superior to</option>*}
{*<option value="2">equals to</option>*}
{*<option value="3">is inferior to</option>*}
{*<option value="4">is inferior or equals to</option>*}
{*<option value="5">is superior or equals to</option>*}
{*</select>*}
{*</div>*}
{*<div class="input-group col-lg-6 date" data-date="12/02/2012" data-date-format="dd/mm/yyyy">*}
{*<input type="text" name="value" class="form-control">*}
{*<span class="input-group-addon"><span class="glyphicon glyphicon-th"></span></span>*}
{*</div>*}
{*</div>*}
{*<label for="operator">Operator :</label>*}
{*<div class="row">*}
{*<div class="col-lg-6">*}
{*<select name="operator" id="operator" class="form-control">*}
{*<option value="1">is superior to</option>*}
{*<option value="2">equals to</option>*}
{*<option value="3">is inferior to</option>*}
{*<option value="4">is inferior or equals to</option>*}
{*<option value="5">is superior or equals to</option>*}
{*</select>*}
{*</div>*}
{*<div class="col-lg-6">*}
{*<input type="text" name="value" class="form-control">*}
{*</div>*}
{*</div>*}
{*<div class="row">*}
{*<div class="col-lg-12">*}
{*<table class="table table-bordered">*}
{*<tr>*}
{*<td id="minibrowser-breadcrumb"></td>*}
{*</tr>*}
{*<tr>*}
{*<th><span class="icon-th-list"></span> Categories list</th>*}
{*</tr>*}
{*<tr>*}
{*<td id="minibrowser-categories"></td>*}
{*</tr>*}
{*</table>*}
{*</div>*}
{*</div>*}
</div>
</div> </div>
</section>
<div id="constraint-add-operators-values" class="form-group col-md-6"> {/if}
{*<label for="operator">{intl l='Operator :'}</label>*}
{*<div class="row">*}
{*<div class="col-lg-6">*}
{*<select name="operator" id="operator" class="form-control">*}
{*<option value="1">is superior to</option>*}
{*<option value="2">equals to</option>*}
{*<option value="3">is inferior to</option>*}
{*<option value="4">is inferior or equals to</option>*}
{*<option value="5">is superior or equals to</option>*}
{*</select>*}
{*</div>*}
{*<div class="input-group col-lg-6">*}
{*<input type="text" name="value" class="form-control">*}
{*<span class="input-group-addon">&euro;</span>*}
{*</div>*}
{*</div>*}
{**}
{*<label for="operator">Operator :</label>*}
{*<div class="row">*}
{*<div class="col-lg-6">*}
{*<select name="operator" id="operator" class="form-control">*}
{*<option value="1">is superior to</option>*}
{*<option value="2">equals to</option>*}
{*<option value="3">is inferior to</option>*}
{*<option value="4">is inferior or equals to</option>*}
{*<option value="5">is superior or equals to</option>*}
{*</select>*}
{*</div>*}
{*<div class="input-group col-lg-6 date" data-date="12/02/2012" data-date-format="dd/mm/yyyy">*}
{*<input type="text" name="value" class="form-control">*}
{*<span class="input-group-addon"><span class="glyphicon glyphicon-th"></span></span>*}
{*</div>*}
{*</div>*}
{*<label for="operator">Operator :</label>*}
{*<div class="row">*}
{*<div class="col-lg-6">*}
{*<select name="operator" id="operator" class="form-control">*}
{*<option value="1">is superior to</option>*}
{*<option value="2">equals to</option>*}
{*<option value="3">is inferior to</option>*}
{*<option value="4">is inferior or equals to</option>*}
{*<option value="5">is superior or equals to</option>*}
{*</select>*}
{*</div>*}
{*<div class="col-lg-6">*}
{*<input type="text" name="value" class="form-control">*}
{*</div>*}
{*</div>*}
{*<div class="row">*}
{*<div class="col-lg-12">*}
{*<table class="table table-bordered">*}
{*<tr>*}
{*<td id="minibrowser-breadcrumb"></td>*}
{*</tr>*}
{*<tr>*}
{*<th><span class="icon-th-list"></span> Categories list</th>*}
{*</tr>*}
{*<tr>*}
{*<td id="minibrowser-categories"></td>*}
{*</tr>*}
{*</table>*}
{*</div>*}
{*</div>*}
</div>
</div>
</section>
</form> </form>

View File

@@ -1,4 +1,3 @@
{*{$inputs.inputs|var_dump}*}
{foreach from=$inputs.inputs key=name item=input} {foreach from=$inputs.inputs key=name item=input}
<label for="operator">{$input.title}</label> <label for="operator">{$input.title}</label>
<div class="row"> <div class="row">
@@ -71,6 +70,8 @@
{*</div>*} {*</div>*}
<script> <script>
// Init Rules to set
var ruleToSave = {}; var ruleToSave = {};
ruleToSave['serviceId'] = '{$ruleId}'; ruleToSave['serviceId'] = '{$ruleId}';
ruleToSave['operators'] = {}; ruleToSave['operators'] = {};
@@ -81,22 +82,23 @@
{/foreach} {/foreach}
// Update ruleToSave Array ready to be saved // Fill in ready to be saved rule array
var onInputsChange = function() {literal}{{/literal} var onInputsChange = function() {literal}{{/literal}
{foreach from=$inputs.inputs key=name item=input} {foreach from=$inputs.inputs key=name item=input}
$('#{$name}-operator').change(function (e) { $('#{$name}-operator').change(function (e) {
var $this = $(this); var $this = $(this);
console.log('{$name}-operator changed by ' + $this.val());
ruleToSave['operators']['{$name nofilter}'] = $this.val(); ruleToSave['operators']['{$name nofilter}'] = $this.val();
console.log('#{$name}-operator changed ' + $this.val());
console.log(ruleToSave);
}); });
$('#{$name}-value').change(function (e) { $('#{$name}-value').change(function (e) {
var $this = $(this); var $this = $(this);
console.log('{$name}-value changed by ' + $this);
ruleToSave['values']['{$name nofilter}'] = $this.val(); ruleToSave['values']['{$name nofilter}'] = $this.val();
console.log('#{$name}-value changed ' + $this.val());
console.log(ruleToSave);
}); });
{/foreach} {/foreach}
console.log('will save ');
console.log(ruleToSave);
{literal}}{/literal} {literal}}{/literal}
onInputsChange(); onInputsChange();
</script> </script>

View File

@@ -1,4 +1,4 @@
{foreach from=$rules item=rule name=rulesForeach} {foreach from=$rules item=rule key=i name=rulesForeach}
<tr> <tr>
<td> <td>
{if !$smarty.foreach.rulesForeach.first} {if !$smarty.foreach.rulesForeach.first}
@@ -7,10 +7,10 @@
{$rule nofilter} {$rule nofilter}
</td> </td>
<td> <td>
<a class="btn btn-default btn-primary btn-medium" href="{$urlEdit}"> <a data-int="{$i}" class="btn btn-default btn-primary btn-medium constraint-update-btn" href="{$urlEdit}">
<span class="glyphicon glyphicon-edit"></span> {intl l='Edit'} <span class="glyphicon glyphicon-edit"></span> {intl l='Edit'}
</a> </a>
<a data-target="#delete" data-toggle="confirm" class="btn btn-default btn-danger btn-medium" href="{$urlDelete}"> <a data-int="{$i}" data-target="#delete" data-toggle="confirm" class="btn btn-default btn-danger btn-medium constraint-delete-btn" href="{$urlDelete}">
<span class="glyphicon glyphicon-remove"></span> {intl l='Delete'} <span class="glyphicon glyphicon-remove"></span> {intl l='Delete'}
</a> </a>
</td> </td>