Боюсь, на текущем функционале промо акций такого не реализовать, логика текущих промо акций скорее всего не позволит подобной реализации. Так что это будет совершенно другой, отдельной реализацией промо, в результате чего встанет ещё одна, также возможно неразрешимая задача, увязать новую реализацию промо со старой.
Однако если кому то это удастся, я буду в ряду первых, кто будет за подобное решение.
Делал такой функционал *не красивым * способом - прямым редактированием функции fn_promotion_apply_cart_rule. Если интересно, то постараюсь вспомнить и описать подробнее
Теоретически можно, но вопрос лицензии модуля от автора.
У нас даже есть запрос стоимости, но клиент не готов пока для такого функционала такую стоимость оплатить (
Выкрутились при помощи веса товара в корзине (при условии, что у остальных товаров вес 0).
Обращаю внимание. Делалось на скорость. Не проверялось на все возможные сочетания промо-акций. Это решение надо выносить в модуль и дорабатывать.
Сам смысл довольно простой. По сути нужно просто создать новый вид бонуса, который можно включать в настройках промо-акции. Будем делать каждый n-й товар бесплатным.
Создаём в схеме app/schemas/promotions/schema.php новый вид бонуса. Ищем в файле описание любого типа бонуса, например, $schema['bonuses']['discount_on_categories']. Вставляем после него свой новый бонус $schema['bonuses']['free_every_n_product'] = array( 'function' => array('fn_promotion_apply_cart_rule', '#this', '@cart', '@auth', '@cart_products'), 'discount_bonuses' => array('number'), 'zones' => array('cart'), 'filter' => 'floatval' );
За применение бонуса отвечает ф-ия fn_promotion_apply_cart_rule. Находим её в файле app/functions/fn.promotions.php .Находим в ней условия применения бонусов и вставляем новое по своему созданному бонусу. Например, вставляем после if ($bonus['bonus'] == 'order_discount') { ...} свой код ` elseif ($bonus[‘bonus’] == ‘free_every_n_product’) {
$free_products = (int)(count($cart_products) / $bonus[‘discount_value’]);
$counter = 0;
$bonus_free = $bonus;
$bonus_free[‘discount_bonus’] = ‘by_percentage’;
$bonus_free[‘discount_value’] = 100;
$cart_products = fn_my_changes_array_sort($cart_products,‘price’, SORT_ASC); //!important fn_my_changes_array_sort is in my-changes module
foreach ($cart_products as $k => $v) {
if ( ++$counter > $free_products ) break;
if (!isset($cart_products[$k]['promotions'])) {
$cart_products[$k]['promotions'] = array();
}
if (isset($cart['products'][$k]['extra']['promotions'][$bonus['promotion_id']])) {
$cart_products[$k]['promotions'][$bonus['promotion_id']] = $cart['products'][$k]['extra']['promotions'][$bonus['promotion_id']];
}
if (!isset($cart_products[$k]['promotions'][$bonus['promotion_id']])
&& fn_promotion_apply_discount($bonus['promotion_id'], $bonus_free, $cart_products[$k], true, $cart, $cart_products)
) {
$cart['use_discount'] = true;
}
}
}. Что тут происходит. По сути нам нужно на каждый n-й товар сделать скидку 100%). Само собой, сортируем сначала товары по стоимости, чтобы сделать скидку на товары с самой низкой стоимостью в корзине. Для сортировки сделал свою ф-ию fn_my_changes_array_sort, к-я сортирует массивы любой степени вложенности по нужному полю. (Возможно в движке есть готовая, её не нашёл). Ф-ию вынес в модуль my_changes. Её добавляем в файл app/addons/my_changes/func.php Код :function fn_my_changes_array_sort($array, $on, $order=SORT_ASC)
{
$new_array = array();
$sortable_array = array();
if (count($array) > 0) {
foreach ($array as $k => $v) {
if (is_array($v)) {
foreach ($v as $k2 => $v2) {
if ($k2 == $on) {
$sortable_array[$k] = $v2;
}
}
} else {
$sortable_array[$k] = $v;
}
}
switch ($order) {
case SORT_ASC:
asort($sortable_array);
break;
case SORT_DESC:
arsort($sortable_array);
break;
}
foreach ($sortable_array as $k => $v) {
$new_array[$k] = $array[$k];
}
}
return $new_array;
}`
3.Не забываем зарегистрировать в админке языковую переменную promotion_bonus_free_every_n_product = Каждый n-ый товар бесплатно. Чистим кэш.
Код сюда вставляется кривовато, следите за скобками и запятыми)
Само собой это не универсальное решение. А делалось под конкретную бизнес-логику. Я поэтому сразу и написал, что нужно дорабатывать. Не вижу проблем в вашем случае повесить ещё условие проверять кол-во товаров и делать скидку не на всю группу. На общую схему добавления промо-кода это не влияет))
Для интереса, поправил для такого случая. Всего-то нужно поменять и поправить пару строк. В итоге для fn_promotion_apply_cart_rule `elseif ($bonus[‘bonus’] == ‘free_every_n_product’) {