Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save flayder/fc9b67ccb2b3bb3f53020bd9f1f4736b to your computer and use it in GitHub Desktop.
Save flayder/fc9b67ccb2b3bb3f53020bd9f1f4736b to your computer and use it in GitHub Desktop.
/**
*
*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