Advertisement
Guest User

Untitled

a guest
Oct 17th, 2019
213
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 12.11 KB | None | 0 0
  1. <?php
  2.  
  3. namespace S7g\Discount;
  4.  
  5. use Bitrix\Main;
  6. use Bitrix\Main\Loader;
  7. use Bitrix\Sale\Internals;
  8. use Bitrix\Main\SystemException;
  9. use CAllDatabase,
  10.     CIBlockElement,
  11.     CSite,
  12.     CSaleDiscount,
  13.     CPrice,
  14.     CCatalogProduct,
  15.     CCatalogDiscount;
  16.  
  17. /**
  18.  * Class AllProductDiscount
  19.  */
  20. class Discount
  21. {
  22.     /**
  23.      * @param array $arUserGroups
  24.      * @return array
  25.      * @throws Main\ArgumentException
  26.      * @throws Main\LoaderException
  27.      * @throws Main\ObjectPropertyException
  28.      * @throws SystemException
  29.      */
  30.     public static function getProductList(array $arUserGroups = [2]): array
  31.     {
  32.         if (!Loader::includeModule('sale')) throw new SystemException('Sale module not found');
  33.  
  34.         // Достаем старым методом только ID скидок привязанных к группам пользователей по ограничениям
  35.         $actionsNotTemp = CSaleDiscount::GetList(["ID" => "ASC"], ["USER_GROUPS" => $arUserGroups], false, false, ["ID"]);
  36.  
  37.         $actionIds = [];
  38.         while ($actionNot = $actionsNotTemp->fetch()) {
  39.             $actionIds[] = $actionNot['ID'];
  40.         }
  41.         $actionIds = array_unique($actionIds);
  42.         sort($actionIds);
  43.  
  44.         // Подготавливаем необходимые переменные для разборчивости кода
  45.         $conditionLogic = ['Equal' => '=', 'Not' => '!', 'Great' => '>', 'Less' => '<', 'EqGr' => '>=', 'EqLs' => '<='];
  46.         $arSelect = ["ID", "IBLOCK_ID", "XML_ID"];
  47.         $productsArray = [];
  48.  
  49.         // Теперь достаем скидки с условиями. Старым методом этого делать не нужно из-за очень высокой нагрузки
  50.         $actions = Internals\DiscountTable::getList([
  51.             'select' => ["ID", "ACTIONS_LIST"],
  52.             'filter' => ["ACTIVE" => "Y", "USE_COUPONS" => "N", "DISCOUNT_TYPE" => "P", "LID" => SITE_ID,
  53.                 "ID" => $actionIds,
  54.                 [
  55.                     "LOGIC" => "OR",
  56.                     [
  57.                         "<=ACTIVE_FROM" => CAllDatabase::FormatDate(date("Y-m-d H:i:s"), "YYYY-MM-DD HH:MI:SS", CSite::GetDateFormat("FULL")),
  58.                         ">=ACTIVE_TO" => CAllDatabase::FormatDate(date("Y-m-d H:i:s"), "YYYY-MM-DD HH:MI:SS", CSite::GetDateFormat("FULL"))
  59.                     ],
  60.                     [
  61.                         "=ACTIVE_FROM" => false,
  62.                         ">=ACTIVE_TO" => CAllDatabase::FormatDate(date("Y-m-d H:i:s"), "YYYY-MM-DD HH:MI:SS", CSite::GetDateFormat("FULL"))
  63.                     ],
  64.                     [
  65.                         "<=ACTIVE_FROM" => CAllDatabase::FormatDate(date("Y-m-d H:i:s"), "YYYY-MM-DD HH:MI:SS", CSite::GetDateFormat("FULL")),
  66.                         "=ACTIVE_TO" => false
  67.                     ],
  68.                     [
  69.                         "=ACTIVE_FROM" => false,
  70.                         "=ACTIVE_TO" => false
  71.                     ],
  72.                 ]]
  73.         ]);
  74.  
  75.         // Перебираем каждую скидку и подготавливаем условия фильтрации для CIBlockElement::GetList
  76.         $arrActions = [];
  77.         while ($arrAction = $actions->fetch()) {
  78.             $arrActions[$arrAction['ID']] = $arrAction;
  79.         }
  80.  
  81.         foreach ($arrActions as $actionId => $action) {
  82.             $arPredFilter = ["ACTIVE_DATE" => "Y", "CAN_BUY" => "Y"];
  83.             $arFilter = $arPredFilter; //Основной фильтр
  84.             $dopArFilter = $arPredFilter; //Фильтр для доп. запроса
  85.             $dopArFilter["=XML_ID"] = []; //Пустое значения для первой отработки array_merge
  86.             foreach ($action['ACTIONS_LIST']['CHILDREN'] as $condition) {
  87.                 foreach ($condition['CHILDREN'] as $keyConditionSub => $conditionSub) {
  88.                     $cs = $conditionSub['DATA']['value']; //Значение условия
  89.                     $cls = $conditionLogic[$conditionSub['DATA']['logic']]; //Оператор условия
  90.                     $CLASS_ID = explode(':', $conditionSub['CLASS_ID']);
  91.  
  92.                     if ($CLASS_ID[0] == 'ActSaleSubGrp') {
  93.                         foreach ($conditionSub['CHILDREN'] as $keyConditionSubElem => $conditionSubElem) {
  94.                             $cse = $conditionSubElem['DATA']['value']; //Значение условия
  95.                             $clse = $conditionLogic[$conditionSubElem['DATA']['logic']]; //Оператор условия
  96.                             $CLASS_ID_EL = explode(':', $conditionSubElem['CLASS_ID']);
  97.  
  98.                             if ($CLASS_ID_EL[0] == 'CondIBProp') {
  99.                                 $arFilter["IBLOCK_ID"] = $CLASS_ID_EL[1];
  100.                                 $arFilter[$clse . "PROPERTY_" . $CLASS_ID_EL[2]] = array_merge((array)$arFilter[$clse . "PROPERTY_" . $CLASS_ID_EL[2]], (array)$cse);
  101.                                 $arFilter[$clse . "PROPERTY_" . $CLASS_ID_EL[2]] = array_unique($arFilter[$clse . "PROPERTY_" . $CLASS_ID_EL[2]]);
  102.                             } elseif ($CLASS_ID_EL[0] == 'CondIBName') {
  103.                                 $arFilter[$clse . "NAME"] = array_merge((array)$arFilter[$clse . "NAME"], (array)$cse);
  104.                                 $arFilter[$clse . "NAME"] = array_unique($arFilter[$clse . "NAME"]);
  105.                             } elseif ($CLASS_ID_EL[0] == 'CondIBElement') {
  106.                                 $arFilter[$clse . "ID"] = array_merge((array)$arFilter[$clse . "ID"], (array)$cse);
  107.                                 $arFilter[$clse . "ID"] = array_unique($arFilter[$clse . "ID"]);
  108.                             } elseif ($CLASS_ID_EL[0] == 'CondIBTags') {
  109.                                 $arFilter[$clse . "TAGS"] = array_merge((array)$arFilter[$clse . "TAGS"], (array)$cse);
  110.                                 $arFilter[$clse . "TAGS"] = array_unique($arFilter[$clse . "TAGS"]);
  111.                             } elseif ($CLASS_ID_EL[0] == 'CondIBSection') {
  112.                                 $arFilter[$clse . "SECTION_ID"] = array_merge((array)$arFilter[$clse . "SECTION_ID"], (array)$cse);
  113.                                 $arFilter[$clse . "SECTION_ID"] = array_unique($arFilter[$clse . "SECTION_ID"]);
  114.                             } elseif ($CLASS_ID_EL[0] == 'CondIBXmlID') {
  115.                                 $arFilter[$clse . "XML_ID"] = array_merge((array)$arFilter[$clse . "XML_ID"], (array)$cse);
  116.                                 $arFilter[$clse . "XML_ID"] = array_unique($arFilter[$clse . "XML_ID"]);
  117.                             } elseif ($CLASS_ID_EL[0] == 'CondBsktAppliedDiscount') { //Условие: Были применены скидки (Y/N)
  118.                                 foreach ($arrActions as $tempAction) {
  119.                                     if (($tempAction['SORT'] < $action['SORT'] && $tempAction['PRIORITY'] > $action['PRIORITY'] && $cse == 'N') || ($tempAction['SORT'] > $action['SORT'] && $tempAction['PRIORITY'] < $action['PRIORITY'] && $cse == 'Y')) {
  120.                                         $arFilter = false;
  121.                                         break 4;
  122.                                     }
  123.                                 }
  124.                             }
  125.                         }
  126.                     } elseif ($CLASS_ID[0] == 'CondIBProp') {
  127.                         $arFilter["IBLOCK_ID"] = $CLASS_ID[1];
  128.                         $arFilter[$cls . "PROPERTY_" . $CLASS_ID[2]] = array_merge((array)$arFilter[$cls . "PROPERTY_" . $CLASS_ID[2]], (array)$cs);
  129.                         $arFilter[$cls . "PROPERTY_" . $CLASS_ID[2]] = array_unique($arFilter[$cls . "PROPERTY_" . $CLASS_ID[2]]);
  130.                     } elseif ($CLASS_ID[0] == 'CondIBName') {
  131.                         $arFilter[$cls . "NAME"] = array_merge((array)$arFilter[$cls . "NAME"], (array)$cs);
  132.                         $arFilter[$cls . "NAME"] = array_unique($arFilter[$cls . "NAME"]);
  133.                     } elseif ($CLASS_ID[0] == 'CondIBElement') {
  134.                         $arFilter[$cls . "ID"] = array_merge((array)$arFilter[$cls . "ID"], (array)$cs);
  135.                         $arFilter[$cls . "ID"] = array_unique($arFilter[$cls . "ID"]);
  136.                     } elseif ($CLASS_ID[0] == 'CondIBTags') {
  137.                         $arFilter[$cls . "TAGS"] = array_merge((array)$arFilter[$cls . "TAGS"], (array)$cs);
  138.                         $arFilter[$cls . "TAGS"] = array_unique($arFilter[$cls . "TAGS"]);
  139.                     } elseif ($CLASS_ID[0] == 'CondIBSection') {
  140.                         $arFilter[$cls . "SECTION_ID"] = array_merge((array)$arFilter[$cls . "SECTION_ID"], (array)$cs);
  141.                         $arFilter[$cls . "SECTION_ID"] = array_unique($arFilter[$cls . "SECTION_ID"]);
  142.                     } elseif ($CLASS_ID[0] == 'CondIBXmlID') {
  143.                         $arFilter[$cls . "XML_ID"] = array_merge((array)$arFilter[$cls . "XML_ID"], (array)$cs);
  144.                         $arFilter[$cls . "XML_ID"] = array_unique($arFilter[$cls . "XML_ID"]);
  145.                     } elseif ($CLASS_ID[0] == 'CondBsktAppliedDiscount') { //Условие: Были применены скидки (Y/N)
  146.                         foreach ($arrActions as $tempAction) {
  147.                             if (($tempAction['SORT'] < $action['SORT'] && $tempAction['PRIORITY'] > $action['PRIORITY'] && $cs == 'N') || ($tempAction['SORT'] > $action['SORT'] && $tempAction['PRIORITY'] < $action['PRIORITY'] && $cs == 'Y')) {
  148.                                 $arFilter = false;
  149.                                 break 3;
  150.                             }
  151.                         }
  152.                     }
  153.                 }
  154.             }
  155.             if ($arFilter !== false && $arFilter != $arPredFilter) {
  156.                 if (!isset($arFilter['=XML_ID'])) {
  157.                     //Делаем запрос по каждому из фильтров, т.к. один фильтр не получится сделать из-за противоречий условий каждой скидки
  158.                     $res = CIBlockElement::GetList(array(), $arFilter, false, false, $arSelect);
  159.                     while ($ob = $res->GetNextElement()) {
  160.                         $arFields = $ob->GetFields();
  161.                         $productsArray[] = $arFields["ID"];
  162.                     }
  163.                 } elseif (!empty($arFilter['=XML_ID'])) {
  164.                     //Подготавливаем массив для отдельного запроса
  165.                     $dopArFilter['=XML_ID'] = array_unique(array_merge($arFilter['=XML_ID'], $dopArFilter['=XML_ID']));
  166.                 }
  167.             }
  168.         }
  169.  
  170.         if (isset($dopArFilter) && !empty($dopArFilter['=XML_ID'])) {
  171.             //Делаем отдельный запрос по конкретным XML_ID
  172.             $res = CIBlockElement::GetList(array(), $dopArFilter, false, array("nTopCount" => count($dopArFilter['=XML_ID'])), $arSelect);
  173.             while ($ob = $res->GetNextElement()) {
  174.                 $arFields = $ob->GetFields();
  175.                 $productsArray[] = $arFields["ID"];
  176.             }
  177.         }
  178.  
  179.         return array_unique($productsArray);
  180.     }
  181.  
  182.     /**
  183.      * @param int $id
  184.      * @param array $arUserGroups
  185.      * @return array|false
  186.      * @throws Main\LoaderException
  187.      * @throws SystemException
  188.      */
  189.     public static function getProductDiscountPrice(int $id, array $arUserGroups = [2]): array
  190.     {
  191.         if (!Loader::includeModule('catalog')) throw new SystemException('Sale module not found');
  192.  
  193.         $dbPrices = CPrice::GetList([], ['PRODUCT_ID' => [$id], 'CATALOG_GROUP_ID' => []]);
  194.  
  195.         if (($price = $dbPrices->Fetch()) && $arDiscounts = CCatalogDiscount::GetDiscountByPrice($price['ID'], $arUserGroups, 'N', 's1', false)) {
  196.  
  197.             $discountPrice = CCatalogProduct::CountPriceWithDiscount($price['PRICE'], $price['CURRENCY'], $arDiscounts);
  198.  
  199.             return [
  200.                 'PRICE' => $price['PRICE'],
  201.                 'DISCOUNT_PRICE' => $discountPrice,
  202.                 'PERCENT' => round(100 - $discountPrice / ($price['PRICE'] / 100)),
  203.             ];
  204.         }
  205.  
  206.         return false;
  207.     }
  208. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement