Merge branch 'coupon' of https://github.com/thelia/thelia
* 'coupon' of https://github.com/thelia/thelia: WIP : Coupon fix coupon creation issue WIP : Coupon fix coupon creation issue Working : bootstrap datepicker commented out to keep style for jquery.datepicker (Mika) Working : Coupon : fix links and errors display Working : Default lang in US, asset not processed by default Working : Coupon - update loop Working : Coupon Controller refactor Working : Coupon Controller refactor Working : Base controller now get type inference of Thelia2 Session component WIP : Coupon event dispatcher + action Working : Adding type inference to the Thelia2 Request->getSession() WIP : Coupon Adapter methods implementation WIP : Coupon event dispatcher + action Working - Coupon Add/Edit/Delete rule AJAX Working - Coupon Add/Edit/Delete rule AJAX WIP - Coupon Add/Edit/Delete rule AJAX Working - CasperJS : coupon rule
This commit is contained in:
@@ -23,10 +23,16 @@
|
||||
|
||||
namespace Thelia\Action;
|
||||
|
||||
use Symfony\Component\Config\Definition\Exception\Exception;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Thelia\Constraint\ConstraintFactory;
|
||||
use Thelia\Core\Event\Coupon\CouponConsumeEvent;
|
||||
use Thelia\Core\Event\Coupon\CouponCreateOrUpdateEvent;
|
||||
use Thelia\Core\Event\TheliaEvents;
|
||||
use Thelia\Core\HttpFoundation\Request;
|
||||
use Thelia\Coupon\CouponFactory;
|
||||
use Thelia\Coupon\CouponManager;
|
||||
use Thelia\Coupon\Type\CouponInterface;
|
||||
use Thelia\Model\Coupon as CouponModel;
|
||||
|
||||
/**
|
||||
@@ -45,7 +51,7 @@ class Coupon extends BaseAction implements EventSubscriberInterface
|
||||
/**
|
||||
* Occurring when a Coupon is about to be created
|
||||
*
|
||||
* @param CouponCreateOrUpdateEvent $event Event creation or update Event
|
||||
* @param CouponCreateOrUpdateEvent $event Event creation or update Coupon
|
||||
*/
|
||||
public function create(CouponCreateOrUpdateEvent $event)
|
||||
{
|
||||
@@ -57,7 +63,7 @@ class Coupon extends BaseAction implements EventSubscriberInterface
|
||||
/**
|
||||
* Occurring when a Coupon is about to be updated
|
||||
*
|
||||
* @param CouponCreateOrUpdateEvent $event Event creation or update Event
|
||||
* @param CouponCreateOrUpdateEvent $event Event creation or update Coupon
|
||||
*/
|
||||
public function update(CouponCreateOrUpdateEvent $event)
|
||||
{
|
||||
@@ -69,7 +75,7 @@ class Coupon extends BaseAction implements EventSubscriberInterface
|
||||
/**
|
||||
* Occurring when a Coupon rule is about to be updated
|
||||
*
|
||||
* @param CouponCreateOrUpdateEvent $event Event creation or update Event
|
||||
* @param CouponCreateOrUpdateEvent $event Event creation or update Coupon Rule
|
||||
*/
|
||||
public function updateRule(CouponCreateOrUpdateEvent $event)
|
||||
{
|
||||
@@ -81,11 +87,43 @@ class Coupon extends BaseAction implements EventSubscriberInterface
|
||||
/**
|
||||
* Occurring when a Coupon rule is about to be consumed
|
||||
*
|
||||
* @param CouponCreateOrUpdateEvent $event Event creation or update Event
|
||||
* @param CouponConsumeEvent $event Event consuming Coupon
|
||||
*/
|
||||
public function consume(CouponCreateOrUpdateEvent $event)
|
||||
public function consume(CouponConsumeEvent $event)
|
||||
{
|
||||
// @todo implements
|
||||
$totalDiscount = 0;
|
||||
|
||||
/** @var CouponFactory $couponFactory */
|
||||
$couponFactory = $this->container->get('thelia.coupon.factory');
|
||||
|
||||
/** @var CouponManager $couponManager */
|
||||
$couponManager = $this->container->get('thelia.coupon.manager');
|
||||
|
||||
/** @var CouponInterface $coupon */
|
||||
$coupon = $couponFactory->buildCouponFromCode($event->getCode());
|
||||
|
||||
$isValid = $coupon->isMatching();
|
||||
if ($isValid) {
|
||||
/** @var Request $request */
|
||||
$request = $this->container->get('request');
|
||||
$consumedCoupons = $request->getSession()->getConsumedCoupons();
|
||||
|
||||
if (!isset($consumedCoupons) || !$consumedCoupons) {
|
||||
$consumedCoupons = array();
|
||||
}
|
||||
|
||||
// Prevent accumulation of the same Coupon on a Checkout
|
||||
$consumedCoupons[$event->getCode()] = $event->getCode();
|
||||
|
||||
$request->getSession()->setConsumedCoupons($consumedCoupons);
|
||||
|
||||
$totalDiscount = $couponManager->getDiscount();
|
||||
|
||||
// @todo modify Cart total discount
|
||||
}
|
||||
|
||||
$event->setIsValid($isValid);
|
||||
$event->setDiscount($totalDiscount);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -165,8 +203,6 @@ class Coupon extends BaseAction implements EventSubscriberInterface
|
||||
return array(
|
||||
TheliaEvents::COUPON_CREATE => array("create", 128),
|
||||
TheliaEvents::COUPON_UPDATE => array("update", 128),
|
||||
TheliaEvents::COUPON_DISABLE => array("disable", 128),
|
||||
TheliaEvents::COUPON_ENABLE => array("enable", 128),
|
||||
TheliaEvents::COUPON_CONSUME => array("consume", 128),
|
||||
TheliaEvents::COUPON_RULE_UPDATE => array("updateRule", 128)
|
||||
);
|
||||
|
||||
@@ -235,6 +235,8 @@
|
||||
<service id="thelia.constraint.factory" class="Thelia\Constraint\ConstraintFactory">
|
||||
<argument type="service" id="service_container" />
|
||||
</service>
|
||||
<service id="thelia.constraint.validator" class="Thelia\Constraint\ConstraintValidator">
|
||||
</service>
|
||||
<service id="thelia.constraint.rule.available_for_everyone" class="Thelia\Constraint\Rule\AvailableForEveryoneManager">
|
||||
<argument type="service" id="thelia.adapter" />
|
||||
<tag name="thelia.coupon.addRule"/>
|
||||
|
||||
@@ -103,25 +103,27 @@
|
||||
|
||||
<!-- Route to the Coupon controller (process Coupon browsing) -->
|
||||
|
||||
<route id="admin.coupon.list" path="/admin/coupon">
|
||||
<route id="admin.coupon.list" path="/admin/coupon/">
|
||||
<default key="_controller">Thelia\Controller\Admin\CouponController::browseAction</default>
|
||||
</route>
|
||||
<route id="admin.coupon.create" path="/admin/coupon/create">
|
||||
<route id="admin.coupon.create" path="/admin/coupon/create/">
|
||||
<default key="_controller">Thelia\Controller\Admin\CouponController::createAction</default>
|
||||
</route>
|
||||
<route id="admin.coupon.update" path="/admin/coupon/update/{couponId}">
|
||||
<route id="admin.coupon.update" path="/admin/coupon/update/{couponId}/">
|
||||
<default key="_controller">Thelia\Controller\Admin\CouponController::updateAction</default>
|
||||
</route>
|
||||
<route id="admin.coupon.read" path="/admin/coupon/read/{couponId}">
|
||||
<route id="admin.coupon.read" path="/admin/coupon/read/{couponId}/">
|
||||
<default key="_controller">Thelia\Controller\Admin\CouponController::readAction</default>
|
||||
</route>
|
||||
<route id="admin.coupon.rule.input" path="/admin/coupon/rule/{ruleId}">
|
||||
<route id="admin.coupon.rule.input" path="/admin/coupon/rule/{ruleId}/">
|
||||
<default key="_controller">Thelia\Controller\Admin\CouponController::getRuleInputAction</default>
|
||||
</route>
|
||||
<route id="admin.coupon.rule.update" path="/admin/coupon/{couponId}/rule/update/">
|
||||
<default key="_controller">Thelia\Controller\Admin\CouponController::updateRulesAction</default>
|
||||
</route>
|
||||
|
||||
<route id="admin.coupon.consume" path="/admin/coupon/consume/{couponCode}/">
|
||||
<default key="_controller">Thelia\Controller\Admin\CouponController::consumeAction</default>
|
||||
</route>
|
||||
|
||||
<!-- Routes to the Config (system variables) controller -->
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ namespace Thelia\Constraint;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\Serializer\Encoder\JsonEncoder;
|
||||
use Thelia\Constraint\Rule\AvailableForEveryoneManager;
|
||||
use Thelia\Constraint\Rule\AvailableForTotalAmountManager;
|
||||
use Thelia\Constraint\Rule\CouponRuleInterface;
|
||||
use Thelia\Constraint\Rule\SerializableRule;
|
||||
@@ -74,11 +75,22 @@ class ConstraintFactory
|
||||
*/
|
||||
public function serializeCouponRuleCollection(CouponRuleCollection $collection)
|
||||
{
|
||||
if ($collection->isEmpty()) {
|
||||
/** @var CouponRuleInterface $ruleNoCondition */
|
||||
$ruleNoCondition = $this->container->get(
|
||||
'thelia.constraint.rule.available_for_everyone'
|
||||
);
|
||||
$collection->add($ruleNoCondition);
|
||||
}
|
||||
$serializableRules = array();
|
||||
$rules = $collection->getRules();
|
||||
if ($rules !== null) {
|
||||
/** @var $rule CouponRuleInterface */
|
||||
foreach ($rules as $rule) {
|
||||
// Remove all rule if the "no condition" rule is found
|
||||
// if ($rule->getServiceId() == 'thelia.constraint.rule.available_for_everyone') {
|
||||
// return base64_encode(json_encode(array($rule->getSerializableRule())));
|
||||
// }
|
||||
$serializableRules[] = $rule->getSerializableRule();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ class ConstraintValidator
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function test(CouponRuleCollection $rules)
|
||||
public function isMatching(CouponRuleCollection $rules)
|
||||
{
|
||||
$isMatching = true;
|
||||
/** @var CouponRuleInterface $rule */
|
||||
|
||||
@@ -25,7 +25,6 @@ namespace Thelia\Constraint\Rule;
|
||||
|
||||
use Symfony\Component\Intl\Exception\NotImplementedException;
|
||||
use Symfony\Component\Translation\Translator;
|
||||
use Thelia\Constraint\ConstraintValidator;
|
||||
use Thelia\Coupon\CouponAdapterInterface;
|
||||
use Thelia\Constraint\Validator\PriceParam;
|
||||
use Thelia\Constraint\Validator\RuleValidator;
|
||||
@@ -168,13 +167,12 @@ class AvailableForTotalAmountManager extends CouponRuleAbstract
|
||||
return false;
|
||||
}
|
||||
|
||||
$constrainValidator = new ConstraintValidator();
|
||||
$constraint1 =$constrainValidator->variableOpComparison(
|
||||
$constraint1 = $this->constraintValidator->variableOpComparison(
|
||||
$this->adapter->getCartTotalPrice(),
|
||||
$this->operators[self::INPUT1],
|
||||
$this->values[self::INPUT1]
|
||||
);
|
||||
$constraint2 =$constrainValidator->variableOpComparison(
|
||||
$constraint2 = $this->constraintValidator->variableOpComparison(
|
||||
$this->adapter->getCheckoutCurrency(),
|
||||
$this->operators[self::INPUT2],
|
||||
$this->values[self::INPUT2]
|
||||
|
||||
@@ -126,8 +126,7 @@ class AvailableForXArticlesManager extends CouponRuleAbstract
|
||||
*/
|
||||
public function isMatching()
|
||||
{
|
||||
$constrainValidator = new ConstraintValidator();
|
||||
$constraint1 =$constrainValidator->variableOpComparison(
|
||||
$constraint1 = $this->constraintValidator->variableOpComparison(
|
||||
$this->adapter->getNbArticlesInCart(),
|
||||
$this->operators[self::INPUT1],
|
||||
$this->values[self::INPUT1]
|
||||
|
||||
@@ -82,6 +82,7 @@ abstract class CouponRuleAbstract implements CouponRuleInterface
|
||||
{
|
||||
$this->adapter = $adapter;
|
||||
$this->translator = $adapter->getTranslator();
|
||||
$this->constraintValidator = $adapter->getConstraintValidator();
|
||||
}
|
||||
|
||||
// /**
|
||||
|
||||
@@ -133,21 +133,21 @@ abstract class Operators
|
||||
break;
|
||||
case self::INFERIOR_OR_EQUAL:
|
||||
$ret = $translator->trans(
|
||||
'inferior or equals to',
|
||||
'inferior or equal to',
|
||||
array(),
|
||||
'constraint'
|
||||
);
|
||||
break;
|
||||
case self::EQUAL:
|
||||
$ret = $translator->trans(
|
||||
'equals to',
|
||||
'equal to',
|
||||
array(),
|
||||
'constraint'
|
||||
);
|
||||
break;
|
||||
case self::SUPERIOR_OR_EQUAL:
|
||||
$ret = $translator->trans(
|
||||
'superior or equals to',
|
||||
'superior or equal to',
|
||||
array(),
|
||||
'constraint'
|
||||
);
|
||||
|
||||
@@ -30,6 +30,7 @@ use Thelia\Constraint\ConstraintFactoryTest;
|
||||
use Thelia\Constraint\Rule\AvailableForTotalAmount;
|
||||
use Thelia\Constraint\Rule\CouponRuleInterface;
|
||||
use Thelia\Constraint\Validator\PriceParam;
|
||||
use Thelia\Core\Event\Coupon\CouponConsumeEvent;
|
||||
use Thelia\Core\Event\Coupon\CouponCreateEvent;
|
||||
use Thelia\Core\Event\Coupon\CouponCreateOrUpdateEvent;
|
||||
use Thelia\Core\Event\Coupon\CouponEvent;
|
||||
@@ -39,6 +40,7 @@ use Thelia\Core\Security\Exception\AuthenticationException;
|
||||
use Thelia\Core\Security\Exception\AuthorizationException;
|
||||
use Thelia\Core\Translation\Translator;
|
||||
use Thelia\Coupon\CouponAdapterInterface;
|
||||
use Thelia\Coupon\CouponFactory;
|
||||
use Thelia\Coupon\CouponManager;
|
||||
use Thelia\Coupon\CouponRuleCollection;
|
||||
use Thelia\Coupon\Type\CouponInterface;
|
||||
@@ -72,7 +74,54 @@ class CouponController extends BaseAdminController
|
||||
{
|
||||
$this->checkAuth('ADMIN', 'admin.coupon.view');
|
||||
|
||||
return $this->render('coupon-list');
|
||||
$args['urlReadCoupon'] = $this->getRoute(
|
||||
'admin.coupon.read',
|
||||
array('couponId' => 'couponId'),
|
||||
Router::ABSOLUTE_URL
|
||||
);
|
||||
|
||||
$args['urlEditCoupon'] = $this->getRoute(
|
||||
'admin.coupon.update',
|
||||
array('couponId' => 'couponId'),
|
||||
Router::ABSOLUTE_URL
|
||||
);
|
||||
|
||||
$args['urlCreateCoupon'] = $this->getRoute(
|
||||
'admin.coupon.create',
|
||||
array(),
|
||||
Router::ABSOLUTE_URL
|
||||
);
|
||||
|
||||
return $this->render('coupon-list', $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Manage Coupons read display
|
||||
*
|
||||
* @param int $couponId Coupon Id
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function readAction($couponId)
|
||||
{
|
||||
$this->checkAuth('ADMIN', 'admin.coupon.read');
|
||||
|
||||
// Database request repeated in the loop but cached
|
||||
$search = CouponQuery::create();
|
||||
$coupon = $search->findOneById($couponId);
|
||||
|
||||
if ($coupon === null) {
|
||||
return $this->pageNotFound();
|
||||
}
|
||||
|
||||
$args['couponId'] = $couponId;
|
||||
$args['urlEditCoupon'] = $this->getRoute(
|
||||
'admin.coupon.update',
|
||||
array('couponId' => $couponId),
|
||||
Router::ABSOLUTE_URL
|
||||
);
|
||||
|
||||
return $this->render('coupon-read', $args);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -93,7 +142,7 @@ class CouponController extends BaseAdminController
|
||||
|
||||
$i18n = new I18n();
|
||||
/** @var Lang $lang */
|
||||
$lang = $this->getSession()->get('lang');
|
||||
$lang = $this->getSession()->getLang();
|
||||
$eventToDispatch = TheliaEvents::COUPON_CREATE;
|
||||
|
||||
if ($this->getRequest()->isMethod('POST')) {
|
||||
@@ -108,10 +157,12 @@ class CouponController extends BaseAdminController
|
||||
// If no input for expirationDate, now + 2 months
|
||||
$defaultDate = new \DateTime();
|
||||
$args['defaultDate'] = $defaultDate->modify('+2 month')
|
||||
->format($lang->getDateFormat());
|
||||
->format('Y-m-d');
|
||||
}
|
||||
|
||||
$args['formAction'] = 'admin/coupon/create';
|
||||
$args['dateFormat'] = $this->getSession()->getLang()->getDateFormat();
|
||||
$args['availableCoupons'] = $this->getAvailableCoupons();
|
||||
$args['formAction'] = 'admin/coupon/create/';
|
||||
|
||||
return $this->render(
|
||||
'coupon-create',
|
||||
@@ -135,7 +186,7 @@ class CouponController extends BaseAdminController
|
||||
}
|
||||
|
||||
/** @var Coupon $coupon */
|
||||
$coupon = CouponQuery::create()->findOneById($couponId);
|
||||
$coupon = CouponQuery::create()->findPk($couponId);
|
||||
if (!$coupon) {
|
||||
$this->pageNotFound();
|
||||
}
|
||||
@@ -148,6 +199,7 @@ class CouponController extends BaseAdminController
|
||||
$lang = $this->getSession()->getLang();
|
||||
$eventToDispatch = TheliaEvents::COUPON_UPDATE;
|
||||
|
||||
// Create
|
||||
if ($this->getRequest()->isMethod('POST')) {
|
||||
$this->validateCreateOrUpdateForm(
|
||||
$i18n,
|
||||
@@ -156,9 +208,9 @@ class CouponController extends BaseAdminController
|
||||
'updated',
|
||||
'update'
|
||||
);
|
||||
} else {
|
||||
// Prepare the data that will hydrate the form
|
||||
} else { // Update
|
||||
|
||||
// Prepare the data that will hydrate the form
|
||||
/** @var ConstraintFactory $constraintFactory */
|
||||
$constraintFactory = $this->container->get('thelia.constraint.factory');
|
||||
$rules = $constraintFactory->unserializeCouponRuleCollection(
|
||||
@@ -173,7 +225,7 @@ class CouponController extends BaseAdminController
|
||||
'shortDescription' => $coupon->getShortDescription(),
|
||||
'description' => $coupon->getDescription(),
|
||||
'isEnabled' => ($coupon->getIsEnabled() == 1),
|
||||
'expirationDate' => $coupon->getExpirationDate($lang->getDateFormat()),
|
||||
'expirationDate' => $coupon->getExpirationDate('Y-m-d'),
|
||||
'isAvailableOnSpecialOffers' => ($coupon->getIsAvailableOnSpecialOffers() == 1),
|
||||
'isCumulative' => ($coupon->getIsCumulative() == 1),
|
||||
'isRemovingPostage' => ($coupon->getIsRemovingPostage() == 1),
|
||||
@@ -202,7 +254,7 @@ class CouponController extends BaseAdminController
|
||||
// Pass it to the parser
|
||||
$this->getParserContext()->addForm($changeForm);
|
||||
}
|
||||
|
||||
$args['couponCode'] = $coupon->getCode();
|
||||
$args['availableCoupons'] = $this->getAvailableCoupons();
|
||||
$args['availableRules'] = $this->getAvailableRules();
|
||||
$args['urlAjaxGetRuleInput'] = $this->getRoute(
|
||||
@@ -222,123 +274,6 @@ class CouponController extends BaseAdminController
|
||||
return $this->render('coupon-update', $args);
|
||||
}
|
||||
|
||||
|
||||
// /**
|
||||
// * Manage Coupons Rule creation display
|
||||
// *
|
||||
// * @param int $couponId Coupon id
|
||||
// *
|
||||
// * @return \Symfony\Component\HttpFoundation\Response
|
||||
// */
|
||||
// public function createRuleAction($couponId)
|
||||
// {
|
||||
// // Check current user authorization
|
||||
// $response = $this->checkAuth('admin.coupon.update');
|
||||
// if ($response !== null) {
|
||||
// return $response;
|
||||
// }
|
||||
//
|
||||
// /** @var Coupon $coupon */
|
||||
// $coupon = CouponQuery::create()->findOneById($couponId);
|
||||
// if (!$coupon) {
|
||||
// $this->pageNotFound();
|
||||
// }
|
||||
//
|
||||
// // Parameters given to the template
|
||||
// $args = array();
|
||||
//
|
||||
// $i18n = new I18n();
|
||||
// /** @var Lang $lang */
|
||||
// $lang = $this->getSession()->get('lang');
|
||||
// $eventToDispatch = TheliaEvents::COUPON_RULE_CREATE;
|
||||
//
|
||||
// if ($this->getRequest()->isMethod('POST')) {
|
||||
// $this->validateCreateOrUpdateForm(
|
||||
// $i18n,
|
||||
// $lang,
|
||||
// $eventToDispatch,
|
||||
// 'updated',
|
||||
// 'update'
|
||||
// );
|
||||
// } else {
|
||||
// // Prepare the data that will hydrate the form
|
||||
//
|
||||
// /** @var ConstraintFactory $constraintFactory */
|
||||
// $constraintFactory = $this->container->get('thelia.constraint.factory');
|
||||
//
|
||||
// $data = array(
|
||||
// 'code' => $coupon->getCode(),
|
||||
// 'title' => $coupon->getTitle(),
|
||||
// 'amount' => $coupon->getAmount(),
|
||||
// 'effect' => $coupon->getType(),
|
||||
// 'shortDescription' => $coupon->getShortDescription(),
|
||||
// 'description' => $coupon->getDescription(),
|
||||
// 'isEnabled' => ($coupon->getIsEnabled() == 1),
|
||||
// 'expirationDate' => $coupon->getExpirationDate($lang->getDateFormat()),
|
||||
// 'isAvailableOnSpecialOffers' => ($coupon->getIsAvailableOnSpecialOffers() == 1),
|
||||
// 'isCumulative' => ($coupon->getIsCumulative() == 1),
|
||||
// 'isRemovingPostage' => ($coupon->getIsRemovingPostage() == 1),
|
||||
// 'maxUsage' => $coupon->getMaxUsage(),
|
||||
// 'rules' => $constraintFactory->unserializeCouponRuleCollection($coupon->getSerializedRules()),
|
||||
// 'locale' => $coupon->getLocale(),
|
||||
// );
|
||||
//
|
||||
// /** @var CouponAdapterInterface $adapter */
|
||||
// $adapter = $this->container->get('thelia.adapter');
|
||||
// /** @var Translator $translator */
|
||||
// $translator = $this->container->get('thelia.translator');
|
||||
//
|
||||
// $args['rulesObject'] = array();
|
||||
// /** @var CouponRuleInterface $rule */
|
||||
// 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());
|
||||
//
|
||||
// // Setup the object form
|
||||
// $changeForm = new CouponCreationForm($this->getRequest(), 'form', $data);
|
||||
//
|
||||
// // Pass it to the parser
|
||||
// $this->getParserContext()->addForm($changeForm);
|
||||
// }
|
||||
//
|
||||
// $args['formAction'] = 'admin/coupon/update/' . $couponId;
|
||||
//
|
||||
// return $this->render(
|
||||
// 'coupon-update',
|
||||
// $args
|
||||
// );
|
||||
// }
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Manage Coupons read display
|
||||
*
|
||||
* @param int $couponId Coupon Id
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function readAction($couponId)
|
||||
{
|
||||
$this->checkAuth('ADMIN', 'admin.coupon.read');
|
||||
|
||||
// Database request repeated in the loop but cached
|
||||
$search = CouponQuery::create();
|
||||
$coupon = $search->findOneById($couponId);
|
||||
|
||||
if ($coupon === null) {
|
||||
return $this->pageNotFound();
|
||||
}
|
||||
|
||||
return $this->render('coupon-read', array('couponId' => $couponId));
|
||||
}
|
||||
|
||||
/**
|
||||
* Manage Coupons read display
|
||||
*
|
||||
@@ -350,17 +285,7 @@ class CouponController extends BaseAdminController
|
||||
{
|
||||
$this->checkAuth('ADMIN', 'admin.coupon.read');
|
||||
|
||||
if ($this->isDebug()) {
|
||||
if (!$this->getRequest()->isXmlHttpRequest()) {
|
||||
$this->redirect(
|
||||
$this->getRoute(
|
||||
'admin',
|
||||
array(),
|
||||
Router::ABSOLUTE_URL
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
$this->checkXmlHttpRequest();
|
||||
|
||||
/** @var ConstraintFactory $constraintFactory */
|
||||
$constraintFactory = $this->container->get('thelia.constraint.factory');
|
||||
@@ -391,17 +316,7 @@ class CouponController extends BaseAdminController
|
||||
{
|
||||
$this->checkAuth('ADMIN', 'admin.coupon.read');
|
||||
|
||||
if ($this->isDebug()) {
|
||||
if (!$this->getRequest()->isXmlHttpRequest()) {
|
||||
$this->redirect(
|
||||
$this->getRoute(
|
||||
'admin',
|
||||
array(),
|
||||
Router::ABSOLUTE_URL
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
$this->checkXmlHttpRequest();
|
||||
|
||||
$search = CouponQuery::create();
|
||||
/** @var Coupon $coupon */
|
||||
@@ -475,6 +390,29 @@ class CouponController extends BaseAdminController
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Coupon consuming
|
||||
*
|
||||
* @param string $couponCode Coupon code
|
||||
*
|
||||
*/
|
||||
public function consumeAction($couponCode)
|
||||
{
|
||||
// @todo remove (event dispatcher testing purpose)
|
||||
$couponConsumeEvent = new CouponConsumeEvent($couponCode);
|
||||
$eventToDispatch = TheliaEvents::COUPON_CONSUME;
|
||||
|
||||
// Dispatch Event to the Action
|
||||
$this->dispatch(
|
||||
$eventToDispatch,
|
||||
$couponConsumeEvent
|
||||
);
|
||||
|
||||
var_dump('test', $couponConsumeEvent->getCode(), $couponConsumeEvent->getDiscount(), $couponConsumeEvent->getIsValid());
|
||||
|
||||
exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a Coupon from its form
|
||||
*
|
||||
@@ -535,7 +473,7 @@ class CouponController extends BaseAdminController
|
||||
/**
|
||||
* Validate the CreateOrUpdate form
|
||||
*
|
||||
* @param string $i18n Local code (fr_FR)
|
||||
* @param I18n $i18n Local code (fr_FR)
|
||||
* @param Lang $lang Local variables container
|
||||
* @param string $eventToDispatch Event which will activate actions
|
||||
* @param string $log created|edited
|
||||
@@ -543,7 +481,7 @@ class CouponController extends BaseAdminController
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
protected function validateCreateOrUpdateForm($i18n, $lang, $eventToDispatch, $log, $action)
|
||||
protected function validateCreateOrUpdateForm(I18n $i18n, Lang $lang, $eventToDispatch, $log, $action)
|
||||
{
|
||||
// Create the form from the request
|
||||
$creationForm = new CouponCreationForm($this->getRequest());
|
||||
@@ -563,7 +501,7 @@ class CouponController extends BaseAdminController
|
||||
$data['shortDescription'],
|
||||
$data['description'],
|
||||
$data['isEnabled'],
|
||||
$i18n->getDateTimeFromForm($lang, $data['expirationDate']),
|
||||
\DateTime::createFromFormat('Y-m-d', $data['expirationDate']),
|
||||
$data['isAvailableOnSpecialOffers'],
|
||||
$data['isCumulative'],
|
||||
$data['isRemovingPostage'],
|
||||
@@ -651,17 +589,17 @@ class CouponController extends BaseAdminController
|
||||
/** @var CouponManager $couponManager */
|
||||
$couponManager = $this->container->get('thelia.coupon.manager');
|
||||
$availableCoupons = $couponManager->getAvailableCoupons();
|
||||
$cleanedRules = array();
|
||||
$cleanedCoupons = array();
|
||||
/** @var CouponInterface $availableCoupon */
|
||||
foreach ($availableCoupons as $availableCoupon) {
|
||||
$rule = array();
|
||||
$rule['serviceId'] = $availableCoupon->getServiceId();
|
||||
$rule['name'] = $availableCoupon->getName();
|
||||
$rule['toolTip'] = $availableCoupon->getToolTip();
|
||||
$cleanedRules[] = $rule;
|
||||
$cleanedCoupons[] = $rule;
|
||||
}
|
||||
|
||||
return $cleanedRules;
|
||||
return $cleanedCoupons;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -127,7 +127,7 @@ class BaseController extends ContainerAware
|
||||
/**
|
||||
* Returns the session from the current request
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Session\SessionInterface
|
||||
* @return \Thelia\Core\HttpFoundation\Session\Session
|
||||
*/
|
||||
protected function getSession()
|
||||
{
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
/**********************************************************************************/
|
||||
|
||||
namespace Thelia\Core\Event\Coupon;
|
||||
use Thelia\Core\Event\ActionEvent;
|
||||
use Thelia\Coupon\CouponRuleCollection;
|
||||
use Thelia\Model\Coupon;
|
||||
|
||||
/**
|
||||
@@ -29,75 +31,112 @@ use Thelia\Model\Coupon;
|
||||
* Date: 8/29/13
|
||||
* Time: 3:45 PM
|
||||
*
|
||||
* Occurring when a Coupon is disabled
|
||||
* Occurring when a Coupon is consumed
|
||||
*
|
||||
* @package Coupon
|
||||
* @author Guillaume MOREL <gmorel@openstudio.fr>
|
||||
*
|
||||
*/
|
||||
class CouponDisableEvent extends ActionEvent
|
||||
class CouponConsumeEvent extends ActionEvent
|
||||
{
|
||||
/** @var int Coupon id */
|
||||
protected $couponId;
|
||||
/** @var string Coupon code */
|
||||
protected $code = null;
|
||||
|
||||
/** @var Coupon Coupon being disabled */
|
||||
protected $disabledCoupon;
|
||||
/** @var float Total discount given by this coupon */
|
||||
protected $discount = 0;
|
||||
|
||||
/** @var bool If Coupon is valid or if Customer meets coupon conditions */
|
||||
protected $isValid = null;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param int $id Coupon Id
|
||||
* @param string $code Coupon code
|
||||
* @param float $discount Total discount given by this coupon
|
||||
* @param bool $isValid If Coupon is valid or
|
||||
* if Customer meets coupon conditions
|
||||
*/
|
||||
public function __construct($id)
|
||||
function __construct($code, $discount = null, $isValid = null)
|
||||
{
|
||||
$this->id = $id;
|
||||
$this->code = $code;
|
||||
$this->discount = $discount;
|
||||
$this->isValid = $isValid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Coupon id
|
||||
* Set Coupon code
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Coupon id
|
||||
*
|
||||
* @param int $id Coupon id
|
||||
* @param string $code Coupon code
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setId($id)
|
||||
public function setCode($code)
|
||||
{
|
||||
$this->id = $id;
|
||||
$this->code = $code;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Coupon being disabled
|
||||
* Get Coupon code
|
||||
*
|
||||
* @return Coupon
|
||||
* @return string
|
||||
*/
|
||||
public function getDisabledCoupon()
|
||||
public function getCode()
|
||||
{
|
||||
return $this->disabledCoupon;
|
||||
return $this->code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Coupon to be disabled
|
||||
* Set total discount given by this coupon
|
||||
*
|
||||
* @param Coupon $disabledCoupon Coupon to disable
|
||||
* @param float $discount Total discount given by this coupon
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setDisabledCoupon(Coupon $disabledCoupon)
|
||||
public function setDiscount($discount)
|
||||
{
|
||||
$this->disabledCoupon = $disabledCoupon;
|
||||
$this->discount = $discount;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get total discount given by this coupon
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getDiscount()
|
||||
{
|
||||
return $this->discount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set if Coupon is valid or if Customer meets coupon conditions
|
||||
*
|
||||
* @param boolean $isValid if Coupon is valid or
|
||||
* if Customer meets coupon conditions
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setIsValid($isValid)
|
||||
{
|
||||
$this->isValid = $isValid;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if Coupon is valid or if Customer meets coupon conditions
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function getIsValid()
|
||||
{
|
||||
return $this->isValid;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
<?php
|
||||
/**********************************************************************************/
|
||||
/* */
|
||||
/* Thelia */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : info@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* This program is free software; you can redistribute it and/or modify */
|
||||
/* it under the terms of the GNU General Public License as published by */
|
||||
/* the Free Software Foundation; either version 3 of the License */
|
||||
/* */
|
||||
/* This program is distributed in the hope that it will be useful, */
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
|
||||
/* GNU General Public License for more details. */
|
||||
/* */
|
||||
/* You should have received a copy of the GNU General Public License */
|
||||
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
/* */
|
||||
/**********************************************************************************/
|
||||
|
||||
namespace Thelia\Core\Event\Coupon;
|
||||
use Thelia\Model\Coupon;
|
||||
|
||||
/**
|
||||
* Created by JetBrains PhpStorm.
|
||||
* Date: 8/29/13
|
||||
* Time: 3:45 PM
|
||||
*
|
||||
* Occurring when a Coupon is enabled
|
||||
*
|
||||
* @package Coupon
|
||||
* @author Guillaume MOREL <gmorel@openstudio.fr>
|
||||
*
|
||||
*/
|
||||
class CouponEnableEvent extends ActionEvent
|
||||
{
|
||||
/** @var int Coupon id */
|
||||
protected $couponId;
|
||||
|
||||
/** @var Coupon Coupon being enabled */
|
||||
protected $enabledCoupon;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param int $id Coupon Id
|
||||
*/
|
||||
public function __construct($id)
|
||||
{
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Coupon id
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Coupon id
|
||||
*
|
||||
* @param int $id Coupon id
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setId($id)
|
||||
{
|
||||
$this->id = $id;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Coupon being enabled
|
||||
*
|
||||
* @return Coupon
|
||||
*/
|
||||
public function getEnabledCoupon()
|
||||
{
|
||||
return $this->enabledCoupon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Coupon to be enabled
|
||||
*
|
||||
* @param Coupon $enabledCoupon Coupon to enabled
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setEnabledCoupon(Coupon $enabledCoupon)
|
||||
{
|
||||
$this->enabledCoupon = $enabledCoupon;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -258,36 +258,6 @@ final class TheliaEvents
|
||||
*/
|
||||
const AFTER_UPDATE_COUPON = "action.after_update_coupon";
|
||||
|
||||
/**
|
||||
* Sent when disabling a Coupon
|
||||
*/
|
||||
const COUPON_DISABLE = "action.disable_coupon";
|
||||
|
||||
/**
|
||||
* Sent just before a successful disable of a new Coupon in the database.
|
||||
*/
|
||||
const BEFORE_DISABLE_COUPON = "action.before_disable_coupon";
|
||||
|
||||
/**
|
||||
* Sent just after a successful disable of a new Coupon in the database.
|
||||
*/
|
||||
const AFTER_DISABLE_COUPON = "action.after_disable_coupon";
|
||||
|
||||
/**
|
||||
* Sent when enabling a Coupon
|
||||
*/
|
||||
const COUPON_ENABLE = "action.enable_coupon";
|
||||
|
||||
/**
|
||||
* Sent just before a successful enable of a new Coupon in the database.
|
||||
*/
|
||||
const BEFORE_ENABLE_COUPON = "action.before_enable_coupon";
|
||||
|
||||
/**
|
||||
* Sent just after a successful enable of a new Coupon in the database.
|
||||
*/
|
||||
const AFTER_ENABLE_COUPON = "action.after_enable_coupon";
|
||||
|
||||
/**
|
||||
* Sent when attempting to use a Coupon
|
||||
*/
|
||||
|
||||
@@ -55,4 +55,15 @@ class Request extends BaseRequest
|
||||
|
||||
return $uri . $additionalQs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Session.
|
||||
*
|
||||
* @return \Thelia\Core\HttpFoundation\Session\Session The session
|
||||
* @api
|
||||
*/
|
||||
public function getSession()
|
||||
{
|
||||
return parent::getSession();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,4 +220,29 @@ class Session extends BaseSession
|
||||
{
|
||||
return $this->get("thelia.delivery_id");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set consumed coupons by the Customer
|
||||
*
|
||||
* @param array $couponsCode An array of Coupon code
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setConsumedCoupons(array $couponsCode)
|
||||
{
|
||||
$this->set('thelia.consumed_coupons', $couponsCode);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Customer consumed coupons
|
||||
*
|
||||
* @return array $couponsCode An array of Coupon code
|
||||
*/
|
||||
public function getConsumedCoupons()
|
||||
{
|
||||
return $this->get('thelia.consumed_coupons');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
namespace Thelia\Core\Template\Loop;
|
||||
|
||||
use Propel\Runtime\ActiveQuery\Criteria;
|
||||
use Propel\Runtime\Util\PropelModelPager;
|
||||
use Thelia\Constraint\ConstraintFactory;
|
||||
use Thelia\Constraint\Rule\CouponRuleInterface;
|
||||
use Thelia\Core\HttpFoundation\Request;
|
||||
@@ -34,9 +35,11 @@ use Thelia\Core\Template\Element\LoopResultRow;
|
||||
use Thelia\Core\Template\Loop\Argument\ArgumentCollection;
|
||||
use Thelia\Core\Template\Loop\Argument\Argument;
|
||||
|
||||
use Thelia\Coupon\Type\CouponInterface;
|
||||
use Thelia\Model\CouponQuery;
|
||||
use Thelia\Model\Coupon as MCoupon;
|
||||
use Thelia\Type;
|
||||
use Thelia\Type\BooleanOrBothType;
|
||||
|
||||
/**
|
||||
* Created by JetBrains PhpStorm.
|
||||
@@ -52,17 +55,22 @@ use Thelia\Type;
|
||||
class Coupon extends BaseI18nLoop
|
||||
{
|
||||
/**
|
||||
* Define all args used in your loop
|
||||
*
|
||||
* @return ArgumentCollection
|
||||
*/
|
||||
protected function getArgDefinitions()
|
||||
{
|
||||
return new ArgumentCollection(
|
||||
Argument::createIntListTypeArgument('id')
|
||||
Argument::createIntListTypeArgument('id'),
|
||||
Argument::createBooleanOrBothTypeArgument('is_enabled', 1)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $pagination
|
||||
* Execute Loop
|
||||
*
|
||||
* @param PropelModelPager $pagination
|
||||
*
|
||||
* @return \Thelia\Core\Template\Element\LoopResult
|
||||
*/
|
||||
@@ -74,11 +82,16 @@ class Coupon extends BaseI18nLoop
|
||||
$locale = $this->configureI18nProcessing($search, array('TITLE', 'DESCRIPTION', 'SHORT_DESCRIPTION'));
|
||||
|
||||
$id = $this->getId();
|
||||
$isEnabled = $this->getIsEnabled();
|
||||
|
||||
if (null !== $id) {
|
||||
$search->filterById($id, Criteria::IN);
|
||||
}
|
||||
|
||||
if ($isEnabled != BooleanOrBothType::ANY) {
|
||||
$search->filterByIsEnabled($isEnabled ? 1 : 0);
|
||||
}
|
||||
|
||||
// Perform search
|
||||
$coupons = $this->search($search, $pagination);
|
||||
|
||||
@@ -98,9 +111,30 @@ class Coupon extends BaseI18nLoop
|
||||
$coupon->getSerializedRules()
|
||||
);
|
||||
|
||||
/** @var CouponInterface $couponManager */
|
||||
$couponManager = $this->container->get($coupon->getType());
|
||||
$couponManager->set(
|
||||
$this->container->get('thelia.adapter'),
|
||||
$coupon->getCode(),
|
||||
$coupon->getTitle(),
|
||||
$coupon->getShortDescription(),
|
||||
$coupon->getDescription(),
|
||||
$coupon->getAmount(),
|
||||
$coupon->getIsCumulative(),
|
||||
$coupon->getIsRemovingPostage(),
|
||||
$coupon->getIsAvailableOnSpecialOffers(),
|
||||
$coupon->getIsEnabled(),
|
||||
$coupon->getMaxUsage(),
|
||||
$coupon->getExpirationDate()
|
||||
);
|
||||
|
||||
$now = time();
|
||||
$datediff = $coupon->getExpirationDate()->getTimestamp() - $now;
|
||||
$daysLeftBeforeExpiration = floor($datediff/(60*60*24));
|
||||
|
||||
$cleanedRules = array();
|
||||
/** @var CouponRuleInterface $rule */
|
||||
foreach ($rules->getRules() as $key => $rule) {
|
||||
foreach ($rules->getRules() as $rule) {
|
||||
$cleanedRules[] = $rule->getToolTip();
|
||||
}
|
||||
$loopResultRow->set("ID", $coupon->getId())
|
||||
@@ -114,9 +148,13 @@ class Coupon extends BaseI18nLoop
|
||||
->set("USAGE_LEFT", $coupon->getMaxUsage())
|
||||
->set("IS_CUMULATIVE", $coupon->getIsCumulative())
|
||||
->set("IS_REMOVING_POSTAGE", $coupon->getIsRemovingPostage())
|
||||
->set("IS_AVAILABLE_ON_SPECIAL_OFFERS", $coupon->getIsAvailableOnSpecialOffers())
|
||||
->set("IS_ENABLED", $coupon->getIsEnabled())
|
||||
->set("AMOUNT", $coupon->getAmount())
|
||||
->set("APPLICATION_CONDITIONS", $cleanedRules);
|
||||
->set("APPLICATION_CONDITIONS", $cleanedRules)
|
||||
->set("TOOLTIP", $couponManager->getToolTip())
|
||||
->set("DAY_LEFT_BEFORE_EXPIRATION", $daysLeftBeforeExpiration)
|
||||
->set("SERVICE_ID", $couponManager->getServiceId());
|
||||
$loopResult->addRow($loopResultRow);
|
||||
}
|
||||
|
||||
|
||||
@@ -155,4 +155,18 @@ interface CouponAdapterInterface
|
||||
*/
|
||||
public function getMainCurrency();
|
||||
|
||||
/**
|
||||
* Return request
|
||||
*
|
||||
* @return Request
|
||||
*/
|
||||
public function getRequest();
|
||||
|
||||
/**
|
||||
* Return Constraint Validator
|
||||
*
|
||||
* @return ConstraintValidator
|
||||
*/
|
||||
public function getConstraintValidator();
|
||||
|
||||
}
|
||||
@@ -27,9 +27,14 @@ use Symfony\Component\DependencyInjection\Container;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\Translation\Translator;
|
||||
use Symfony\Component\Translation\TranslatorInterface;
|
||||
use Thelia\Constraint\ConstraintValidator;
|
||||
use Thelia\Core\HttpFoundation\Request;
|
||||
use Thelia\Core\Security\SecurityContext;
|
||||
use Thelia\Coupon\Type\CouponInterface;
|
||||
use Thelia\Model\Coupon;
|
||||
use Thelia\Model\CouponQuery;
|
||||
use Thelia\Cart\CartTrait;
|
||||
use Thelia\Model\Currency;
|
||||
|
||||
/**
|
||||
* Created by JetBrains PhpStorm.
|
||||
@@ -43,6 +48,10 @@ use Thelia\Model\CouponQuery;
|
||||
*/
|
||||
class CouponBaseAdapter implements CouponAdapterInterface
|
||||
{
|
||||
use CartTrait {
|
||||
CartTrait::getCart as getCartFromTrait;
|
||||
}
|
||||
|
||||
/** @var ContainerInterface Service Container */
|
||||
protected $container = null;
|
||||
|
||||
@@ -66,7 +75,7 @@ class CouponBaseAdapter implements CouponAdapterInterface
|
||||
*/
|
||||
public function getCart()
|
||||
{
|
||||
// TODO: Implement getCart() method.
|
||||
return $this->getCartFromTrait($this->getRequest());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -86,7 +95,7 @@ class CouponBaseAdapter implements CouponAdapterInterface
|
||||
*/
|
||||
public function getCustomer()
|
||||
{
|
||||
// TODO: Implement getCustomer() method.
|
||||
return $this->container->get('thelia.securityContext')->getCustomerUser();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -122,11 +131,11 @@ class CouponBaseAdapter implements CouponAdapterInterface
|
||||
/**
|
||||
* Return the Checkout currency EUR|USD
|
||||
*
|
||||
* @return string
|
||||
* @return Currency
|
||||
*/
|
||||
public function getCheckoutCurrency()
|
||||
{
|
||||
// TODO: Implement getCheckoutCurrency() method.
|
||||
$this->getRequest()->getSession()->getCurrency();
|
||||
}
|
||||
|
||||
|
||||
@@ -147,9 +156,14 @@ class CouponBaseAdapter implements CouponAdapterInterface
|
||||
*/
|
||||
public function getCurrentCoupons()
|
||||
{
|
||||
// @todo implement
|
||||
// $consumedCoupons = $this->getRequest()->getSession()->getConsumedCoupons();
|
||||
// @todo convert coupon code to coupon Interface
|
||||
|
||||
|
||||
$couponFactory = $this->container->get('thelia.coupon.factory');
|
||||
|
||||
// @todo Get from Session
|
||||
// @todo get from cart
|
||||
$couponCodes = array('XMAS', 'SPRINGBREAK');
|
||||
|
||||
$coupons = array();
|
||||
@@ -208,7 +222,7 @@ class CouponBaseAdapter implements CouponAdapterInterface
|
||||
*/
|
||||
public function getContainer()
|
||||
{
|
||||
// TODO: Implement getContainer() method.
|
||||
return $this->container;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -232,4 +246,24 @@ class CouponBaseAdapter implements CouponAdapterInterface
|
||||
{
|
||||
// TODO: Implement getMainCurrency() method.
|
||||
}
|
||||
|
||||
/**
|
||||
* Return request
|
||||
*
|
||||
* @return Request
|
||||
*/
|
||||
public function getRequest()
|
||||
{
|
||||
return $this->container->get('request');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return Constraint Validator
|
||||
*
|
||||
* @return ConstraintValidator
|
||||
*/
|
||||
public function getConstraintValidator()
|
||||
{
|
||||
return $this->container->get('thelia.constraint.validator');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -183,6 +183,7 @@ class CouponManager
|
||||
$discount = 0.00;
|
||||
/** @var CouponInterface $coupon */
|
||||
foreach ($coupons as $coupon) {
|
||||
// @todo modify Cart with discount for each cart item
|
||||
$discount += $coupon->getDiscount($this->adapter);
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ namespace Thelia\Coupon\Type;
|
||||
use Symfony\Component\Intl\Exception\NotImplementedException;
|
||||
use Thelia\Constraint\ConstraintManager;
|
||||
use Thelia\Constraint\ConstraintValidator;
|
||||
use Thelia\Core\Translation\Translator;
|
||||
use Thelia\Coupon\CouponAdapterInterface;
|
||||
use Thelia\Coupon\CouponRuleCollection;
|
||||
use Thelia\Coupon\RuleOrganizerInterface;
|
||||
@@ -44,9 +45,6 @@ use Thelia\Exception\InvalidRuleException;
|
||||
*/
|
||||
abstract class CouponAbstract implements CouponInterface
|
||||
{
|
||||
/** @var string Service Id */
|
||||
protected $serviceId = null;
|
||||
|
||||
/** @var CouponAdapterInterface Provide necessary value from Thelia */
|
||||
protected $adapter = null;
|
||||
|
||||
@@ -62,9 +60,19 @@ abstract class CouponAbstract implements CouponInterface
|
||||
/** @var ConstraintValidator Constraint validator */
|
||||
protected $constraintValidator = null;
|
||||
|
||||
|
||||
|
||||
/** @var string Service Id */
|
||||
protected $serviceId = null;
|
||||
|
||||
/** @var float Amount that will be removed from the Checkout (Coupon Effect) */
|
||||
protected $amount = 0;
|
||||
|
||||
/** @var string Coupon code (ex: XMAS) */
|
||||
protected $code = null;
|
||||
|
||||
|
||||
|
||||
/** @var string Coupon title (ex: Coupon for XMAS) */
|
||||
protected $title = null;
|
||||
|
||||
@@ -74,6 +82,8 @@ abstract class CouponAbstract implements CouponInterface
|
||||
/** @var string Coupon description */
|
||||
protected $description = null;
|
||||
|
||||
|
||||
|
||||
/** @var bool if Coupon is enabled */
|
||||
protected $isEnabled = false;
|
||||
|
||||
@@ -86,9 +96,6 @@ abstract class CouponAbstract implements CouponInterface
|
||||
/** @var bool if Coupon is removing postage */
|
||||
protected $isRemovingPostage = false;
|
||||
|
||||
/** @var float Amount that will be removed from the Checkout (Coupon Effect) */
|
||||
protected $amount = 0;
|
||||
|
||||
/** @var int Max time a Coupon can be used (-1 = unlimited) */
|
||||
protected $maxUsage = -1;
|
||||
|
||||
@@ -105,6 +112,7 @@ abstract class CouponAbstract implements CouponInterface
|
||||
{
|
||||
$this->adapter = $adapter;
|
||||
$this->translator = $adapter->getTranslator();
|
||||
$this->constraintValidator = $adapter->getConstraintValidator();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -220,17 +228,6 @@ abstract class CouponAbstract implements CouponInterface
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the current Coupon is matching its conditions (Rules)
|
||||
* Thelia variables are given by the CouponAdapterInterface
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isMatching()
|
||||
{
|
||||
return $this->constraintValidator->test($this->rules);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return Coupon expiration date
|
||||
*
|
||||
@@ -302,4 +299,16 @@ abstract class CouponAbstract implements CouponInterface
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if the current Coupon is matching its conditions (Rules)
|
||||
* Thelia variables are given by the CouponAdapterInterface
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isMatching()
|
||||
{
|
||||
return $this->constraintValidator->isMatching($this->rules);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -39,6 +39,27 @@ use Thelia\Coupon\CouponRuleCollection;
|
||||
*/
|
||||
interface CouponInterface
|
||||
{
|
||||
/**
|
||||
* Get I18n name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName();
|
||||
|
||||
/**
|
||||
* Get I18n tooltip
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getToolTip();
|
||||
|
||||
/**
|
||||
* Get Coupon Manager service Id
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getServiceId();
|
||||
|
||||
/**
|
||||
* Set Coupon
|
||||
*
|
||||
@@ -114,18 +135,7 @@ interface CouponInterface
|
||||
*/
|
||||
public function isRemovingPostage();
|
||||
|
||||
/**
|
||||
* Return effects generated by the coupon
|
||||
* A positive value
|
||||
*
|
||||
* Effects could also affect something else than the final Checkout price
|
||||
* CouponAdapter $adapter could be use to directly pass a Session value
|
||||
* some would wish to modify
|
||||
* Hence affecting a wide variety of Thelia elements
|
||||
*
|
||||
* @return float Amount removed from the Total Checkout
|
||||
*/
|
||||
public function getDiscount();
|
||||
|
||||
|
||||
/**
|
||||
* Return condition to validate the Coupon or not
|
||||
@@ -134,14 +144,6 @@ interface CouponInterface
|
||||
*/
|
||||
public function getRules();
|
||||
|
||||
/**
|
||||
* Check if the current Coupon is matching its conditions (Rules)
|
||||
* Thelia variables are given by the CouponAdapterInterface
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isMatching();
|
||||
|
||||
/**
|
||||
* Replace the existing Rules by those given in parameter
|
||||
* If one Rule is badly implemented, no Rule will be added
|
||||
@@ -191,25 +193,26 @@ interface CouponInterface
|
||||
*/
|
||||
public function isExpired();
|
||||
|
||||
/**
|
||||
* Get I18n name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName();
|
||||
|
||||
/**
|
||||
* Get I18n tooltip
|
||||
* Return effects generated by the coupon
|
||||
* A positive value
|
||||
*
|
||||
* @return string
|
||||
* Effects could also affect something else than the final Checkout price
|
||||
* CouponAdapter $adapter could be use to directly pass a Session value
|
||||
* some would wish to modify
|
||||
* Hence affecting a wide variety of Thelia elements
|
||||
*
|
||||
* @return float Amount removed from the Total Checkout
|
||||
*/
|
||||
public function getToolTip();
|
||||
public function getDiscount();
|
||||
|
||||
/**
|
||||
* Get Coupon Manager service Id
|
||||
* Check if the current Coupon is matching its conditions (Rules)
|
||||
* Thelia variables are given by the CouponAdapterInterface
|
||||
*
|
||||
* @return string
|
||||
* @return bool
|
||||
*/
|
||||
public function getServiceId();
|
||||
public function isMatching();
|
||||
|
||||
}
|
||||
|
||||
@@ -23,7 +23,11 @@
|
||||
|
||||
namespace Thelia\Form;
|
||||
|
||||
use Symfony\Component\Validator\Constraints\Date;
|
||||
use Symfony\Component\Validator\Constraints\DateTime;
|
||||
use Symfony\Component\Validator\Constraints\GreaterThanOrEqual;
|
||||
use Symfony\Component\Validator\Constraints\NotBlank;
|
||||
use Symfony\Component\Validator\Constraints\NotEqualTo;
|
||||
|
||||
/**
|
||||
* Created by JetBrains PhpStorm.
|
||||
@@ -68,7 +72,6 @@ class CouponCreationForm extends BaseForm
|
||||
'shortDescription',
|
||||
'text',
|
||||
array(
|
||||
'invalid_message' => 'test',
|
||||
'constraints' => array(
|
||||
new NotBlank()
|
||||
)
|
||||
@@ -78,7 +81,6 @@ class CouponCreationForm extends BaseForm
|
||||
'description',
|
||||
'textarea',
|
||||
array(
|
||||
'invalid_message' => 'test',
|
||||
'constraints' => array(
|
||||
new NotBlank()
|
||||
)
|
||||
@@ -88,16 +90,23 @@ class CouponCreationForm extends BaseForm
|
||||
'effect',
|
||||
'text',
|
||||
array(
|
||||
'invalid_message' => 'test',
|
||||
'constraints' => array(
|
||||
new NotBlank()
|
||||
new NotBlank(),
|
||||
new NotEqualTo(
|
||||
array(
|
||||
'value' => -1
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
->add(
|
||||
'amount',
|
||||
'money',
|
||||
array()
|
||||
array(
|
||||
'constraints' => array(
|
||||
new NotBlank()
|
||||
))
|
||||
)
|
||||
->add(
|
||||
'isEnabled',
|
||||
@@ -109,7 +118,8 @@ class CouponCreationForm extends BaseForm
|
||||
'text',
|
||||
array(
|
||||
'constraints' => array(
|
||||
new NotBlank()
|
||||
new NotBlank(),
|
||||
new Date()
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -133,7 +143,12 @@ class CouponCreationForm extends BaseForm
|
||||
'text',
|
||||
array(
|
||||
'constraints' => array(
|
||||
new NotBlank()
|
||||
new NotBlank(),
|
||||
new GreaterThanOrEqual(
|
||||
array(
|
||||
'value' => -1
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -76,7 +76,6 @@ class Coupon extends BaseCoupon
|
||||
->setType($effect)
|
||||
->setAmount($amount)
|
||||
->setIsRemovingPostage($isRemovingPostage)
|
||||
->setType($amount)
|
||||
->setIsEnabled($isEnabled)
|
||||
->setExpirationDate($expirationDate)
|
||||
->setIsAvailableOnSpecialOffers($isAvailableOnSpecialOffers)
|
||||
|
||||
@@ -79,7 +79,7 @@ class ConstraintValidatorTest extends \PHPUnit_Framework_TestCase
|
||||
$rules = new CouponRuleCollection();
|
||||
$rules->add($rule1);
|
||||
|
||||
$isValid = $ConstraintValidator->test($rules);
|
||||
$isValid = $ConstraintValidator->isMatching($rules);
|
||||
|
||||
$expected = true;
|
||||
$actual =$isValid;
|
||||
@@ -113,7 +113,7 @@ class ConstraintValidatorTest extends \PHPUnit_Framework_TestCase
|
||||
$rules = new CouponRuleCollection();
|
||||
$rules->add($rule1);
|
||||
|
||||
$isValid = $ConstraintValidator->test($rules);
|
||||
$isValid = $ConstraintValidator->isMatching($rules);
|
||||
|
||||
$expected = false;
|
||||
$actual =$isValid;
|
||||
@@ -160,7 +160,7 @@ class ConstraintValidatorTest extends \PHPUnit_Framework_TestCase
|
||||
$rules->add($rule1);
|
||||
$rules->add($rule2);
|
||||
|
||||
$isValid = $ConstraintValidator->test($rules);
|
||||
$isValid = $ConstraintValidator->isMatching($rules);
|
||||
|
||||
$expected = true;
|
||||
$actual =$isValid;
|
||||
@@ -207,7 +207,7 @@ class ConstraintValidatorTest extends \PHPUnit_Framework_TestCase
|
||||
$rules->add($rule1);
|
||||
$rules->add($rule2);
|
||||
|
||||
$isValid = $ConstraintValidator->test($rules);
|
||||
$isValid = $ConstraintValidator->isMatching($rules);
|
||||
|
||||
$expected = false;
|
||||
$actual =$isValid;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
INSERT INTO `lang`(`id`,`title`,`code`,`locale`,`url`,`date_format`,`time_format`,`datetime_format`,`decimal_separator`,`thousands_separator`,`decimals`,`by_default`,`created_at`,`updated_at`)VALUES
|
||||
(1, 'Français', 'fr', 'fr_FR', '', 'd/m/Y', 'H:i:s', 'd/m/y H:i:s', ',', ' ', '2', '1', NOW(), NOW()),
|
||||
(2, 'English', 'en', 'en_US', '', 'm-d-Y', 'h:i:s', 'm-d-Y h:i:s', '.', ' ', '2', '0', NOW(), NOW()),
|
||||
(1, 'Français', 'fr', 'fr_FR', '', 'd/m/Y', 'H:i:s', 'd/m/y H:i:s', ',', ' ', '2', '0', NOW(), NOW()),
|
||||
(2, 'English', 'en', 'en_US', '', 'm-d-Y', 'h:i:s', 'm-d-Y h:i:s', '.', ' ', '2', '1', NOW(), NOW()),
|
||||
(3, 'castellano', 'es', 'es_ES', '', 'm-d-Y', 'h:i:s', 'm-d-Y h:i:s', ',', '.', '2', '0', NOW(), NOW()),
|
||||
(4, 'Italiano', 'it', 'it_IT', '', 'd/m/Y', 'H:i:s', 'd/m/y H:i:s', ',', ' ', '2', '0', NOW(), NOW());
|
||||
|
||||
|
||||
@@ -146,7 +146,7 @@
|
||||
|
||||
{loop name="menu-auth-coupon" type="auth" roles="ADMIN" permissions="admin.coupon.view"}
|
||||
<li class="{if $admin_current_location == 'coupon'}active{/if}" id="coupon_menu">
|
||||
<a href="{url path='/admin/coupon-list'}">{intl l="Coupons"}</a>
|
||||
<a href="{url path='/admin/coupon/'}">{intl l="Coupons"}</a>
|
||||
</li>
|
||||
{/loop}
|
||||
|
||||
|
||||
@@ -1,474 +1,474 @@
|
||||
/* =========================================================
|
||||
* bootstrap-datepicker.js
|
||||
* http://www.eyecon.ro/bootstrap-datepicker
|
||||
* =========================================================
|
||||
* Copyright 2012 Stefan Petre
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ========================================================= */
|
||||
|
||||
!function( $ ) {
|
||||
|
||||
// Picker object
|
||||
|
||||
var Datepicker = function(element, options){
|
||||
this.element = $(element);
|
||||
this.format = DPGlobal.parseFormat(options.format||this.element.data('date-format')||'mm/dd/yyyy');
|
||||
this.picker = $(DPGlobal.template)
|
||||
.appendTo('body')
|
||||
.on({
|
||||
click: $.proxy(this.click, this)//,
|
||||
//mousedown: $.proxy(this.mousedown, this)
|
||||
});
|
||||
this.isInput = this.element.is('input');
|
||||
this.component = this.element.is('.date') ? this.element.find('.add-on') : false;
|
||||
|
||||
if (this.isInput) {
|
||||
this.element.on({
|
||||
focus: $.proxy(this.show, this),
|
||||
//blur: $.proxy(this.hide, this),
|
||||
keyup: $.proxy(this.update, this)
|
||||
});
|
||||
} else {
|
||||
if (this.component){
|
||||
this.component.on('click', $.proxy(this.show, this));
|
||||
} else {
|
||||
this.element.on('click', $.proxy(this.show, this));
|
||||
}
|
||||
}
|
||||
|
||||
this.minViewMode = options.minViewMode||this.element.data('date-minviewmode')||0;
|
||||
if (typeof this.minViewMode === 'string') {
|
||||
switch (this.minViewMode) {
|
||||
case 'months':
|
||||
this.minViewMode = 1;
|
||||
break;
|
||||
case 'years':
|
||||
this.minViewMode = 2;
|
||||
break;
|
||||
default:
|
||||
this.minViewMode = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.viewMode = options.viewMode||this.element.data('date-viewmode')||0;
|
||||
if (typeof this.viewMode === 'string') {
|
||||
switch (this.viewMode) {
|
||||
case 'months':
|
||||
this.viewMode = 1;
|
||||
break;
|
||||
case 'years':
|
||||
this.viewMode = 2;
|
||||
break;
|
||||
default:
|
||||
this.viewMode = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.startViewMode = this.viewMode;
|
||||
this.weekStart = options.weekStart||this.element.data('date-weekstart')||0;
|
||||
this.weekEnd = this.weekStart === 0 ? 6 : this.weekStart - 1;
|
||||
this.onRender = options.onRender;
|
||||
this.fillDow();
|
||||
this.fillMonths();
|
||||
this.update();
|
||||
this.showMode();
|
||||
};
|
||||
|
||||
Datepicker.prototype = {
|
||||
constructor: Datepicker,
|
||||
|
||||
show: function(e) {
|
||||
this.picker.show();
|
||||
this.height = this.component ? this.component.outerHeight() : this.element.outerHeight();
|
||||
this.place();
|
||||
$(window).on('resize', $.proxy(this.place, this));
|
||||
if (e ) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
}
|
||||
if (!this.isInput) {
|
||||
}
|
||||
var that = this;
|
||||
$(document).on('mousedown', function(ev){
|
||||
if ($(ev.target).closest('.datepicker').length == 0) {
|
||||
that.hide();
|
||||
}
|
||||
});
|
||||
this.element.trigger({
|
||||
type: 'show',
|
||||
date: this.date
|
||||
});
|
||||
},
|
||||
|
||||
hide: function(){
|
||||
this.picker.hide();
|
||||
$(window).off('resize', this.place);
|
||||
this.viewMode = this.startViewMode;
|
||||
this.showMode();
|
||||
if (!this.isInput) {
|
||||
$(document).off('mousedown', this.hide);
|
||||
}
|
||||
//this.set();
|
||||
this.element.trigger({
|
||||
type: 'hide',
|
||||
date: this.date
|
||||
});
|
||||
},
|
||||
|
||||
set: function() {
|
||||
var formated = DPGlobal.formatDate(this.date, this.format);
|
||||
if (!this.isInput) {
|
||||
if (this.component){
|
||||
this.element.find('input').prop('value', formated);
|
||||
}
|
||||
this.element.data('date', formated);
|
||||
} else {
|
||||
this.element.prop('value', formated);
|
||||
}
|
||||
},
|
||||
|
||||
setValue: function(newDate) {
|
||||
if (typeof newDate === 'string') {
|
||||
this.date = DPGlobal.parseDate(newDate, this.format);
|
||||
} else {
|
||||
this.date = new Date(newDate);
|
||||
}
|
||||
this.set();
|
||||
this.viewDate = new Date(this.date.getFullYear(), this.date.getMonth(), 1, 0, 0, 0, 0);
|
||||
this.fill();
|
||||
},
|
||||
|
||||
place: function(){
|
||||
var offset = this.component ? this.component.offset() : this.element.offset();
|
||||
this.picker.css({
|
||||
top: offset.top + this.height,
|
||||
left: offset.left
|
||||
});
|
||||
},
|
||||
|
||||
update: function(newDate){
|
||||
this.date = DPGlobal.parseDate(
|
||||
typeof newDate === 'string' ? newDate : (this.isInput ? this.element.prop('value') : this.element.data('date')),
|
||||
this.format
|
||||
);
|
||||
this.viewDate = new Date(this.date.getFullYear(), this.date.getMonth(), 1, 0, 0, 0, 0);
|
||||
this.fill();
|
||||
},
|
||||
|
||||
fillDow: function(){
|
||||
var dowCnt = this.weekStart;
|
||||
var html = '<tr>';
|
||||
while (dowCnt < this.weekStart + 7) {
|
||||
html += '<th class="dow">'+DPGlobal.dates.daysMin[(dowCnt++)%7]+'</th>';
|
||||
}
|
||||
html += '</tr>';
|
||||
this.picker.find('.datepicker-days thead').append(html);
|
||||
},
|
||||
|
||||
fillMonths: function(){
|
||||
var html = '';
|
||||
var i = 0
|
||||
while (i < 12) {
|
||||
html += '<span class="month">'+DPGlobal.dates.monthsShort[i++]+'</span>';
|
||||
}
|
||||
this.picker.find('.datepicker-months td').append(html);
|
||||
},
|
||||
|
||||
fill: function() {
|
||||
var d = new Date(this.viewDate),
|
||||
year = d.getFullYear(),
|
||||
month = d.getMonth(),
|
||||
currentDate = this.date.valueOf();
|
||||
this.picker.find('.datepicker-days th:eq(1)')
|
||||
.text(DPGlobal.dates.months[month]+' '+year);
|
||||
var prevMonth = new Date(year, month-1, 28,0,0,0,0),
|
||||
day = DPGlobal.getDaysInMonth(prevMonth.getFullYear(), prevMonth.getMonth());
|
||||
prevMonth.setDate(day);
|
||||
prevMonth.setDate(day - (prevMonth.getDay() - this.weekStart + 7)%7);
|
||||
var nextMonth = new Date(prevMonth);
|
||||
nextMonth.setDate(nextMonth.getDate() + 42);
|
||||
nextMonth = nextMonth.valueOf();
|
||||
var html = [];
|
||||
var clsName,
|
||||
prevY,
|
||||
prevM;
|
||||
while(prevMonth.valueOf() < nextMonth) {
|
||||
if (prevMonth.getDay() === this.weekStart) {
|
||||
html.push('<tr>');
|
||||
}
|
||||
clsName = this.onRender(prevMonth);
|
||||
prevY = prevMonth.getFullYear();
|
||||
prevM = prevMonth.getMonth();
|
||||
if ((prevM < month && prevY === year) || prevY < year) {
|
||||
clsName += ' old';
|
||||
} else if ((prevM > month && prevY === year) || prevY > year) {
|
||||
clsName += ' new';
|
||||
}
|
||||
if (prevMonth.valueOf() === currentDate) {
|
||||
clsName += ' active';
|
||||
}
|
||||
html.push('<td class="day '+clsName+'">'+prevMonth.getDate() + '</td>');
|
||||
if (prevMonth.getDay() === this.weekEnd) {
|
||||
html.push('</tr>');
|
||||
}
|
||||
prevMonth.setDate(prevMonth.getDate()+1);
|
||||
}
|
||||
this.picker.find('.datepicker-days tbody').empty().append(html.join(''));
|
||||
var currentYear = this.date.getFullYear();
|
||||
|
||||
var months = this.picker.find('.datepicker-months')
|
||||
.find('th:eq(1)')
|
||||
.text(year)
|
||||
.end()
|
||||
.find('span').removeClass('active');
|
||||
if (currentYear === year) {
|
||||
months.eq(this.date.getMonth()).addClass('active');
|
||||
}
|
||||
|
||||
html = '';
|
||||
year = parseInt(year/10, 10) * 10;
|
||||
var yearCont = this.picker.find('.datepicker-years')
|
||||
.find('th:eq(1)')
|
||||
.text(year + '-' + (year + 9))
|
||||
.end()
|
||||
.find('td');
|
||||
year -= 1;
|
||||
for (var i = -1; i < 11; i++) {
|
||||
html += '<span class="year'+(i === -1 || i === 10 ? ' old' : '')+(currentYear === year ? ' active' : '')+'">'+year+'</span>';
|
||||
year += 1;
|
||||
}
|
||||
yearCont.html(html);
|
||||
},
|
||||
|
||||
click: function(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
var target = $(e.target).closest('span, td, th');
|
||||
if (target.length === 1) {
|
||||
switch(target[0].nodeName.toLowerCase()) {
|
||||
case 'th':
|
||||
switch(target[0].className) {
|
||||
case 'switch':
|
||||
this.showMode(1);
|
||||
break;
|
||||
case 'prev':
|
||||
case 'next':
|
||||
this.viewDate['set'+DPGlobal.modes[this.viewMode].navFnc].call(
|
||||
this.viewDate,
|
||||
this.viewDate['get'+DPGlobal.modes[this.viewMode].navFnc].call(this.viewDate) +
|
||||
DPGlobal.modes[this.viewMode].navStep * (target[0].className === 'prev' ? -1 : 1)
|
||||
);
|
||||
this.fill();
|
||||
this.set();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'span':
|
||||
if (target.is('.month')) {
|
||||
var month = target.parent().find('span').index(target);
|
||||
this.viewDate.setMonth(month);
|
||||
} else {
|
||||
var year = parseInt(target.text(), 10)||0;
|
||||
this.viewDate.setFullYear(year);
|
||||
}
|
||||
if (this.viewMode !== 0) {
|
||||
this.date = new Date(this.viewDate);
|
||||
this.element.trigger({
|
||||
type: 'changeDate',
|
||||
date: this.date,
|
||||
viewMode: DPGlobal.modes[this.viewMode].clsName
|
||||
});
|
||||
}
|
||||
this.showMode(-1);
|
||||
this.fill();
|
||||
this.set();
|
||||
break;
|
||||
case 'td':
|
||||
if (target.is('.day') && !target.is('.disabled')){
|
||||
var day = parseInt(target.text(), 10)||1;
|
||||
var month = this.viewDate.getMonth();
|
||||
if (target.is('.old')) {
|
||||
month -= 1;
|
||||
} else if (target.is('.new')) {
|
||||
month += 1;
|
||||
}
|
||||
var year = this.viewDate.getFullYear();
|
||||
this.date = new Date(year, month, day,0,0,0,0);
|
||||
this.viewDate = new Date(year, month, Math.min(28, day),0,0,0,0);
|
||||
this.fill();
|
||||
this.set();
|
||||
this.element.trigger({
|
||||
type: 'changeDate',
|
||||
date: this.date,
|
||||
viewMode: DPGlobal.modes[this.viewMode].clsName
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
mousedown: function(e){
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
},
|
||||
|
||||
showMode: function(dir) {
|
||||
if (dir) {
|
||||
this.viewMode = Math.max(this.minViewMode, Math.min(2, this.viewMode + dir));
|
||||
}
|
||||
this.picker.find('>div').hide().filter('.datepicker-'+DPGlobal.modes[this.viewMode].clsName).show();
|
||||
}
|
||||
};
|
||||
|
||||
$.fn.datepicker = function ( option, val ) {
|
||||
return this.each(function () {
|
||||
var $this = $(this),
|
||||
data = $this.data('datepicker'),
|
||||
options = typeof option === 'object' && option;
|
||||
if (!data) {
|
||||
$this.data('datepicker', (data = new Datepicker(this, $.extend({}, $.fn.datepicker.defaults,options))));
|
||||
}
|
||||
if (typeof option === 'string') data[option](val);
|
||||
});
|
||||
};
|
||||
|
||||
$.fn.datepicker.defaults = {
|
||||
onRender: function(date) {
|
||||
return '';
|
||||
}
|
||||
};
|
||||
$.fn.datepicker.Constructor = Datepicker;
|
||||
|
||||
var DPGlobal = {
|
||||
modes: [
|
||||
{
|
||||
clsName: 'days',
|
||||
navFnc: 'Month',
|
||||
navStep: 1
|
||||
},
|
||||
{
|
||||
clsName: 'months',
|
||||
navFnc: 'FullYear',
|
||||
navStep: 1
|
||||
},
|
||||
{
|
||||
clsName: 'years',
|
||||
navFnc: 'FullYear',
|
||||
navStep: 10
|
||||
}],
|
||||
dates:{
|
||||
days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"],
|
||||
daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
|
||||
daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"],
|
||||
months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
|
||||
monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
|
||||
},
|
||||
isLeapYear: function (year) {
|
||||
return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0))
|
||||
},
|
||||
getDaysInMonth: function (year, month) {
|
||||
return [31, (DPGlobal.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month]
|
||||
},
|
||||
parseFormat: function(format){
|
||||
var separator = format.match(/[.\/\-\s].*?/),
|
||||
parts = format.split(/\W+/);
|
||||
if (!separator || !parts || parts.length === 0){
|
||||
throw new Error("Invalid date format.");
|
||||
}
|
||||
return {separator: separator, parts: parts};
|
||||
},
|
||||
parseDate: function(date, format) {
|
||||
var parts = date.split(format.separator),
|
||||
date = new Date(),
|
||||
val;
|
||||
date.setHours(0);
|
||||
date.setMinutes(0);
|
||||
date.setSeconds(0);
|
||||
date.setMilliseconds(0);
|
||||
if (parts.length === format.parts.length) {
|
||||
var year = date.getFullYear(), day = date.getDate(), month = date.getMonth();
|
||||
for (var i=0, cnt = format.parts.length; i < cnt; i++) {
|
||||
val = parseInt(parts[i], 10)||1;
|
||||
switch(format.parts[i]) {
|
||||
case 'dd':
|
||||
case 'd':
|
||||
day = val;
|
||||
date.setDate(val);
|
||||
break;
|
||||
case 'mm':
|
||||
case 'm':
|
||||
month = val - 1;
|
||||
date.setMonth(val - 1);
|
||||
break;
|
||||
case 'yy':
|
||||
year = 2000 + val;
|
||||
date.setFullYear(2000 + val);
|
||||
break;
|
||||
case 'yyyy':
|
||||
year = val;
|
||||
date.setFullYear(val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
date = new Date(year, month, day, 0 ,0 ,0);
|
||||
}
|
||||
return date;
|
||||
},
|
||||
formatDate: function(date, format){
|
||||
var val = {
|
||||
d: date.getDate(),
|
||||
m: date.getMonth() + 1,
|
||||
yy: date.getFullYear().toString().substring(2),
|
||||
yyyy: date.getFullYear()
|
||||
};
|
||||
val.dd = (val.d < 10 ? '0' : '') + val.d;
|
||||
val.mm = (val.m < 10 ? '0' : '') + val.m;
|
||||
var date = [];
|
||||
for (var i=0, cnt = format.parts.length; i < cnt; i++) {
|
||||
date.push(val[format.parts[i]]);
|
||||
}
|
||||
return date.join(format.separator);
|
||||
},
|
||||
headTemplate: '<thead>'+
|
||||
'<tr>'+
|
||||
'<th class="prev">‹</th>'+
|
||||
'<th colspan="5" class="switch"></th>'+
|
||||
'<th class="next">›</th>'+
|
||||
'</tr>'+
|
||||
'</thead>',
|
||||
contTemplate: '<tbody><tr><td colspan="7"></td></tr></tbody>'
|
||||
};
|
||||
DPGlobal.template = '<div class="datepicker dropdown-menu">'+
|
||||
'<div class="datepicker-days">'+
|
||||
'<table class=" table-condensed">'+
|
||||
DPGlobal.headTemplate+
|
||||
'<tbody></tbody>'+
|
||||
'</table>'+
|
||||
'</div>'+
|
||||
'<div class="datepicker-months">'+
|
||||
'<table class="table-condensed">'+
|
||||
DPGlobal.headTemplate+
|
||||
DPGlobal.contTemplate+
|
||||
'</table>'+
|
||||
'</div>'+
|
||||
'<div class="datepicker-years">'+
|
||||
'<table class="table-condensed">'+
|
||||
DPGlobal.headTemplate+
|
||||
DPGlobal.contTemplate+
|
||||
'</table>'+
|
||||
'</div>'+
|
||||
'</div>';
|
||||
|
||||
}( window.jQuery );
|
||||
///* =========================================================
|
||||
// * bootstrap-datepicker.js
|
||||
// * http://www.eyecon.ro/bootstrap-datepicker
|
||||
// * =========================================================
|
||||
// * Copyright 2012 Stefan Petre
|
||||
// *
|
||||
// * Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// * you may not use this file except in compliance with the License.
|
||||
// * You may obtain a copy of the License at
|
||||
// *
|
||||
// * http://www.apache.org/licenses/LICENSE-2.0
|
||||
// *
|
||||
// * Unless required by applicable law or agreed to in writing, software
|
||||
// * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// * See the License for the specific language governing permissions and
|
||||
// * limitations under the License.
|
||||
// * ========================================================= */
|
||||
//
|
||||
//!function( $ ) {
|
||||
//
|
||||
// // Picker object
|
||||
//
|
||||
// var Datepicker = function(element, options){
|
||||
// this.element = $(element);
|
||||
// this.format = DPGlobal.parseFormat(options.format||this.element.data('date-format')||'mm/dd/yyyy');
|
||||
// this.picker = $(DPGlobal.template)
|
||||
// .appendTo('body')
|
||||
// .on({
|
||||
// click: $.proxy(this.click, this)//,
|
||||
// //mousedown: $.proxy(this.mousedown, this)
|
||||
// });
|
||||
// this.isInput = this.element.is('input');
|
||||
// this.component = this.element.is('.date') ? this.element.find('.add-on') : false;
|
||||
//
|
||||
// if (this.isInput) {
|
||||
// this.element.on({
|
||||
// focus: $.proxy(this.show, this),
|
||||
// //blur: $.proxy(this.hide, this),
|
||||
// keyup: $.proxy(this.update, this)
|
||||
// });
|
||||
// } else {
|
||||
// if (this.component){
|
||||
// this.component.on('click', $.proxy(this.show, this));
|
||||
// } else {
|
||||
// this.element.on('click', $.proxy(this.show, this));
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// this.minViewMode = options.minViewMode||this.element.data('date-minviewmode')||0;
|
||||
// if (typeof this.minViewMode === 'string') {
|
||||
// switch (this.minViewMode) {
|
||||
// case 'months':
|
||||
// this.minViewMode = 1;
|
||||
// break;
|
||||
// case 'years':
|
||||
// this.minViewMode = 2;
|
||||
// break;
|
||||
// default:
|
||||
// this.minViewMode = 0;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// this.viewMode = options.viewMode||this.element.data('date-viewmode')||0;
|
||||
// if (typeof this.viewMode === 'string') {
|
||||
// switch (this.viewMode) {
|
||||
// case 'months':
|
||||
// this.viewMode = 1;
|
||||
// break;
|
||||
// case 'years':
|
||||
// this.viewMode = 2;
|
||||
// break;
|
||||
// default:
|
||||
// this.viewMode = 0;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// this.startViewMode = this.viewMode;
|
||||
// this.weekStart = options.weekStart||this.element.data('date-weekstart')||0;
|
||||
// this.weekEnd = this.weekStart === 0 ? 6 : this.weekStart - 1;
|
||||
// this.onRender = options.onRender;
|
||||
// this.fillDow();
|
||||
// this.fillMonths();
|
||||
// this.update();
|
||||
// this.showMode();
|
||||
// };
|
||||
//
|
||||
// Datepicker.prototype = {
|
||||
// constructor: Datepicker,
|
||||
//
|
||||
// show: function(e) {
|
||||
// this.picker.show();
|
||||
// this.height = this.component ? this.component.outerHeight() : this.element.outerHeight();
|
||||
// this.place();
|
||||
// $(window).on('resize', $.proxy(this.place, this));
|
||||
// if (e ) {
|
||||
// e.stopPropagation();
|
||||
// e.preventDefault();
|
||||
// }
|
||||
// if (!this.isInput) {
|
||||
// }
|
||||
// var that = this;
|
||||
// $(document).on('mousedown', function(ev){
|
||||
// if ($(ev.target).closest('.datepicker').length == 0) {
|
||||
// that.hide();
|
||||
// }
|
||||
// });
|
||||
// this.element.trigger({
|
||||
// type: 'show',
|
||||
// date: this.date
|
||||
// });
|
||||
// },
|
||||
//
|
||||
// hide: function(){
|
||||
// this.picker.hide();
|
||||
// $(window).off('resize', this.place);
|
||||
// this.viewMode = this.startViewMode;
|
||||
// this.showMode();
|
||||
// if (!this.isInput) {
|
||||
// $(document).off('mousedown', this.hide);
|
||||
// }
|
||||
// //this.set();
|
||||
// this.element.trigger({
|
||||
// type: 'hide',
|
||||
// date: this.date
|
||||
// });
|
||||
// },
|
||||
//
|
||||
// set: function() {
|
||||
// var formated = DPGlobal.formatDate(this.date, this.format);
|
||||
// if (!this.isInput) {
|
||||
// if (this.component){
|
||||
// this.element.find('input').prop('value', formated);
|
||||
// }
|
||||
// this.element.data('date', formated);
|
||||
// } else {
|
||||
// this.element.prop('value', formated);
|
||||
// }
|
||||
// },
|
||||
//
|
||||
// setValue: function(newDate) {
|
||||
// if (typeof newDate === 'string') {
|
||||
// this.date = DPGlobal.parseDate(newDate, this.format);
|
||||
// } else {
|
||||
// this.date = new Date(newDate);
|
||||
// }
|
||||
// this.set();
|
||||
// this.viewDate = new Date(this.date.getFullYear(), this.date.getMonth(), 1, 0, 0, 0, 0);
|
||||
// this.fill();
|
||||
// },
|
||||
//
|
||||
// place: function(){
|
||||
// var offset = this.component ? this.component.offset() : this.element.offset();
|
||||
// this.picker.css({
|
||||
// top: offset.top + this.height,
|
||||
// left: offset.left
|
||||
// });
|
||||
// },
|
||||
//
|
||||
// update: function(newDate){
|
||||
// this.date = DPGlobal.parseDate(
|
||||
// typeof newDate === 'string' ? newDate : (this.isInput ? this.element.prop('value') : this.element.data('date')),
|
||||
// this.format
|
||||
// );
|
||||
// this.viewDate = new Date(this.date.getFullYear(), this.date.getMonth(), 1, 0, 0, 0, 0);
|
||||
// this.fill();
|
||||
// },
|
||||
//
|
||||
// fillDow: function(){
|
||||
// var dowCnt = this.weekStart;
|
||||
// var html = '<tr>';
|
||||
// while (dowCnt < this.weekStart + 7) {
|
||||
// html += '<th class="dow">'+DPGlobal.dates.daysMin[(dowCnt++)%7]+'</th>';
|
||||
// }
|
||||
// html += '</tr>';
|
||||
// this.picker.find('.datepicker-days thead').append(html);
|
||||
// },
|
||||
//
|
||||
// fillMonths: function(){
|
||||
// var html = '';
|
||||
// var i = 0
|
||||
// while (i < 12) {
|
||||
// html += '<span class="month">'+DPGlobal.dates.monthsShort[i++]+'</span>';
|
||||
// }
|
||||
// this.picker.find('.datepicker-months td').append(html);
|
||||
// },
|
||||
//
|
||||
// fill: function() {
|
||||
// var d = new Date(this.viewDate),
|
||||
// year = d.getFullYear(),
|
||||
// month = d.getMonth(),
|
||||
// currentDate = this.date.valueOf();
|
||||
// this.picker.find('.datepicker-days th:eq(1)')
|
||||
// .text(DPGlobal.dates.months[month]+' '+year);
|
||||
// var prevMonth = new Date(year, month-1, 28,0,0,0,0),
|
||||
// day = DPGlobal.getDaysInMonth(prevMonth.getFullYear(), prevMonth.getMonth());
|
||||
// prevMonth.setDate(day);
|
||||
// prevMonth.setDate(day - (prevMonth.getDay() - this.weekStart + 7)%7);
|
||||
// var nextMonth = new Date(prevMonth);
|
||||
// nextMonth.setDate(nextMonth.getDate() + 42);
|
||||
// nextMonth = nextMonth.valueOf();
|
||||
// var html = [];
|
||||
// var clsName,
|
||||
// prevY,
|
||||
// prevM;
|
||||
// while(prevMonth.valueOf() < nextMonth) {
|
||||
// if (prevMonth.getDay() === this.weekStart) {
|
||||
// html.push('<tr>');
|
||||
// }
|
||||
// clsName = this.onRender(prevMonth);
|
||||
// prevY = prevMonth.getFullYear();
|
||||
// prevM = prevMonth.getMonth();
|
||||
// if ((prevM < month && prevY === year) || prevY < year) {
|
||||
// clsName += ' old';
|
||||
// } else if ((prevM > month && prevY === year) || prevY > year) {
|
||||
// clsName += ' new';
|
||||
// }
|
||||
// if (prevMonth.valueOf() === currentDate) {
|
||||
// clsName += ' active';
|
||||
// }
|
||||
// html.push('<td class="day '+clsName+'">'+prevMonth.getDate() + '</td>');
|
||||
// if (prevMonth.getDay() === this.weekEnd) {
|
||||
// html.push('</tr>');
|
||||
// }
|
||||
// prevMonth.setDate(prevMonth.getDate()+1);
|
||||
// }
|
||||
// this.picker.find('.datepicker-days tbody').empty().append(html.join(''));
|
||||
// var currentYear = this.date.getFullYear();
|
||||
//
|
||||
// var months = this.picker.find('.datepicker-months')
|
||||
// .find('th:eq(1)')
|
||||
// .text(year)
|
||||
// .end()
|
||||
// .find('span').removeClass('active');
|
||||
// if (currentYear === year) {
|
||||
// months.eq(this.date.getMonth()).addClass('active');
|
||||
// }
|
||||
//
|
||||
// html = '';
|
||||
// year = parseInt(year/10, 10) * 10;
|
||||
// var yearCont = this.picker.find('.datepicker-years')
|
||||
// .find('th:eq(1)')
|
||||
// .text(year + '-' + (year + 9))
|
||||
// .end()
|
||||
// .find('td');
|
||||
// year -= 1;
|
||||
// for (var i = -1; i < 11; i++) {
|
||||
// html += '<span class="year'+(i === -1 || i === 10 ? ' old' : '')+(currentYear === year ? ' active' : '')+'">'+year+'</span>';
|
||||
// year += 1;
|
||||
// }
|
||||
// yearCont.html(html);
|
||||
// },
|
||||
//
|
||||
// click: function(e) {
|
||||
// e.stopPropagation();
|
||||
// e.preventDefault();
|
||||
// var target = $(e.target).closest('span, td, th');
|
||||
// if (target.length === 1) {
|
||||
// switch(target[0].nodeName.toLowerCase()) {
|
||||
// case 'th':
|
||||
// switch(target[0].className) {
|
||||
// case 'switch':
|
||||
// this.showMode(1);
|
||||
// break;
|
||||
// case 'prev':
|
||||
// case 'next':
|
||||
// this.viewDate['set'+DPGlobal.modes[this.viewMode].navFnc].call(
|
||||
// this.viewDate,
|
||||
// this.viewDate['get'+DPGlobal.modes[this.viewMode].navFnc].call(this.viewDate) +
|
||||
// DPGlobal.modes[this.viewMode].navStep * (target[0].className === 'prev' ? -1 : 1)
|
||||
// );
|
||||
// this.fill();
|
||||
// this.set();
|
||||
// break;
|
||||
// }
|
||||
// break;
|
||||
// case 'span':
|
||||
// if (target.is('.month')) {
|
||||
// var month = target.parent().find('span').index(target);
|
||||
// this.viewDate.setMonth(month);
|
||||
// } else {
|
||||
// var year = parseInt(target.text(), 10)||0;
|
||||
// this.viewDate.setFullYear(year);
|
||||
// }
|
||||
// if (this.viewMode !== 0) {
|
||||
// this.date = new Date(this.viewDate);
|
||||
// this.element.trigger({
|
||||
// type: 'changeDate',
|
||||
// date: this.date,
|
||||
// viewMode: DPGlobal.modes[this.viewMode].clsName
|
||||
// });
|
||||
// }
|
||||
// this.showMode(-1);
|
||||
// this.fill();
|
||||
// this.set();
|
||||
// break;
|
||||
// case 'td':
|
||||
// if (target.is('.day') && !target.is('.disabled')){
|
||||
// var day = parseInt(target.text(), 10)||1;
|
||||
// var month = this.viewDate.getMonth();
|
||||
// if (target.is('.old')) {
|
||||
// month -= 1;
|
||||
// } else if (target.is('.new')) {
|
||||
// month += 1;
|
||||
// }
|
||||
// var year = this.viewDate.getFullYear();
|
||||
// this.date = new Date(year, month, day,0,0,0,0);
|
||||
// this.viewDate = new Date(year, month, Math.min(28, day),0,0,0,0);
|
||||
// this.fill();
|
||||
// this.set();
|
||||
// this.element.trigger({
|
||||
// type: 'changeDate',
|
||||
// date: this.date,
|
||||
// viewMode: DPGlobal.modes[this.viewMode].clsName
|
||||
// });
|
||||
// }
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
//
|
||||
// mousedown: function(e){
|
||||
// e.stopPropagation();
|
||||
// e.preventDefault();
|
||||
// },
|
||||
//
|
||||
// showMode: function(dir) {
|
||||
// if (dir) {
|
||||
// this.viewMode = Math.max(this.minViewMode, Math.min(2, this.viewMode + dir));
|
||||
// }
|
||||
// this.picker.find('>div').hide().filter('.datepicker-'+DPGlobal.modes[this.viewMode].clsName).show();
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// $.fn.datepicker = function ( option, val ) {
|
||||
// return this.each(function () {
|
||||
// var $this = $(this),
|
||||
// data = $this.data('datepicker'),
|
||||
// options = typeof option === 'object' && option;
|
||||
// if (!data) {
|
||||
// $this.data('datepicker', (data = new Datepicker(this, $.extend({}, $.fn.datepicker.defaults,options))));
|
||||
// }
|
||||
// if (typeof option === 'string') data[option](val);
|
||||
// });
|
||||
// };
|
||||
//
|
||||
// $.fn.datepicker.defaults = {
|
||||
// onRender: function(date) {
|
||||
// return '';
|
||||
// }
|
||||
// };
|
||||
// $.fn.datepicker.Constructor = Datepicker;
|
||||
//
|
||||
// var DPGlobal = {
|
||||
// modes: [
|
||||
// {
|
||||
// clsName: 'days',
|
||||
// navFnc: 'Month',
|
||||
// navStep: 1
|
||||
// },
|
||||
// {
|
||||
// clsName: 'months',
|
||||
// navFnc: 'FullYear',
|
||||
// navStep: 1
|
||||
// },
|
||||
// {
|
||||
// clsName: 'years',
|
||||
// navFnc: 'FullYear',
|
||||
// navStep: 10
|
||||
// }],
|
||||
// dates:{
|
||||
// days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"],
|
||||
// daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
|
||||
// daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"],
|
||||
// months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
|
||||
// monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
|
||||
// },
|
||||
// isLeapYear: function (year) {
|
||||
// return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0))
|
||||
// },
|
||||
// getDaysInMonth: function (year, month) {
|
||||
// return [31, (DPGlobal.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month]
|
||||
// },
|
||||
// parseFormat: function(format){
|
||||
// var separator = format.match(/[.\/\-\s].*?/),
|
||||
// parts = format.split(/\W+/);
|
||||
// if (!separator || !parts || parts.length === 0){
|
||||
// throw new Error("Invalid date format.");
|
||||
// }
|
||||
// return {separator: separator, parts: parts};
|
||||
// },
|
||||
// parseDate: function(date, format) {
|
||||
// var parts = date.split(format.separator),
|
||||
// date = new Date(),
|
||||
// val;
|
||||
// date.setHours(0);
|
||||
// date.setMinutes(0);
|
||||
// date.setSeconds(0);
|
||||
// date.setMilliseconds(0);
|
||||
// if (parts.length === format.parts.length) {
|
||||
// var year = date.getFullYear(), day = date.getDate(), month = date.getMonth();
|
||||
// for (var i=0, cnt = format.parts.length; i < cnt; i++) {
|
||||
// val = parseInt(parts[i], 10)||1;
|
||||
// switch(format.parts[i]) {
|
||||
// case 'dd':
|
||||
// case 'd':
|
||||
// day = val;
|
||||
// date.setDate(val);
|
||||
// break;
|
||||
// case 'mm':
|
||||
// case 'm':
|
||||
// month = val - 1;
|
||||
// date.setMonth(val - 1);
|
||||
// break;
|
||||
// case 'yy':
|
||||
// year = 2000 + val;
|
||||
// date.setFullYear(2000 + val);
|
||||
// break;
|
||||
// case 'yyyy':
|
||||
// year = val;
|
||||
// date.setFullYear(val);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// date = new Date(year, month, day, 0 ,0 ,0);
|
||||
// }
|
||||
// return date;
|
||||
// },
|
||||
// formatDate: function(date, format){
|
||||
// var val = {
|
||||
// d: date.getDate(),
|
||||
// m: date.getMonth() + 1,
|
||||
// yy: date.getFullYear().toString().substring(2),
|
||||
// yyyy: date.getFullYear()
|
||||
// };
|
||||
// val.dd = (val.d < 10 ? '0' : '') + val.d;
|
||||
// val.mm = (val.m < 10 ? '0' : '') + val.m;
|
||||
// var date = [];
|
||||
// for (var i=0, cnt = format.parts.length; i < cnt; i++) {
|
||||
// date.push(val[format.parts[i]]);
|
||||
// }
|
||||
// return date.join(format.separator);
|
||||
// },
|
||||
// headTemplate: '<thead>'+
|
||||
// '<tr>'+
|
||||
// '<th class="prev">‹</th>'+
|
||||
// '<th colspan="5" class="switch"></th>'+
|
||||
// '<th class="next">›</th>'+
|
||||
// '</tr>'+
|
||||
// '</thead>',
|
||||
// contTemplate: '<tbody><tr><td colspan="7"></td></tr></tbody>'
|
||||
// };
|
||||
// DPGlobal.template = '<div class="datepicker dropdown-menu">'+
|
||||
// '<div class="datepicker-days">'+
|
||||
// '<table class=" table-condensed">'+
|
||||
// DPGlobal.headTemplate+
|
||||
// '<tbody></tbody>'+
|
||||
// '</table>'+
|
||||
// '</div>'+
|
||||
// '<div class="datepicker-months">'+
|
||||
// '<table class="table-condensed">'+
|
||||
// DPGlobal.headTemplate+
|
||||
// DPGlobal.contTemplate+
|
||||
// '</table>'+
|
||||
// '</div>'+
|
||||
// '<div class="datepicker-years">'+
|
||||
// '<table class="table-condensed">'+
|
||||
// DPGlobal.headTemplate+
|
||||
// DPGlobal.contTemplate+
|
||||
// '</table>'+
|
||||
// '</div>'+
|
||||
// '</div>';
|
||||
//
|
||||
//}( window.jQuery );
|
||||
@@ -22,17 +22,15 @@ $(function($){
|
||||
};
|
||||
|
||||
// Add 1 Rule / or update the temporary Rules array then Save Rules via AJAX
|
||||
couponManager.addRuleAjax = function(id) {
|
||||
console.log('addRuleAjax '+ id);
|
||||
couponManager.createOrUpdateRuleAjax = function() {
|
||||
var id = couponManager.ruleToUpdateId;
|
||||
// If create
|
||||
if(!id) {
|
||||
console.log('pushing');
|
||||
couponManager.rulesToSave.push(couponManager.ruleToSave);
|
||||
} else { // else update
|
||||
console.log('editing ' + id);
|
||||
couponManager.rulesToSave[id] = couponManager.ruleToSave;
|
||||
// reset edit mode to off
|
||||
couponManager.ruleIdToUpdate = false;
|
||||
couponManager.ruleToUpdateId = false;
|
||||
}
|
||||
|
||||
// Save
|
||||
@@ -40,57 +38,54 @@ $(function($){
|
||||
};
|
||||
|
||||
// Set rule inputs to allow editing
|
||||
couponManager.updateRuleAjax = function(id) {
|
||||
couponManager.ruleToUpdate = couponManager.rulesToSave[id];
|
||||
console.log('Set id to edit to ' + id);
|
||||
couponManager.ruleIdToUpdate = id;
|
||||
|
||||
// Deleting this rule, we will reset it
|
||||
delete couponManager.rulesToSave[id];
|
||||
couponManager.updateRuleSelectAjax = function(id) {
|
||||
couponManager.ruleToUpdateId = id;
|
||||
couponManager.ruleToSave = couponManager.rulesToSave[id];
|
||||
|
||||
// Set the rule selector
|
||||
$("#category-rule option").filter(function() {
|
||||
return $(this).val() == couponManager.ruleToUpdate.serviceId;
|
||||
return $(this).val() == couponManager.ruleToSave.serviceId;
|
||||
}).prop('selected', true);
|
||||
|
||||
// Force rule input refresh
|
||||
couponManager.loadRuleInputs(couponManager.ruleToUpdate.serviceId, function() {
|
||||
couponManager.loadRuleInputs(couponManager.ruleToSave.serviceId, function() {
|
||||
couponManager.fillInRuleInputs();
|
||||
});
|
||||
};
|
||||
|
||||
// Fill in rule inputs
|
||||
couponManager.fillInRuleInputs = function() {
|
||||
console.log('fillInRuleInputs with');
|
||||
console.log(couponManager.ruleToUpdate);
|
||||
var operatorId = null;
|
||||
var valueId = null;
|
||||
var idName = null;
|
||||
|
||||
for (idName in couponManager.ruleToUpdate.operators) {
|
||||
var id = couponManager.ruleToUpdateId;
|
||||
if(id) {
|
||||
couponManager.ruleToSave = couponManager.rulesToSave[id];
|
||||
}
|
||||
|
||||
for (idName in couponManager.ruleToSave.operators) {
|
||||
// Setting idName operator select
|
||||
operatorId = idName + '-operator';
|
||||
$('#' + operatorId).val(couponManager.ruleToUpdate.operators[idName]);
|
||||
$('#' + operatorId).val(couponManager.ruleToSave.operators[idName]);
|
||||
|
||||
valueId = idName + '-value';
|
||||
// Setting idName value input
|
||||
$('#' + valueId).val(couponManager.ruleToUpdate.values[idName]);
|
||||
}
|
||||
couponManager.ruleToSave = couponManager.ruleToUpdate;
|
||||
|
||||
var id = couponManager.ruleIdToUpdate;
|
||||
console.log('id to edit = ' + id);
|
||||
if(id) {
|
||||
console.log('setint rulesToSave[' + id + ']');
|
||||
console.log(couponManager.ruleToSave);
|
||||
couponManager.rulesToSave[id] = couponManager.ruleToSave;
|
||||
valueId = idName + '-value';
|
||||
$('#' + valueId).val(couponManager.ruleToSave.values[idName]);
|
||||
}
|
||||
};
|
||||
|
||||
// Save rules on click
|
||||
couponManager.onClickSaveRule = function() {
|
||||
$('#constraint-save-btn').on('click', function () {
|
||||
couponManager.addRuleAjax(couponManager.ruleIdToUpdate);
|
||||
if($('#category-rule').val() == 'thelia.constraint.rule.available_for_everyone') {
|
||||
// @todo translate + modal
|
||||
var r= confirm("Do you really want to set this coupon available to everyone ?");
|
||||
if (r == true) {
|
||||
couponManager.createOrUpdateRuleAjax();
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
};
|
||||
couponManager.onClickSaveRule();
|
||||
@@ -110,7 +105,7 @@ $(function($){
|
||||
$('.constraint-update-btn').on('click', function (e) {
|
||||
e.preventDefault();
|
||||
var $this = $(this);
|
||||
couponManager.updateRuleAjax($this.attr('data-int'));
|
||||
couponManager.updateRuleSelectAjax($this.attr('data-int'));
|
||||
|
||||
// Hide row being updated
|
||||
$this.parent().parent().remove();
|
||||
@@ -120,6 +115,8 @@ $(function($){
|
||||
|
||||
// Reload effect inputs when changing effect
|
||||
couponManager.onEffectChange = function() {
|
||||
var optionSelected = $("option:selected", this);
|
||||
$('#effectToolTip').html(optionSelected.attr("data-description"));
|
||||
$('#effect').on('change', function () {
|
||||
var optionSelected = $("option:selected", this);
|
||||
$('#effectToolTip').html(optionSelected.attr("data-description"));
|
||||
@@ -130,7 +127,7 @@ $(function($){
|
||||
// Reload rule inputs when changing effect
|
||||
couponManager.onRuleChange = function() {
|
||||
$('#category-rule').on('change', function () {
|
||||
couponManager.loadRuleInputs($(this).val(), function(ruleToSave) {});
|
||||
couponManager.loadRuleInputs($(this).val(), function() {});
|
||||
});
|
||||
};
|
||||
couponManager.onRuleChange();
|
||||
@@ -139,10 +136,37 @@ $(function($){
|
||||
// var onInputsChange = function()
|
||||
// In AJAX response
|
||||
|
||||
// Set max usage to unlimited or not
|
||||
couponManager.onUsageUnlimitedChange = function() {
|
||||
if (!$('#max-usage').parent().hasClass('has-error')) {
|
||||
$('#max-usage').hide().attr('value', '-1');
|
||||
$('#max-usage-label').hide();
|
||||
}
|
||||
$('#is-unlimited').change(function(){
|
||||
var $this = $(this);
|
||||
if ($this.is(':checked')) {
|
||||
$('#max-usage').hide().attr('value', '-1');
|
||||
$('#max-usage-label').hide();
|
||||
} else {
|
||||
$('#max-usage').show().val('').attr('value', '');
|
||||
$('#max-usage-label').show();
|
||||
}
|
||||
});
|
||||
};
|
||||
couponManager.onUsageUnlimitedChange();
|
||||
|
||||
});
|
||||
|
||||
// Rule to save
|
||||
|
||||
var couponManager = {};
|
||||
// Rule to be saved
|
||||
couponManager.ruleToSave = {};
|
||||
couponManager.ruleIdToUpdate = false;
|
||||
couponManager.ruleToSave.serviceId = false;
|
||||
couponManager.ruleToSave.operators = {};
|
||||
couponManager.ruleToSave.values = {};
|
||||
// Rules payload to save
|
||||
couponManager.rulesToSave = [];
|
||||
// Rule being updated id
|
||||
couponManager.ruleToUpdateId = false;
|
||||
|
||||
|
||||
@@ -40,34 +40,7 @@
|
||||
});
|
||||
}*/
|
||||
|
||||
// -- Effect description
|
||||
if($('[name=effect]').length){
|
||||
var $effectSelect = $('[name=effect]'),
|
||||
$helpBlock = $effectSelect.next('.help-block');
|
||||
|
||||
$effectSelect.change(function(){
|
||||
var description = $(this).find(":selected").data('description');
|
||||
$helpBlock.text(description);
|
||||
});
|
||||
}
|
||||
|
||||
// -- Max usage --
|
||||
if($('#is-unlimited').length){
|
||||
|
||||
if($('#is-unlimited').is(':checked')){
|
||||
$('#max-usage').hide().attr('value', '-1');
|
||||
}
|
||||
|
||||
$('#is-unlimited').change(function(){
|
||||
if($('#is-unlimited').is(':checked')){
|
||||
$('#max-usage').hide().attr('value', '-1');
|
||||
}
|
||||
else{
|
||||
$('#max-usage').show().val('').attr('value', '');
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// -- Bootstrap tooltip --
|
||||
if($('[rel="tooltip"]').length){
|
||||
|
||||
@@ -7,18 +7,19 @@
|
||||
|
||||
<nav>
|
||||
<ul class="breadcrumb">
|
||||
{include file="includes/coupon_breadcrumb.html"}
|
||||
<li><a href="{url path='admin/home'}">{intl l='Home'}</a></li>
|
||||
<li><a href="{url path='admin/coupon/'}">{intl l='Coupon'}</a></li>
|
||||
<li>{intl l='Create'}</li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<div class="page-header">
|
||||
<h1>Coupons : <small>Add a coupon</small></h1>
|
||||
<h1>{intl l='Coupons : '}<small>{intl l='Create a new coupon'}</small></h1>
|
||||
</div>
|
||||
|
||||
{form name="thelia.admin.coupon.creation"}
|
||||
{include file='coupon/form.html' formAction={url path={$formAction}} noRules=true}
|
||||
{/form}
|
||||
|
||||
</section> <!-- #wrapper -->
|
||||
|
||||
{include file='includes/confirmation-modal.html'}
|
||||
@@ -33,9 +34,20 @@
|
||||
<script src="{$asset_url}"></script>
|
||||
{/javascripts}
|
||||
|
||||
{javascripts file='assets/js/json2.js'}
|
||||
<script src="{$asset_url}"></script>
|
||||
{/javascripts}
|
||||
|
||||
{javascripts file='assets/js/coupon.js'}
|
||||
<script src="{$asset_url}"></script>
|
||||
{/javascripts}
|
||||
|
||||
{*<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>*}
|
||||
{*<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />*}
|
||||
<script>
|
||||
$(function($){
|
||||
miniBrowser(0, '/test_to_remove/datas_coupon_edit.json');
|
||||
{*$('.datepicker').datepicker({ dateFormat: "{$dateFormat}", defaultDate: +60, minDate: "+0m" });*}
|
||||
});
|
||||
</script>
|
||||
|
||||
{/block}
|
||||
|
||||
@@ -7,70 +7,50 @@
|
||||
|
||||
<nav>
|
||||
<ul class="breadcrumb">
|
||||
{include file="includes/coupon_breadcrumb.html"}
|
||||
<li><a href="{url path='admin/home'}">{intl l='Home'}</a></li>
|
||||
<li><a href="{url path='admin/coupon/'}">{intl l='Coupon'}</a></li>
|
||||
<li>{intl l='Browse'}</li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<div class="page-header">
|
||||
<h1>Coupons : <small>List of coupons</small></h1>
|
||||
<h1>{intl l='Coupons : '}<small>{intl l='List'}</small></h1>
|
||||
<a href="{$urlCreateCoupon}" class="btn btn-default btn-primary btn-medium">
|
||||
<span class="glyphicon glyphicon-add"></span> {intl l='Create a new coupon'}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<section class="row">
|
||||
<div class="col-md-12 general-block-decorator">
|
||||
<table class="table table-striped tablesorter">
|
||||
<caption>
|
||||
List of enabled coupons
|
||||
{intl l='Enabled coupons'}
|
||||
</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Code</th>
|
||||
<th>Title</th>
|
||||
<th>Expiration date</th>
|
||||
<th>Usage left</th>
|
||||
<th class="sorter-false filter-false">Actions</th>
|
||||
<th>{block name="coupon-label-code"}{intl l='Code'}{/block}</th>
|
||||
<th>{block name="coupon-label-title"}{intl l='Title'}{/block}</th>
|
||||
<th>{block name="coupon-label-expiration-date"}{intl l='Expiration date'}{/block}</th>
|
||||
<th>{block name="coupon-label-usage-left"}{intl l='Usage left'}{/block}</th>
|
||||
<th class="sorter-false filter-false">{block name="coupon-label-action"}{/block}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><a href="#">XMAS13</a></td>
|
||||
<td>Coupon for XMAS -30 €</td>
|
||||
<td>18/10/2013</td>
|
||||
<td>49</td>
|
||||
<td>
|
||||
<a href="#url" class="btn btn-default btn-primary btn-medium"><span class="glyphicon glyphicon-edit"></span> Edit</a>
|
||||
<a href="#url" class="btn btn-default btn-danger btn-medium" data-toggle="confirm" data-target="#disable"><span class="glyphicon glyphicon-off"></span> Disable</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="#">XMAS13</a></td>
|
||||
<td>Coupon for XMAS -30 €</td>
|
||||
<td>05/09/2013</td>
|
||||
<td>20</td>
|
||||
<td>
|
||||
<a href="#url" class="btn btn-default btn-primary btn-medium"><span class="glyphicon glyphicon-edit"></span> Edit</a>
|
||||
<a href="#url" class="btn btn-default btn-danger btn-medium" data-toggle="confirm" data-target="#disable"><span class="glyphicon glyphicon-off"></span> Disable</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="#">XMAS13</a></td>
|
||||
<td>Coupon for XMAS -30 €</td>
|
||||
<td>03/12/2013</td>
|
||||
<td>9</td>
|
||||
<td>
|
||||
<a href="#url" class="btn btn-default btn-primary btn-medium"><span class="glyphicon glyphicon-edit"></span> Edit</a>
|
||||
<a href="#url" class="btn btn-default btn-danger btn-medium" data-toggle="confirm" data-target="#disable"><span class="glyphicon glyphicon-off"></span> Disable</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="#">XMAS13</a></td>
|
||||
<td>Coupon for XMAS -30 €</td>
|
||||
<td>25/01/2013</td>
|
||||
<td>4</td>
|
||||
<td>
|
||||
<a href="#url" class="btn btn-default btn-primary btn-medium"><span class="glyphicon glyphicon-edit"></span> Edit</a>
|
||||
<a href="#url" class="btn btn-default btn-danger btn-medium" data-toggle="confirm" data-target="#disable"><span class="glyphicon glyphicon-off"></span> Disable</a>
|
||||
</td>
|
||||
</tr>
|
||||
{loop type="coupon" name="list_coupon" is_enabled="1" backend_context="true"}
|
||||
<tr>
|
||||
<td>{block name="coupon-code"}<a href="{$urlReadCoupon|replace:'couponId':$ID}">{$CODE}</a>{/block}</td>
|
||||
<td>{block name="coupon-title"}{$TITLE}{/block}</td>
|
||||
<td>{block name="coupon-expiration-date"}{$EXPIRATION_DATE}{/block}</td>
|
||||
<td>{block name="coupon-usage-left"}{$USAGE_LEFT}{/block}</td>
|
||||
<td>
|
||||
{block name="coupon-action"}
|
||||
<a href="{$urlEditCoupon|replace:'couponId':$ID}" class="btn btn-default btn-primary btn-medium">
|
||||
<span class="glyphicon glyphicon-edit"></span> {intl l='Edit'}
|
||||
</a>
|
||||
{/block}
|
||||
</td>
|
||||
</tr>
|
||||
{/loop}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@@ -80,58 +60,33 @@
|
||||
<div class="col-md-12 general-block-decorator">
|
||||
<table class="table table-striped tablesorter">
|
||||
<caption>
|
||||
List of disabled coupons
|
||||
{intl l='Disabled coupons'}
|
||||
</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Code</th>
|
||||
<th>Title</th>
|
||||
<th>Expiration date</th>
|
||||
<th>Usage left</th>
|
||||
<th class="sorter-false filter-false">Actions</th>
|
||||
<th>{block name="coupon-label-code"}{intl l='Code'}{/block}</th>
|
||||
<th>{block name="coupon-label-title"}{intl l='Title'}{/block}</th>
|
||||
<th>{block name="coupon-label-expiration-date"}{intl l='Expiration date'}{/block}</th>
|
||||
<th>{block name="coupon-label-usage-left"}{intl l='Usage left'}{/block}</th>
|
||||
<th class="sorter-false filter-false">{block name="coupon-label-action"}{/block}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>XMAS13</td>
|
||||
<td>Coupon for XMAS -30 €</td>
|
||||
<td>18/10/2013</td>
|
||||
<td>49</td>
|
||||
<td>
|
||||
<a href="#url" class="btn btn-default btn-primary btn-medium"><span class="glyphicon glyphicon-edit"></span> Edit</a>
|
||||
<a href="#url" class="btn btn-default btn-success btn-medium" data-toggle="confirm" data-target="#enable"><span class="glyphicon glyphicon-ok"></span> Enabled</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>XMAS13</td>
|
||||
<td>Coupon for XMAS -20 €</td>
|
||||
<td>05/09/2013</td>
|
||||
<td>49</td>
|
||||
<td>
|
||||
<a href="#url" class="btn btn-default btn-primary btn-medium"><span class="glyphicon glyphicon-edit"></span> Edit</a>
|
||||
<a href="#url" class="btn btn-default btn-success btn-medium" data-toggle="confirm" data-target="#enable"><span class="glyphicon glyphicon-ok"></span> Enabled</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>XMAS13</td>
|
||||
<td>Coupon for XMAS -50 €</td>
|
||||
<td>03/12/2013</td>
|
||||
<td>49</td>
|
||||
<td>
|
||||
<a href="#url" class="btn btn-default btn-primary btn-medium"><span class="glyphicon glyphicon-edit"></span> Edit</a>
|
||||
<a href="#url" class="btn btn-default btn-success btn-medium" data-toggle="confirm" data-target="#enable"><span class="glyphicon glyphicon-ok"></span> Enabled</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>XMAS13</td>
|
||||
<td>Coupon for XMAS -5 €</td>
|
||||
<td>25/01/2013</td>
|
||||
<td>49</td>
|
||||
<td>
|
||||
<a href="#url" class="btn btn-default btn-primary btn-medium"><span class="glyphicon glyphicon-edit"></span> Edit</a>
|
||||
<a href="#url" class="btn btn-default btn-success btn-medium" data-toggle="confirm" data-target="#enable"><span class="glyphicon glyphicon-ok"></span> Enabled</a>
|
||||
</td>
|
||||
</tr>
|
||||
{loop type="coupon" name="list_coupon" is_enabled="0" backend_context="true"}
|
||||
<tr>
|
||||
<td>{block name="coupon-code"}<a href="{$urlReadCoupon|replace:'couponId':$ID}">{$CODE}</a>{/block}</td>
|
||||
<td>{block name="coupon-title"}{$TITLE}{/block}</td>
|
||||
<td>{block name="coupon-expiration-date"}{$EXPIRATION_DATE}{/block}</td>
|
||||
<td>{block name="coupon-usage-left"}{$USAGE_LEFT}{/block}</td>
|
||||
<td>
|
||||
{block name="coupon-action"}
|
||||
<a href="{$urlEditCoupon|replace:'couponId':$ID}" class="btn btn-default btn-primary btn-medium">
|
||||
<span class="glyphicon glyphicon-edit"></span> {intl l='Edit'}
|
||||
</a>
|
||||
{/block}
|
||||
</td>
|
||||
</tr>
|
||||
{/loop}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@@ -139,9 +94,6 @@
|
||||
|
||||
</section> <!-- #wrapper -->
|
||||
|
||||
{include file='includes/confirmation-modal.html' id="disable" message="{intl l='Do you really want to disable this element ?'}"}
|
||||
{include file='includes/confirmation-modal.html' id="enable" message="{intl l='Do you really want to enable this element ?'}"}
|
||||
|
||||
{/block}
|
||||
|
||||
|
||||
|
||||
@@ -4,112 +4,146 @@
|
||||
|
||||
{block name="main-content"}
|
||||
<section id="wrapper" class="container">
|
||||
|
||||
{loop type="coupon" name="read_coupon" id={$couponId} backend_context="true"}
|
||||
<nav>
|
||||
<ul class="breadcrumb">
|
||||
{include file="includes/coupon_breadcrumb.html"}
|
||||
<li><a href="{url path='admin/home'}">{intl l='Home'}</a></li>
|
||||
<li><a href="{url path='admin/coupon/'}">{intl l='Coupon'}</a></li>
|
||||
<li>{$CODE}</li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
{loop type="coupon" name="read_coupon" id={$couponId} backend_context="true"}
|
||||
<div class="page-header">
|
||||
<h1>{intl l='Coupon : '}<small>{$CODE}</small></h1>
|
||||
</div>
|
||||
|
||||
<div class="page-header">
|
||||
<h1>{intl l='Coupon : '}<small>{$CODE}</small></h1>
|
||||
</div>
|
||||
|
||||
<section class="row">
|
||||
<div class="col-md-12 general-block-decorator">
|
||||
<section class="row">
|
||||
<div class="col-md-12 general-block-decorator">
|
||||
|
||||
<div class="alert alert-info">
|
||||
<span class="glyphicon glyphicon-question-sign"></span>
|
||||
{if !$IS_ENABLED}{intl l='This coupon is disabled, you can enable to the bottom of this form.'}{/if}
|
||||
</div>
|
||||
{if !$IS_ENABLED}
|
||||
<div class="alert alert-info">
|
||||
<span class="glyphicon glyphicon-question-sign"></span>
|
||||
{intl l='This coupon is disabled, you can enable to the bottom of this form.'}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<table class="table table-striped">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{intl l='Title'}</td>
|
||||
<td>{$TITLE}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{intl l='Expiration date'}</td>
|
||||
<td>{$EXPIRATION_DATE}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{intl l='Usage left'}</td>
|
||||
<td>
|
||||
{if $USAGE_LEFT}
|
||||
<span class="label label-success">
|
||||
{$USAGE_LEFT}
|
||||
</span>
|
||||
{else}
|
||||
<span class="label label-important">
|
||||
0
|
||||
</span>
|
||||
{/if}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">{$SHORT_DESCRIPTION}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">{$DESCRIPTION}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
{if $IS_CUMULATIVE}
|
||||
<span class="label label-success">
|
||||
{intl l="May be cumulative"}
|
||||
</span>
|
||||
{else}
|
||||
<span class="label label-important">
|
||||
{intl l="Can't be cumulative"}
|
||||
</span>
|
||||
{/if}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
{if $IS_REMOVING_POSTAGE}
|
||||
<span class="label label-important">
|
||||
<table class="table table-striped">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{intl l='Title'}</td>
|
||||
<td>{$TITLE}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
{if $IS_ENABLED}
|
||||
<span class="label label-success">
|
||||
{intl l="Is enabled"}
|
||||
</span>
|
||||
{else}
|
||||
<span class="label label-warning">
|
||||
{intl l="Is disabled"}
|
||||
</span>
|
||||
{/if}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
{$TOOLTIP}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{intl l='Amount'}</td>
|
||||
<td>{$AMOUNT}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{intl l='Expiration date'}</td>
|
||||
<td>{$EXPIRATION_DATE} ({$DAY_LEFT_BEFORE_EXPIRATION} {intl l="days left"})</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{intl l='Usage left'}</td>
|
||||
<td>
|
||||
{if $USAGE_LEFT}
|
||||
<span class="label label-success">
|
||||
{$USAGE_LEFT}
|
||||
</span>
|
||||
{else}
|
||||
<span class="label label-warning">
|
||||
0
|
||||
</span>
|
||||
{/if}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
{if $IS_CUMULATIVE}
|
||||
<span class="label label-success">
|
||||
{intl l="May be cumulative"}
|
||||
</span>
|
||||
{else}
|
||||
<span class="label label-warning">
|
||||
{intl l="Can't be cumulative"}
|
||||
</span>
|
||||
{/if}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
{if $IS_REMOVING_POSTAGE}
|
||||
<span class="label label-warning">
|
||||
{intl l="Will remove postage"}
|
||||
</span>
|
||||
{else}
|
||||
<span class="label label-success">
|
||||
{else}
|
||||
<span class="label label-success">
|
||||
{intl l="Won't remove postage"}
|
||||
</span>
|
||||
{/if}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{intl l='Amount'}</td>
|
||||
<td>{$AMOUNT}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{intl l='Application field'}</td>
|
||||
<td>
|
||||
<ul class="list-unstyled">
|
||||
{foreach from=$APPLICATION_CONDITIONS item=rule name=rulesForeach}
|
||||
{if !$smarty.foreach.rulesForeach.first}
|
||||
<li><span class="label label-info">{intl l='And'}</span></li>
|
||||
{/if}
|
||||
<li>{$rule nofilter}</li>
|
||||
{/foreach}
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{intl l='Actions'}</td>
|
||||
<td>
|
||||
<a href="#url" class="btn btn-default btn-primary btn-medium"><span class="icon-edit icon-white"></span> {intl l='Edit'}</a>
|
||||
<a href="#url" class="btn btn-default btn-success btn-medium" data-toggle="confirm" data-target="#enable"><span class="glyphicon glyphicon-ok"></span> {intl l='Enabled'}</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
{/loop}
|
||||
</div>
|
||||
</section>
|
||||
{/if}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
{if $IS_AVAILABLE_ON_SPECIAL_OFFERS}
|
||||
<span class="label label-warning">
|
||||
{intl l="Will be available on special offers"}
|
||||
</span>
|
||||
{else}
|
||||
<span class="label label-success">
|
||||
{intl l="Won't be available on special offers"}
|
||||
</span>
|
||||
{/if}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{intl l='Application field'}</td>
|
||||
<td>
|
||||
<ul class="list-unstyled">
|
||||
{foreach from=$APPLICATION_CONDITIONS item=rule name=rulesForeach}
|
||||
{if !$smarty.foreach.rulesForeach.first}
|
||||
<li><span class="label label-info">{intl l='And'}</span></li>
|
||||
{/if}
|
||||
<li>{$rule nofilter}</li>
|
||||
{/foreach}
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">{$SHORT_DESCRIPTION}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">{$DESCRIPTION}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<a href="{$urlEditCoupon}" class="btn btn-default btn-primary btn-medium">
|
||||
<span class="icon-edit icon-white"></span> {intl l='Edit'}
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
{/loop}
|
||||
</section> <!-- #wrapper -->
|
||||
|
||||
{include file='includes/confirmation-modal.html' id="enable" message="{intl l='Do you really want to enable this element ?'}"}
|
||||
|
||||
@@ -7,19 +7,20 @@
|
||||
|
||||
<nav>
|
||||
<ul class="breadcrumb">
|
||||
{include file="includes/coupon_breadcrumb.html"}
|
||||
<li><a href="{url path='admin/home'}">{intl l='Home'}</a></li>
|
||||
<li><a href="{url path='admin/coupon/'}">{intl l='Coupon'}</a></li>
|
||||
<li>{intl l='Update'} {$couponCode}</li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<div class="page-header">
|
||||
<h1>Coupons : <small>Update a coupon</small></h1>
|
||||
<h1>{intl l='Coupons : '}<small>{intl l='Update'} {$couponCode}</small></h1>
|
||||
</div>
|
||||
|
||||
{form name="thelia.admin.coupon.creation"}
|
||||
{include file='coupon/form.html' formAction={url path={$formAction}} form=$form noRules=false}
|
||||
{/form}
|
||||
|
||||
|
||||
</section> <!-- #wrapper -->
|
||||
{/block}
|
||||
|
||||
@@ -71,8 +72,6 @@
|
||||
// Save Rules AJAX
|
||||
couponManager.saveRuleAjax = function() {
|
||||
$('#constraint-add-operators-values').html('<div class="loading" ></div>');
|
||||
console.log('about to save');
|
||||
console.log(couponManager.rulesToSave);
|
||||
var $url = '{$urlAjaxUpdateRules}';
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
@@ -88,6 +87,11 @@
|
||||
}).done(function(data) {
|
||||
$('#constraint-list').html(data);
|
||||
$('#constraint-add-operators-values').html('');
|
||||
// Set the rule selector
|
||||
$("#category-rule option").filter(function() {
|
||||
return $(this).val() == 'thelia.constraint.rule.available_for_everyone';
|
||||
}).prop('selected', true);
|
||||
|
||||
couponManager.onClickUpdateRule();
|
||||
couponManager.onClickDeleteRule();
|
||||
});
|
||||
@@ -109,13 +113,22 @@
|
||||
}
|
||||
}).done(function(data) {
|
||||
$('#constraint-add-operators-values').html(data);
|
||||
|
||||
couponManager.ruleToSave.serviceId = ruleId;
|
||||
if (ruleId == -1) {
|
||||
// Placeholder can't be saved
|
||||
$('#constraint-save-btn').hide();
|
||||
} else {
|
||||
$('#constraint-save-btn').show();
|
||||
}
|
||||
return callBack();
|
||||
});
|
||||
};
|
||||
|
||||
// Rules which will be saved
|
||||
couponManager.rulesToSave = couponManager.initRules();
|
||||
|
||||
$('#constraint-save-btn').hide();
|
||||
|
||||
});
|
||||
</script>
|
||||
{/block}
|
||||
|
||||
@@ -11,152 +11,155 @@
|
||||
{/form_field}
|
||||
|
||||
{form_field form=$form field='success_url'}
|
||||
<input type="hidden" name="{$name}" value="{url path='/admin/coupon/read/{id}'}" />
|
||||
<input type="hidden" name="{$name}" value="{url path='/admin/coupon/update/{id}/'}" />
|
||||
{/form_field}
|
||||
|
||||
<div class="span4">
|
||||
<div class="control-group">
|
||||
<div class="col-md-4">
|
||||
<div class="form-group">
|
||||
<label for="code">{intl l='Code :'}</label>
|
||||
{form_field form=$form field='code'}
|
||||
{form_field form=$form field='code'}
|
||||
<div class="form-group {if $error}has-error{/if}">
|
||||
<label class="control-label" for="code">{intl l='Code :'}</label>
|
||||
<input id="code" class="form-control" type="text" name="{$name}" value="{$value}" placeholder="{intl l='code'}">
|
||||
{if $error}{$message}{/if}
|
||||
{/form_field}
|
||||
</div>
|
||||
</div>
|
||||
{/form_field}
|
||||
|
||||
<div class="form-group">
|
||||
<label for="title">{intl l='Title :'}</label>
|
||||
{form_field form=$form field='title'}
|
||||
{form_field form=$form field='title'}
|
||||
<div class="form-group {if $error}has-error{/if}">
|
||||
<label for="title" class="control-label" >{intl l='Title :'}</label>
|
||||
<input id="title" class="form-control" type="text" name="{$name}" value="{$value}" placeholder="{intl l='title'}">
|
||||
{if $error}{$message}{/if}
|
||||
{/form_field}
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="enabled" class="checkbox">
|
||||
{form_field form=$form field='isEnabled'}
|
||||
<input id="enabled" type="checkbox" name="{$name}" {if $value}value="1" checked{else}value="0"{/if} >
|
||||
{if $error}{$message}{/if}
|
||||
{/form_field}
|
||||
{intl l='Is enabled ?'}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="available-on-special-offers" class="checkbox">
|
||||
{form_field form=$form field='isAvailableOnSpecialOffers'}
|
||||
<input id="available-on-special-offers" type="checkbox" name="{$name}" {if $value}value="1" checked{else}value="0"{/if} >
|
||||
{if $error}{$message}{/if}
|
||||
{/form_field}
|
||||
{intl l='Is available on special offers ?'}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="cumulative" class="checkbox">
|
||||
{form_field form=$form field='isCumulative'}
|
||||
<input id="cumulative" type="checkbox" name="{$name}" {if $value}value="1" checked{else}value="0"{/if} >
|
||||
{if $error}{$message}{/if}
|
||||
{/form_field}
|
||||
{intl l='Is cumulative ?'}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="renoving-postage" class="checkbox">
|
||||
{form_field form=$form field='isRemovingPostage'}
|
||||
<input id="renoving-postage" type="checkbox" name="{$name}" {if $value}value="1" checked{else}value="0"{/if} >
|
||||
{if $error}{$message}{/if}
|
||||
{/form_field}
|
||||
{intl l='Is removing postage ?'}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="expiration-date">{intl l='Expiration date :'}</label>
|
||||
<div class="input-append date" data-date="12/02/2012" data-date-format="dd/mm/yyyy">
|
||||
{form_field form=$form field='expirationDate'}
|
||||
<input type="text" id="expiration-date" name="{$name}" value="{if $defaultDate}{$defaultDate}{else}{$value}{/if}">
|
||||
{if $error}{$message}{/if}
|
||||
{/form_field}
|
||||
<span class="add-on"><span class="icon-th"></span></span>
|
||||
</div>
|
||||
</div>
|
||||
{/form_field}
|
||||
|
||||
<div class="form-group">
|
||||
<label for="max-usage">{intl l='Max usage :'}</label>
|
||||
<label for="is-unlimited" class="checkbox">
|
||||
<input id="is-unlimited" type="checkbox" name="is-unlimited" checked >
|
||||
{intl l='Is unlimited ?'}
|
||||
</label>
|
||||
{form_field form=$form field='maxUsage'}
|
||||
{form_field form=$form field='isEnabled'}
|
||||
<div class="form-group {if $error}has-error{/if}">
|
||||
<label for="is-enabled" class="checkbox control-label">
|
||||
<input id="is-enabled" type="checkbox" name="{$name}" {if $value}value="1" checked{else}value="0"{/if} >
|
||||
{if $error}{$message}{/if}
|
||||
{intl l='Is enabled'}
|
||||
</label>
|
||||
</div>
|
||||
{/form_field}
|
||||
|
||||
{form_field form=$form field='isAvailableOnSpecialOffers'}
|
||||
<div class="form-group {if $error}has-error{/if}">
|
||||
<label for="is-available-on-special-offers" class="checkbox control-label">
|
||||
<input id="is-available-on-special-offers" type="checkbox" name="{$name}" {if $value}value="1" checked{else}value="0"{/if} >
|
||||
{if $error}{$message}{/if}
|
||||
{intl l='Is available on special offers'}
|
||||
</label>
|
||||
</div>
|
||||
{/form_field}
|
||||
|
||||
{form_field form=$form field='isCumulative'}
|
||||
<div class="form-group {if $error}has-error{/if}">
|
||||
<label for="is-cumulative" class="checkbox control-label">
|
||||
<input id="is-cumulative" type="checkbox" name="{$name}" {if $value}value="1" checked{else}value="0"{/if} >
|
||||
{if $error}{$message}{/if}
|
||||
{intl l='Is cumulative'}
|
||||
</label>
|
||||
</div>
|
||||
{/form_field}
|
||||
|
||||
{form_field form=$form field='isRemovingPostage'}
|
||||
<div class="form-group {if $error}has-error{/if}">
|
||||
<label for="is-removing-postage" class="checkbox control-label">
|
||||
<input id="is-removing-postage" type="checkbox" name="{$name}" {if $value}value="1" checked{else}value="0"{/if} >
|
||||
{if $error}{$message}{/if}
|
||||
{intl l='Is removing postage'}
|
||||
</label>
|
||||
</div>
|
||||
{/form_field}
|
||||
|
||||
{form_field form=$form field='expirationDate'}
|
||||
<div class="form-group {if $error}has-error{/if}">
|
||||
<label for="expiration-date" class="control-label">{intl l='Expiration date :'}</label>
|
||||
<div class="input-append date" data-date="12/02/2012" data-date-format="dd/mm/yyyy">
|
||||
<input type="text" id="expiration-date" name="{$name}" class="form-control datepicker" data-date-format="yyyy-mm-dd" value="{if $defaultDate}{$defaultDate}{else}{$value}{/if}" placeholder="{intl l='yyyy-mm-dd'}">
|
||||
{if $error}{$message}{/if}
|
||||
<span class="add-on"><span class="icon-th"></span></span>
|
||||
</div>
|
||||
</div>
|
||||
{/form_field}
|
||||
|
||||
{form_field form=$form field='maxUsage'}
|
||||
<div class="form-group {if $error}has-error{/if}">
|
||||
|
||||
<label for="is-unlimited" class="checkbox control-label">
|
||||
<input id="is-unlimited" type="checkbox" name="is-unlimited" {if $error}{else}checked{/if} >
|
||||
{intl l='Is unlimited'}
|
||||
</label>
|
||||
<label id="max-usage-label" for="max-usage" class="control-label">{intl l='Max usage :'}</label>
|
||||
<input id="max-usage" type="text" class="form-control" name="{$name}" value="{$value}" placeholder="{intl l='max usage'}">
|
||||
{if $error}{$message}{/if}
|
||||
{/form_field}
|
||||
</div>
|
||||
</div>
|
||||
{/form_field}
|
||||
</div>
|
||||
|
||||
<div class="col-md-8">
|
||||
<div class="well clearfix">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label for="effect">{intl l='Effect :'}</label>
|
||||
{form_field form=$form field='effect'}
|
||||
{form_field form=$form field='effect'}
|
||||
<div class="form-group {if $error}has-error{/if}">
|
||||
<label for="effect" class="control-label">{intl l='Effect :'}</label>
|
||||
<select name="{$name}" value="{$value}" id="effect" class="col-md-12 form-control">
|
||||
<option value="-1" data-description="">{intl l='Please select an effect'}</option>
|
||||
{foreach from=$availableCoupons item=availableCoupon}
|
||||
<option value="{$availableCoupon.serviceId}" data-description="{$availableCoupon.toolTip}">{$availableCoupon.name}</option>
|
||||
<option value="{$availableCoupon.serviceId}" data-description="{$availableCoupon.toolTip}" {if $value == $availableCoupon.serviceId}selected="selected"{/if}>{$availableCoupon.name}</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
{if $error}{$message}{/if}
|
||||
{/form_field}
|
||||
<span id="effectToolTip" class="help-block">{$availableCoupons.0.toolTip}</span>
|
||||
</div>
|
||||
<span id="effectToolTip" class="help-block">{$availableCoupons.0.toolTip}</span>
|
||||
</div>
|
||||
{/form_field}
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label for="amount">{intl l='Amount :'}</label>
|
||||
{form_field form=$form field='amount'}
|
||||
{form_field form=$form field='amount'}
|
||||
<div class="form-group {if $error}has-error{/if}">
|
||||
{$value}
|
||||
<label for="amount" class="control-label">{intl l='Amount :'}</label>
|
||||
<input id="amount" type="text" class="form-control" name="{$name}" value="{$value}" placeholder="{intl l='14.50'}">
|
||||
{if $error}{$message}{/if}
|
||||
{/form_field}
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="category">Category :</label>
|
||||
</div>
|
||||
{/form_field}
|
||||
{*<div class="form-group {if $error}has-error{/if}">*}
|
||||
{*<label for="category">Category :</label>*}
|
||||
{*form_field form=$form field='category'*}
|
||||
<select name="{$name}" value="{$value}" id="category" class="form-control">
|
||||
<option value="1">Category 1</option>
|
||||
<option value="1">Category 2</option>
|
||||
<option value="1">Category 3</option>
|
||||
</select>
|
||||
{*<select name="{$name}" value="{$value}" id="category" class="form-control">*}
|
||||
{*<option value="1">Category 1</option>*}
|
||||
{*<option value="1">Category 2</option>*}
|
||||
{*<option value="1">Category 3</option>*}
|
||||
{*</select>*}
|
||||
{*if $error}{$message}{/if}*}
|
||||
{*/form_field*}
|
||||
</div>
|
||||
{*</div>*}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="short-description">{intl l='Short description :'}</label>
|
||||
{form_field form=$form field='shortDescription'}
|
||||
<textarea id="short-description" name="{$name}" placeholder="{intl l='short description'}" class="span12" rows="5">{$value nofilter}</textarea>
|
||||
{form_field form=$form field='shortDescription'}
|
||||
<div class="form-group {if $error}has-error{/if}">
|
||||
<label for="short-description" class="control-label">{intl l='Short description :'}</label>
|
||||
<textarea id="short-description" name="{$name}" class="form-control" placeholder="{intl l='short description'}" class="span12" rows="5">{$value nofilter}</textarea>
|
||||
{if $error}{$message}{/if}
|
||||
{/form_field}
|
||||
</div>
|
||||
</div>
|
||||
{/form_field}
|
||||
</div>
|
||||
|
||||
<div class="clearfix"></div>
|
||||
<div class="col-md-12">
|
||||
|
||||
<div class="form-group">
|
||||
<label for="description">{intl l='Long description :'}</label>
|
||||
{form_field form=$form field='description'}
|
||||
{form_field form=$form field='description'}
|
||||
<div class="form-group {if $error}has-error{/if}">
|
||||
<label for="description" class="control-label">{intl l='Long description :'}</label>
|
||||
<textarea id="description" name="{$name}" placeholder="{intl l='long description'}" class="form-control wysiwyg" rows="10">{$value nofilter}</textarea>
|
||||
{if $error}{$message}{/if}
|
||||
{/form_field}
|
||||
</div>
|
||||
</div>
|
||||
{/form_field}
|
||||
|
||||
<button type="submit" class="btn btn-default btn-primary">{intl l='Save'}</button>
|
||||
<button id="save-coupon-btn" type="submit" class="btn btn-default btn-primary">{intl l='Save your modifications'}</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -186,22 +189,23 @@
|
||||
<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>
|
||||
<span class="glyphicon glyphicon-plus-sign"></span> {intl l='Save this rule'}
|
||||
</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'}
|
||||
<input type="radio" name="type" class="form-control" id="type" value="1" checked> {intl l='And'}
|
||||
</label>
|
||||
<label class="radio">
|
||||
<input type="radio" name="type" value="2"> {intl l='Or'}
|
||||
<input type="radio" name="type" class="form-control" 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">
|
||||
<option value="-1" >{intl l='Please select a rule category'}</option>
|
||||
{foreach from=$availableRules item=availableRule}
|
||||
<option value="{$availableRule.serviceId}" data-description="{$availableRule.toolTip}">{$availableRule.name}</option>
|
||||
{/foreach}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<div class="row">
|
||||
<div class="col-lg-6">
|
||||
<select class="form-control" id="{$name}-operator" name="{$name}[operator]">
|
||||
{foreach from=$input.availableOperators key=k item=availableOperator}
|
||||
{foreach from=$input.availableOperators key=k item=availableOperator name=availableOperators}
|
||||
<option value="{$k}">{$availableOperator}</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
@@ -11,7 +11,7 @@
|
||||
<div class="input-group col-lg-6">
|
||||
{if $input.type == 'select'}
|
||||
<select class="{$input.class}" id="{$name}-value" name="{$name}[value]">
|
||||
{foreach from=$input.availableValues key=code item=availableValue}
|
||||
{foreach from=$input.availableValues key=code item=availableValue name=availableValues}
|
||||
<option value="{$code}">{$availableValue}</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
@@ -72,12 +72,16 @@
|
||||
<script>
|
||||
|
||||
// Init Rules to set
|
||||
couponManager.ruleToSave['serviceId'] = '{$ruleId}';
|
||||
couponManager.ruleToSave['operators'] = {literal}{}{/literal};
|
||||
couponManager.ruleToSave['values'] = {literal}{}{/literal};
|
||||
// Update only if no rule are already set
|
||||
if(!couponManager.ruleToSave){
|
||||
couponManager.ruleToSave['serviceId'] = '{$ruleId}';
|
||||
couponManager.ruleToSave['operators'] = {literal}{}{/literal};
|
||||
couponManager.ruleToSave['values'] = {literal}{}{/literal};
|
||||
} else {
|
||||
}
|
||||
{foreach from=$inputs.inputs key=name item=input}
|
||||
couponManager.ruleToSave['operators']['{$name nofilter}'] = '{foreach from=$inputs.inputs[$name].availableOperators key=keyOperator item=valueOperator name=operators}{if $smarty.foreach.operators.first}{$keyOperator nofilter}{/if}{/foreach}';
|
||||
couponManager.ruleToSave['values']['{$name nofilter}'] = '{if count($inputs.inputs[$name].availableValues) != 0}{foreach from=$inputs.inputs[$name].availableValues key=keyValue item=valueValue name=values}{if $smarty.foreach.values.first}{$keyValue nofilter}{/if}{/foreach}{else}to set{/if}';
|
||||
couponManager.ruleToSave['operators']['{$name nofilter}'] = '{foreach from=$inputs.inputs[$name].availableOperators key=keyOperator item=valueOperator name=operators}{if $smarty.foreach.operators.first}{$keyOperator nofilter}{/if}{/foreach}';
|
||||
couponManager.ruleToSave['values']['{$name nofilter}'] = '{if count($inputs.inputs[$name].availableValues) != 0}{foreach from=$inputs.inputs[$name].availableValues key=keyValue item=valueValue name=values}{if $smarty.foreach.values.first}{$keyValue nofilter}{/if}{/foreach}{else}to set{/if}';
|
||||
{/foreach}
|
||||
|
||||
|
||||
@@ -86,13 +90,11 @@
|
||||
{foreach from=$inputs.inputs key=name item=input}
|
||||
// Operator selector
|
||||
$('#{$name}-operator').change(function (e) {
|
||||
console.log('changin operator');
|
||||
var $this = $(this);
|
||||
couponManager.ruleToSave['operators']['{$name nofilter}'] = $this.val();
|
||||
});
|
||||
// Value input
|
||||
$('#{$name}-value').change(function (e) {
|
||||
console.log('changin value');
|
||||
var $this = $(this);
|
||||
couponManager.ruleToSave['values']['{$name nofilter}'] = $this.val();
|
||||
});
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
{* Breadcrumb for coupon browsing and editing *}
|
||||
|
||||
<li><a href="{url path='admin/home'}">Home</a></li>
|
||||
<li><a href="{url path='admin/coupon'}">Coupon</a></li>
|
||||
<li><a href="{url path="admin/coupon/browse/$ID"}">Browse</a></li>
|
||||
@@ -3,7 +3,7 @@ casper.test.comment('Please edit 00_parameters.js to add your configuration');
|
||||
|
||||
var thelia2_login_admin_url = thelia2_base_url + 'admin/login';
|
||||
var thelia2_login_coupon_list_url = thelia2_base_url + 'admin/login';
|
||||
var thelia2_login_coupon_create_url = thelia2_base_url + 'admin/coupon/create';
|
||||
var thelia2_login_coupon_create_url = thelia2_base_url + 'admin/coupon/create/';
|
||||
var thelia2_login_coupon_read_url = thelia2_base_url + 'admin/coupon/read/1';
|
||||
var thelia2_login_coupon_update_url = thelia2_base_url + 'admin/coupon/update/1';
|
||||
|
||||
|
||||
@@ -1,51 +1,151 @@
|
||||
casper.test.comment('Testing coupons');
|
||||
//
|
||||
//var casper = require('casper').create({
|
||||
// viewportSize:{
|
||||
// width:1024, height:768
|
||||
// },
|
||||
// pageSettings:{
|
||||
// userAgent:'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_2) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.79 Safari/535.11'
|
||||
// },
|
||||
// verbose:true
|
||||
//});
|
||||
|
||||
casper.test.comment('Testing coupons');
|
||||
|
||||
////LIST
|
||||
// @todo implement
|
||||
|
||||
////CREATE
|
||||
// @todo implement
|
||||
|
||||
//UPDATE COUPON RULE
|
||||
casper.start(thelia2_login_coupon_update_url, function() {
|
||||
casper.start(thelia2_login_coupon_create_url, function() {
|
||||
this.test.assertHttpStatus(200);
|
||||
this.test.comment('Now on : ' + this.getCurrentUrl());
|
||||
this.capture('tests/functionnal/casperjs/screenshot/coupons/init.png');
|
||||
this.echo('\nCOUPON RULE - EDIT');
|
||||
this.test.assertTitle('Update coupon - Thelia Back Office', 'Web page title OK');
|
||||
// this.test.assertSelectorHasText('#content-header > h1', 'Liste des pays', 'Web page main content OK');
|
||||
this.test.assertSelectorHasText('tbody#constraint-list tr:nth-child(1)', 'If cart total amount is superior to 40 EUR','1st default rule found');
|
||||
this.test.assertSelectorHasText('tbody#constraint-list tr:nth-child(2)', 'If cart total amount is inferior to 400 EUR','2nd default rule found');
|
||||
this.test.comment('COUPON - CREATE EMPTY');
|
||||
|
||||
// Create rule
|
||||
// Click on is unlimited button
|
||||
this.click("form #is-unlimited");
|
||||
this.sendKeys('input#max-usage', '-2');
|
||||
|
||||
// cleaning expiration date default value
|
||||
this.evaluate(function() {
|
||||
$('#category-rule').val('thelia.constraint.rule.available_for_x_articles').change();
|
||||
$("#expiration-date").val('').change();
|
||||
return true;
|
||||
});
|
||||
this.capture('tests/functionnal/casperjs/screenshot/coupons/rule-selected.png');
|
||||
|
||||
this.capture('tests/functionnal/casperjs/screenshot/coupons/creating-new-coupon.png');
|
||||
this.click("form .control-group .btn.btn-default.btn-primary");
|
||||
|
||||
});
|
||||
|
||||
casper.wait(1000, function() {
|
||||
this.echo("\nWaiting....");
|
||||
});
|
||||
|
||||
// Test Coupon creation if no input
|
||||
casper.then(function(){
|
||||
this.evaluate(function() {
|
||||
$('#quantity-operator').val('>=').change();
|
||||
return true;
|
||||
});
|
||||
this.sendKeys('input#quantity-value', '4');
|
||||
this.click('#constraint-save-btn');
|
||||
this.test.assertHttpStatus(200);
|
||||
this.capture('tests/functionnal/casperjs/screenshot/coupons/created-new-empty-coupon.png');
|
||||
this.test.assertExists('.has-error #code', 'Error on code input found');
|
||||
this.test.assertExists('.has-error #title', 'Error on title input found');
|
||||
|
||||
this.test.assertExists('.has-error #expiration-date', 'Error on expiration date input found');
|
||||
this.test.assertExists('.has-error #max-usage', 'Error on max usage input found');
|
||||
this.test.assertExists('.has-error #description', 'Error on description input found');
|
||||
this.test.assertExists('.has-error #effect', 'Error on effect input found');
|
||||
this.test.assertExists('.has-error #amount', 'Error on amount input found');
|
||||
this.test.assertExists('.has-error #short-description', 'Error on short-description input found');
|
||||
});
|
||||
|
||||
casper.wait(1000, function() {
|
||||
// Test Coupon creation if good input
|
||||
casper.then(function(){
|
||||
|
||||
this.sendKeys('input#code', 'XMAS10');
|
||||
this.sendKeys('input#title', 'christmas');
|
||||
this.click("form #is-enabled");
|
||||
this.click("form #is-available-on-special-offers");
|
||||
this.click("form #is-cumulative");
|
||||
this.click("form #is-removing-postage");
|
||||
|
||||
this.evaluate(function() {
|
||||
$("#expiration-date").val('2013-11-14').change();
|
||||
return true;
|
||||
});
|
||||
|
||||
// Click on is unlimited button
|
||||
this.click("form #is-unlimited");
|
||||
this.sendKeys('input#max-usage', '40');
|
||||
|
||||
this.evaluate(function() {
|
||||
$('#effect').val('thelia.coupon.type.remove_x_amount').change();
|
||||
return true;
|
||||
});
|
||||
|
||||
this.test.assertSelectorHasText(
|
||||
'#effectToolTip',
|
||||
this.evaluate(function () {
|
||||
return $("#effect option[value^='thelia.coupon.type.remove_x_amount']").attr('data-description');
|
||||
}),
|
||||
'Tooltip found'
|
||||
);
|
||||
this.sendKeys('input#amount', '42.12');
|
||||
this.sendKeys('#short-description', 'Mauris sed risus imperdiet, blandit arcu ac, tempus metus. Aliquam erat volutpat. Nullam dictum sed.');
|
||||
this.sendKeys('#description', 'Etiam sodales non nisi a condimentum. Morbi luctus mauris mattis sem ornare; ac blandit tortor porta! Sed vel viverra dolor. Nulla eget viverra eros. Donec rutrum felis ut quam blandit, eu massa nunc.');
|
||||
|
||||
this.capture('tests/functionnal/casperjs/screenshot/coupons/coupon-created-ready-to-be-saved.png');
|
||||
this.click("#save-coupon-btn");
|
||||
});
|
||||
|
||||
casper.wait(2000, function() {
|
||||
this.echo("\nWaiting....");
|
||||
});
|
||||
|
||||
// Test Coupon creation if good input is well saved
|
||||
casper.then(function(){
|
||||
this.capture('tests/functionnal/casperjs/screenshot/coupons/rule-added.png');
|
||||
this.test.assertSelectorHasText('tbody#constraint-list tr:nth-child(3)', ' If cart products quantity is superior or equals to 4','3rd rule found');
|
||||
});
|
||||
this.test.assertHttpStatus(302);
|
||||
this.test.comment('Now on : ' + this.getCurrentUrl());
|
||||
this.capture('tests/functionnal/casperjs/screenshot/coupons/created-new-coupon.png');
|
||||
this.test.assertField('thelia_coupon_creation[code]', 'XMAS10', 'Code found');
|
||||
this.test.assertField('thelia_coupon_creation[title]', 'christmas', 'Title found');
|
||||
|
||||
this.test.assert(this.evaluate(function () {
|
||||
return document.getElementById('is-enabled').checked;
|
||||
}), 'Checkbox is enabled checked');
|
||||
this.test.assert(this.evaluate(function () {
|
||||
return document.getElementById('is-available-on-special-offers').checked;
|
||||
}), 'Checkbox is available on special offers checked');
|
||||
this.test.assert(this.evaluate(function () {
|
||||
return document.getElementById('is-cumulative').checked;
|
||||
}), 'Checkbox is cumulative checked');
|
||||
this.test.assert(this.evaluate(function () {
|
||||
return document.getElementById('is-removing-postage').checked;
|
||||
}), 'Checkbox is cumulative checked');
|
||||
|
||||
this.test.assertField('thelia_coupon_creation[expirationDate]', '2013-11-14', 'Expiration date found');
|
||||
this.test.assertField('thelia_coupon_creation[maxUsage]', '40', 'Max usage found');
|
||||
this.test.assert(this.evaluate(function () {
|
||||
return !document.getElementById('is-unlimited').checked;
|
||||
}), 'Checkbox is unlimited not checked');
|
||||
|
||||
this.test.assert(
|
||||
this.evaluate(function () {
|
||||
return $("#effect").val();
|
||||
}),
|
||||
'thelia.coupon.type.remove_x_amount',
|
||||
'Effect found'
|
||||
);
|
||||
this.test.assertSelectorHasText(
|
||||
'#effectToolTip',
|
||||
this.evaluate(function () {
|
||||
return $("#effect option[value^='thelia.coupon.type.remove_x_amount']").attr('data-description');
|
||||
}),
|
||||
'Tooltip found'
|
||||
);
|
||||
this.test.assertField('thelia_coupon_creation[amount]', '42.12', 'Amount found');
|
||||
|
||||
this.test.assertField('thelia_coupon_creation[shortDescription]', 'Mauris sed risus imperdiet, blandit arcu ac, tempus metus. Aliquam erat volutpat. Nullam dictum sed.', 'Short description found');
|
||||
this.test.assertField('thelia_coupon_creation[description]', 'Etiam sodales non nisi a condimentum. Morbi luctus mauris mattis sem ornare; ac blandit tortor porta! Sed vel viverra dolor. Nulla eget viverra eros. Donec rutrum felis ut quam blandit, eu massa nunc.', 'Description found');
|
||||
|
||||
|
||||
});
|
||||
////EDIT CHECK
|
||||
// @todo implement
|
||||
|
||||
|
||||
312
tests/functionnal/casperjs/exe/31_coupons_rule.js
Normal file
312
tests/functionnal/casperjs/exe/31_coupons_rule.js
Normal file
@@ -0,0 +1,312 @@
|
||||
////
|
||||
////var casper = require('casper').create({
|
||||
//// viewportSize:{
|
||||
//// width:1024, height:768
|
||||
//// },
|
||||
//// pageSettings:{
|
||||
//// userAgent:'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_2) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.79 Safari/535.11'
|
||||
//// },
|
||||
//// verbose:true
|
||||
////});
|
||||
//
|
||||
//casper.test.comment('Testing coupons rules');
|
||||
//
|
||||
////UPDATE COUPON RULE
|
||||
//casper.start(thelia2_login_coupon_update_url, function() {
|
||||
// this.test.assertHttpStatus(200);
|
||||
// this.test.comment('Now on : ' + this.getCurrentUrl());
|
||||
// this.capture('tests/functionnal/casperjs/screenshot/coupons/init.png');
|
||||
// this.test.comment('COUPON RULE - EDIT');
|
||||
// this.test.assertTitle('Update coupon - Thelia Back Office', 'Web page title OK');
|
||||
// this.test.assertSelectorHasText('tbody#constraint-list tr:nth-child(1)', 'If cart total amount is superior to 40 EUR','1) 1st default rule found');
|
||||
// this.test.assertSelectorHasText('tbody#constraint-list tr:nth-child(2)', 'If cart total amount is inferior to 400 EUR','1) 2nd default rule found');
|
||||
//
|
||||
// // Create rule
|
||||
// this.evaluate(function() {
|
||||
// $('#category-rule').val('thelia.constraint.rule.available_for_x_articles').change();
|
||||
// return true;
|
||||
// });
|
||||
// this.capture('tests/functionnal/casperjs/screenshot/coupons/rule-selected.png');
|
||||
//});
|
||||
//
|
||||
//casper.wait(1000, function() {
|
||||
// this.echo("\nWaiting....");
|
||||
//});
|
||||
//
|
||||
//// Test Rule updating
|
||||
//casper.then(function(){
|
||||
// this.evaluate(function() {
|
||||
// $('#quantity-operator').val('>=').change();
|
||||
// return true;
|
||||
// });
|
||||
// this.sendKeys('input#quantity-value', '4');
|
||||
// this.click('#constraint-save-btn');
|
||||
//});
|
||||
//
|
||||
//casper.wait(1000, function() {
|
||||
// this.echo("\nWaiting....");
|
||||
//});
|
||||
//
|
||||
//casper.then(function(){
|
||||
// this.capture('tests/functionnal/casperjs/screenshot/coupons/rule-added.png');
|
||||
// this.test.assertSelectorHasText('tbody#constraint-list tr:nth-child(1)', 'If cart total amount is superior to 40 EUR','2) 1st default rule found');
|
||||
// this.test.assertSelectorHasText('tbody#constraint-list tr:nth-child(2)', 'If cart total amount is inferior to 400 EUR','2) 2nd default rule found');
|
||||
// this.test.assertSelectorHasText('tbody#constraint-list tr:nth-child(3)', ' If cart products quantity is superior or equal to 4','2) 3rd rule found');
|
||||
//
|
||||
// // Click on Edit button
|
||||
// this.click('tbody#constraint-list tr:nth-child(3) .constraint-update-btn');
|
||||
//});
|
||||
//
|
||||
//casper.wait(2000, function() {
|
||||
// this.echo("\nWaiting....");
|
||||
//});
|
||||
//
|
||||
//casper.then(function(){
|
||||
// this.evaluate(function() {
|
||||
// $('#quantity-operator').val('==').change();
|
||||
// return true;
|
||||
// });
|
||||
//
|
||||
// // Removing old value
|
||||
//// casper.evaluate(function triggerKeyDownEvent() {
|
||||
//// var e = $.Event("keydown");
|
||||
//// e.which = 8;
|
||||
//// e.keyCode = 8;
|
||||
//// $("#quantity-value").trigger(e);
|
||||
//// });
|
||||
// this.evaluate(function() {
|
||||
// $("#quantity-value").val('').change();
|
||||
// return true;
|
||||
// });
|
||||
//
|
||||
// // Adding new value
|
||||
// this.sendKeys('#quantity-value', '5');
|
||||
// this.capture('tests/functionnal/casperjs/screenshot/coupons/rule-being-edited.png');
|
||||
// this.click('#constraint-save-btn');
|
||||
//});
|
||||
//
|
||||
//casper.wait(2000, function() {
|
||||
// this.echo("\nWaiting....");
|
||||
//});
|
||||
//// Check if updated rule has been saved and list refreshed
|
||||
//casper.then(function(){
|
||||
// this.capture('tests/functionnal/casperjs/screenshot/coupons/rule-edited.png');
|
||||
// this.test.assertSelectorHasText('tbody#constraint-list tr:nth-child(1)', 'If cart total amount is superior to 40 EUR','3) 1st default rule found');
|
||||
// this.test.assertSelectorHasText('tbody#constraint-list tr:nth-child(2)', 'If cart total amount is inferior to 400 EUR','3) 2nd default rule found');
|
||||
// this.test.assertSelectorHasText('tbody#constraint-list tr:nth-child(3)', 'If cart products quantity is equal to 5','3) 3rd rule updated found');
|
||||
//});
|
||||
//
|
||||
//// Check if updated rule has been well saved
|
||||
//casper.thenOpen(thelia2_login_coupon_update_url, function() {
|
||||
// this.test.assertHttpStatus(200);
|
||||
// this.test.comment('Now on : ' + this.getCurrentUrl());
|
||||
// this.capture('tests/functionnal/casperjs/screenshot/coupons/rule-edited-refreshed.png');
|
||||
// this.test.assertSelectorHasText('tbody#constraint-list tr:nth-child(1)', 'If cart total amount is superior to 40 EUR','4) 1st default rule found');
|
||||
// this.test.assertSelectorHasText('tbody#constraint-list tr:nth-child(2)', 'If cart total amount is inferior to 400 EUR','4) 2nd default rule found');
|
||||
// this.test.assertSelectorHasText('tbody#constraint-list tr:nth-child(3)', 'If cart products quantity is equal to 5','4) 3rd rule updated found');
|
||||
//
|
||||
// // Click on Delete button
|
||||
// this.click('tbody#constraint-list tr:nth-child(2) .constraint-delete-btn');
|
||||
//});
|
||||
//
|
||||
//casper.wait(2000, function() {
|
||||
// this.echo("\nWaiting....");
|
||||
//});
|
||||
//
|
||||
//casper.then(function(){
|
||||
// this.test.assertSelectorHasText('tbody#constraint-list tr:nth-child(1)', 'If cart total amount is superior to 40 EUR','5) 1st default rule found');
|
||||
// this.test.assertSelectorDoesntHaveText('tbody#constraint-list tr:nth-child(2)', 'If cart total amount is inferior to 400 EUR','5) 2nd default rule found');
|
||||
// this.test.assertSelectorHasText('tbody#constraint-list tr:nth-child(2)', 'If cart products quantity is equal to 5','5) 3rd rule updated found');
|
||||
//});
|
||||
//
|
||||
//// Check if updated rule has been well saved
|
||||
//casper.thenOpen(thelia2_login_coupon_update_url, function() {
|
||||
// this.test.assertHttpStatus(200);
|
||||
// this.test.comment('Now on : ' + this.getCurrentUrl());
|
||||
// this.capture('tests/functionnal/casperjs/screenshot/coupons/rule-deleted-refreshed.png');
|
||||
// this.test.assertSelectorHasText('tbody#constraint-list tr:nth-child(1)', 'If cart total amount is superior to 40 EUR','6) 1st default rule found');
|
||||
// this.test.assertSelectorDoesntHaveText('tbody#constraint-list tr:nth-child(2)', 'If cart total amount is inferior to 400 EUR','6) 2nd default rule found');
|
||||
// this.test.assertSelectorHasText('tbody#constraint-list tr:nth-child(2)', 'If cart products quantity is equal to 5','6) 3rd rule updated found');
|
||||
//});
|
||||
//
|
||||
//// Test creating rule that won't be edited
|
||||
//casper.then(function(){
|
||||
//// Create rule
|
||||
// this.evaluate(function() {
|
||||
// $('#category-rule').val('thelia.constraint.rule.available_for_total_amount').change();
|
||||
// return true;
|
||||
// });
|
||||
// this.capture('tests/functionnal/casperjs/screenshot/coupons/rule-selected2.png');
|
||||
//});
|
||||
//
|
||||
//casper.wait(2000, function() {
|
||||
// this.echo("\nWaiting....");
|
||||
//});
|
||||
//
|
||||
//// Test Rule creation
|
||||
//casper.then(function(){
|
||||
// this.evaluate(function() {
|
||||
// $('#price-operator').val('<=').change();
|
||||
// return true;
|
||||
// });
|
||||
// // Removing old value
|
||||
//// casper.evaluate(function triggerKeyDownEvent() {
|
||||
//// var e = $.Event("keydown");
|
||||
//// e.which = 8;
|
||||
//// e.keyCode = 8;
|
||||
//// $("input#price-value").trigger(e);
|
||||
//// });
|
||||
// this.evaluate(function() {
|
||||
// $("input#price-value").val('').change();
|
||||
// return true;
|
||||
// });
|
||||
//
|
||||
// // Changing 400 to 401
|
||||
// this.sendKeys('input#price-value', '401');
|
||||
// this.evaluate(function() {
|
||||
// $('#currency-value').val('GBP').change();
|
||||
// return true;
|
||||
// });
|
||||
// this.capture('tests/functionnal/casperjs/screenshot/coupons/rule-saved-edited-before-click-save.png');
|
||||
// this.click('#constraint-save-btn');
|
||||
//});
|
||||
//
|
||||
//casper.wait(2000, function() {
|
||||
// this.echo("\nWaiting....");
|
||||
//});
|
||||
//
|
||||
//casper.then(function(){
|
||||
// this.test.assertSelectorHasText('tbody#constraint-list tr:nth-child(1)', 'If cart total amount is superior to 40 EUR','7) 1st default rule found');
|
||||
// this.test.assertSelectorDoesntHaveText('tbody#constraint-list tr:nth-child(2)', 'If cart total amount is inferior to 400 EUR','7) 2nd default rule found');
|
||||
// this.test.assertSelectorHasText('tbody#constraint-list tr:nth-child(2)', 'If cart products quantity is equal to 5','7) 3rd rule updated found');
|
||||
// this.test.assertSelectorHasText('tbody#constraint-list tr:nth-child(3)', 'If cart total amount is inferior or equal to 401 GBP','7) 4rd rule created found');
|
||||
//});
|
||||
//
|
||||
//// Check if created rule has been well saved
|
||||
//casper.thenOpen(thelia2_login_coupon_update_url, function() {
|
||||
// this.test.assertHttpStatus(200);
|
||||
// this.test.comment('Now on : ' + this.getCurrentUrl());
|
||||
// this.capture('tests/functionnal/casperjs/screenshot/coupons/rule-added-refreshed.png');
|
||||
// this.test.assertSelectorHasText('tbody#constraint-list tr:nth-child(1)', 'If cart total amount is superior to 40 EUR','8) 1st default rule found');
|
||||
// this.test.assertSelectorDoesntHaveText('tbody#constraint-list tr:nth-child(2)', 'If cart total amount is inferior to 400 EUR','8) 2nd default rule found');
|
||||
// this.test.assertSelectorHasText('tbody#constraint-list tr:nth-child(2)', 'If cart products quantity is equal to 5','8) 3rd rule updated found');
|
||||
// this.test.assertSelectorHasText('tbody#constraint-list tr:nth-child(3)', 'If cart total amount is inferior or equal to 401 GBP','8) 4rd rule created found');
|
||||
//});
|
||||
//
|
||||
//// Testing deleting all rules
|
||||
//casper.then(function(){
|
||||
//// Click on Delete button
|
||||
// this.click('tbody#constraint-list tr:nth-child(1) .constraint-delete-btn');
|
||||
//});
|
||||
//casper.wait(1000, function() {
|
||||
// this.echo("\nWaiting....");
|
||||
//});
|
||||
//casper.then(function(){
|
||||
//// Click on Delete button
|
||||
// this.click('tbody#constraint-list tr:nth-child(1) .constraint-delete-btn');
|
||||
//});
|
||||
//casper.wait(1000, function() {
|
||||
// this.echo("\nWaiting....");
|
||||
//});
|
||||
//casper.then(function(){
|
||||
//// Click on Delete button
|
||||
// this.click('tbody#constraint-list tr:nth-child(1) .constraint-delete-btn');
|
||||
//});
|
||||
//casper.wait(1000, function() {
|
||||
// this.echo("\nWaiting....");
|
||||
//});
|
||||
//casper.then(function(){
|
||||
// this.capture('tests/functionnal/casperjs/screenshot/coupons/rule-all-deleted.png');
|
||||
// this.test.assertSelectorHasText('tbody#constraint-list tr:nth-child(1)', 'No conditions','9) 1st default rule found');
|
||||
// test.assertDoesntExist('tbody#constraint-list tr:nth-child(2)');
|
||||
//});
|
||||
//
|
||||
//// Check if created rule has been well saved
|
||||
//casper.thenOpen(thelia2_login_coupon_update_url, function() {
|
||||
// this.test.assertHttpStatus(200);
|
||||
// this.test.comment('Now on : ' + this.getCurrentUrl());
|
||||
// this.capture('tests/functionnal/casperjs/screenshot/coupons/rule-all-deleted-refreshed.png');
|
||||
// this.test.assertSelectorHasText('tbody#constraint-list tr:nth-child(1)', 'No conditions','10) 1st default rule found');
|
||||
// test.assertDoesntExist('tbody#constraint-list tr:nth-child(2)');
|
||||
//});
|
||||
//
|
||||
//
|
||||
//// Test add no condition rule
|
||||
//casper.then(function(){
|
||||
// this.evaluate(function() {
|
||||
// $('#category-rule').val('thelia.constraint.rule.available_for_x_articles').change();
|
||||
// return true;
|
||||
// });
|
||||
//});
|
||||
//
|
||||
//casper.wait(1000, function() {
|
||||
// this.echo("\nWaiting....");
|
||||
//});
|
||||
//
|
||||
//// Test Rule updating
|
||||
//casper.then(function(){
|
||||
// this.evaluate(function() {
|
||||
// $('#quantity-operator').val('>').change();
|
||||
// return true;
|
||||
// });
|
||||
// this.sendKeys('input#quantity-value', '4');
|
||||
// this.click('#constraint-save-btn');
|
||||
//});
|
||||
//
|
||||
//casper.wait(1000, function() {
|
||||
// this.echo("\nWaiting....");
|
||||
//});
|
||||
//
|
||||
//casper.then(function(){
|
||||
// this.capture('tests/functionnal/casperjs/screenshot/coupons/rule-all-deleted.png');
|
||||
// this.test.assertSelectorHasText('tbody#constraint-list tr:nth-child(1)', 'If cart products quantity is superior to 4', '11) 1st default rule found');
|
||||
// test.assertDoesntExist('tbody#constraint-list tr:nth-child(2)');
|
||||
//});
|
||||
//
|
||||
//// Check if created rule has been well saved
|
||||
//casper.thenOpen(thelia2_login_coupon_update_url, function() {
|
||||
// this.test.assertHttpStatus(200);
|
||||
// this.test.comment('Now on : ' + this.getCurrentUrl());
|
||||
// this.capture('tests/functionnal/casperjs/screenshot/coupons/rule-all-deleted-refreshed.png');
|
||||
// this.test.assertSelectorHasText('tbody#constraint-list tr:nth-child(1)', 'If cart products quantity is superior to 4','12) 1st default rule found');
|
||||
// test.assertDoesntExist('tbody#constraint-list tr:nth-child(2)');
|
||||
//});
|
||||
//
|
||||
//casper.then(function(){
|
||||
// this.evaluate(function() {
|
||||
// $('#category-rule').val('thelia.constraint.rule.available_for_everyone').change();
|
||||
// return true;
|
||||
// });
|
||||
//});
|
||||
//
|
||||
//casper.wait(1000, function() {
|
||||
// this.echo("\nWaiting....");
|
||||
//});
|
||||
//
|
||||
//// Test Rule updating
|
||||
//casper.then(function(){
|
||||
// this.click('#constraint-save-btn');
|
||||
//});
|
||||
//
|
||||
//casper.wait(1000, function() {
|
||||
// this.echo("\nWaiting....");
|
||||
//});
|
||||
//casper.then(function(){
|
||||
// this.capture('tests/functionnal/casperjs/screenshot/coupons/rule-all-deleted.png');
|
||||
// this.test.assertSelectorHasText('tbody#constraint-list tr:nth-child(1)', 'No conditions','13) 1st default rule found');
|
||||
// test.assertDoesntExist('tbody#constraint-list tr:nth-child(2)');
|
||||
//});
|
||||
//
|
||||
//// Check if created rule has been well saved
|
||||
//casper.thenOpen(thelia2_login_coupon_update_url, function() {
|
||||
// this.test.assertHttpStatus(200);
|
||||
// this.test.comment('Now on : ' + this.getCurrentUrl());
|
||||
// this.capture('tests/functionnal/casperjs/screenshot/coupons/rule-all-deleted-refreshed.png');
|
||||
// this.test.assertSelectorHasText('tbody#constraint-list tr:nth-child(1)', 'No conditions','14) 1st default rule found');
|
||||
// test.assertDoesntExist('tbody#constraint-list tr:nth-child(2)');
|
||||
//});
|
||||
//
|
||||
////RUN
|
||||
//casper.run(function() {
|
||||
// this.test.done();
|
||||
//});
|
||||
Reference in New Issue
Block a user