@tgarl

Как сделать акцию в битриксе 3 товара по цене 2?

В битриксе есть модуль скидок, но не для любого варианта скидок он подходит.
Если есть опыт или можете рассказать как организовать скидку 3 товара по цене 2, или как прервать цикл пересохранений при событии OnSaleBasketSaved спасибо.
  • Вопрос задан
  • 5455 просмотров
Решения вопроса 1
@iitovka
в смысле один и тот же товар, если штук 3 - то цена как для двух?
1) в переводе на математический язык: если кол-во 3 штуки, то скидка на товар - 33,33%.
такое правило стандартными скидками можно задать
2) если все таки еще какие то условия, или если товаров больше чем 3 штуки, и поведение стандартной скидки не то, что ожидаете, то я использовала бы
$eventManager->addEventHandler('sale', 'OnBasketUpdate', function($ID, $arItem){})
внутри этого обработчика получаем корзину текущего пользователя, в корзине находим нужный товар, смотрим его колво, и если надо - проставляем кастомную цену, если нет - то возвращаем оптимальную цену товара для группы этого пользователя.
у меня только такое событие отработала как надо.
(сичтали скидки на комплекты, если в корзине есть например и шапка и шарф и варежки - то всем скидка, если 2 шарфа - то скидка только на один из них, так как второй уже не комплект. но цена идет на позицию корзины)
Ответ написан
Пригласить эксперта
Ответы на вопрос 3
@tgarl Автор вопроса
Приведу итоговое решение для того кто будет искать.
Некоторые вещи нужно будеть немного адаптировать, но в целом вот решение:
public static function OnBasketUpdateHandler($ID, $arItem)
    {
        global $USER;
	if(!is_object($USER)){
		$USER = new CUser();
	}
	$userId=$USER->GetID();
	$strGroups = $USER->GetUserGroupString();
	$arUserGroups = explode(',', $strGroups); 


    $productID = $arItem['PRODUCT_ID'];
    $quantity = $arItem['QUANTITY'];

		
	if ($userId=="81035" ){//Пока выводим только для меня
		\Bitrix\Main\Loader::IncludeModule('iblock');
		\Bitrix\Main\Loader::IncludeModule('catalog');
		\Bitrix\Main\Loader::IncludeModule('sale');

		$fuser=\Bitrix\Sale\Fuser::getId();
		$basket = \Bitrix\Sale\Basket::loadItemsForFUser( $fuser, \Bitrix\Main\Context::getCurrent()->getSite() );
		
		$res=[];
		$tovar=[];
		foreach ($basket as $basketItem) {
			if(!$basketItem->isDelay()){
				$mxResult=[];
				$aa = \CCatalogSku::GetProductInfo($basketItem->getProductId())['ID'];
				$mxResult[$aa] = $aa;
				\CIBlockElement::GetPropertyValuesArray($mxResult, 26, array(
					'ID' => $mxResult,
					'IBLOCK_ID' => 26,
				));
				$raschet='';
				if(in_array($mxResult[$aa]['ROZNICHNAYA_SET']['VALUE_ENUM_ID'], [1753,1754]) && $mxResult[$aa]['RASPRODAZHA']['VALUE']=='true'){$raschet='raschet';}
								
				$basketPropertyCollection = $basketItem->getPropertyCollection(); 				
				$res[]=[$basketItem->getProductId(),$basketItem->getPrice(), $basketItem->getQuantity(), $basketItem->getFinalPrice(), $basketPropertyCollection->getPropertyValues()['BAR_CODE']['VALUE'], $raschet];
				$tovar[]=$basketPropertyCollection->getPropertyValues()['BAR_CODE']['VALUE'];
					
			}
		}
		
		$coli=[];
		$coli0=[];
		foreach($res as $vl){
			if($vl[5]=='raschet'){
			for ($x=1; $x<=$vl[2]; $x++){
				$coli[]=[$vl[0],$vl[1],$vl[5]];
			}
			}else{
				$coli0[]=[$vl[0],$vl[1],$vl[5]];
			}
		}
		$cont=count($coli);
		usort($coli, function($a, $b){
			return $a['1'] <=> $b['1'];
		});
		$skidka = floor($cont / 3);
		for ($x=0; $x<$skidka; $x++){
			$coli[$x][1]=0;
		}
		$coli = array_reverse($coli)+$coli0;
		$arFilter = Array( "IBLOCK_ID"=>27, "PROPERTY_CML2_BAR_CODE"=>$tovar );
		$res = \CIBlockElement::GetList(Array("SORT"=>"ASC",), $arFilter, false,false,array('ID',"PROPERTY_CML2_BAR_CODE",'CATALOG_QUANTITY','PROPERTY_CML2_LINK','IBLOCK_EXTERNAL_ID','XML_ID'));
		$productsId=[];
		$productsIdXml=[];
		
		while($ar_fields = $res->GetNext())
		{
			$productsId[$ar_fields["PROPERTY_CML2_BAR_CODE_VALUE"]]=$ar_fields['ID'];
			$productsIdXml[$ar_fields["PROPERTY_CML2_BAR_CODE_VALUE"]]=['IBLOCK_EXTERNAL_ID'=>$ar_fields['IBLOCK_EXTERNAL_ID'],'XML_ID'=>$ar_fields['XML_ID']];
			$productsIdXml2[$ar_fields["ID"]]=['IBLOCK_EXTERNAL_ID'=>$ar_fields['IBLOCK_EXTERNAL_ID'],'XML_ID'=>$ar_fields['XML_ID']];
		}
		$itogTovar=[];
		
		foreach($coli as $val){
			$itogTovar[$val[0]][$val[1]]++;
		}
				
		$itogo=[];	
		foreach($itogTovar as $productID0=>$value){
			$itogo[$productID0]['price']=0;
			$itogo[$productID0]['quantity']=0;
			$itogo[$productID0]['custom']='N';
			foreach($value as $price0=>$qunt0){
				if($price0>0){
					$arPrice0 = \bh\catalog\tools::getPrc($productID0);
					$itogo[$productID0]['price']=$itogo[$productID0]['price']+$arPrice0*$qunt0;
					$itogo[$productID0]['quantity']=$itogo[$productID0]['quantity']+$qunt0;
				}else{
					$itogo[$productID0]['quantity']=$itogo[$productID0]['quantity']+$qunt0;
					$itogo[$productID0]['custom']='Y';
				}
			}
			$itogo[$productID0]['price']=floor($itogo[$productID0]['price']/$itogo[$productID0]['quantity']);
		}
		foreach ($basket as $basketItem) {
			$id=$basketItem->getField('PRODUCT_ID');
			if($itogo[$id]['custom']=='Y'){
				$basketItem->setFields(array(
						'CUSTOM_PRICE' => 'Y',
						'PRICE' => $itogo[$id]['price'],
						'CATALOG_XML_ID'=>$productsIdXml2[$id]['IBLOCK_EXTERNAL_ID'],
						'PRODUCT_XML_ID'=>$productsIdXml2[$id]['XML_ID']
					));
				$basketItem->save();
				$basketPropertyCollection = $basketItem->getPropertyCollection(); 
				$basketPropertyCollection->setProperty(array(
					'ACTION'=>array(
					   'NAME' => 'Акция',
					   'CODE' => 'ACTION',
					   'VALUE' => 'Товар по акции 2=3',
					   'SORT' => 1000,
					),
					'CATALOG_XML_ID'=>array(
							'NAME' => 'Catalog XML_ID',
							'CODE' => 'CATALOG.XML_ID',
							'VALUE' => $productsIdXml2[$id]['IBLOCK_EXTERNAL_ID']
						),
					'PRODUCT_XML_ID'=>array(
							"NAME" => "Product XML_ID",
							"CODE" => "PRODUCT.XML_ID",
							"VALUE" => $productsIdXml2[$id]['XML_ID']
						)
				));
				$basketPropertyCollection->save();
			}else{
				$basketItem->setFields(array(
						'CATALOG_XML_ID'=>$productsIdXml2[$id]['IBLOCK_EXTERNAL_ID'],
						'PRODUCT_XML_ID'=>$productsIdXml2[$id]['XML_ID']
					));
				$basketItem->save();
				$basketPropertyCollection = $basketItem->getPropertyCollection(); 
				$basketPropertyCollection->setProperty(array(
					'CATALOG_XML_ID'=>array(
							'NAME' => 'Catalog XML_ID',
							'CODE' => 'CATALOG.XML_ID',
							'VALUE' => $productsIdXml2[$id]['IBLOCK_EXTERNAL_ID']
						),
					'PRODUCT_XML_ID'=>array(
							"NAME" => "Product XML_ID",
							"CODE" => "PRODUCT.XML_ID",
							"VALUE" => $productsIdXml2[$id]['XML_ID']
						)
				));
				$basketPropertyCollection->save();
			}
		}
		
	}
		
    }
Ответ написан
Комментировать
winer
@winer
занимаюсь разработкой сайтов на 1c-bitrix
Насчёт реализации такой скидки стандартными средствами подсказать не смогу, сам не знаю. Можно попробовать через события корзины. ( я так понимаю вы пошли по этому же пути)

Чтобы убрать рекурсию в событии:
- в начале обработчика объявите глобальную переменную (или статическую в классе). и проверяйте ее наличие.
global $isOnSaleBasketSavedHandler; 
$isOnSaleBasketSavedHandler = true;
if(!$isOnSaleBasketSavedHandler){
     //Ваш код
}


- дальше проверяете эту переменную
<?
Ответ написан
@scoder
Добрый день.

Возможно прозвучит как реклама. Может потому что по большей части так оно и есть )
Но есть готовый модуль, решающий данный вопрос: marketplace.1c-bitrix.ru/solutions/scoder.buymore
Для тех, кот не программист и затруднительно разбираться в кодах.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы