11use Bitrix\Crm\Service\Container;
36 private const PERSONALIZE_NAMESPACE =
"\\Bitrix\\Sender\\Integration\\Crm\\Connectors\\Personalize\\";
48 return new Orm\Fields\ExpressionField(
50 '(' . $sqlHelper->getTopSql(
53 FROM b_crm_field_multi FM
54 WHERE FM.ENTITY_ID = '$entityName'
55 AND FM.ELEMENT_ID = %s
56 AND FM.TYPE_ID = '$multiFieldTypeId'
80 array(
'CODE' =>
'CRM_ENTITY_TYPE'),
81 array(
'CODE' =>
'CRM_ENTITY_TYPE_ID'),
82 array(
'CODE' =>
'CRM_ENTITY_ID'),
88 $documentClass = self::PERSONALIZE_NAMESPACE.ucfirst($entityType);
90 if(!is_subclass_of($documentClass, BasePersonalize::class))
95 $fields = $documentClass::isFactoryBased($entityType)
96 ? FactoryBased::getEntityFields($entityType)
97 : $documentClass::getEntityFields($entityType);
104 return static::preparePersonalizeList($entityType, $fields);
113 foreach ($fields as $fieldCode => $field)
115 $items[$counter++] = [
116 'CODE' => $entityType.
'.'.$fieldCode,
117 'NAME' => $field[
'Name'],
118 'DESC' => $field[
'Name'],
120 if(isset($field[
'personalizeCode']) && $field[
'personalizeCode'])
122 $items[$counter - 1][
'CODE'] = implode(
124 Integration\Crm\Connectors\Personalize\BasePersonalize::getMap()[$field[
'personalizeCode']]
129 $name =
Loc::getMessage(
'SENDER_INTEGRATION_CRM_CONNECTOR_'.$entityType);
132 $name = \CCrmOwnerType::GetDescription(\CCrmOwnerType::ResolveID($entityType));
135 'CODE' => $entityType,
143 public static function getData($entityType, $entityIds, $fields = [
'*'])
145 $documentClass = self::PERSONALIZE_NAMESPACE.ucfirst($entityType);
147 if(!is_subclass_of($documentClass, BasePersonalize::class))
152 return $documentClass::isFactoryBased($entityType)
153 ? FactoryBased::getData($entityType, $entityIds, $fields)
154 : $documentClass::getData($entityType, $entityIds, $fields)
160 $connectors = Connector\Manager::getConnectorList();
170 if(method_exists(
$connector,
'getPersonalizeList'))
175 foreach ($list as $key => $data)
177 if(isset($data[
'ITEMS']) && in_array($data[
'CODE'], [
'LEAD',
'CONTACT',
'COMPANY']))
185 $items = array_merge($items, $list);
203 $ufManager = is_object(
$GLOBALS[
'USER_FIELD_MANAGER']) ?
$GLOBALS[
'USER_FIELD_MANAGER'] :
null;
209 $ufEntityId = \CCrmOwnerType::resolveUserFieldEntityID($entityTypeId);
210 $crmUserType = new \CCrmUserType($ufManager, $ufEntityId);
211 $logicFilter = array();
214 if (!$checkAccessRights)
216 $fieldsParams = [
'skipUserFieldVisibilityCheck' =>
true];
218 $crmUserType->prepareListFilterFields($list, $logicFilter, $fieldsParams);
219 $originalList = $crmUserType->getFields($fieldsParams);
220 $restrictedTypes = [
'address',
'file',
'crm',
'resourcebooking'];
222 $list = array_filter(
224 function ($field) use ($originalList, $restrictedTypes)
226 if (empty($originalList[$field[
'id']]))
231 $type = $originalList[$field[
'id']][
'USER_TYPE'][
'USER_TYPE_ID'];
232 return !in_array($type, $restrictedTypes);
236 foreach ($list as $index => $field)
238 if ($field[
'type'] ===
'date')
240 $list[$index][
'include'] = [
241 AdditionalDateType::CUSTOM_DATE,
242 AdditionalDateType::PREV_DAY,
243 AdditionalDateType::NEXT_DAY,
244 AdditionalDateType::MORE_THAN_DAYS_AGO,
245 AdditionalDateType::AFTER_DAYS,
247 if (!isset($list[$index][
'allow_years_switcher']))
249 $list[$index][
'allow_years_switcher'] =
true;
252 if ($originalList[$field[
'id']][
'MULTIPLE'] ==
'Y')
254 $list[$index][
'multiple_uf'] =
true;
271 $entityDbName =
null,
276 Recipient\Type::EMAIL => [
277 'name' =>
'HAS_EMAIL',
281 Recipient\Type::PHONE => [
282 'name' =>
'HAS_PHONE',
286 Recipient\Type::IM => [
287 'name' =>
'HAS_IMOL',
291 Recipient\Type::CRM_CONTACT_ID => [
292 'name' =>
'CONTACT_ID',
296 Recipient\Type::CRM_COMPANY_ID => [
297 'name' =>
'COMPANY_ID',
303 $entityName = $entityName ?? mb_strtoupper($query->getEntity()->getName());
307 if (!isset($map[$dataTypeId]))
312 $field = $map[$dataTypeId];
314 if($field[
'operator'] ===
null)
319 if ($dataTypeId == Recipient\Type::CRM_COMPANY_ID && in_array($entityName, [
'CONTACT']))
321 $field[
'name'] =
'CRM_COMPANY_ID';
324 $query->where($field[
'name'], $field[
'operator'], $field[
'value']);
325 if ($dataTypeId === Recipient\Type::IM)
327 $query->whereExists(self::getImSqlExpression($query, $entityDbName, $entityName));
330 else if (!in_array($entityName, [
'CONTACT',
'COMPANY']))
332 $filter = Entity\Query::filter();
333 foreach ($map as $dataTypeId => $field)
335 if($field[
'operator'] ===
null)
339 if ($dataTypeId === Recipient\Type::IM)
343 ->where($field[
'name'], $field[
'operator'], $field[
'value'])
344 ->whereExists(self::getImSqlExpression($query, $entityDbName, $entityName))
349 $filter->where($field[
'name'], $field[
'operator'], $field[
'value']);
353 if (count($filter->getConditions()) > 0)
355 $filter->logic(
'or');
356 $query->where($filter);
366 $entityDbName =
null,
370 $codes = Integration\Im\Service::getExcludedChannelCodes();
373 $codes = array(
'livechat',
'network');
376 $column = $entityDbName ?
'CRM_ENTITY_ID' :
'ID';
378 $entityTypeName = $entityName ?? mb_strtoupper($query->getEntity()->getName());
381 $regexp =
"'^imol\\\\|(" . implode(
'|', $codes) .
")'";
383 $filterImolSql =
"SELECT FM.VALUE " .
384 "FROM b_crm_field_multi FM " .
385 "WHERE FM.ENTITY_ID = '$entityTypeName' AND FM.ELEMENT_ID = ?#.{$column} " .
386 "AND FM.TYPE_ID = 'IM' " .
387 "AND NOT {$sqlHelper->getRegexpOperator('FM.VALUE', $regexp)} " .
388 "ORDER BY FM.ID LIMIT 1";
390 return new SqlExpression($filterImolSql, $query->getInitAlias());
401 if (isset(self::$runtimeByEntity[$entityTypeName]))
403 return self::$runtimeByEntity[$entityTypeName];
411 foreach ($filter as $key => $item)
413 if (!($item instanceof Connector\Filter\RuntimeFilter))
418 unset($filter[$key]);
419 $filter[$item->getKey()] = $item->getValue();
420 if (empty(self::$runtimeByEntity[$entityTypeName]))
422 self::$runtimeByEntity[$entityTypeName] = [];
424 self::$runtimeByEntity[$entityTypeName] = array_merge(
425 self::$runtimeByEntity[$entityTypeName],
427 function ($item) use ($entityTypeName)
429 $search = $entityTypeName ? $entityTypeName .
'_' :
'';
430 $runtimeName = $entityTypeName ? $entityTypeName .
'.' :
'';
431 $item[
'expression'] = str_replace(
436 $item[
'buildFrom'] = array_map(
437 function ($from) use ($search, $runtimeName)
439 return str_replace($search, $runtimeName, $from);
459 public static function getFilterByEntity(array $fields = array(), array $values = array(), array $entityTypeNames = array())
462 foreach ($entityTypeNames as $entityTypeName)
464 $map[$entityTypeName] = array($entityTypeName);
466 $map[
'CLIENT'] = array(\CCrmOwnerType::CompanyName, \CCrmOwnerType::ContactName);
467 $map[\CCrmOwnerType::CompanyName] = array(\CCrmOwnerType::CompanyName);
468 $map[\CCrmOwnerType::ContactName] = array(\CCrmOwnerType::ContactName);
471 foreach ($fields as $field)
473 if (!self::isFieldFilterable($field, $values))
479 foreach ($map as $prefix => $entityTypes)
481 $search = $prefix .
'_';
482 if (mb_strpos($id, $search) !== 0)
487 foreach ($entityTypes as $entityTypeName)
489 $filterKey =
"$entityTypeName.".mb_substr($id, mb_strlen($search));
490 if (!self::isFieldTypeFilter($field[
'type']))
492 $filterKey =
"=$filterKey";
494 if ($field[
'multiple_uf'] ??
false)
496 $filterKey .=
"_SINGLE";
499 $field[
'sender_segment_filter'] = $filterKey;
500 if (!isset($result[$entityTypeName]))
502 $result[$entityTypeName] = array();
505 $result[$entityTypeName][] = $field;
512 self::$runtimeByEntity = [];
513 foreach ($result as $entityTypeName => $fields)
515 $items = self::getFilterByFields($fields, $values, $entityTypeName);
517 $result[$entityTypeName] = $items;
523 private static function isFieldFilterable(array $field = array(), array $values = array())
526 $codeKey =
'sender_segment_filter';
527 if (isset($field[$codeKey]) && $field[$codeKey] ===
false)
532 if (!isset($values[$id]) || (!$values[$id] && !is_numeric($values[$id])))
548 public static function getFilterByFields(array $fields = array(), array $values = array(), $entityTypeName =
'')
552 if (!empty(self::$runtimeByEntity[$entityTypeName]))
554 self::$runtimeByEntity[$entityTypeName] = [];
559 self::$runtimeByEntity = [];
563 foreach ($fields as $field)
565 if (!self::isFieldFilterable($field, $values))
571 if (isset($field[
'params']) && is_array($field[
'params']))
573 if (isset($field[
'params'][
'multiple']) && $field[
'params'][
'multiple'])
580 $value = $values[$id];
581 $value = $isMultiple && !is_array($value) ? array($value) :
582 ($value ===
"" ?
null:$value);
586 foreach($value as &$val)
595 $field[
'value'] = $value;
597 if ($field[
'filter_callback'] ??
false)
599 $extraCallbackParams = [
601 'ENTITY_TYPE_NAME' => $entityTypeName
603 call_user_func_array($field[
'filter_callback'], [$value, &$filter, $extraCallbackParams]);
607 $filterKey = self::getFilterFieldKey($field);
608 if (is_array($filterKey))
610 foreach ($filterKey as $fieldValue => $fieldFilter)
612 if ($value !== $fieldValue)
617 $filter[$fieldFilter[0]] = $fieldFilter[1];
620 elseif (self::isFieldTypeFilter($field[
'type']))
622 self::setFieldTypeFilter($filterKey, $field, $filter);
623 self::processRuntimeFilter($filter, $entityTypeName);
627 $filter[$filterKey] = $value;
636 $codeKey =
'sender_segment_filter';
639 if (isset($field[$codeKey]) && $field[$codeKey])
641 return $field[$codeKey];
644 if (self::isFieldTypeFilter($field[
'type']))
659 return in_array(mb_strtoupper($type), $types);
664 $fieldData[
'filter-key'] = $filterKey;
665 switch(mb_strtoupper($fieldData[
'type']))
668 Connector\Filter\DateField::create($fieldData)->applyFilter($filter);
671 Connector\Filter\NumberField::create($fieldData)->applyFilter($filter);
674 Connector\Filter\DestSelectorField::create($fieldData)->applyFilter($filter);
681 if (in_array(\CCrmFieldMulti::PHONE, $commTypes))
683 $filter[
'=HAS_PHONE'] =
'Y';
685 if (in_array(\CCrmFieldMulti::EMAIL, $commTypes))
687 $filter[
'=HAS_EMAIL'] =
'Y';
689 if (in_array(\CCrmFieldMulti::IM, $commTypes))
691 $filter[
'=HAS_IMOL'] =
'Y';
697 if (is_array($value))
702 $filter[
'@CRM_ENTITY_ID'] = array_map(
'trim', explode(
",", $value));
707 $entityTypeName = $extraCallbackParams[
'ENTITY_TYPE_NAME'];
708 $field = $extraCallbackParams[
'FIELD'];
709 if (!$entityTypeName)
712 if ($value[$field[
'id'] .
'_datesel'] !=
'NONE')
714 $filter[
'NO_PURCHASES'] = [];
715 self::setFieldTypeFilter(
'%PURCHASE_DATE%', $field, $filter[
'NO_PURCHASES']);
716 self::processRuntimeFilter($filter[
'NO_PURCHASES'], $entityTypeName);
722 if ($filter[
'NO_PURCHASES'] || $filter[
'=COMPANY.PRODUCT_ID'] || $filter[
'=CONTACT.PRODUCT_ID'])
724 if (!is_array($value) || in_array(
"", $value))
728 $filter[
'PRODUCT_SOURCE'] = $value;
734 $filter[
'DEAL'] = [];
735 foreach ($values as $k => $value)
739 $filter[
'DEAL'][] = [
'SGT_DEAL.ID',
'=', $value];
740 $filter[
'DEAL'][
'JOIN_TYPE'] =
'LEFT';
746 $filter[
'DEAL'][] = [
'SGT_DEAL.CATEGORY_ID',
'in', $values];
758 switch ($row[
'CRM_ENTITY_TYPE_ID'])
760 case \CCrmOwnerType::Company:
761 $crmRow = \Bitrix\Crm\CompanyTable::getRowById($row[
'CRM_ENTITY_ID']);
762 $row[
'~NAME'] = self::getResultViewTitle(
763 $row[
'CRM_ENTITY_TYPE_ID'],
764 $row[
'CRM_ENTITY_ID'],
766 \CCrmOwnerType::GetDescription($row[
'CRM_ENTITY_TYPE_ID']),
767 self::getCrmStatusName(
'COMPANY_TYPE', $crmRow[
'COMPANY_TYPE'])
770 case \CCrmOwnerType::Contact:
771 $crmRow = \Bitrix\Crm\ContactTable::getRowById($row[
'CRM_ENTITY_ID']);
772 $row[
'~NAME'] = self::getResultViewTitle(
773 $row[
'CRM_ENTITY_TYPE_ID'],
774 $row[
'CRM_ENTITY_ID'],
776 \CCrmOwnerType::GetDescription($row[
'CRM_ENTITY_TYPE_ID']),
777 self::getCrmStatusName(
'SOURCE', $crmRow[
'SOURCE_ID'])
780 case \CCrmOwnerType::Lead:
781 $crmRow = \Bitrix\Crm\LeadTable::getRowById($row[
'CRM_ENTITY_ID']);
782 $row[
'CRM_LEAD'] = $row[
'~CRM_LEAD'] = self::getResultViewTitle(
783 $row[
'CRM_ENTITY_TYPE_ID'],
784 $row[
'CRM_ENTITY_ID'],
786 self::getCrmStatusName(
'SOURCE', $crmRow[
'SOURCE_ID']),
787 $crmRow[
'IS_RETURN_CUSTOMER'] ===
'Y' ?
Loc::getMessage(
'SENDER_INTEGRATION_CRM_CONNECTOR_LEAD_FIELD_RC_LEAD') : null
800 $sources = \CCrmStatus::GetStatus($statusType);
801 if (empty($sources[$statusId]))
806 return $sources[$statusId][
'NAME'];
809 protected function getResultViewTitle($entityTypeId, $entityId, $title, $secondTitle =
null, $thirdTitle =
null)
811 $url = self::getPathToDetail($entityTypeId, $entityId);
812 $title = htmlspecialcharsbx($title);
813 if ($url && \CCrmAuthorizationHelper::checkReadPermission($entityTypeId, $entityId))
815 $title =
'<a href="' . $url .
'">' . $title .
'</a>';
820 $title .=
"<br><span style=\"color:grey; font-size: 12px;\">";
821 $title .= htmlspecialcharsbx($secondTitle);
827 $title .=
"<br><span style=\"color:grey; font-size: 12px;\">";
828 $title .= htmlspecialcharsbx($thirdTitle);
839 return Container::getInstance()->getRouter()->getItemDetailUrl($entityTypeId, $entityId);
841 switch ($entityTypeId)
843 case \CCrmOwnerType::Company:
844 $optionName =
'path_to_company_details';
846 case \CCrmOwnerType::Contact:
847 $optionName =
'path_to_contact_details';
849 case \CCrmOwnerType::Lead:
850 $optionName =
'path_to_lead_details';
856 $url = $optionName ? Option::get(
'crm', $optionName) :
null;
860 [
'#company_id#',
'#contact_id#',
'#lead_id#'],
static getConnection($name="")
static includeModule($moduleName)
static loadMessages($file)
static getMessage($code, $replace=null, $language=null)
getResultViewTitle($entityTypeId, $entityId, $title, $secondTitle=null, $thirdTitle=null)
static getPersonalizeFieldsFromConnectors($isTrigger=false)
static getCommunicationTypeFilter(array $commTypes, &$filter, $extraCallbackParams=[])
static isCrmSaleEnabled()
static setFieldTypeFilter($filterKey, array $fieldData, &$filter)
static productSourceFilter($value, &$filter, $extraCallbackParams=[])
static buildPersonalizeList($entityType)
static getFilterFieldKey(array $field)
static preparePersonalizeList(string $entityType, array $fields)
getCrmStatusName($statusType, $statusId)
static getFilterByFields(array $fields=array(), array $values=array(), $entityTypeName='')
static isFieldTypeFilter($type)
static processRuntimeFilter(array &$filter, $entityTypeName='')
static getDealCategoryFilter($values, &$filter, $extraCallbackParams=[])
static getImSqlExpression(Entity\Query $query, $entityDbName=null, $entityName=null)
static getData($entityType, $entityIds, $fields=[' *'])
static prepareQuery(Entity\Query $query, $dataTypeId=null, $entityDbName=null, $entityName=null)
static createExpressionMultiField($entityName, $multiFieldTypeId)
static getFilterByEntity(array $fields=array(), array $values=array(), array $entityTypeNames=array())
getPathToDetail($entityTypeId, $entityId)
static getIdFilter($value, &$filter)
onResultViewDraw(array &$row)
static getPersonalizeList()
static getNoPurchasesFilter($value, &$filter, $extraCallbackParams=[])
static getRuntimeByEntity($entityTypeName='')
static getFilterUserFields(int $entityTypeId, bool $checkAccessRights=true)
$GLOBALS['____1444769544']