UMI.CMS. Дисконтная карта пользователю

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

Для начала нужно перейти в модуль шаблон данных и добавить новый шаблон данных, который будет дочерним шаблону «Правила скидок». Название нового шаблона «Номер карты»(делаем как показано на скриншетах):

UMI.CMS. Дисконтная карта пользователю

UMI.CMS. Дисконтная карта пользователю

У вас должно получиться вот так:

UMI.CMS. Дисконтная карта пользователю

Далее нужно перейти в справочники и найти там «Типы правил для скидок», нажать на иконку «глаз» и перейти к просмотру содержимого справочника.

UMI.CMS. Дисконтная карта пользователю

Перейдя в справочник, нужно добавить новый, нажать на иконку «карандаш» и перейти к редактированию элемента справочника.

UMI.CMS. Дисконтная карта пользователю

Далее нужно выставить следующие настойки:

  • Название - Дисконтная карта
  • Идентификатор  - counts
  • Тип данных (id) — id вашего типа данных «номер карты»
  • Допустимые типы скидки — на заказ

UMI.CMS. Дисконтная карта пользователю

Далее в типе данных «Пользователь» необходимо добавить поле для номера дисконтной карты. Пользователь будет заполнить его в личном кабинете.

Я создал новую группу «Накопительная карта». В группу добавил поле типа строка, название — «Номер дисконтной карты», идентификатор — «card_discount»:

UMI.CMS. Дисконтная карта пользователю

Далее, чтобы добавить новую скидку, вам нужно создать файл 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/) и добавьте новую скидку:
UMI.CMS. Дисконтная карта пользователю

UMI.CMS. Дисконтная карта пользователю

UMI.CMS. Дисконтная карта пользователю

У меня был установлены следующие опции:

  • Название — Накопительная карта
  • Тип скидки — На заказ (Данный тип скидок используется для расчета итоговой цены заказа)
  • Модификатор цены — Фиксированный размер
  • Правила валидации — Номер карты

Для того, чтобы назначить скидку по карте вашему пользователю, следует проверить, а ввел корректные ли он данные. Для этого нужно написать кастомный макрос для модуля «Шаблоны данных».

В файл __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:alex@pontyk.com.ua">alex@pontyk.com.ua</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, то у вас пользователь сразу получит возможность вводить номер карты в личном кабинете:
UMI.CMS. Дисконтная карта пользователю
Если свой шаблон, но нужно будет поколдовать 😉

Если честно, я не представляю, ваш шаблон, я вам дам исходник своего шаблона ввода номера дисконтной карты, я уверен, что вы разберетесь:

<?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>

Все секции шаблона я прокомментировал. И он у меня не большой, я уверен, что вы все поймете. Если будут вопросы, с радостью обсужу в комментариях к данной статье.

Для добавления номеров карт, вам нужно нажать на иконку «глаз» у типа данных «номер карты»:
UMI.CMS. Дисконтная карта пользователю