Permalink
Browse files

Добавляет страницу настроек процесса генерации купонов

Добавляет пункт меню для перехода к настройкам генерации с помощью обработчика события OnBuildGlobalMenu
Расширяет инсталлятор БД обработчиками событий
Исправляет недочеты инсталлятора БД
  • Loading branch information...
Журов Михаил
Журов Михаил committed Nov 7, 2017
1 parent 3462601 commit f404260ab16cb8a74d62c006b53e0bd847746454
View
@@ -0,0 +1,11 @@
<?php
require_once $_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/main/include/prolog_admin_before.php';
// TODO проверить последствия подключения сразу после admin_before
require_once $_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/main/include/prolog_admin_after.php';
global $APPLICATION;
$APPLICATION->IncludeComponent('maximaster:coupanda.coupon.generator', 'admin');
require_once $_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/main/include/epilog_admin.php';
View
@@ -1,2 +1 @@
<?php
@@ -21,15 +21,28 @@ public function __construct($moduleId, Connection $connection)
public function install()
{
/**
* Если вдруг у нас отсутствует движок транзакций для каких-то таблиц, то:
* - возникновение ошибки в момент регистрации модуля приведет к тому, что будет выброшено исключение, и
* регистрация модуля будет отмененеа в блоке catch
* - возникновение ошибки в момент создания таблицы (например по причине отсутствия прав) также приведет к
* исключению, и тогда снова регистрация будет снята в блоке catch
* - возникновение ошибки при модификации колонки в существующей таблице скажет о том, что либо такая колонка
* уже существует (и модуль был вообще ранее установлен, что само по себе крайне исключительная ситуация), либо
* пользователю субд не хватило прав на добавление колонки, что тоже довольно редкий кейс, т.к. сам битрикс
* нормально работать в таких условиях не будет
*/
try {
$this->connection->startTransaction();
ModuleManager::registerModule($this->moduleId);
Loader::includeModule($this->moduleId);
$this->createProcessTable();
$this->addPIDColumn();
$this->addEventHandlers();
$this->connection->commitTransaction();
} catch (\Exception $e) {
$this->connection->rollbackTransaction();
ModuleManager::unRegisterModule($this->moduleId);
throw new \Exception($e->getMessage(), $e->getCode());
}
@@ -38,11 +51,21 @@ public function install()
public function uninstall()
{
/**
* Если вдруг отсутствует движок транзакций, то:
* - возникновение исключения при удалении таблицы приведет к тому, что модуль останется установленным
* - возникновение исключения в процессе изменения таблицы практически исключено, т.к. битрикс сам работать в таких
* условиях не сможет
* - возникновение исключения в процессе снятия регистрации модуля - это единственная ситуция, в которой деинсталлятор
* может отработать некорректно, но данная ситуация видится мне невозможной, если только специально не вмешаться
* в процесс снятия регистрации модуля
*/
try {
Loader::includeModule($this->moduleId);
$this->connection->startTransaction();
$this->dropProcessTable();
$this->dropPIDColumn();
$this->dropEventHandlers();
ModuleManager::unRegisterModule($this->moduleId);
$this->connection->commitTransaction();
} catch (\Exception $e) {
@@ -79,4 +102,29 @@ protected function dropPIDColumn()
{
$this->connection->queryExecute('ALTER TABLE `b_sale_discount_coupon` DROP `MAXIMASTER_COUPANDA_PID`');
}
protected function addEventHandlers()
{
\RegisterModuleDependences(
'main',
'OnPageStart',
$this->moduleId,
EventHandlersRegistry::class,
'register',
100,
__DIR__ . '/../lib/eventhandlersregistry.php'
);
}
protected function dropEventHandlers()
{
\UnRegisterModuleDependences(
'main',
'OnPageStart',
$this->moduleId,
EventHandlersRegistry::class,
'register',
__DIR__ . '/../lib/eventhandlersregistry.php'
);
}
}
@@ -0,0 +1,21 @@
<?php
use \Bitrix\Main\Localization\Loc;
if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED!==true) {
die();
}
$arComponentDescription = [
'NAME' => Loc::getMessage('MAXIMASTER:COUPANDA.COUPON.GENERATOR:COMPONENT_NAME'),
'DESCRIPTION' => Loc::getMessage('MAXIMASTER:COUPANDA.COUPON.GENERATOR:COMPONENT_DESCRIPTION'),
'CACHE_PATH' => 'Y',
'PATH' => [
'ID' => 'maximaster',
'NAME' => Loc::getMessage('MAXIMASTER:COUPANDA.COUPON.GENERATOR:VENDOR_NAME'),
'CHILD' => [
'ID' => 'coupanda.coupon.generator',
'NAME' => Loc::getMessage('MAXIMASTER:COUPANDA.COUPON.GENERATOR:COMPONENT_NAME')
]
],
];
@@ -0,0 +1,140 @@
<?php
namespace Maximaster\Coupanda;
use Bitrix\Main\Loader;
use Bitrix\Main\Localization\Loc;
use Bitrix\Main\SystemException;
use Bitrix\Sale\Internals\DiscountCouponTable;
use Bitrix\Sale\Internals\DiscountTable;
class CoupandaCouponGenerator extends \CBitrixComponent
{
public function onPrepareComponentParams($params)
{
$params['CACHE_TIME'] = 0;
$params['CACHE_TYPE'] = 'N';
return parent::onPrepareComponentParams($params);
}
public function onIncludeComponentLang()
{
parent::onIncludeComponentLang();
Loc::loadLanguageFile(__FILE__);
}
public function executeComponent()
{
$this->setFrameMode(false);
try {
$this->checkPermissions();
$this->loadModules();
if ($this->isAjaxRequest()) {
//$this->handleAjax();
return null;
} else {
return $this->handle();
}
} catch (\Exception $e) {
if ($this->isAjaxRequest()) {
} else {
\ShowError($e->getMessage());
}
}
}
protected function loadModules()
{
array_map(function ($moduleId) {
if (!Loader::includeModule($moduleId)) {
throw new SystemException('Модуль ' . $moduleId . ' не установлен');
}
}, ['sale', 'maximaster.coupanda']);
}
protected function checkPermissions()
{
global $APPLICATION;
$permission = $APPLICATION->GetGroupRight('maximaster.coupanda');
if ($permission < 'W') {
throw new SystemException('Недостаточно прав для использования генератора');
}
}
protected function isAjaxRequest()
{
return isset($this->request['ajax_action']) && $this->request->isPost() && $this->request->isAjaxRequest();
}
protected function handle()
{
$this->setPageParameters();
$this->setAdminContextMenu();
$this->arResult['DISCOUNTS'] = $this->getDiscountList();
$this->arResult['COUPON_TYPES'] = $this->getCouponTypes();
$this->arResult['LINKS'] = $this->getLinks();
$this->includeComponentTemplate();
}
protected function setPageParameters()
{
global $APPLICATION;
$APPLICATION->SetTitle('Генератор купонов');
}
protected function setAdminContextMenu()
{
if (!$this->request->isAdminSection()) {
return;
}
/*$menu = array(
array(
"TEXT" => Loc::getMessage("BTN_TO_LIST"),
"TITLE" => Loc::getMessage("BTN_TO_LIST"),
"LINK" => "/bitrix/admin/coupons_list.php?lang=".LANG,
"ICON" => "btn_list"
),
);
$menu[] = [
"TEXT" => Loc::getMessage("BTN_TO_LIST"),
"TITLE" => Loc::getMessage("BTN_TO_LIST"),
"LINK" => "/bitrix/admin/coupons_list.php?lang=".LANG,
"ICON" => ""
];
$context = new \CAdminContextMenu($menu);
$context->Show();
*/
}
protected function getDiscountList()
{
$q = DiscountTable::query()
->addOrder('ID', 'desc')
->setSelect(['ID', 'NAME', 'ACTIVE']);
$discounts = [];
$discountList = $q->exec();
while ($discount = $discountList->fetch()) {
$discounts[] = $discount;
}
return $discounts;
}
protected function getLinks()
{
return [
'new_discount' => '/bitrix/admin/sale_discount_edit.php?lang=' . LANGUAGE_ID
];
}
protected function getCouponTypes()
{
return DiscountCouponTable::getCouponTypes(true);
}
}
@@ -0,0 +1,5 @@
<?php
$MESS['MAXIMASTER:COUPANDA.COUPON.GENERATOR:COMPONENT_NAME'] = 'Coupon generator';
$MESS['MAXIMASTER:COUPANDA.COUPON.GENERATOR:COMPONENT_DESCRIPTION'] = 'Used to generate promocodes with Coupanda! module';
$MESS['MAXIMASTER:COUPANDA.COUPON.GENERATOR:VENDOR_NAME'] = 'Maximaster';
@@ -0,0 +1,5 @@
<?php
$MESS['MAXIMASTER:COUPANDA.COUPON.GENERATOR:COMPONENT_NAME'] = 'Генератор купонов';
$MESS['MAXIMASTER:COUPANDA.COUPON.GENERATOR:COMPONENT_DESCRIPTION'] = 'Предназначен для генерации купонов средствами модуля Coupanda!';
$MESS['MAXIMASTER:COUPANDA.COUPON.GENERATOR:VENDOR_NAME'] = 'Максимастер';
@@ -0,0 +1,116 @@
<?php
namespace Maximaster\Coupanda;
/**
* @var \CAdminTabControl $tabControl
*/
?>
<form name="coupon_generator_form">
<input type="hidden" name="ajax_action" value="generation_start">
<input type="hidden" name="lang" value="<?=LANGUAGE_ID?>">
<?=bitrix_sessid_post();?>
<tr>
<td>
<?=getHint('discount_id', 'Все сгенерированные купоны попадут в тот пул, который выбран в данной настройке. Под пулом купонов понимается Правило работы корзины');?>
<label for="discount_id">Выбрать пул:</label></td>
<td>
<select name="DISCOUNT_ID" id="discount_id">
<?if (!empty($arResult['DISCOUNTS'])):?>
<?foreach ($arResult['DISCOUNTS'] as $discount):?>
<option value="<?=$discount['ID']?>">[<?=$discount['ID']?>] <?=$discount['NAME']?></option>
<?endforeach;?>
<?else:?>
<option>Нет доступных пулов</option>
<?endif;?>
</select>
</td>
</tr>
<tr>
<td></td>
<td>или <a href="<?=$arResult['LINKS']['new_discount']?>">создать новый пул</a></td>
</tr>
<tr>
<td>
<?=getHint('template', 'Шаблон представляет из себя набор символов, в котором некоторые символы являются статическими, а некоторые - динамическими. Подробнее о шаблонах');?>
<label for="template">Шаблон купона:</label></td>
<td>
<input type="text" id="template" name="TEMPLATE">
</td>
</tr>
<tr>
<td></td>
<td>
<?=\BeginNote();?>
Шаблон купона - это простой набор символов. Часть символов являются зарезервированными, и они могут быть
использованы в шаблоне для формирования динамически генерируемой части. Перечень зарезервированных символов:<br>
& - английская буква<br>
@ - русская буква<br>
# - число от 0 до 9<br>
<?=\EndNote();?>
</td>
</tr>
<tr>
<td>
<?=getHint('count', 'Сколько купонов нужно сгенерировать по выбранному шаблону');?>
<label for="count">Количество для генерации:</label></td>
<td>
<input type="text" id="count" name="COUNT">
</td>
</tr>
<tr>
<td>
<?=getHint('coupon_type', 'Подробнее о типах купонов можно прочитать в <a href="https://dev.1c-bitrix.ru/learning/course/?COURSE_ID=42&LESSON_ID=3453" target="_blank">документации</a>');?>
<label for="coupon_type">Тип купона:</label></td>
<td>
<select name="COUPON_TYPE" id="coupon_type">
<?foreach ($arResult['COUPON_TYPES'] as $typeCode => $type):?>
<option value="<?=$typeCode?>"><?=$type?></option>
<?endforeach;?>
</select>
</td>
</tr>
<tr>
<td>
<?=getHint('coupon_period', 'Период жизни купона выставляется с помощью двух дат - даты начала и даты окончания. Купон считается неограниченным по времени жизни с той стороны, с которой дата не заполнена');?>
<label for="coupon_period">Период жизни купона:</label>
</td>
<td>
<?=\CalendarPeriod("ACTIVE_FROM", null, "ACTIVE_TO", null, "coupon_generator_form", "N", "", "", 20);?>
</td>
</tr>
<tr>
<td>
<?=getHint('max_use_count', 'Сколько раз покупатели можно воспользоваться купоном. Актуально только для многоразовых купонов');?>
<label for="max_use_count">Максимальное количество использований:</label></td>
<td>
<input type="text" id="max_use_count" name="MAX_USE_COUNT">
</td>
</tr>
<tr>
<td>
<?=getHint('active', 'Все купоны из пула могут быть либо активными, либо неактивными');?>
<label for="active">Активность:</label></td>
<td>
<input type="checkbox" id="active" name="ACTIVE" checked>
</td>
</tr>
<tr>
<td>
<?=getHint('user', 'Все купоны из пула будут принадлежать одному человеку и только он сможет ими воспользоваться');?>
<label for="user">Владелец:</label></td>
<td>
<?=\FindUserID('USER', null, '', 'coupon_generator_form');?>
</td>
</tr>
<tr>
<td></td>
<td>
<input type="button" id="js-coupon-generation-preview" value="Превью">
<input type="button" class="adm-btn-save" id="js-start-coupon-generation" value="Начать генерацию">
</td>
</tr>
</form>
Oops, something went wrong.

0 comments on commit f404260

Please sign in to comment.