T
T
tgarl2019-01-16 14:28:59
1C-Bitrix
tgarl, 2019-01-16 14:28:59

How to make a promotion in Bitrix 3 products at a price of 2?

Bitrix has a discount module, but it is not suitable for any discount option.
If you have experience or can tell how to organize a discount of 3 products for the price of 2, or how to interrupt the resave cycle during the OnSaleBasketSaved event, thank you.

Answer the question

In order to leave comments, you need to log in

4 answer(s)
I
Irina, 2019-01-16
@tgarl

in the sense of the same product, if there are 3 pieces, then the price is for two?
1) translated into mathematical language: if the quantity is 3 pieces, then the discount on the product is 33.33%.
such a rule can be set by standard discounts
2) if there are still some other conditions, or if there are more than 3 products, and the behavior of the standard discount is not what you expect, then I would use
$eventManager->addEventHandler('sale', 'OnBasketUpdate ', function($ID, $arItem){})
inside this handler, we get the current user's cart, find the desired product in the cart, look at its quantity, and if necessary, put down a custom price, if not, then return the optimal price of the product for this group user.
I have only such an event worked as it should.
(we considered discounts for sets, if the basket contains, for example, a hat and a scarf and mittens, then everyone has a discount, if there are 2 scarves, then a discount is only for one of them, since the second is no longer a set. but the price goes to the basket position)

T
tgarl, 2019-01-18
@tgarl

I will give the final solution for those who will search.
Some things will need to be adapted a bit, but in general here is the solution:

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();
      }
    }
    
  }
    
    }

R
Roman Gritsuk, 2019-01-16
@winer

I can’t tell you about the implementation of such a discount by standard means, I don’t know myself. You can try through the cart events. (As I understand it, you went the same way)
To remove recursion in an event:
- at the beginning of the handler, declare a global variable (or a static one in the class). and check for it.

global $isOnSaleBasketSavedHandler; 
$isOnSaleBasketSavedHandler = true;
if(!$isOnSaleBasketSavedHandler){
     //Ваш код
}

- then check this variable
<?

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question