Добавить поле в почтовый шаблон.

После оформления заказа, покупателю приходит письмо с уведомлением, о сделанном заказе и данными, которые он указал.

Задача: Добавить в почтовый шаблон CMS 1c-битрикс «о новом заказе» поля: «Адрес доставки», «Способ доставки», «Комментарии заказчика», «телефон».

Решение:

Использовать метод, описанный в этой статье не рекомендуется!!! Есть метод проще, правильнее в этой статье.

Способ решения данной проблемы не единственный.

Оформление заказа у меня на сайте происходит через компонент Одношаговое оформление заказа(bitrix:sale.order.ajax).

Нам предстоит кастомизация этого компонента. Чтобы изменения не затерлись, при следующем обновлении ядра, нужно скопировать компонент в другое пространство имён и смело издеваться над ним =) .

Создали новое пространство имён(в моём случае оно называется demo и имеет вот какой путь /bitrix/components/demo/sale.order.ajax/). Находим там файл «component.php» .

В моём файле, кусок кода, отвечающий за формирования массива для почтового шаблона, начинается с 2060 строки и обозначен комментарием:


// mail message

Если не нашли его в своём файле, то ориентируйтесь по строке, содержащей отправку письма:


$event->Send

Эта функция принимает три аргумента:

  1. Идентификатор типа почтового события.
  2. Идентификатор сайта, либо массив идентификаторов сайта.
  3. Массив полей типа почтового события идентификатор которого задается в параметре event_type. Массив имеет следующий формат: array(«поле»=>»значение» [, …]).
  4. Отправить ли копию письма на адрес указанный в настройках главного модуля в поле «E-Mail адрес или список адресов через запятую на который будут дублироваться все исходящие сообщения».Необязательный. По умолчанию «Y».
  5. Идентификатор почтового шаблона по которому будет отправлено письмо.Если данный параметр не задан, либо равен «», то письма будут отправлены по всем шаблонам привязанным к типу почтового события, идентификатор которого задается в параметре event_type, а также привязанных к сайту(ам) идентификатор которого указан в параметре site.Необязательный. По умолчанию — «».

Моя функция имеет вид:


$event->Send($eventName, SITE_ID, $arFields, "N");

Чуть выше я определил переменные:


$eventName = "SALE_NEW_ORDER";// тип почтового события

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

type-of-template-mail-
тип почтового события

SITE_ID – глобальная константа, отвечающая за текущий сайт.

На 3-ем параметре остановимся поподробнее, как раз он нас  больше всего интересует. Там хранится массив данных, который будет передаваться в почтовый шаблон bitrix. Чтобы не перегружать вас информацией оставлю в массиве только поля, которые нужно добавить.

Массив полей для почтового шаблона.


$arFields = Array(

"ORDER_LIST" => $strOrderList,

"DELIVERY_LOCATION" => $locat,

"DELIVERY_PRICE" => $arResult["DELIVERY_PRICE"],

"TELEFON" => $arUserResult["ORDER_PROP"][33],

"ADRES" => $arUserResult["ORDER_PROP"][38],

"DELIVERY_NAME" => $dostav,

"ORDER_DESCRIPTION" => $arUserResult["ORDER_DESCRIPTION"]

);

Как вы заметили , для телефона и адреса, я передал странные переменные с индексами. В массиве число   33 это ID свойства «телефон»(PHONE), а 38 ID  «адреса»(ADDRESS), которые вы можете просмотреть в админке:  Магазин-> Настройки-> Свойства заказа-> Список свойств.

свойства-заказа-битрикс
Свойства заказа 1с-битрикс.

Заранее нужно заполнить переменные $locat и $dostav.

Выбранное пользователем местоположение (регион и город) получаем с помощью функции CSaleLocation::GetByID.


// вытаскиваем местоположение

$arLocs = CSaleLocation::GetByID($arUserResult["ORDER_PROP"][37], LANGUAGE_ID);

$locat=$arLocs[REGION_NAME].','.$arLocs[CITY_NAME];

Как я описывал выше в $arUserResult[«ORDER_PROP»][25]  25 это ID

свойства «Местоположение»(« LOCATION»).Таким образом и определяются другие данные введенные пользователем.

Способ доставки определяем через 1с-Битрикс API  CSaleDelivery::GetByID.


// получаем способ доставки

$arDeliv = CSaleDelivery::GetByID($arUserResult["DELIVERY_ID"]);

if ($arDeliv)

{

$dostav= arDeliv["NAME"];

}

Если вас не устраивает вывод заказанных товаров, цены и количества, то нужно редактировать массив $strOrderLis. Тут уже дело вкуса.

Еще раз посмотрим на функцию:


$event->Send($eventName, SITE_ID, $arFields, "N");

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

Так же есть возможность разделить пользователей на физ. лица и юр. лица. Нужно перед заполнением массива $arFields поставить проверку на текущего типа плательщика. Предварительно смотрим по адресу «Магазин-> Настройки-> Типы плательщиков» , какие группы плательщиков имеются:

типы-плательщиков-битрикс
Группы плательщиков bitrix.
  1. Физическое лицо ID=3
  2. Юридическое лицо ID=4 (для текущего сайта s1)

// проверка что юрид. лицо

$arTypeFace = CSaleOrder::GetByID($arOrder["ACCOUNT_NUMBER"]);

if ($arTypeFace["PERSON_TYPE_ID"] == 4)

{

// заполняем поля для юрид. лица

}

В результате у меня получилось следующее:

<?// mail message

if (empty($arResult["ERROR"]))
{
$arTypeFace = CSaleOrder::GetByID($arOrder["ACCOUNT_NUMBER"]);

if ($arTypeFace["PERSON_TYPE_ID"] == 4)
{
/* вытаскиваем местоположение*/

$arLocs = CSaleLocation::GetByID($arUserResult["ORDER_PROP"][37], LANGUAGE_ID);

$locat=$arLocs[REGION_NAME].','.$arLocs[CITY_NAME];

/*end вытаскиваем местоположение*/

/* вытаскиваем способ доставки*/

$arDeliv = CSaleDelivery::GetByID($arUserResult["DELIVERY_ID"]);

if ($arDeliv)

{
$dostav="Доставка ".$arDeliv["NAME"];
}

/*end вытаскиваем способ доставки*/

$strOrderList = "";

$dbBasketItems = CSaleBasket::GetList(

array("NAME" => "ASC"),

array("ORDER_ID" => $arResult["ORDER_ID"]),

false,

false,

array("ID", "NAME", "QUANTITY", "PRICE", "CURRENCY")

);

while ($arBasketItems = $dbBasketItems->Fetch())

{
$strOrderList .= $arBasketItems["NAME"]." - ".$arBasketItems["QUANTITY"]." ".GetMessage("SOA_SHT").": ".SaleFormatCurrency($arBasketItems["PRICE"], $arBasketItems["CURRENCY"]);

$strOrderList .= "\n";
}

$cssProp='';

$arFields = Array(

"ORDER_ID" => $arOrder["ACCOUNT_NUMBER"],

"ORDER_DATE" => Date($DB->DateFormatToPHP(CLang::GetDateFormat("SHORT", SITE_ID))),

"ORDER_USER" => ( (strlen($arUserResult["PAYER_NAME"]) > 0) ? $arUserResult["PAYER_NAME"] : $USER->GetFormattedName(false)),

"PRICE" => SaleFormatCurrency($orderTotalSum, $arResult["BASE_LANG_CURRENCY"]),

"BCC" => COption::GetOptionString("sale", "order_email", "order@".$SERVER_NAME),

"EMAIL" => "E-mail заказчика: ".(strlen($arUserResult["USER_EMAIL"])>0 ? $arUserResult["USER_EMAIL"] : $USER->GetEmail()),

"ORDER_LIST" => $strOrderList,

"SALE_EMAIL" => COption::GetOptionString("sale", "order_email", "order@".$SERVER_NAME),

"DELIVERY_PRICE" => $arResult["DELIVERY_PRICE"],

"DELIVERY_LOCATION" => "Адрес заказчика:".$locat,

"TELEFON" => "Телефон заказчика: ".$arUserResult["ORDER_PROP"][33],

"ADRES" => $arUserResult["ORDER_PROP"][38],

"DELIVERY_NAME" => $dostav,

"ORDER_DESCRIPTION" => $arUserResult["ORDER_DESCRIPTION"],

"NAME_COMPANY" => $cssProp.'Название компании:'.$arUserResult["ORDER_PROP"][27].' ',

"LEGAL_ADRESS" => $cssProp.'Юридический адрес компании:'.$arUserResult["ORDER_PROP"][28].' ',

"INN" => $cssProp.'ИНН:'.$arUserResult["ORDER_PROP"][29].' ',

"KPP" => $cssProp.'КПП:'.$arUserResult["ORDER_PROP"][30].' '

);

$eventName = "SALE_NEW_ORDER";

$bSend = true;

foreach(GetModuleEvents("sale", "OnOrderNewSendEmail", true) as $arEvent)

if (ExecuteModuleEventEx($arEvent, Array($arResult["ORDER_ID"], $eventName, $arFields))===false)

$bSend = false;

if($bSend)
{
$event = new CEvent;

$event->Send($eventName, SITE_ID, $arFields, "N");
}
}
}
?>

Теперь в имеющийся Почтовый шаблон нужно добавить поля которые мы передали(см. первый рисунок., там я их объявил, это не обязательная процедура, но упрощающая дальнейшую работу с полями, которые мы передали).

Не поленитесь прочитать статью о том Как зарегистрировать домен дешево? Экономия нужно везде ребятки.

ПоделитьсяShare on Facebook0Share on VKShare on Google+0Tweet about this on TwitterShare on LinkedIn0Pin on Pinterest0

19 комментариев

  • Hrianagks:

    Огромное спасибо автору материала! Много полезного у Вас на сайте. Добавил в ридер теперь буду почаще заходить.

  • Денис:

    Добрый день!

    Сделал как у Вас написано, почтовое событие приходит, но поля которые я добавил пустые, видимо не передаются значения, не могу понять почему, может что то еще надо?
    Спасибо!

    • shapito27:

      Здравствуйте, Денис.
      Во-первых проверьте правильные ли id вы поставили в $arUserResult[«ORDER_PROP»][id]. Например: $arUserResult[«ORDER_PROP»][38]
      точно ли что 38 это свойство адрес у юридического лица?
      Во-вторых, если поставили условие на тип плательщика, то проверьте правильный ли id плательщика ?
      В-третьих, правильно ли подставили в почтовом шаблоне? Если в массиве $arFields свойство названо «ADRES», то в почтовом шаблоне нужно писать его #ADRES#

      • Денис:

        Все проверил, все правильно, я так думаю если бы свойства были не правильными то приходило бы в таком виде #ADRES#, а так он передает пустое поле.
        Проверку на юр и физ лицо вроде бы он отрабатывает, так как с физ лица приходят свойства в виде #ADRES#.
        И еще такой вопросик как разделить почтовые события на юр и физ лица, надо создать новый почтовый шаблон?

        • shapito27:

          можно разными методами, создайте новый почтовый шаблон и посмотрите 5-ый аргумент в $event->Send тут
          и используйте условие по типам плательщиков.
          p.s. если до сих пор пустые поля скиньте код, посмотрим

          • Денис:

            // mail message
            if (strlen($arResult[«ERROR_MESSAGE»]) «ASC»),
            array(«ORDER_ID» => $arResult[«ORDER_ID»]),
            false,
            false,
            array(«ID», «NAME», «QUANTITY»)
            );
            while ($arBasketItems = $dbBasketItems->Fetch())
            {
            $strOrderList .= $arBasketItems[«NAME»].» — «.$arBasketItems[«QUANTITY»].» «.GetMessage(«SALE_QUANTITY_UNIT»);
            $strOrderList .= «\n»;
            }
            // проверка что юрид. лицо

            $arTypeFace = CSaleOrder::GetByID($arOrder[«ACCOUNT_NUMBER»]);

            if ($arTypeFace[«PERSON_TYPE_ID»] == 2)

            {
            $arFields = Array(
            «ORDER_ID» => $arOrder[«ACCOUNT_NUMBER»],
            «ORDER_DATE» => Date($DB->DateFormatToPHP(CLang::GetDateFormat(«SHORT», SITE_ID))),
            «ORDER_USER» => ( (strlen($arResult[«PAYER_NAME»]) > 0) ? $arResult[«PAYER_NAME»] : $USER->GetFormattedName(false) ),
            «PRICE» => SaleFormatCurrency($totalOrderPrice, $arResult[«BASE_LANG_CURRENCY»]),
            «BCC» => COption::GetOptionString(«sale», «order_email», «order@».$SERVER_NAME),
            «ADRES» => implode(‘, ‘, $arAddress),
            «TELEFON» => $arProps[‘PHONE’][‘VALUE’],
            «EMAIL» => $arResult[«USER_EMAIL»],
            «NAME_COMPANY» => (isset($arProps[‘F_COMPANY_NAME’]) ? ‘Организация: ‘.$arProps[‘F_COMPANY_NAME’][‘VALUE’].»\n» : »),
            «LEGAL_ADRESS» => $arUserResult[«ORDER_PROP»][8],
            «INN» => $arResult[«ORDER_PROP»][15],
            «KPP» => $arResult[«ORDER_PROP»][16],
            «ORDER_DESCRIPTION» => $arUserResult[«ORDER_DESCRIPTION»],
            «ORDER_LIST» => $strOrderList,
            «SALE_EMAIL» => COption::GetOptionString(«sale», «order_email», «order@».$SERVER_NAME)
            );
            }
            // проверка что физ. лицо

            $arTypeFace = CSaleOrder::GetByID($arOrder[«ACCOUNT_NUMBER»]);

            if ($arTypeFace[«PERSON_TYPE_ID»] == 1)

            {
            $arFields = Array(
            «ORDER_ID» => $arOrder[«ACCOUNT_NUMBER»],
            «ORDER_DATE» => Date($DB->DateFormatToPHP(CLang::GetDateFormat(«SHORT», SITE_ID))),
            «ORDER_USER» => ( (strlen($arResult[«PAYER_NAME»]) > 0) ? $arResult[«PAYER_NAME»] : $USER->GetFormattedName(false) ),
            «PRICE» => SaleFormatCurrency($totalOrderPrice, $arResult[«BASE_LANG_CURRENCY»]),
            «BCC» => COption::GetOptionString(«sale», «order_email», «order@».$SERVER_NAME),
            «ADRES» => $arUserResult[«ORDER_PROP»][5],
            «TELEFON» => «Телефон заказчика: «.$arUserResult[«ORDER_PROP»][23],
            «EMAIL» => $arResult[«USER_EMAIL»],
            «ORDER_LIST» => $strOrderList,
            «SALE_EMAIL» => COption::GetOptionString(«sale», «order_email», «order@».$SERVER_NAME)
            );
            }
            $eventName = «SALE_NEW_ORDER»;

            $bSend = true;
            foreach(GetModuleEvents(«sale», «OnOrderNewSendEmail», true) as $arEvent)
            if (ExecuteModuleEventEx($arEvent, Array($arResult[«ORDER_ID»], &$eventName, &$arFields))===false)
            $bSend = false;

            if($bSend)
            {
            $event = new CEvent;
            $event->Send($eventName, SITE_ID, $arFields, «N»);
            }

            CSaleMobileOrderPush::send(«ORDER_CREATED», array(«ORDER_ID» => $arFields[«ORDER_ID»]));
            }
            if (strlen($arResult[«ERROR_MESSAGE»]) 0)
            $arResult[«CurrentStep»] = 5;
            }
            }
            }

          • shapito27:

            Не приходит только адрес? Или остальные поля тоже?
            попробуйте локализовать ошибку, сначала вне условия проверки на тип плательщика, задайте конкретный адрес «ADRES» =>»ул.Мира»
            если значение подставится, попробуйте внести в условие, если оба варианта сработают, то ошибка тут:
            «ADRES» => $arUserResult[«ORDER_PROP»][5]
            «ADRES» => implode(‘, ‘, $arAddress),

          • Деним:

            Новые поля все не приходят.
            Значение подставляется, правда иероглифами, но все таки подставляет.
            Может быть такое что значения формируются где то еще? Или может быть позже этого события, блин уже всю голову сломал(

  • Алекс:

    Напишите пжл подробнее что делать с папкой sale.order.ajax куда ёё ложить, где прописывать

    • shapito27:

      Сейчас у вас sale.order.ajax тут :
      /bitrix/components/bitrix/sale.order.ajax/
      создаем новую папку(новое пространство имен, которое при обновлении не затрется) например «new»(её адрес /bitrix/components/new/).
      в эту папку «new» копируем папку sale.order.ajax из
      /bitrix/components/bitrix/.
      Когда это проделаете замените уже на странице оформления заказа компонент sale.order.ajax. Например через визуальный редактор в режиме кода замените этот кусок:
      < ?$APPLICATION->IncludeComponent(
      «bitrix:sale.order.ajax»,
      «template»,…..
      на этот:
      < ?$APPLICATION->IncludeComponent(
      «new:sale.order.ajax»,
      «template»,…..

  • Александр:

    Добрый вечер! Замечательное руководство, очень доходчивое.
    Но у меня подтянулись названия настраиваемых служб доставки, а названия автоматизированных не хотят.
    Не подскажете куда смотреть?

    • shapito27:

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

  • Дмитрий:

    Спасибо огромное! Воспользовался Вашей инструкцией — всё получилось!..)) Причем php редактировал впервые в жизни…))

  • Виктор:

    Здравствуйте спасибо за статью, очень полезный материал! Но после обновления на 16 версию, данный метод не работает. Есть варианты как это вылечить shapito27?

  • Влад:

    Здравствуйте!
    Объясните чайнику.
    У меня файл component.php находится в папке sale.order.full
    а в папке sale.order.ajax такого файла нет . . . как быть? как поступить?
    Решение по последней ссылке?

Добавить комментарий