53 public static function getById($deliveryId)
55 $id = intval($deliveryId);
60 if(!isset(self::$cachedFields[$deliveryId]) || !is_array(self::$cachedFields[$deliveryId]))
62 self::$cachedFields[$deliveryId] = array();
64 $resSrvParams = Table::getList(array(
65 'filter' => array(
"=ID" => $deliveryId)
68 if($srvParams = $resSrvParams->fetch())
69 self::$cachedFields[$srvParams[
"ID"]] = $srvParams;
72 return self::$cachedFields[$deliveryId];
84 return Table::getList($params);
95 $services = self::getRestrictedList($shipment, $restrictionMode);
97 foreach($services as $srvParams)
99 if($srvParams[
"CLASS_NAME"]::canHasProfiles())
102 if(is_callable($srvParams[
"CLASS_NAME"].
"::canHasChildren") && $srvParams[
"CLASS_NAME"]::canHasChildren())
105 $service = self::getPooledObject($srvParams);
110 if(!$service->isCompatible($shipment))
113 if($shipment->
getCurrency() != $service->getCurrency())
115 $service->getExtraServices()->setOperationCurrency(
120 $result[$srvParams[
"ID"]] = $service;
133 if(intval($deliveryId) <= 0)
136 $srv = self::getById($deliveryId);
147 public static function getActiveList($calculatingOnly =
false, $restrictedIds =
null)
150 static $isDataPrepared =
false;
151 static $activeIds = array();
152 static $canHasProfiles = array();
153 static $canHasChildren = array();
154 static $DontHaveRestrictionsIds = array();
156 if(is_array($restrictedIds))
158 $unPreparedRestrictedIds = array_diff_key(
165 $unPreparedRestrictedIds = array_keys($unPreparedRestrictedIds);
169 $unPreparedRestrictedIds = array();
172 if(!$isDataPrepared || !empty($unPreparedRestrictedIds))
175 self::initHandlers();
182 'order' => array(
'SORT' =>
'ASC',
'NAME' =>
'ASC'),
186 $params[
'runtime'] = array(
188 'RESTRICTIONS_EXIST',
190 'SELECT 1 FROM b_sale_service_rstr SSR WHERE SSR.SERVICE_ID = %s AND SSR.SERVICE_TYPE = '.Restrictions\Manager::SERVICE_TYPE_SHIPMENT.
') THEN 1 ELSE 0 END',
195 $params[
'select'] = array(
'*',
'RESTRICTIONS_EXIST');
197 if(!empty($unPreparedRestrictedIds))
201 $params[
'filter'][
'ID'] = $unPreparedRestrictedIds;
205 $params[
'filter'][] = array(
207 "ID" => $unPreparedRestrictedIds,
208 'RESTRICTIONS_EXIST' => 0
213 $dbRes = Table::getList($params);
214 $profilesParentsIds = array();
216 while($service = $dbRes->fetch())
218 if(!is_subclass_of($service[
"CLASS_NAME"],
'Bitrix\Sale\Delivery\Services\Base'))
221 if(!$service[
'RESTRICTIONS_EXIST'])
222 $DontHaveRestrictionsIds[] = $service[
'ID'];
224 if($service[
"CLASS_NAME"]::canHasChildren())
225 $canHasChildren[$service[
"ID"]] =
true;
227 if ($service[
'CLASS_NAME']::canHasProfiles())
228 $canHasProfiles[$service[
"ID"]] =
true;
230 if($service[
"PARENT_ID"] != 0)
231 $profilesParentsIds[$service[
"PARENT_ID"]] = $service[
'ID'];
233 $result[$service[
"ID"]] = $service;
235 if($service[
'ACTIVE'] ==
'Y')
236 $activeIds[$service[
"ID"]] = $service[
"ID"];
239 foreach(array_diff_key($canHasProfiles, $profilesParentsIds) as $id => $tmp)
242 self::$cachedFields = self::$cachedFields + $result;
243 Restrictions\Manager::prepareData(array_keys($result));
244 ExtraServices\Manager::prepareData(array_keys($result));
247 if(!$isDataPrepared && empty($unPreparedRestrictedIds))
248 $isDataPrepared =
true;
251 if(is_array($restrictedIds) && !empty($restrictedIds))
252 $storedIds = array_diff($restrictedIds, $unPreparedRestrictedIds);
254 $storedIds = array();
256 if(!empty($storedIds) && is_array($storedIds))
258 foreach($storedIds as $storedId)
260 if(empty(self::$cachedFields[$storedId]))
263 $service = self::$cachedFields[$storedId];
265 if(!class_exists($service[
"CLASS_NAME"]))
268 if($service[
"CLASS_NAME"]::canHasChildren())
269 $canHasChildren[$storedId] =
true;
271 if ($service[
'CLASS_NAME']::canHasProfiles())
272 $canHasProfiles[$storedId] =
true;
274 if($service[
'ACTIVE'] ==
'Y')
275 $activeIds[$storedId] = $storedId;
279 $active = array_intersect_key(self::$cachedFields, array_flip($activeIds));
281 if(is_array($restrictedIds))
283 $result = array_intersect_key($active, array_flip($DontHaveRestrictionsIds));
285 if(!empty($restrictedIds))
286 $result = $result + array_intersect_key($active, array_flip($restrictedIds));
299 foreach($result as $id => $fields)
301 if(intval($fields[
'PARENT_ID']) <= 0)
304 if(empty($result[$fields[
'PARENT_ID']]))
309 $result = array_diff_key($result, $canHasChildren, $canHasProfiles);
312 sortByColumn($result, array(
"SORT" => SORT_ASC,
"NAME" => SORT_ASC),
'',
null,
true);
327 if(empty($skipChecks))
330 self::SKIP_CHILDREN_PARENT_CHECK,
331 self::SKIP_PROFILE_PARENT_CHECK
336 $restrictedSrvIds = Restrictions\Manager::getRestrictedIds($shipment, $restrictionMode);
338 $services = self::getActiveList(
false, array_keys($restrictedSrvIds));
340 foreach($services as $srvParams)
342 $srvParams[
"RESTRICTED"] =
false;
344 if(!in_array(self::SKIP_PROFILE_PARENT_CHECK, $skipChecks))
345 if($srvParams[
"CLASS_NAME"]::canHasProfiles())
348 if(!in_array(self::SKIP_CHILDREN_PARENT_CHECK, $skipChecks))
349 if(is_callable($srvParams[
"CLASS_NAME"].
"::canHasChildren") && $srvParams[
"CLASS_NAME"]::canHasChildren())
352 if(isset($restrictedSrvIds[$srvParams[
"ID"]]) && $restrictedSrvIds[$srvParams[
"ID"]] == Restrictions\Manager::SEVERITY_SOFT)
353 $srvParams[
"RESTRICTED"] =
true;
355 $result[$srvParams[
"ID"]] = $srvParams;
369 self::initHandlers();
373 if(!isset($srvParams[
'PARENT_ID']))
375 $srvParams[
'PARENT_ID'] = 0;
378 if(class_exists($srvParams[
'CLASS_NAME']))
380 if(is_subclass_of($srvParams[
'CLASS_NAME'], Base::class))
384 $service =
new $srvParams[
'CLASS_NAME']($srvParams);
388 $errorMsg = $err->getMessage();
393 $errorMsg =
'Class "' . $srvParams[
'CLASS_NAME'] .
'" is not subclass of of Bitrix\Sale\Delivery\Services\Base';
398 $errorMsg =
'Can\'t create delivery object. Class "'.$srvParams[
'CLASS_NAME'].
'" does not exist.';
405 'SEVERITY' => \CEventLog::SEVERITY_ERROR,
406 'AUDIT_TYPE_ID' =>
'SALE_DELIVERY_CREATE_OBJECT_ERROR',
407 'MODULE_ID' =>
'sale',
408 'ITEM_ID' =>
'createObject()',
409 'DESCRIPTION' => $errorMsg.
' Fields: '.serialize($srvParams),
419 protected static function log(array $params): void
421 \CEventLog::Add($params);
426 if(self::$objectsPool ===
null)
429 return self::$objectsPool->getObject($fields);
440 if(intval($deliveryId) <= 0 )
443 $srvParams = self::getById($deliveryId);
445 if(empty($srvParams))
448 return self::getPooledObject($srvParams);
460 if($serviceCode ==
'' )
463 $srvParams = array();
465 foreach(self::$cachedFields as $id => $srv)
467 if($srv[
'CODE'] == $serviceCode)
473 if(empty($srvParams))
475 $resSrvParams = Table::getList(array(
476 'filter' => array(
'=CODE' => $serviceCode)
479 if(!($srvParams = $resSrvParams->fetch()))
480 throw new SystemException(
"Can't get delivery service data with code: \"".$serviceCode.
"\"");
482 self::$cachedFields[$srvParams[
'ID']] = $srvParams;
485 return self::getPooledObject($srvParams);
495 protected static function initHandlers()
497 if(self::$handlers !==
null)
500 self::$handlersDirectories = array(
501 'LOCAL' =>
'/local/php_interface/include/sale_delivery/',
502 'CUSTOM' => Option::get(
'sale',
'delivery_handles_custom_path', BX_PERSONAL_ROOT.
'/php_interface/include/sale_delivery/'),
503 'SYSTEM' =>
'/bitrix/modules/sale/handlers/delivery/'
507 '\Bitrix\Sale\Delivery\Services\Group' =>
'lib/delivery/services/group.php',
508 '\Bitrix\Sale\Delivery\Services\Automatic' =>
'lib/delivery/services/automatic.php',
509 '\Bitrix\Sale\Delivery\Services\Configurable' =>
'lib/delivery/services/configurable.php',
510 '\Bitrix\Sale\Delivery\Services\AutomaticProfile' =>
'lib/delivery/services/automatic_profile.php',
511 '\Bitrix\Sale\Delivery\Services\EmptyDeliveryService' =>
'lib/delivery/services/emptydeliveryservice.php',
514 \Bitrix\Main\Loader::registerAutoLoadClasses(
'sale', $result);
533 $event =
new Event(
'sale',
'onSaleDeliveryHandlersClassNamesBuildList');
535 $resultList = $event->getResults();
537 if (is_array($resultList) && !empty($resultList))
539 $customClasses = array();
541 foreach ($resultList as $eventResult)
544 if ($eventResult->getType() != EventResult::SUCCESS)
547 $params = $eventResult->getParameters();
549 if(!empty($params) && is_array($params))
550 $customClasses = array_merge($customClasses, $params);
553 if(!empty($customClasses))
555 \Bitrix\Main\Loader::registerAutoLoadClasses(
null, $customClasses);
556 $result = array_merge($result, $customClasses);
560 $handlers = self::getHandlersClasses();
562 if(!empty($handlers))
564 \Bitrix\Main\Loader::registerAutoLoadClasses(
null, $handlers);
565 $result = array_merge($result, self::getHandlersClasses());
568 self::$handlers = array_keys($result);
570 for($idx = count(self::$handlers) - 1; $idx >= 0; $idx--)
573 $handler = self::$handlers[$idx];
575 if(!$handler::isHandlerCompatible())
577 unset(self::$handlers[$idx]);
581 $profiles = $handler::getChildrenClassNames();
583 if(!empty($profiles))
585 self::$handlers = array_merge(self::$handlers, $profiles);
596 protected static function getHandlersClasses()
600 foreach(self::$handlersDirectories as $handlersDirectory)
602 $dirPath = $_SERVER[
'DOCUMENT_ROOT'].$handlersDirectory;
607 $dir =
new Directory($_SERVER[
'DOCUMENT_ROOT'].$handlersDirectory);
609 foreach ($dir->getChildren() as $handler)
611 if (!$handler->isDirectory())
616 $handlerDir = $handler->getPath();
617 $handlerPath = $handlerDir.
'/handler.php';
619 if(!File::isFileExists($handlerPath))
622 $handlerClassName = ucfirst($handler->getName().
'Handler');
623 $fullClassName =
'\Sale\Handlers\Delivery\\'.$handlerClassName;
624 $result[$fullClassName] = $handlersDirectory.$handler->getName().
'/handler.php';
625 require_once($handlerPath);
638 if(self::$handlers ===
null)
639 self::initHandlers();
641 return self::$handlers;
652 static $init =
false;
656 $restHandlerList = \Bitrix\Sale\Delivery\Rest\Internals\DeliveryRestHandlerTable::getList([
657 'select' => [
'ID',
'NAME',
'CODE',
'SORT',
'DESCRIPTION',
'SETTINGS',
'PROFILES'],
659 foreach ($restHandlerList as $restHandler)
661 self::$restHandlers[$restHandler[
'CODE']] = $restHandler;
665 return self::$restHandlers;
685 $result = $delivery->calculate($shipment, $extraServices);
690 $result->addError(
new Error(
"Can't create delivery service object with id: \"".$deliveryId.
"\""));
706 $group = Table::getRow([
710 '=CLASS_NAME' =>
'\Bitrix\Sale\Delivery\Services\Group',
716 $result = $group[
"ID"];
722 'CLASS_NAME' =>
'\Bitrix\Sale\Delivery\Services\Group',
724 'CURRENCY' => Option::get(
'sale',
'default_currency'),
727 if($res->isSuccess())
728 $result = (int)$res->getId();
744 $srvList = self::getActiveList();
746 foreach($srvList as $id => $srv)
748 if($srv[
'PARENT_ID'] == $parentId)
750 $result[$srv[
'ID']] = $srv;
763 return 'Bitrix\Sale\Delivery\DeliveryLocation';
773 public static function add(array $fields)
775 self::initHandlers();
777 if(!empty($fields[
"CLASS_NAME"]))
780 $onBeforeAddResult = $fields[
"CLASS_NAME"]::onBeforeAdd($fields);
781 if (!$onBeforeAddResult->isSuccess())
783 return (
new AddResult())->addErrors($onBeforeAddResult->getErrors());
787 $res = \Bitrix\Sale\Delivery\Services\Table::add($fields);
789 if($res->isSuccess())
791 if(!empty($fields[
"CLASS_NAME"]))
792 $fields[
"CLASS_NAME"]::onAfterAdd($res->getId(), $fields);
794 if(!empty($fields[
'CODE']))
795 self::setIdCodeCached($res->getId(), $fields[
'CODE']);
806 return uniqid(
'bx_');
817 public static function update($id, array $fields)
819 self::initHandlers();
821 if (!empty($fields[
"CLASS_NAME"]) && class_exists($fields[
"CLASS_NAME"]))
823 $fields[
"CLASS_NAME"]::onBeforeUpdate($id, $fields);
826 $res = \Bitrix\Sale\Delivery\Services\Table::update($id, $fields);
828 if ($res->isSuccess())
830 if (!empty($fields[
"CLASS_NAME"]) && class_exists($fields[
"CLASS_NAME"]))
832 $fields[
"CLASS_NAME"]::onAfterUpdate($res->getId(), $fields);
835 if (isset($fields[
'CODE']))
837 self::cleanIdCodeCached($id);
840 if (Loader::includeModule(
'pull'))
842 \CPullWatch::AddToStack(
843 'SALE_DELIVERY_SERVICE',
845 'module_id' =>
'sale',
846 'command' =>
'onDeliveryServiceSave',
868 public static function delete($id,
bool $checkServiceUsage =
true)
875 if ($checkServiceUsage)
877 $res = self::checkServiceUsage($id);
878 if (!$res->isSuccess())
884 self::initHandlers();
886 $res = Table::getList(array(
890 'select' => array(
'ID',
'CLASS_NAME',
'LOGOTIP')
896 if ($service = $res->fetch())
898 $className = $service[
'CLASS_NAME'];
899 $logotip = intval($service[
'LOGOTIP']);
902 $res = \Bitrix\Sale\Delivery\Services\Table::delete($id);
904 if ($res->isSuccess())
906 if (!empty($className) && class_exists($className))
908 $className::onAfterDelete($id);
911 self::deleteRelatedEntities($id, $checkServiceUsage);
915 \CFile::Delete($logotip);
929 public static function onGetBusinessValueConsumers()
931 static $result =
null;
937 $handlers = self::getHandlersList();
938 $consumers = array();
941 foreach($handlers as $handlerClassName)
943 $tmpCons = $handlerClassName::onGetBusinessValueConsumers();
947 $consumers[$handlerClassName] = $tmpCons;
950 $res = Table::getList(array(
952 '=CLASS_NAME' => array_keys($consumers),
955 'select' => array(
'ID',
'CLASS_NAME',
'NAME')
958 while($dlv = $res->fetch())
960 $result[
'DELIVERY_'.$dlv[
'ID']] = $consumers[$dlv[
'CLASS_NAME']];
961 $result[
'DELIVERY_'.$dlv[
'ID']][
'NAME'] = $dlv[
'NAME'];
967 public static function onGetBusinessValueGroups()
970 'DELIVERY' => array(
'NAME' =>
Loc::getMessage(
'SALE_DLVR_MNGR_DLV_SRVS'),
'SORT' => 100),
973 $handlers = self::getHandlersList();
976 foreach($handlers as $handlerClassName)
977 $result = array_merge($result, $handlerClassName::onGetBusinessValueGroups());
996 $res = Table::getList(array(
997 'filter' => array(
'PARENT_ID' => $id),
998 'select' => array(
'ID')
1001 while($child = $res->fetch())
1003 $ures = self::update($child[
'ID'], $fields);
1005 if($ures->isSuccess())
1008 $counter += self::setChildrenFieldsValues($child[
'ID'], $fields);
1020 $result = self::getIdCodeCached($code,
"code");
1022 if($result !==
false)
1025 foreach(self::$cachedFields as $id => $srv)
1027 if($srv[
'CODE'] == $code)
1033 if(intval($result) <= 0)
1035 $res = Table::getList(array(
1041 if($handler = $res->fetch())
1043 $result = $handler[
"ID"];
1044 self::$cachedFields[$handler[
"ID"]] = $handler;
1048 $result = intval($result);
1049 self::setIdCodeCached($result, $code);
1060 $result = self::getIdCodeCached($id,
"id");
1062 if($result !==
false)
1065 $srv = self::getById($id);
1067 $result = $srv[
'CODE'];
1068 self::setIdCodeCached($id, $result);
1082 $cacheId =
"SALE_DELIVERY_ID_CODE_MAP_".($type ==
"id" ?
"I" :
"C").
"_".$value;
1083 $cacheManager = \Bitrix\Main\Application::getInstance()->getManagedCache();
1085 if($cacheManager->read($ttl, $cacheId))
1086 $result = $cacheManager->get($cacheId);
1098 $cacheManager = \Bitrix\Main\Application::getInstance()->getManagedCache();
1099 $cacheManager->set(
"SALE_DELIVERY_ID_CODE_MAP_I_".$id, $code);
1100 $cacheManager->set(
"SALE_DELIVERY_ID_CODE_MAP_C_".$code, $id);
1109 $cacheManager = \Bitrix\Main\Application::getInstance()->getManagedCache();
1110 $code = self::getIdCodeCached($id,
"id");
1111 $cacheManager->clean(
"SALE_DELIVERY_ID_CODE_MAP_I_".$id);
1114 $cacheManager->clean(
"SALE_DELIVERY_ID_CODE_MAP_C_".$code);
1124 $res = ShipmentTable::getList(array(
1126 "=DELIVERY_ID" => $deliveryId,
1129 'select' => array(
"ID")
1150 if(self::isDeliveryInShipments($deliveryId))
1156 $dbRes = Table::getList(array(
1158 "PARENT_ID" => $deliveryId
1160 'select' => array(
"ID")
1163 while($child = $dbRes->fetch())
1165 if(self::isDeliveryInShipments($child[
"ID"]))
1187 $con = \Bitrix\Main\Application::getConnection();
1188 $deliveryId = (int)$deliveryId;
1190 $con->queryExecute(
"
1191 DELETE FROM b_sale_service_rstr
1193 SERVICE_ID = " . $deliveryId .
"
1194 AND SERVICE_TYPE = " . (
int)Restrictions\Manager::SERVICE_TYPE_SHIPMENT .
"
1196 $con->queryExecute(
"DELETE FROM b_sale_delivery2location WHERE DELIVERY_ID=".$deliveryId);
1197 $con->queryExecute(
"DELETE FROM b_sale_delivery2paysystem WHERE DELIVERY_ID=".$deliveryId);
1198 $con->queryExecute(
"DELETE FROM b_sale_delivery_es WHERE DELIVERY_ID=".$deliveryId);
1200 $dbRes = Table::getList(array(
1202 "PARENT_ID" => $deliveryId
1204 'select' => array(
"ID")
1207 while ($child = $dbRes->fetch())
1209 self::delete($child[
"ID"], $checkServiceUsage);
1212 self::cleanIdCodeCached($deliveryId);
1222 self::initHandlers();
1223 return \Bitrix\Sale\Delivery\Services\EmptyDeliveryService::getEmptyDeliveryServiceId();
1237 public static function checkServiceRestriction($deliveryId, $checkParams, $restrictionClassName)
1239 if(empty($deliveryId))
1242 if(!is_array($deliveryId))
1243 $deliveryId = array($deliveryId);
1245 $dbRstrRes = ServiceRestrictionTable::getList(array(
1247 '=SERVICE_ID' => $deliveryId,
1248 '=SERVICE_TYPE' => Restrictions\Manager::SERVICE_TYPE_SHIPMENT,
1249 '=CLASS_NAME' => $restrictionClassName
1255 $restriction = static::getRestrictionObject($restrictionClassName);
1257 while($rstFields = $dbRstrRes->fetch())
1259 $rstParams = is_array($rstFields[
"PARAMS"]) ? $rstFields[
"PARAMS"] : array();
1260 $tmp[$rstFields[
'SERVICE_ID']] = $restriction->check($checkParams, $rstParams, $rstFields[
'SERVICE_ID']);
1263 if(count($deliveryId) == 1)
1264 return current($tmp);
1268 foreach($deliveryId as $id)
1269 if(!isset($tmp[$id]) || (isset($tmp[$id]) && $tmp[$id] ==
true))
1286 self::initHandlers();
1288 if(!class_exists($class))
1291 if(!is_subclass_of($class,
'Bitrix\Sale\Delivery\Services\Base'))
1307 return $delivery->calculate($shipment);
1315 if(!class_exists($className))
1318 static $cache = array();
1320 if(isset($cache[$className]))
1321 return $cache[$className];
1323 $restriction =
new $className;
1325 if(!is_subclass_of($className,
'Bitrix\Sale\Services\Base\Restriction'))
1326 throw new SystemException(
'Object must be the instance of Bitrix\Sale\Services\Base\Restriction');
1328 $cache[$className] = $restriction;
1329 return $restriction;
1337 return Restrictions\Manager::checkService($deliveryId, $shipment) == Restrictions\Manager::SEVERITY_NONE;
1345 return self::getRestrictedObjectsList($shipment);
1353 return self::isServiceExist($deliveryId);
1361 return self::getActiveList();
1369 return self::getRestrictedList($shipment, Restrictions\Manager::MODE_CLIENT, $skipChecks);
1377 return self::createObject($srvParams);
1393 return self::getObjectByCode($serviceCode);
1401 return self::getHandlersList();
1409 return Restrictions\Manager::getClassesList();
1417 return Restrictions\Manager::getRestrictionsList($deliveryId);
static getMessage($code, $replace=null, $language=null)