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> <default key="_controller">Thelia\Controller\Admin\CouponController::readAction</default>
<requirement key="couponId">\d+</requirement> <requirement key="couponId">\d+</requirement>
</route> </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}"> <route id="admin.coupon.condition.input" path="/admin/coupon/condition/{conditionId}">
<default key="_controller">Thelia\Controller\Admin\CouponController::getConditionInputAction</default> <default key="_controller">Thelia\Controller\Admin\CouponController::getConditionInputAction</default>
<requirement key="conditionId">.*</requirement> <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\Coupon\CouponCreateOrUpdateEvent;
use Thelia\Core\Event\TheliaEvents; use Thelia\Core\Event\TheliaEvents;
use Thelia\Core\Security\AccessManager; use Thelia\Core\Security\AccessManager;
use Thelia\Coupon\CouponFactory;
use Thelia\Coupon\CouponManager; use Thelia\Coupon\CouponManager;
use Thelia\Condition\ConditionCollection; use Thelia\Condition\ConditionCollection;
use Thelia\Coupon\Type\CouponInterface; use Thelia\Coupon\Type\CouponInterface;
@@ -41,6 +42,7 @@ use Thelia\Model\Coupon;
use Thelia\Model\CouponQuery; use Thelia\Model\CouponQuery;
use Thelia\Model\Lang; use Thelia\Model\Lang;
use Thelia\Tools\I18n; use Thelia\Tools\I18n;
use Thelia\Tools\Rest\ResponseRest;
/** /**
* Created by JetBrains PhpStorm. * Created by JetBrains PhpStorm.
@@ -152,6 +154,11 @@ class CouponController extends BaseAdminController
$args['dateFormat'] = $this->getSession()->getLang()->getDateFormat(); $args['dateFormat'] = $this->getSession()->getLang()->getDateFormat();
$args['availableCoupons'] = $this->getAvailableCoupons(); $args['availableCoupons'] = $this->getAvailableCoupons();
$args['urlAjaxAdminCouponDrawInputs'] = $this->getRoute(
'admin.coupon.draw.inputs',
array('couponServiceId' => 'couponServiceId'),
Router::ABSOLUTE_URL
);
$args['formAction'] = 'admin/coupon/create'; $args['formAction'] = 'admin/coupon/create';
return $this->render( return $this->render(
@@ -181,6 +188,9 @@ class CouponController extends BaseAdminController
return $this->pageNotFound(); return $this->pageNotFound();
} }
/** @var CouponFactory $couponFactory */
$couponFactory = $this->container->get('thelia.coupon.factory');
$couponManager = $couponFactory->buildCouponFromModel($coupon);
// Parameters given to the template // Parameters given to the template
$args = array(); $args = array();
@@ -233,6 +243,7 @@ class CouponController extends BaseAdminController
'serviceId' => $condition->getServiceId(), 'serviceId' => $condition->getServiceId(),
'name' => $condition->getName(), 'name' => $condition->getName(),
'tooltip' => $condition->getToolTip(), 'tooltip' => $condition->getToolTip(),
'tooltip' => $condition->getToolTip(),
'validators' => $condition->getValidators() 'validators' => $condition->getValidators()
); );
} }
@@ -247,6 +258,12 @@ class CouponController extends BaseAdminController
} }
$args['couponCode'] = $coupon->getCode(); $args['couponCode'] = $coupon->getCode();
$args['availableCoupons'] = $this->getAvailableCoupons(); $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['availableConditions'] = $this->getAvailableConditions();
$args['urlAjaxGetConditionInput'] = $this->getRoute( $args['urlAjaxGetConditionInput'] = $this->getRoute(
'admin.coupon.condition.input', 'admin.coupon.condition.input',
@@ -461,6 +478,9 @@ class CouponController extends BaseAdminController
$couponEvent = new CouponCreateOrUpdateEvent( $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'] $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 // Dispatch Event to the Action
$this->dispatch( $this->dispatch(
@@ -524,7 +544,6 @@ class CouponController extends BaseAdminController
$condition = array(); $condition = array();
$condition['serviceId'] = $availableCondition->getServiceId(); $condition['serviceId'] = $availableCondition->getServiceId();
$condition['name'] = $availableCondition->getName(); $condition['name'] = $availableCondition->getName();
// $condition['toolTip'] = $availableCondition->getToolTip();
$cleanedConditions[] = $condition; $cleanedConditions[] = $condition;
} }
@@ -548,6 +567,7 @@ class CouponController extends BaseAdminController
$condition['serviceId'] = $availableCoupon->getServiceId(); $condition['serviceId'] = $availableCoupon->getServiceId();
$condition['name'] = $availableCoupon->getName(); $condition['name'] = $availableCoupon->getName();
$condition['toolTip'] = $availableCoupon->getToolTip(); $condition['toolTip'] = $availableCoupon->getToolTip();
$condition['inputName'] = $availableCoupon->getInputName();
$cleanedCoupons[] = $condition; $cleanedCoupons[] = $condition;
} }
@@ -572,4 +592,26 @@ class CouponController extends BaseAdminController
return $cleanedConditions; 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(); 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); 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(); public function getName();
/**
* Get I18n amount input name
*
* @return string
*/
public function getInputName();
/** /**
* Get I18n tooltip * Get I18n tooltip
* *
@@ -215,4 +222,12 @@ interface CouponInterface
*/ */
public function isMatching(); 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 return $this->facade
->getTranslator() ->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( ->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.', '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(), array(),
'constraint' 'coupon'
); );
return $toolTip; return $toolTip;

View File

@@ -122,7 +122,19 @@ class RemoveXPercent extends CouponAbstract
{ {
return $this->facade return $this->facade
->getTranslator() ->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( ->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.', '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(), array(),
'constraint' 'coupon'
); );
return $toolTip; return $toolTip;

View File

@@ -127,13 +127,42 @@ $(function($){
}; };
$.couponManager.onClickUpdateCondition(); $.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 // Reload effect inputs when changing effect
$.couponManager.onEffectChange = function() { $.couponManager.onEffectChange = function() {
var optionSelected = $("option:selected", this); var mainDiv = $('#coupon-type');
$('#effectToolTip').html(optionSelected.attr("data-description")); var optionSelected = mainDiv.find('#type option:selected');
$('#effect').on('change', function () { mainDiv.find('.typeToolTip').html(optionSelected.attr('data-description'));
var optionSelected = $("option:selected", this);
$('#effectToolTip').html(optionSelected.attr("data-description")); mainDiv.find('#type').on('change', function () {
var optionSelected = $('option:selected', this);
$.couponManager.displayEfffect(optionSelected);
}); });
}; };
$.couponManager.onEffectChange(); $.couponManager.onEffectChange();

View File

@@ -59,6 +59,11 @@
filemanager_title:"{intl l='Files manager'}" , filemanager_title:"{intl l='Files manager'}" ,
external_plugins: { "filemanager" : "{url file='/tinymce/plugins/filemanager/plugin.min.js'}"} 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> </script>
{/block} {/block}

View File

@@ -36,6 +36,8 @@
<script src="{$asset_url}"></script> <script src="{$asset_url}"></script>
{/javascripts} {/javascripts}
<script>
</script>
{javascripts file='assets/js/coupon.js'} {javascripts file='assets/js/coupon.js'}
<script src="{$asset_url}"></script> <script src="{$asset_url}"></script>
{/javascripts} {/javascripts}
@@ -62,6 +64,10 @@
$(function($){ $(function($){
// miniBrowser(0, '/test_to_remove/datas_coupon_edit.json'); // 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 // Init Conditions
$.couponManager.initConditions = function() { $.couponManager.initConditions = function() {
var conditions = []; var conditions = [];

View File

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