UMI.CMS. Дисконтная карта пользователю
Задача следующая, вы можете выдавать пользователям дисконтную карту, он зайдя в личный кабинет активирует ее.
Пример реализации подобной задачи рассмотрен на wiki umi.cms. Но я если честно читая эту заметку ничего не понял, пока не написал и не пообщался со службой заботы UMI.CMS.

Для начала нужно перейти в модуль шаблон данных и добавить новый шаблон данных, который будет дочерним шаблону «Правила скидок». Название нового шаблона «Номер карты»(делаем как показано на скриншетах):
У вас должно получиться вот так:
Далее нужно перейти в справочники и найти там «Типы правил для скидок», нажать на иконку «глаз» и перейти к просмотру содержимого справочника.
Перейдя в справочник, нужно добавить новый, нажать на иконку «карандаш» и перейти к редактированию элемента справочника.
Далее нужно выставить следующие настойки:
- Название - Дисконтная карта
- Идентификатор - counts
- Тип данных (id) — id вашего типа данных «номер карты»
- Допустимые типы скидки — на заказ
Далее в типе данных «Пользователь» необходимо добавить поле для номера дисконтной карты. Пользователь будет заполнить его в личном кабинете.
Я создал новую группу «Накопительная карта». В группу добавил поле типа строка, название — «Номер дисконтной карты», идентификатор — «card_discount»:
Далее, чтобы добавить новую скидку, вам нужно создать файл counts.php в папке /classes/modules/emarket/classes/discounts/rules/ и добавить в него следующее содержимое:
<?php
class countsDiscountRule extends discountRule implements orderDiscountRule {
public function validateOrder(order $order) {
$permissions = permissionsCollection::getInstance();
$currentUserId = $permissions->getUserId();
$objects = umiObjectsCollection::getInstance();
$userObject = $objects->getObject($currentUserId);
if($userObject instanceof umiObject) {
$cardNum = $userObject->getValue("card_discount"); /* id поля номер карты с типе данных "пользователь" */
$nums = new selector ('objects');
$nums->types('object-type')->id('132'); /* id справочника "номер карты" */
$nums->where('name')->equals($cardNum);
$res = $nums->result;
if( count($res) ) return true;
else return false;
}
}
};
?>
Для проверки корректности работы перейдите в раздел «Скидки» модуля «Интернет магазин»(/admin/emarket/discounts/) и добавьте новую скидку:

У меня был установлены следующие опции:
- Название — Накопительная карта
- Тип скидки — На заказ (Данный тип скидок используется для расчета итоговой цены заказа)
- Модификатор цены — Фиксированный размер
- Правила валидации — Номер карты
Для того, чтобы назначить скидку по карте вашему пользователю, следует проверить, а ввел корректные ли он данные. Для этого нужно написать кастомный макрос для модуля «Шаблоны данных».
В файл __custom.php (путь — \classes\modules\data) нужно добавить код:
/*
* @param Number $guide_id - справочник где хранятся номера карт
* @param String $cart_num - номер дисконтной карты из профиля пользователя
*/
public function checkDiscountCart($guide_id, $cart_num) {
$guide_items = umiObjectsCollection::getInstance()->getGuidedItems($guide_id);
$key = array_search($cart_num, $guide_items);
if($key == '') {
$str = '<div class="checkDiscountCart"><p>Указанный Вами номер дисконтной карты является НЕ действительным.</p>';
$str .= '<p>Обратитесь в нашу поддержку и сообщите о своей проблеме.</p>';
$str .= '<p>Вы можете написать на почту <a href="mailto:[email protected]">[email protected]</a>';
$str .= ' или через форму <a href="/contacts/"> контактной связи</a></p></div>';
return $str;
}
}
Также нужно добавить файл permissions.custom.php (путь — \classes\modules\data) с содержимым:
<?php
$permissions = Array('main' => Array('checkDiscountCart'));
?>
Параметры которые принимает функция я прокомментировал.
Теперь нужно реализовать возможность ввода номера карта пользователем. Хочу вам напомнить, что я работаю с XSLT-шаблонизатором и шаблоном DemoDizzy, я об этом писал в статье UMI.CMS Товары данной коллекции.
1. Нужно открыть файл default.xsl (\templates\demodizzy\xslt\) и перед подключением модулей добавить строчку:
<xsl:variable name="user-discount_cart" select="$user-info//property[@name = 'card_discount']/value" />
Здесь создается переменная, которая содержит значение поля «номер карты», если пользователь указывал его.
2. Если вы используете шаблон DemoDizzy, то у вас пользователь сразу получит возможность вводить номер карты в личном кабинете:

Если свой шаблон, но нужно будет поколдовать 😉
Если честно, я не представляю, ваш шаблон, я вам дам исходник своего шаблона ввода номера дисконтной карты, я уверен, что вы разберетесь:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xsl:stylesheet SYSTEM "ulang://i18n/constants.dtd:file">
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:umi="http://www.umi-cms.ru/TR/umi"
xmlns:xlink="http://www.w3.org/TR/xlink">
<!-- Пользовательские настройки -->
<xsl:template match="udata[@method = 'settings']" mode="user-settings">
<!-- Проверка, активирована ли дисконтная карта -->
<xsl:choose>
<xsl:when test="$user-discount_cart = ''">
<form enctype="multipart/form-data" method="post" action="{$lang-prefix}/users/settings_do/">
<table>
<tr>
<td class="labels" colspan="2">
<h2>Дисконтная карта</h2>
</td>
</tr>
<xsl:apply-templates select="document(concat('udata://data/getEditForm/', $user-id, '/(0)/(nakopitelnaya_karta)'))/udata" mode="personal-info" />
<tr>
<td class="labels" />
<td class="inputs">
<input type="submit" class="button" value="&save-changes;" />
</td>
</tr>
</table>
</form>
</xsl:when>
<xsl:otherwise>
<h2>Дисконтная карта</h2>
<p>
Номер Вашей дисконтной карты: <b><xsl:value-of select="$user-discount_cart" /></b>
<!-- здесь происходит ображение к катомному макросу модуля "Шаблон данных" -->
<xsl:apply-templates select="document(concat('udata://data/checkDiscountCart/(152)/(', $user-discount_cart, ')'))/udata" mode="checkDiscountCart" />
</p>
</xsl:otherwise>
</xsl:choose>
<!-- / Проверка, активирована ли дисконтная карта -->
<form enctype="multipart/form-data" method="post" action="{$lang-prefix}/users/settings_do/">
<table>
<tr>
<td class="labels" colspan="2">
<h2>Изменить персональные данные</h2>
</td>
</tr>
<xsl:apply-templates select="document(concat('udata://data/getEditForm/', $user-id, '/(0)/(short_info)'))/udata" mode="personal-info" />
<tr>
<td class="labels" />
<td class="inputs">
<input type="submit" class="button" value="&save-changes;" />
</td>
</tr>
</table>
</form>
<form enctype="multipart/form-data" method="post" action="{$lang-prefix}/users/settings_do/">
<table class="tbl-user-settings">
<tr style="display: none">
<td class="labels">
<xsl:text>&login;:</xsl:text>
</td>
<td class="inputs">
<input type="text" name="login" class="textinputs" disabled="disabled" value="{$user-info//property[@name = 'login']/value}" />
</td>
</tr>
<tr style="display: none">
<td class="labels">
<xsl:text>&e-mail;:</xsl:text>
</td>
<td class="inputs">
<input type="text" name="email" class="textinputs" disabled="disabled" value="{$user-info//property[@name = 'e-mail']/value}" />
</td>
</tr>
<tr>
<td class="labels" colspan="2">
<h2>Изменить пароль</h2>
</td>
</tr>
<tr>
<td class="labels">
<label for="password"><xsl:text>&password;:</xsl:text></label>
</td>
<td class="inputs">
<input type="password" name="password" id="password" />
</td>
</tr>
<tr>
<td class="labels">
<label for="password_confirm"><xsl:text>&password-confirm;:</xsl:text></label>
</td>
<td class="inputs">
<input type="password" name="password_confirm" id="password_confirm" />
</td>
</tr>
<tr>
<td class="labels" />
<td class="inputs">
<input type="submit" class="button" value="&save-changes;" />
</td>
</tr>
</table>
</form>
</xsl:template>
<!-- Отображение ошибки при заполнение формы дисконтной карты -->
<xsl:template match="udata[@method = 'checkDiscountCart']" mode="checkDiscountCart">
<xsl:value-of select="." disable-output-escaping="yes" />
</xsl:template>
<!-- / Отображение ошибки при заполнение формы дисконтной карты -->
<!-- Отображение элементов для редактирования данных -->
<xsl:template match="udata[@method = 'getEditForm']" mode="personal-info">
<xsl:apply-templates select="group" mode="form" />
</xsl:template>
<xsl:template match="group" mode="form">
<xsl:apply-templates select="field" mode="form-input" />
</xsl:template>
<xsl:template match="field[@type = 'string']" mode="form-input">
<tr>
<td class="labels">
<label for="{@input_name}"><xsl:value-of select="concat(@title, ':')" /></label>
</td>
<td class="inputs">
<input type="text" name="{@input_name}" id="{@input_name}" value="{.}" />
</td>
</tr>
</xsl:template>
<xsl:template match="field[@type = 'text']" mode="form-input">
<tr>
<td class="labels">
<label for="{@input_name}"><xsl:value-of select="concat(@title, ':')" /></label>
</td>
<td class="inputs">
<textarea name="{@input_name}" id="{@input_name}">
<xsl:value-of select="." />
</textarea>
</td>
</tr>
</xsl:template>
<!-- / Отображение элементов для редактирования данных -->
<!-- / Пользовательские настройки -->
</xsl:stylesheet>
Все секции шаблона я прокомментировал. И он у меня не большой, я уверен, что вы все поймете. Если будут вопросы, с радостью обсужу в комментариях к данной статье.
Для добавления номеров карт, вам нужно нажать на иконку «глаз» у типа данных «номер карты»:





