Профиль покупателя - типы плательщика, повторный заказ, правка из кода
Профиль покупателя хранит реквизиты и данные доставки, и магазин подставляет их при следующем заказе. Разбираемся, откуда профиль берётся и как поправить его из кода.
Решение
Смотрим профили одного покупателя:
\Bitrix\Main\Loader::includeModule('sale');$rs = \CSaleOrderUserProps::GetList(['DATE_UPDATE' => 'DESC'], ['USER_ID' => $userId], // профили одного покупателя false, false, ['ID', 'NAME', 'PERSON_TYPE_ID']);while ($profile = $rs->Fetch()) { printf("%-4d %-24s тип плательщика %d\n", $profile['ID'], $profile['NAME'], $profile['PERSON_TYPE_ID']);}Профиль создаётся только после оформления заказа, поэтому у нового покупателя список пуст. Профилей у покупателя столько, сколько на сайте заведено типов плательщика: по умолчанию их два.
Читаем значения выбранного профиля:
$rs = \CSaleOrderUserPropsValue::GetList([], ['USER_PROPS_ID' => $profileId], false, false, ['ID', 'ORDER_PROPS_ID', 'NAME', 'VALUE']);while ($value = $rs->Fetch()) { printf("%-20s = %s\n", $value['NAME'], $value['VALUE']);}Значение связывается с профилем через USER_PROPS_ID, а с полем формы заказа -
через ORDER_PROPS_ID. Поэтому один и тот же телефон в двух профилях - это две
разные записи.
Смотрим, какие поля ждёт тип плательщика:
$rs = \CSaleOrderProps::GetList([], ['PERSON_TYPE_ID' => $personTypeId], false, false, ['ID', 'CODE', 'NAME', 'REQUIED']); // да, поле пишется REQUIEDwhile ($prop = $rs->Fetch()) { printf("%-4d %-14s обязательное=%s\n", $prop['ID'], $prop['CODE'], $prop['REQUIED']);}Идентификатор свойства из этой выборки и уходит в ORDER_PROPS_ID значения
профиля. Опечатка в имени поля обязательности живёт в старом ядре с самого
начала и закреплена навсегда.
Добавляем в профиль недостающее поле:
\CSaleOrderUserPropsValue::Add([ 'USER_PROPS_ID' => $profileId, // к какому профилю относится значение 'ORDER_PROPS_ID' => $propId, // какое поле формы заказа заполняем 'NAME' => 'Телефон', 'VALUE' => '+7 900 123-45-67',]);Значения профиля заполняет сам покупатель при штатном оформлении, но заказ из своей формы этого не делает. Тогда и запись профиля, и каждое её значение создаёт код своего обработчика.
Правим значение в профиле:
\CSaleOrderUserPropsValue::Update($valueId, [ 'ID' => $valueId, // ID дублируется внутри массива полей 'VALUE' => '+7 900 765-43-21',]);Дублирование идентификатора внутри массива полей - это требование легаси-API, а
не описка в примере. Без второй копии ID правка молча не доезжает до базы, и
ошибки при этом нет.
Меняем тип плательщика в готовом заказе:
$order = \Bitrix\Sale\Order::load($orderId);$order->setPersonTypeId($companyTypeId); // коллекция свойств собирается заново$props = $order->getPropertyCollection();$props->getItemByOrderPropertyId($innPropId)->setValue('7701234567');$order->save();Свойства заказа принадлежат типу плательщика, поэтому смена типа собирает коллекцию свойств заново. Значения прежнего типа в новую коллекцию не переезжают, и реквизиты заполняют повторно.
Сам профиль в заказе не хранится: при оформлении его значения копируются в свойства заказа. Дальше заказ живёт своей копией данных, поэтому правка профиля прошлые заказы уже не трогает.
Д7-замены у этого API нет: профили покупателя остаются в старом ядре и правятся
классами CSaleOrderUserProps и CSaleOrderUserPropsValue. Сам заказ при этом
собирают объектами D7, и смешение двух ядер в одном обработчике здесь нормально.
Типичные проблемы
Заказ создан своей формой, а профиля покупателя нет.
Профиль появляется только после штатного оформления заказа, и свой обработчик его не создаёт. Запись профиля и каждое её значение в этом случае добавляют кодом.
В кабинете профиль можно править и удалять, но не добавлять.
У штатного компонента профилей кнопки добавления нет, и это поведение не менялось годами. Новый профиль заводится при оформлении заказа либо своим компонентом на основе типового.
Профиль в заказе сменили, а данные покупателя прежние.
Заказ хранит копию значений, а не ссылку на профиль, поэтому подмена идентификатора ничего не даёт. Значения свойств заказа переписывают из нужного профиля вручную.
Тип плательщика не удаляется: в заказах он используется.
Тип держат прежние заказы и профили покупателей, а чистка таблиц базы ломает и те и другие. Тип плательщика не удаляют, а выключают полем ACTIVE.
Покупатель не находит свой профиль в списке при оформлении.
Список профилей в форме отфильтрован по выбранному типу плательщика, а не по одному покупателю. Профиль другого типа появится только после смены типа в самой форме.
Частые вопросы
Может ли покупатель сам добавить новый профиль?
Штатно - нет: типовой компонент профилей умеет только править и удалять. Новый профиль появляется при оформлении очередного заказа, а кнопку добавления делают своим компонентом на основе типового.
Как изменить профиль покупателя в уже созданном заказе?
Напрямую никак: поля профиля у заказа нет, есть только USER_ID. Берут значения нужного профиля и переписывают ими свойства заказа через коллекцию свойств.
Сколько профилей бывает у одного пользователя?
Столько, сколько на сайте типов плательщика, и по одному на каждый новый набор данных. Один логин спокойно держит профили на себя, на родственника и на своё ИП.
Как связать профиль покупателя с данными пользователя?
Своим обработчиком на событии сохранения заказа: нужные поля переносят в карточку пользователя. Учитываем, что профилей у пользователя несколько, и слепая перезапись затрёт чужие данные.
Почему обмен с 1С путает контрагентов при нескольких профилях?
Штатный обмен строит идентификатор контрагента по данным пользователя, а не по профилю. Несколько профилей на один логин в такой схеме схлопываются в одного контрагента.
Смежное
- Оформление заказа - оглавление подтемы
- Личный кабинет покупателя и онлайн-кассы - страницы профилей в кабинете
- Заказ для юрлица: тип плательщика, реквизиты, счёт - второй тип плательщика и поля реквизитов
- Своё поле в оформлении заказа: свойство, группа, свой тип - откуда берутся поля профиля
- Оформление заказа: настройка компонента и правка шаблона - форма, подставляющая профиль
- Свойства заказа: чтение, запись и фильтрация по значению - куда копируются значения профиля
- Личный кабинет покупателя: список заказов, повтор и отмена - повтор заказа и страницы кабинета
- Свои страницы личного кабинета: раздел, меню, права, данные - своя страница для профилей
- Состав заказа и контрагенты при обмене - профиль и контрагент в обмене с 1С