Телеграм: @camouf_ru Почта: mihail@bazarow.ru

Не дать пользователю купить больше одного товара, в Битрикс

Просмотров: 5149

Иногда нужно и такое: Например: на одном из разрабатываемых сайтов, мне нужно было создать всего 4 товара. при этом покупателю не доступна возможность купить два товара, только один. Но у него должна остаться возможность "передумать".

Если пользователь уже кинул товар в корзину, он может его из корзины удалить и положить новый товар. Но это не удобно. Мы сделаем так- если у пользователя в корзине есть товар. Но он нажал кнопку "Купить" у другого товара, мы будем удалять (полностью очищать корзину) предыдущий из корзины и ложить новый.

В файл /local/php_interface/init.php добавляем обработчик. Он просто, по нажатию кнопки с name="BasketDelete", где бы она не была, полностью очищает корзину.

if ($_POST["BasketDelete"] and CModule::IncludeModule("sale"))
{
    CSaleBasket::DeleteAll(CSaleBasket::GetBasketUserID());
}

К кнопкам "Купить", в списке товаров, применяем пример из заметки Информация о заказах и содержимое корзины текущего пользователя.

Если в корзине у пользователя есть товар, то заменяем ссылку "Купить", у других товаров, на "Купить" ведущую на новую страницу (предварительно создаем ее) "/newitem<? echo $arOffer["BUY_URL"] &rt;?"

У товара который есть в корзине, заменяем кнопку "Купить" на ссылку в оформление заказа

В index.php раздела /newitem/ размещае вот такой код:

<?
$APPLICATION->SetTitle("Изменение тарифа");
$page = $_SERVER['REQUEST_URI'];
$actionPage = array('/newitem/');
$clearpage = str_replace($actionPage, "", $page);
?>
<form method="post" action="/<?echo $clearpage;?>" class="newtarif">
    Ваш тариф будет изменен (любой текст)
    <input id="delme" type="submit" value="ОК" name="BasketDelete">
</form>

Пояснения:
— Мы предупредили пользователя, что товар будет заменен на новый
— Пользователь должен согласиться нажав "ОК". Нажимая на "ОК" он полностью очищает корзину и иницирует POST запрос
— Мы, POST запросом отправляем его по ссылке инициирующей добавление нового товара в корзину
— Ссылку добавления мы взяли прямо из URL браузера очистив от не нужных данных с помощью регулярного выражения str_replace

Один минус этого решения, если пользователь не нажмет на "ОК"- то вся наша хитрость не сработает. Он может просто вернуться на главную страницу и потом пройти в корзину. Тогда у него там будет два товара

Победить это можно:
Добавив javascript на страницу /newitem/index.php который будет принудительно кликать на "ОК".

<script>
    setTimeout(function () {
        document.getElementById('delme').click();
    }, 100);
</script>

Просто кликаем на элемент с id="delme" (input c "ОК") через 100 миллисекунд. Время можете выставить самостоятельно или вообще обнулить. Тогда пользователь даже не заметит страницу со сменой

Само собой, если пользователь совсем "хитрый" он может отключить js и не нажать на "ОК". Бороться с такими, пока не знаю как. Но думаю, способ додумать можно.

Дополнено, тоже самое но на php

Вариант на php без использования js и, как следствие, вариант без изъяна. Вся суть сводится к: отправляем пользователя по ссылке с параметром, внутри которого завернут ID товара, который должен заменить уже существующие.


// подключаем ядро
require_once($_SERVER['DOCUMENT_ROOT'] . "/bitrix/modules/main/include/prolog_before.php");

// подключаем модули
Bitrix\Main\Loader::includeModule("sale");
Bitrix\Main\Loader::includeModule("catalog");

// очищаем корзину
CSaleBasket::DeleteAll(CSaleBasket::GetBasketUserID());

// выдергиваем ID  товара из ссылки
$curUrl = $APPLICATION->GetCurPageParam();
$curArParams = explode('=', $curUrl);

// Добавляем товар в корзину
    $fields = [
        'PRODUCT_ID' => $curArParams['1'],
        'QUANTITY' => 1,
    ];
    $r = Bitrix\Catalog\Product\Basket::addProduct($fields);

//Отправляем в корзину
    header('Location: /mobileapp/order/index.php', true, 301);
exit();

Здесь, методом CSaleBasket::DeleteAll(CSaleBasket::GetBasketUserID()); зачистили корзину, вообще полностью и методом Basket::addProduct добавили новый товар.

Михаил Базаров 19.05.2022
Вариант без передачи параметра в  ссылке.
Смысл заключается в том что: получаем всю корзину пользователя, выделяем из нее самый свежий товар (из добавленных в корзину).
Очищаем и снова наполняем корзину этим, одним товаром.

Код
<?
// подключаем ядро
require_once($_SERVER['DOCUMENT_ROOT'] . "/bitrix/modules/main/include/prolog_before.php");

// подключаем модули
Bitrix\Main\Loader::includeModule("sale");
Bitrix\Main\Loader::includeModule("catalog");

$arBasketItems = array();
$dbBasketItems = CSaleBasket::GetList(
    // Сортируем состав корзины по ID что бы самый новый, добавленный товар
    // Оказался в конце массива
    array("ID" => "ASC"),
    array(
        "FUSER_ID" => CSaleBasket::GetBasketUserID(),
        "LID" => SITE_ID,
        "ORDER_ID" => "NULL"
    ),
    false,
    false,
    array("PRODUCT_ID", 'ID')
);
while ($arItems = $dbBasketItems->Fetch())
{
    // В этой переменной последний добавленный товар
    $arToCart = $arItems['PRODUCT_ID'];
}

// очищаем корзину
CSaleBasket::DeleteAll(CSaleBasket::GetBasketUserID());

// Добавляем товар в корзину
$fields = [
    'PRODUCT_ID' => $arToCart, // ID самого свежего добавленного товара
    'QUANTITY' => 1,
];
$r = Bitrix\Catalog\Product\Basket::addProduct($fields);

//Отправляем в оформление или корзину
header('Location: /personal/order/index.php', true, 301);
exit();
?>

Записная книжка разработчика

Примерно с 2013-го года пишу заметки по разработке сайтов на Битрикс.
Вы можете задавать уточняющие вопросы в комментариях- отвечаю или дополняю заметки по возможности.

Заполнение габаритов товара, после обмена с 1С, из свойств элемента и... Просмотров: 10423 Если Ваш интернет-магазин интегрирован с 1С, скорее всего столкнулись с такой проблемой: 1... Данные о заказе текущего пользователя Просмотров: 12901 Иногда нужно получить данные о заказе текущего пользователя. Не через компонент, а непосре... Мобильные версии страниц и поисковые системы Просмотров: 5849 Согласно требования поисковых систем: Яндекс и Google, в случае если у вашего сайта имеетс... Композитный сайт на 1С-Битрикс Просмотров: 3037 Для новых клиентов: Все новые проекты будут включать в себя применение технологии "Компози... Открытие мобильного приложения Apache Cordova по ссылке Просмотров: 683 Достаточно часто нужно реализовывать открытие мобильного приложения по ссылке. Например: п... Фотогалерея на базе компонента новостей, с fancybox. Просмотров: 1542 Это заметка обновление к очень старой, уже имеющейся на сайте. Сделаем что-то типа фотогал... Добавить свойство в административную форму заказа Просмотров: 2809 Задача, кастомизировать административную форму заказа: добавить свойство заказа в шапку фо... Прятать или показывать описание раздела каталога Просмотров: 598 В новых компонентах и шаблонах catalog.section есть не документированный и не выводимый па... Получение доступа к железу устройства из Битрикс мобильное приложение Просмотров: 5603 Документация к мобильному приложению 1С-Битрикс очень куцая. В основном описывает функцион... Валидация пароля и подтверждения при регистрации в битрикс Просмотров: 14264 Встала задачка сделать валидацию пароля и его подтверждения в стандартной форме регистраци... Основные функции вывода в шаблонах Битрикс Просмотров: 155357 Знаю, что все их знают. Но иногда не бывает лишним собрать все самое используемое в одну к... Цвета торговых предложений из Highload инфоблоков в списке товаров Просмотров: 14086 Подвернулся на доработку очень старый сайт, работал еще на 11-ой версии Битрикс. Выполнили... Вывести все товары, с постраничной навигацией, из всех разделов инфоб... Просмотров: 28421 По сути, эта заметка, небольшой лайфхак. Достаточно часто нужно, в корне каталога, в ТОП-е... Умный фильтр на главной странице Битрикс Просмотров: 20882 Редкая но востребованная задачка- это вывести компонент "умный фильтр" на главную страницу... Отсортировать элементы в Битрикс по свойству привязка к разделам Просмотров: 27915 При создании достаточно сложных интернет-магазинов на Битрикс, иногда встает задача помимо... Дать пользователю возможность быстро отредактировать материал Просмотров: 4364 На одном из разрабатываемых сайтов, пользователи формирую его контент. После регистрации, ... AJAX корзина с отправкой количества из раздела каталога Просмотров: 19124 Столкнулся с задачкой: нужно было на одном сайте реализовать интерактивный прайс лист. При... Автоматическая загрузка каталогов из csv файлов в Битрикс Просмотров: 10631 Если требуется настроить автоматический импорт каталогов из csv файлов, от поставщиков. В... Связанные элементы в карточке товара, с помощью catalog.section Просмотров: 14029 Достаточно часто, при разработке магазинов на битрикс, требуется выводить связанные элемен... Добавление своих полей в почтовые шаблоны Битрикс Просмотров: 43635 Иногда нужно внести свои поля в почтовые шаблоны битрикс. Например: добавить имя и номе...