Refactor : Coupon effect inputs are now more customisable (input text, select, ajax, etc.. are usable) and unlimited amount of input for coupon effect are now possible too (Event are used for custom inputs)

This commit is contained in:
gmorel
2013-12-26 23:47:07 +01:00
parent 8f9b86ff6a
commit e18298bbba
11 changed files with 170 additions and 21 deletions

View File

@@ -499,6 +499,10 @@
<default key="_controller">Thelia\Controller\Admin\CouponController::readAction</default>
<requirement key="couponId">\d+</requirement>
</route>
<route id="admin.coupon.draw.inputs" path="/admin/coupon/draw/inputs/{couponServiceId}">
<default key="_controller">Thelia\Controller\Admin\CouponController::getBackOfficeInputsAction</default>
<requirement key="couponServiceId">.*</requirement>
</route>
<route id="admin.coupon.condition.input" path="/admin/coupon/condition/{conditionId}">
<default key="_controller">Thelia\Controller\Admin\CouponController::getConditionInputAction</default>
<requirement key="conditionId">.*</requirement>

View File

@@ -31,6 +31,7 @@ use Thelia\Core\Security\Resource\AdminResources;
use Thelia\Core\Event\Coupon\CouponCreateOrUpdateEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Core\Security\AccessManager;
use Thelia\Coupon\CouponFactory;
use Thelia\Coupon\CouponManager;
use Thelia\Condition\ConditionCollection;
use Thelia\Coupon\Type\CouponInterface;
@@ -41,6 +42,7 @@ use Thelia\Model\Coupon;
use Thelia\Model\CouponQuery;
use Thelia\Model\Lang;
use Thelia\Tools\I18n;
use Thelia\Tools\Rest\ResponseRest;
/**
* Created by JetBrains PhpStorm.
@@ -152,6 +154,11 @@ class CouponController extends BaseAdminController
$args['dateFormat'] = $this->getSession()->getLang()->getDateFormat();
$args['availableCoupons'] = $this->getAvailableCoupons();
$args['urlAjaxAdminCouponDrawInputs'] = $this->getRoute(
'admin.coupon.draw.inputs',
array('couponServiceId' => 'couponServiceId'),
Router::ABSOLUTE_URL
);
$args['formAction'] = 'admin/coupon/create';
return $this->render(
@@ -181,6 +188,9 @@ class CouponController extends BaseAdminController
return $this->pageNotFound();
}
/** @var CouponFactory $couponFactory */
$couponFactory = $this->container->get('thelia.coupon.factory');
$couponManager = $couponFactory->buildCouponFromModel($coupon);
// Parameters given to the template
$args = array();
@@ -233,6 +243,7 @@ class CouponController extends BaseAdminController
'serviceId' => $condition->getServiceId(),
'name' => $condition->getName(),
'tooltip' => $condition->getToolTip(),
'tooltip' => $condition->getToolTip(),
'validators' => $condition->getValidators()
);
}
@@ -247,6 +258,12 @@ class CouponController extends BaseAdminController
}
$args['couponCode'] = $coupon->getCode();
$args['availableCoupons'] = $this->getAvailableCoupons();
$args['couponInputsHtml'] = $couponManager->drawBackOfficeInputs();
$args['urlAjaxAdminCouponDrawInputs'] = $this->getRoute(
'admin.coupon.draw.inputs',
array('couponServiceId' => 'couponServiceId'),
Router::ABSOLUTE_URL
);
$args['availableConditions'] = $this->getAvailableConditions();
$args['urlAjaxGetConditionInput'] = $this->getRoute(
'admin.coupon.condition.input',
@@ -461,6 +478,9 @@ class CouponController extends BaseAdminController
$couponEvent = new CouponCreateOrUpdateEvent(
$data['code'], $data['title'], $data['amount'], $data['type'], $data['shortDescription'], $data['description'], $data['isEnabled'], \DateTime::createFromFormat('Y-m-d', $data['expirationDate']), $data['isAvailableOnSpecialOffers'], $data['isCumulative'], $data['isRemovingPostage'], $data['maxUsage'], $data['locale']
);
$couponQuery = new CouponQuery();
$coupon = $couponQuery->findOneByCode($data['code']);
$couponEvent->setCouponModel($coupon);
// Dispatch Event to the Action
$this->dispatch(
@@ -524,7 +544,6 @@ class CouponController extends BaseAdminController
$condition = array();
$condition['serviceId'] = $availableCondition->getServiceId();
$condition['name'] = $availableCondition->getName();
// $condition['toolTip'] = $availableCondition->getToolTip();
$cleanedConditions[] = $condition;
}
@@ -548,6 +567,7 @@ class CouponController extends BaseAdminController
$condition['serviceId'] = $availableCoupon->getServiceId();
$condition['name'] = $availableCoupon->getName();
$condition['toolTip'] = $availableCoupon->getToolTip();
$condition['inputName'] = $availableCoupon->getInputName();
$cleanedCoupons[] = $condition;
}
@@ -572,4 +592,26 @@ class CouponController extends BaseAdminController
return $cleanedConditions;
}
/**
* Draw the input displayed in the BackOffice
* allowing Admin to set its Coupon effect
*
* @param string $couponServiceId Coupon service id
*
* @return ResponseRest
*/
public function getBackOfficeInputsAction($couponServiceId)
{
/** @var CouponInterface $coupon */
$coupon = $this->container->get($couponServiceId);
if (!$coupon instanceof CouponInterface) {
$this->pageNotFound();
}
$response = new ResponseRest($coupon->drawBackOfficeInputs());
return $response;
}
}

View File

@@ -167,4 +167,11 @@ interface FacadeInterface
*/
public function getAvailableCurrencies();
/**
* Return the event dispatcher,
*
* @return \Symfony\Component\EventDispatcher\EventDispatcher
*/
public function getDispatcher();
}

View File

@@ -307,4 +307,25 @@ abstract class CouponAbstract implements CouponInterface
return $this->conditionEvaluator->isMatching($this->conditions);
}
/**
* Draw the input displayed in the BackOffice
* allowing Admin to set its Coupon effect
*
* @return string HTML string
*/
public function drawBackOfficeInputs()
{
$label = $this->getInputName();
$value = $this->amount;
$html = '
<div class="form-group input-amount ">
<label for="amount" class="control-label">' . $label . '</label>
<input id="amount" type="text" class="form-control" name="thelia_coupon_creation[amount]" value="' . $value . '" placeholder="14.50">
</div>
';
return $html;
}
}

View File

@@ -46,6 +46,13 @@ interface CouponInterface
*/
public function getName();
/**
* Get I18n amount input name
*
* @return string
*/
public function getInputName();
/**
* Get I18n tooltip
*
@@ -215,4 +222,12 @@ interface CouponInterface
*/
public function isMatching();
/**
* Draw the input displayed in the BackOffice
* allowing Admin to set its Coupon effect
*
* @return string HTML string
*/
public function drawBackOfficeInputs();
}

View File

@@ -100,7 +100,19 @@ class RemoveXAmount extends CouponAbstract
{
return $this->facade
->getTranslator()
->trans('Remove X amount to total cart', array(), 'constraint');
->trans('Remove X amount to total cart', array(), 'coupon');
}
/**
* Get I18n amount input name
*
* @return string
*/
public function getInputName()
{
return $this->facade
->getTranslator()
->trans('Amount removed from the cart', array(), 'coupon');
}
/**
@@ -115,7 +127,7 @@ class RemoveXAmount extends CouponAbstract
->trans(
'This coupon will remove the entered amount to the customer total checkout. If the discount is superior to the total checkout price the customer will only pay the postage. Unless if the coupon is set to remove postage too.',
array(),
'constraint'
'coupon'
);
return $toolTip;

View File

@@ -122,7 +122,19 @@ class RemoveXPercent extends CouponAbstract
{
return $this->facade
->getTranslator()
->trans('Remove X percent to total cart', array(), 'constraint');
->trans('Remove X percent to total cart', array(), 'coupon');
}
/**
* Get I18n amount input name
*
* @return string
*/
public function getInputName()
{
return $this->facade
->getTranslator()
->trans('Percentage removed from the cart', array(), 'coupon');
}
/**
@@ -137,7 +149,7 @@ class RemoveXPercent extends CouponAbstract
->trans(
'This coupon will remove the entered percentage to the customer total checkout. If the discount is superior to the total checkout price the customer will only pay the postage. Unless if the coupon is set to remove postage too.',
array(),
'constraint'
'coupon'
);
return $toolTip;

View File

@@ -127,13 +127,42 @@ $(function($){
};
$.couponManager.onClickUpdateCondition();
$.couponManager.displayEfffect = function(optionSelected) {
var mainDiv = $('#coupon-type');
mainDiv.find('.typeToolTip').html(optionSelected.attr('data-description'));
var inputsDiv = mainDiv.find('.inputs');
inputsDiv.html('<div class="loading" ></div>');
var url = $.couponManager.urlAjaxAdminCouponDrawInputs;
url = url.replace('couponServiceId', optionSelected.val());
$.ajax({
type: "GET",
url: url,
data: '',
statusCode: {
404: function() {
inputsDiv.html($.couponManager.intlPleaseRetry);
},
500: function() {
inputsDiv.html($.couponManager.intlPleaseRetry);
}
}
}).done(function(data) {
inputsDiv.html(data);
});
};
// 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"));
var mainDiv = $('#coupon-type');
var optionSelected = mainDiv.find('#type option:selected');
mainDiv.find('.typeToolTip').html(optionSelected.attr('data-description'));
mainDiv.find('#type').on('change', function () {
var optionSelected = $('option:selected', this);
$.couponManager.displayEfffect(optionSelected);
});
};
$.couponManager.onEffectChange();

View File

@@ -59,6 +59,11 @@
filemanager_title:"{intl l='Files manager'}" ,
external_plugins: { "filemanager" : "{url file='/tinymce/plugins/filemanager/plugin.min.js'}"}
});
// Url alowing to get coupon inputs
$.couponManager.urlAjaxAdminCouponDrawInputs = "{$urlAjaxAdminCouponDrawInputs}";
$.couponManager.intlPleaseRetry = '{intl l='Please retry'}';
</script>
{/block}

View File

@@ -36,6 +36,8 @@
<script src="{$asset_url}"></script>
{/javascripts}
<script>
</script>
{javascripts file='assets/js/coupon.js'}
<script src="{$asset_url}"></script>
{/javascripts}
@@ -62,6 +64,10 @@
$(function($){
// miniBrowser(0, '/test_to_remove/datas_coupon_edit.json');
// Url alowing to get coupon inputs
$.couponManager.urlAjaxAdminCouponDrawInputs = "{$urlAjaxAdminCouponDrawInputs}";
$.couponManager.intlPleaseRetry = '{intl l='Please retry'}';
// Init Conditions
$.couponManager.initConditions = function() {
var conditions = [];

View File

@@ -99,32 +99,28 @@
</div>
<div class="col-md-8">
<div class="well clearfix">
<div id="coupon-type" class="well clearfix">
<div class="col-md-6">
{form_field form=$form field='type'}
<div class="form-group {if $error}has-error{/if}">
<label for="type" class="control-label">{intl l='Type :'}</label>
<select name="{$name}" id="type" class="col-md-12 form-control">
<option value="-1" data-description="">{intl l='Please select a coupon type'}</option>
<option value="-1" data-description="" data-inputName="">{intl l='Please select a coupon type'}</option>
{foreach from=$availableCoupons item=availableCoupon}
<option value="{$availableCoupon.serviceId}" {if $value == $availableCoupon.serviceId}selected{/if}>
<option value="{$availableCoupon.serviceId}" data-description="{$availableCoupon.toolTip}" data-inputName="{$availableCoupon.inputName}" {if $value == $availableCoupon.serviceId}selected{/if}>
{$availableCoupon.name}
</option>
{/foreach}
</select>
{if $error}{$message}{/if}
<span id="typeToolTip" class="help-block">{$availableCoupons.0.toolTip}</span>
<span class="help-block typeToolTip">{$availableCoupons.0.toolTip}</span>
</div>
{/form_field}
</div>
<div class="col-md-6">
<div class="col-md-6 inputs">
{form_field form=$form field='amount'}
<div class="form-group {if $error}has-error{/if}">
<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}
</div>
{$couponInputsHtml nofilter}
{/form_field}
{*<div class="form-group {if $error}has-error{/if}">*}
{*<label for="category">Category :</label>*}
@@ -208,7 +204,7 @@
<select name="categoryCondition" id="category-condition" class="form-control">
<option value="-1" >{intl l='Please select a condition category'}</option>
{foreach from=$availableConditions item=availableCondition}
<option value="{$availableCondition.serviceId}" data-description="{$availableCondition.toolTip}">{$availableCondition.name}</option>
<option value="{$availableCondition.serviceId}" >{$availableCondition.name}</option>
{/foreach}
</select>
</div>