Advertisement
Guest User

Untitled

a guest
Dec 5th, 2024
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 13.32 KB | None | 0 0
  1. <?php
  2. /**
  3.  * скидка, акция 1+1=3,
  4.  * разделение корзины
  5.  * создание коппи пункта корзины,
  6.  * копирование свойств пункта корзины,
  7.  * извление свойств пункта корзины
  8.  */
  9.  
  10. namespace App\Discounts;
  11.  
  12. use \Bitrix\Main\Loader;
  13.  
  14. class Specials {
  15.  
  16.     private static $Bypass = false;
  17.  
  18.  
  19.  
  20.     // public static function applyDiscountMark_test($_=0,$__=0,$___=0)
  21.     // {
  22.     //     $Div = \Bitrix\Main\Config\Option::get('.app', 'specdiscount');
  23.     //     //\Bitrix\Main\Config\Option::set('.app', 'specdiscount','Y');
  24.     //     if ($Div != 'Y') return;
  25.  
  26.     //     if (self::$Bypass) return;
  27.     //     self::$Bypass = true;
  28.  
  29.     //     \Bitrix\Main\Loader::includeModule('sale');
  30.  
  31.     //     $basket = \Bitrix\Sale\Basket::loadItemsForFUser(
  32.     //             \Bitrix\Sale\Fuser::getId(),
  33.     //             \Bitrix\Main\Context::getCurrent()->getSite()
  34.     //         );
  35.        
  36.     //     // очищаем от всех SPECIALDISCOUNT
  37.     //     self::clear($basket);
  38.  
  39.     //     //
  40.     //     self::Dicqount403020($basket);
  41.        
  42.  
  43.     //     self::$Bypass = false;
  44.     //     return;
  45.     // }
  46.  
  47.  
  48.  
  49.     public static function applyDiscountMark($_=0,$__=0,$___=0)
  50.     {
  51.         //return;
  52.  
  53.         $Div = \Bitrix\Main\Config\Option::get('.app', 'specdiscount');
  54.         //\Bitrix\Main\Config\Option::set('.app', 'specdiscount','Y');
  55.         if ($Div != 'Y') return;
  56.  
  57.         if (self::$Bypass) return;
  58.         self::$Bypass = true;
  59.  
  60.         \Bitrix\Main\Loader::includeModule('sale');
  61.  
  62.         $basket = \Bitrix\Sale\Basket::loadItemsForFUser(
  63.                 \Bitrix\Sale\Fuser::getId(),
  64.                 \Bitrix\Main\Context::getCurrent()->getSite()
  65.             );
  66.        
  67.         // очищаем от всех SPECIALDISCOUNT
  68.         self::clear($basket);
  69.  
  70.         //
  71.         self::SecondProduct40($basket);
  72.         //self::OnePlusOneEq3($basket); // до 13,06
  73.         //self::Dicqount403020($basket);
  74.        
  75.  
  76.         self::$Bypass = false;
  77.         return;
  78.     }
  79.  
  80.  
  81.  
  82.     /**
  83.      * 40% на второй продукт
  84.      */
  85.     private static function SecondProduct40 ($basket)
  86.     {
  87.         if (!$basket) $basket = \Bitrix\Sale\Basket::loadItemsForFUser(
  88.                 \Bitrix\Sale\Fuser::getId(),
  89.                 \Bitrix\Main\Context::getCurrent()->getSite()
  90.             );
  91.  
  92.         // получаем список товаров которые подходят под условие
  93.         $lstItem = [];
  94.         $Q = 0;
  95.         foreach ($basket as $item) {
  96.  
  97.             $ProductId = $item->getProductId();
  98.             $dctCatalogElement = \App\Catalog::getElement(
  99.                     ['ID'=>$ProductId],
  100.                     ['PROPERTY_SEZON','PROPERTY__DISCOUNTCODE']
  101.                 );
  102.  
  103.             if (defined('HUMAN_DEBUG') && HUMAN_DEBUG) {
  104.                 \Kint\Kint::dump($dctCatalogElement);
  105.             }
  106.             if (!$dctCatalogElement['GOODS']['PROPERTY__DISCOUNTCODE_VALUE']
  107.                     && ($dctCatalogElement['GOODS']['PROPERTY_SEZON_VALUE'] == 'AW24/25'
  108.                             || $dctCatalogElement['GOODS']['PROPERTY_SEZON_VALUE'] == 'Demi-season'
  109.                         )
  110.                 ) { // проверка условия
  111.                 $lstItem[$item->getId()] = [
  112.                         'item' => $item,
  113.                         'price' => $item->getPrice(),
  114.                         'quantity' => $item->getQuantity(),
  115.                     ];
  116.                 $Q = $Q + $item->getQuantity();
  117.             }
  118.  
  119.            
  120.         }
  121.  
  122.         usort($lstItem,function($a, $b) {
  123.                 if ($a['price'] == $b['price']) {
  124.                     return 0;
  125.                 }
  126.                 return ($a['price'] < $b['price']) ? -1 : 1;
  127.             });
  128.  
  129.         if (defined('HUMAN_DEBUG') && HUMAN_DEBUG) {
  130.             \Kint\Kint::dump($lstItem);
  131.         }
  132.  
  133.         if ($Q > 1) {
  134.             // расчет количества
  135.             $K = floor($Q/2);
  136.             self::apply($lstItem[0]['item'], $K,'second40');
  137.         }
  138.     }
  139.  
  140.     /**
  141.      * Скикда 1+1=3
  142.      */
  143.     private static function OnePlusOneEq3 ($basket)
  144.     {
  145.         if (!$basket) $basket = \Bitrix\Sale\Basket::loadItemsForFUser(
  146.                 \Bitrix\Sale\Fuser::getId(),
  147.                 \Bitrix\Main\Context::getCurrent()->getSite()
  148.             );
  149.  
  150.         // получаем список товаров которые подходят под условие
  151.         $lstItem = [];
  152.         $Q = 0;
  153.         foreach ($basket as $item) {
  154.  
  155.             $ProductId = $item->getProductId();
  156.             $dctCatalogElement = \App\Catalog::getElement(
  157.                     ['ID'=>$ProductId],
  158.                     ['PROPERTY_SEZON','PROPERTY__DISCOUNTCODE']
  159.                 );
  160.  
  161.  
  162.             if ($dctCatalogElement['GOODS']['PROPERTY_SEZON_VALUE'] == 'SS23'
  163.                     || $dctCatalogElement['GOODS']['PROPERTY_SEZON_VALUE'] == 'SS22'
  164.                     || $dctCatalogElement['GOODS']['PROPERTY_SEZON_VALUE'] == 'SS21'
  165.                     || $dctCatalogElement['GOODS']['PROPERTY_SEZON_VALUE'] == 'SS20'
  166.                 ) { // проверка условия
  167.                 $lstItem[$item->getId()] = [
  168.                         'item' => $item,
  169.                         'price' => $item->getPrice(),
  170.                         'quantity' => $item->getQuantity(),
  171.                     ];
  172.                 $Q = $Q + $item->getQuantity();
  173.             }
  174.  
  175.            
  176.         }
  177.  
  178.         usort($lstItem,function($a, $b) {
  179.                 if ($a['price'] == $b['price']) {
  180.                     return 0;
  181.                 }
  182.                 return ($a['price'] < $b['price']) ? -1 : 1;
  183.             });
  184.  
  185.         if ($Q > 2) {
  186.             // расчет количества
  187.             $K = floor($Q/3);
  188.             self::apply($lstItem[0]['item'], $K,'1+1=3');
  189.         }
  190.     }
  191.  
  192.     /**
  193.      * Скикда 40% на самый дешевый товар, 30 на следующий и 20 на следующий
  194.      */
  195.     private static function Dicqount403020 ($basket)
  196.     {
  197.         if (!$basket) $basket = \Bitrix\Sale\Basket::loadItemsForFUser(
  198.                 \Bitrix\Sale\Fuser::getId(),
  199.                 \Bitrix\Main\Context::getCurrent()->getSite()
  200.             );
  201.  
  202.         // получаем список товаров которые подходят под условие
  203.         $lstItem = [];
  204.         $Q = 0;
  205.         foreach ($basket as $item) {
  206.  
  207.             $ProductId = $item->getProductId();
  208.             $dctCatalogElement = \App\Catalog::getElement(
  209.                     ['ID'=>$ProductId],
  210.                     ['PROPERTY_SEZON','PROPERTY__DISCOUNTCODE']
  211.                 );
  212.  
  213.  
  214.             if (!$dctCatalogElement['GOODS']['PROPERTY__DISCOUNTCODE_VALUE']
  215.                     && ($dctCatalogElement['GOODS']['PROPERTY_SEZON_VALUE'] == 'SS24'
  216.                             || $dctCatalogElement['GOODS']['PROPERTY_SEZON_VALUE'] == 'Demi-season'
  217.                         )
  218.                 ) { // проверка условия
  219.                 $lstItem[$item->getId()] = [
  220.                         'item' => $item,
  221.                         'price' => $item->getPrice(),
  222.                         'quantity' => $item->getQuantity(),
  223.                     ];
  224.                 $Q = $Q + $item->getQuantity();
  225.             }
  226.         }
  227.  
  228.         usort($lstItem,function($a, $b) {
  229.                 if ($a['price'] == $b['price']) {
  230.                     return 0;
  231.                 }
  232.                 return ($a['price'] < $b['price']) ? -1 : 1;
  233.             });
  234.  
  235.  
  236.        
  237.         if ($Q) {
  238.             if ($Q > 3) $Q=3;
  239.             $I = 0;
  240.             for ($Q=$Q; $Q; $Q--) {
  241.                 $Disqount = 10*($Q+1);
  242.                 if (!$lstItem[$I]['quantity']) {
  243.                     $I++;
  244.                 }
  245.                 $lstItem[$I]['quantity']--;
  246.                 self::apply($lstItem[$I]['item'], 1,'Скидка '.$Disqount.'%');
  247.             }
  248.  
  249.         }
  250.  
  251.  
  252.     }
  253.  
  254.  
  255.     /**
  256.      * разделяет $item корзины на два item'a и пременят к остатку спецакцию $Action
  257.      * @param $item - запись которую надо разделить
  258.      * @param $Quantity - количество которое надо оставить в этой записи
  259.      */
  260.     public static function apply ($item, $Quantity, $Action)
  261.     {
  262.  
  263.         $basket = $item->getBasket();
  264.  
  265.         if ($item->getQuantity() > $Quantity) { // необходимо отделение!
  266.             $QuantityNewItem = $item->getQuantity() - $Quantity;
  267.             $newItem = $basket->createItem('catalog', $item->getField('PRODUCT_ID')); //создаём новый товар в корзине
  268.             $newItem->setFields(array(
  269.                     'QUANTITY' => $QuantityNewItem,
  270.                     'CURRENCY' => $item->getField('CURRENCY'),
  271.                     'LID' => $item->getField('LID'),
  272.                     'PRODUCT_PROVIDER_CLASS' => $item->getField('PRODUCT_PROVIDER_CLASS')
  273.                 ));
  274.  
  275.             // перенос свойств
  276.             $propCollectionNewItem = $newItem->getPropertyCollection();
  277.             $refPropsNewItem = self::extractProps($item);
  278.  
  279.             $propCollectionNewItem->setProperty($refPropsNewItem);
  280.             // конец переноса свойств
  281.  
  282.             $item->setField('QUANTITY',$Quantity);
  283.         }
  284.  
  285.         $propCollection = $item->getPropertyCollection();
  286.         $propCollection->setProperty(['SPECIALDISCOUNT' => [
  287.                 'NAME' => 'Акция',
  288.                 'CODE' => 'SPECIALDISCOUNT',
  289.                 'VALUE' => $Action,
  290.                 'SORT' => 500
  291.             ]]);
  292.         $propCollection->save();
  293.  
  294.         if ($newItem) {
  295.             $basket->addItem($newItem);
  296.         }
  297.  
  298.         $basket->save();
  299.     }
  300.  
  301.  
  302.    /**
  303.      * Очищает SPECIALDISCOUNT на товарах
  304.      */
  305.     public static function clear ($basket=false)
  306.     {
  307.         if (!$basket) $basket = \Bitrix\Sale\Basket::loadItemsForFUser(
  308.                 \Bitrix\Sale\Fuser::getId(),
  309.                 \Bitrix\Main\Context::getCurrent()->getSite()
  310.             );
  311.  
  312.         // сбросим все значения SPECIALDISCOUNT и вычислим хэши
  313.         $refItems = []; // карта хэшПункта => СписокIdсЭтимХэшем
  314.         foreach ($basket as $item) {
  315.  
  316.             $refProps = self::extractProps($item);
  317.            
  318.             if ($refProps['SPECIALDISCOUNT']) {
  319.                 unset($refProps['SPECIALDISCOUNT']); // это свойство не надо учитывать в хэше
  320.                 // его надо удалить
  321.                 $propCollection = $item->getPropertyCollection();
  322.                 foreach ($propCollection as $I=>$prop) {
  323.                     $Code = $prop->getField('CODE');
  324.                     if ($Code == 'SPECIALDISCOUNT') {
  325.                         $propCollection->deleteItem($I);
  326.                         $propCollection->save();
  327.                         break;
  328.                     }
  329.                 }
  330.             }
  331.            
  332.             $arHash = [
  333.                     'PRODUCT_ID' => $item->getField('PRODUCT_ID'),
  334.                     'PRICE' => $item->getField('PRICE'),
  335.                     'CURRENCY' => $item->getField('CURRENCY'),
  336.                     'LID' => $item->getField('LID'),
  337.                     'PRODUCT_PROVIDER_CLASS' => $item->getField('PRODUCT_PROVIDER_CLASS'),
  338.                     'PROPS' => $refProps
  339.                 ];
  340.             $Hash = md5(serialize($arHash));
  341.             $refItems[$Hash][] = $item->getId();
  342.  
  343.             $arDebug[$Hash] = ['hash'=>$arHash,'id'=>$item->getId()];
  344.         }
  345.  
  346.         if (defined('HUMAN_DEBUG')) {
  347.             \Kint\Kint::dump('пункты для объединения',$arDebug,$refItems);
  348.         } else {
  349.             unset($arDebug);
  350.         }
  351.  
  352.         // объединим пункты с одинаковым хэшем
  353.         foreach ($refItems as $lstItemsId) {
  354.             if (count($lstItemsId) > 1) {
  355.                 $Quantity = 0;
  356.                 for ($I=count($lstItemsId)-1; $I>-1; $I--) {
  357.                     $item = $basket->getItemById($lstItemsId[$I]);
  358.                     $Quantity = $Quantity+$item->getQuantity();
  359.                     if ($I) {
  360.                         $item->setField('QUANTITY',0);
  361.                         $item->delete();
  362.                     } else {
  363.                         $item->setField('QUANTITY',$Quantity);
  364.                         $item->save();
  365.                     }
  366.                 }
  367.             }
  368.         }
  369.  
  370.         $basket->save();
  371.     }
  372.  
  373.     // извлекает свойства из item корзины
  374.     public static function extractProps ($item): array
  375.     {
  376.         $propCollection = $item->getPropertyCollection();
  377.         $refProps = [];
  378.         foreach ($propCollection as $prop) {
  379.             $Code = $prop->getField('CODE');
  380.             $refProps[$Code] = [
  381.                     'NAME' => $prop->getField('NAME'),
  382.                     'CODE' => $Code,
  383.                     'VALUE' => $prop->getField('VALUE'),
  384.                     'SORT' => $prop->getField('SORT'),
  385.                 ];
  386.         }
  387.  
  388.         return $refProps;
  389.     }
  390.  
  391. }
Tags: bitrix
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement