Created
April 8, 2018 19:24
-
-
Save flayder/fc9b67ccb2b3bb3f53020bd9f1f4736b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* | |
*The class for work with discounts and coupons. | |
*Developed by: http://lost-service.ru/ | |
* | |
*/ | |
class DiscountCalculation | |
{ | |
/** | |
*This function returns a operator from documentation of the site: https://dev.1c-bitrix.ru/api_help/catalog/classes/ccatalogdiscount/ccatalogdiscount.update.php | |
* | |
*@param array $data | |
*@return string $operator | |
*/ | |
private function getMainOperator($data) | |
{ | |
if(!empty($data) && is_array($data)) $operation = $data['DATA']['All']; | |
elseif(is_string($data)) $operator = $data; | |
else $operator = $this->$array['DATA']['All']; | |
return $operator; | |
} | |
/** | |
*This function returns a condition | |
* | |
*@param array $data | |
*@return string $condition | |
*/ | |
private function getMainCondition($data) | |
{ | |
if(!empty($data) && is_array($data)) $condition = $data['DATA']['True']; | |
elseif(is_string($data)) $condition = $data; | |
else $condition = $this->$array['DATA']['True']; | |
return $condition; | |
} | |
/** | |
*This function returns a operator from documentation of the site: https://dev.1c-bitrix.ru/api_help/catalog/classes/ccatalogdiscount/ccatalogdiscount.update.php | |
* | |
*@param string $operator | |
*@return string $operator | |
*/ | |
private function getOperator($operator) | |
{ | |
if(!$operator) return ''; | |
switch ($operator) { | |
case 'Equal': | |
return '='; | |
break; | |
case 'Not': | |
return '!'; | |
break; | |
case 'Great': | |
return '>'; | |
break; | |
case 'Less': | |
return '<'; | |
break; | |
case 'EqGr': | |
return '>='; | |
break; | |
case 'EqLs': | |
return '<='; | |
break; | |
} | |
} | |
/** | |
*This function prepares data for $arFilter of CIBlockElement::GetList. It depends for conditions of discounts. | |
* | |
*@param array $arr | |
*@return array $data | |
*/ | |
public function parse($arr = array()) | |
{ | |
if(empty($arr)) return null; | |
global $DB; | |
$array = array(); | |
$i = 0; | |
foreach ($arr as $par) { | |
switch ($par['CLASS_ID']) { | |
case 'CondIBElement': | |
$op = $this->getOperator($par['DATA']['logic']); | |
if(is_array($par['DATA']['value'])) { | |
$array['ID_ELEMENTS'][$op.'ID'] = $par['DATA']['value']; | |
} else $array['ID_ELEMENTS'][$op.'ID'][] = $par['DATA']['value']; | |
continue; | |
case 'CondIBIBlock': | |
$op = $this->getOperator($par['DATA']['logic']); | |
if(is_array($par['DATA']['value'])) { | |
$array[$op.'IBLOCK_ID'] = $par['DATA']['value']; | |
} else $array[$op.'IBLOCK_ID'][] = $par['DATA']['value']; | |
continue; | |
case 'CondIBSection': | |
$op = $this->getOperator($par['DATA']['logic']); | |
if(is_array($par['DATA']['value'])) { | |
$array[$op.'SECTION_ID'] = $par['DATA']['value']; | |
} else $array[$op.'SECTION_ID'][] = $par['DATA']['value']; | |
continue; | |
case 'CondIBCode': | |
$op = $this->getOperator($par['DATA']['logic']); | |
if(is_array($par['DATA']['value'])) { | |
$array[$op.'CODE'] = $par['DATA']['value']; | |
} else $array[$op.'CODE'][] = $par['DATA']['value']; | |
continue; | |
case 'CondIBXmlID': | |
$op = $this->getOperator($par['DATA']['logic']); | |
if(is_array($par['DATA']['value'])) { | |
$array[$op.'IBLOCK_EXTERNAL_ID'] = $par['DATA']['value']; | |
} else $array[$op.'IBLOCK_EXTERNAL_ID'][] = $par['DATA']['value']; | |
continue; | |
case 'CondIBName': | |
$op = $this->getOperator($par['DATA']['logic']); | |
if(is_array($par['DATA']['value'])) { | |
$array[$op.'NAME'] = $par['DATA']['value']; | |
} else $array[$op.'NAME'][] = $par['DATA']['value']; | |
continue; | |
case 'CondIBActive': | |
$op = $this->getOperator($par['DATA']['logic']); | |
if(is_array($par['DATA']['value'])) { | |
$array[$op.'ACTIVE'] = $par['DATA']['value']; | |
} else $array[$op.'ACTIVE'][] = $par['DATA']['value']; | |
continue; | |
case 'CondIBDateActiveFrom': | |
$op = $this->getOperator($par['DATA']['logic']); | |
if(is_array($par['DATA']['value'])) { | |
$array[$op.'ACTIVE_FROM'] = date($DB->DateFormatToPHP(CSite::GetDateFormat("FULL")), $par['DATA']['value']); | |
} else $array[$op.'ACTIVE_FROM'][] = date($DB->DateFormatToPHP(CSite::GetDateFormat("FULL")), $par['DATA']['value']); | |
continue; | |
case 'CondIBDateActiveTo': | |
$op = $this->getOperator($par['DATA']['logic']); | |
if(is_array($par['DATA']['value'])) { | |
$array[$op.'ACTIVE_TO'] = date($DB->DateFormatToPHP(CSite::GetDateFormat("FULL")), $par['DATA']['value']); | |
} else $array[$op.'ACTIVE_TO'][] = date($DB->DateFormatToPHP(CSite::GetDateFormat("FULL")), $par['DATA']['value']); | |
continue; | |
case 'CondIBSort': | |
$op = $this->getOperator($par['DATA']['logic']); | |
if(is_array($par['DATA']['value'])) { | |
$array[$op.'SORT'] = $par['DATA']['value']; | |
} else $array[$op.'SORT'][] = $par['DATA']['value']; | |
continue; | |
case 'CondIBPreviewText': | |
$op = $this->getOperator($par['DATA']['logic']); | |
if(is_array($par['DATA']['value'])) { | |
$array[$op.'PREVIEW_TEXT'] = $par['DATA']['value']; | |
} else $array[$op.'PREVIEW_TEXT'][] = $par['DATA']['value']; | |
continue; | |
case 'CondIBDetailText': | |
$op = $this->getOperator($par['DATA']['logic']); | |
if(is_array($par['DATA']['value'])) { | |
$array[$op.'DETAIL_TEXT'] = $par['DATA']['value']; | |
} else $array[$op.'DETAIL_TEXT'][] = $par['DATA']['value']; | |
continue; | |
case 'CondIBDateCreate': | |
$op = $this->getOperator($par['DATA']['logic']); | |
if(is_array($par['DATA']['value'])) { | |
$array[$op.'DATE_CREATE'] = date($DB->DateFormatToPHP(CSite::GetDateFormat("FULL")), $par['DATA']['value']); | |
} else $array[$op.'DATE_CREATE'][] = date($DB->DateFormatToPHP(CSite::GetDateFormat("FULL")), $par['DATA']['value']); | |
continue; | |
case 'CondIBCreatedBy': | |
$op = $this->getOperator($par['DATA']['logic']); | |
if(is_array($par['DATA']['value'])) { | |
$array[$op.'CREATED_BY'] = $par['DATA']['value']; | |
} else $array[$op.'CREATED_BY'][] = $par['DATA']['value']; | |
continue; | |
case 'CondIBTimestampX': | |
$op = $this->getOperator($par['DATA']['logic']); | |
if(is_array($par['DATA']['value'])) { | |
$array[$op.'TIMESTAMP_X'] = date($DB->DateFormatToPHP(CSite::GetDateFormat("FULL")), $par['DATA']['value']); | |
} else $array[$op.'TIMESTAMP_X'][] = date($DB->DateFormatToPHP(CSite::GetDateFormat("FULL")), $par['DATA']['value']); | |
continue; | |
case 'CondIBModifiedBy': | |
$op = $this->getOperator($par['DATA']['logic']); | |
if(is_array($par['DATA']['value'])) { | |
$array[$op.'MODIFIED_BY'] = $par['DATA']['value']; | |
} else $array[$op.'MODIFIED_BY'][] = $par['DATA']['value']; | |
continue; | |
case 'CondIBTags': | |
$op = $this->getOperator($par['DATA']['logic']); | |
if(is_array($par['DATA']['value'])) { | |
$array[$op.'TAGS'] = $par['DATA']['value']; | |
} else $array[$op.'TAGS'][] = $par['DATA']['value']; | |
continue; | |
case 'CondCatQuantity': | |
$op = $this->getOperator($par['DATA']['logic']); | |
if(is_array($par['DATA']['value'])) { | |
$array['CATALOG'][$op.'QUANTITY'] = $par['DATA']['value']; | |
} else $array['CATALOG'][$op.'QUANTITY'][] = $par['DATA']['value']; | |
continue; | |
case 'CondCatWeight': | |
$op = $this->getOperator($par['DATA']['logic']); | |
if(is_array($par['DATA']['value'])) { | |
$array['CATALOG'][$op.'WEIGHT'] = $par['DATA']['value']; | |
} else $array['CATALOG'][$op.'WEIGHT'][] = $par['DATA']['value']; | |
continue; | |
case 'CondCatVatID': | |
$op = $this->getOperator($par['DATA']['logic']); | |
if(is_array($par['DATA']['value'])) { | |
$array['CATALOG'][$op.'VAT_ID'] = $par['DATA']['value']; | |
} else $array['CATALOG'][$op.'VAT_ID'][] = $par['DATA']['value']; | |
continue; | |
case 'CondCatVatIncluded': | |
$op = $this->getOperator($par['DATA']['logic']); | |
if(is_array($par['DATA']['value'])) { | |
$array['CATALOG'][$op.'VAT_INCLUDED'] = $par['DATA']['value']; | |
} else $array['CATALOG'][$op.'VAT_INCLUDED'][] = $par['DATA']['value']; | |
continue; | |
case (strpos($par['CLASS_ID'], 'CondIBProp') !== false): | |
$ID = (int)preg_replace('/^CondIBProp(\:[0-9]\:)+/', "", $par['CLASS_ID']); | |
if($ID > 0) { | |
$op = $this->getOperator($par['DATA']['logic']); | |
$array['PROPERTIES'][$i][$op]['ID'] = $ID; | |
$array['PROPERTIES'][$i][$op]['VALUE'] = $par['DATA']['value']; | |
} | |
continue; | |
} | |
$i++; | |
} | |
return $array; | |
} | |
/** | |
*This function does $data of $this->parse($data) valid for the CIBlockElement::GetList | |
* | |
*@param array $data | |
*@param integer $IBLOCK_ID | |
*@return | |
*/ | |
private function validArFilter($data = array(), $IBLOCK_ID = null) | |
{ | |
if(empty($data) && !is_array($data)) return; | |
if(is_null($IBLOCK_ID)) return; | |
\Bitrix\Main\Loader::IncludeModule('iblock'); | |
\Bitrix\Main\Loader::IncludeModule('catalog'); | |
$unvalFilter = $this->parse($data); | |
$arFilter = array(); | |
$i = 0; | |
if(isset($unvalFilter['ID_ELEMENTS']) && is_array($unvalFilter['ID_ELEMENTS'])) { | |
$arr = array(); | |
foreach ($unvalFilter['ID_ELEMENTS'] as $key => $value) { | |
foreach ($value as $data) { | |
$arFilter[][$key] = $data; | |
} | |
} | |
} | |
unset($unvalFilter['ID_ELEMENTS']); | |
if(isset($unvalFilter['CATALOG']) && is_array($unvalFilter['CATALOG'])) { | |
foreach ($unvalFilter['CATALOG'] as $key => $value) { | |
foreach ($value as $data) { | |
$res = CCatalogProduct::GetList(array(), array($key => $data, 'ELEMENT_IBLOCK_ID' => $IBLOCK_ID, 'AVAILABLE' => 'Y'), false, false, array('ID')); | |
$op = preg_replace('/([a-zA-Z])*/', "", $key); | |
while ($ids = $res->Fetch()) { | |
$arFilter[][$op.'ID'] = $ids['ID']; | |
} | |
} | |
} | |
} | |
unset($unvalFilter['CATALOG']); | |
if(isset($unvalFilter['PROPERTIES']) && is_array($unvalFilter['PROPERTIES'])) { | |
foreach ($unvalFilter['PROPERTIES'] as $value) { | |
foreach ($value as $key => $data) { | |
$res = CIBlock::GetProperties($IBLOCK_ID, array(), Array("ID" => $data['ID'])); | |
if ($iblProperty = $res->Fetch()) { | |
switch ($iblProperty['PROPERTY_TYPE']) { | |
case 'L': | |
$arFilter[][$key.'PROPERTY_'.$iblProperty['CODE'].'_VALUE'] = $data['VALUE']; | |
break; | |
default: | |
$arFilter[][$key.'PROPERTY_'.$iblProperty['CODE']] = $data['VALUE']; | |
break; | |
} | |
} | |
} | |
} | |
} | |
unset($unvalFilter['PROPERTIES']); | |
foreach ($unvalFilter as $key => $value) { | |
foreach ($value as $data) { | |
$arFilter[][$key] = $data; | |
} | |
} | |
return $arFilter; | |
} | |
/** | |
*This function constructs data for CIBlockElement::GetList | |
* | |
*@param array $this->parse($arr) | |
*@param integer $IBLOCK_ID | |
*@return array $arFilter | |
*/ | |
public function getDataFilter($arr = array(), $IBLOCK_ID = null) | |
{ | |
if(!is_array($arr) || is_null($IBLOCK_ID) || !isset($arr['CHILDREN'])) return; | |
$arFilter = array(); | |
$i = 0; | |
$arFilter[$i] = $this->validArFilter($arr['CHILDREN'], $IBLOCK_ID); | |
if(!empty($arr['DATA']['All'])) { | |
$arFilter[$i]['LOGIC'] = $arr['DATA']['All']; | |
$arFilter[$i]['COND'] = $arr['DATA']['True']; | |
} | |
foreach ($arr['CHILDREN'] as $key) { | |
if(isset($key['CHILDREN']) && is_array($key['CHILDREN'])) { | |
$arFilter[$i] = $this->validArFilter($key['CHILDREN'], $IBLOCK_ID); | |
if(isset($key['DATA']['All'])) { | |
$arFilter[$i]['LOGIC'] = $key['DATA']['All']; | |
$arFilter[$i]['COND'] = $key['DATA']['True']; | |
} | |
} | |
$i++; | |
} | |
return $arFilter; | |
} | |
/** | |
*This function compares $ID of products with condition of discount | |
* | |
*@param array $data | |
*@param integer $IBLOCK_ID | |
*@return boolean | |
*/ | |
public function compare($data = array(), $IBLOCK_ID = null, $ID = null) | |
{ | |
if(empty($data) | |
|| !is_array($data) | |
|| is_null($IBLOCK_ID) | |
|| is_null($ID)) | |
return; | |
\Bitrix\Main\Loader::IncludeModule('iblock'); | |
if(isset($data["CHILDREN"])) { | |
$arFilters = $this->getDataFilter($data, $IBLOCK_ID); | |
} | |
else $arFilters = $data; | |
foreach ($arFilters as $key => $arFilter) { | |
$COND = $arFilter['COND']; | |
$arFil = array($arFilter); | |
unset($arFil['COND']); | |
$res = CIBlockElement::GetList(Array("SORT"=>"ASC"), $arFil, false, false, Array('ID')); | |
while($ob = $res->Fetch()) { | |
if($COND == 'True') { | |
if(in_array($ID, $ob)) { | |
return true; | |
break; | |
} | |
} elseif($COND == 'False') { | |
if(!in_array($ID, $ob)) { | |
return true; | |
break; | |
} | |
} | |
} | |
} | |
return false; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment