Example #1
0
 public static function getConnectedEntitiesQuery($locationPrimary, $linkType = 'id', $parameters = array())
 {
     if ($linkType == 'id') {
         $locationPrimary = Assert::expectIntegerPositive($locationPrimary, Loc::getMessage('SALE_LOCATION_CONNECTOR_ENTITY_LOCATION_PRIMARY_FLD_NAME'));
     } else {
         $locationPrimary = Assert::expectStringNotNull($locationPrimary, Loc::getMessage('SALE_LOCATION_CONNECTOR_ENTITY_LOCATION_PRIMARY_FLD_NAME'));
     }
     $useGroups = GroupTable::checkGroupUsage() && static::getUseGroups();
     // check if we have groups in project and entity uses groups
     $useCodes = static::getUseCodes();
     // this entity uses codes
     $groupUseCodes = GroupLocationTable::getUseCodes();
     // group entity uses codes
     $typeFld = static::getTypeField();
     /*LOCATION_TYPE*/
     $linkFld = static::getLinkField();
     /*DELIVERY_ID*/
     $locationLinkFld = static::getLocationLinkField();
     /*LOCATION_ID*/
     $targetPrimaryFld = static::getTargetEntityPrimaryField();
     /*ID*/
     $groupLocationLinkFld = GroupLocationTable::getLocationLinkField();
     /*LOCATION_ID*/
     $groupLinkFld = GroupLocationTable::getLinkField();
     /*LOCATION_GROUP_ID*/
     $seachById = $linkType == 'id';
     $dbConnection = Main\HttpApplication::getConnection();
     if (!is_array($parameters)) {
         $parameters = array();
     }
     if (is_array($parameters['runtime'])) {
         Assert::announceNotImplemented('Sorry, runtime clause is not implemented currently.');
     }
     $order = array();
     if (is_array($parameters['order'])) {
         Assert::announceNotImplemented('Sorry, order-over-union clause is not implemented currently.');
     }
     $filter = array();
     if (is_array($parameters['filter']) && !empty($parameters['filter'])) {
         $filter = $parameters['filter'];
     }
     $select = array('*');
     if (is_array($parameters['select']) && !empty($parameters['select'])) {
         $select = $parameters['select'];
     }
     /*
     query example when working with delivery:
     
     select distinct D.* from b_sale_delivery D
     	inner join b_sale_delivery2location DL on D.ID = DL.DELIVERY_ID and DL.LOCATION_TYPE = 'L'
     	inner join b_sale_location L1 on L1.CODE = DL.LOCATION_ID
     	inner join b_sale_location L2 on L2.ID(there will be CODE, if we search by code) = 65683 and L2.LEFT_MARGIN >= L1.LEFT_MARGIN and L2.RIGHT_MARGIN <= L1.RIGHT_MARGIN;
     */
     $query = new Entity\Query(static::getTargetEntityName());
     $DLCondition = array('=this.' . $targetPrimaryFld => 'ref.' . $linkFld);
     if ($useGroups) {
         $DLCondition['=ref.' . $typeFld] = array('?', self::DB_LOCATION_FLAG);
     }
     $query->registerRuntimeField('DL', array('data_type' => get_called_class(), 'reference' => $DLCondition, 'join_type' => 'inner'))->registerRuntimeField('L1', array('data_type' => '\\Bitrix\\Sale\\Location\\Location', 'reference' => array('=this.DL.' . $locationLinkFld => 'ref.' . ($useCodes ? 'CODE' : 'ID')), 'join_type' => 'inner'))->registerRuntimeField('L2', array('data_type' => '\\Bitrix\\Sale\\Location\\Location', 'reference' => array('=ref.' . ($seachById ? 'ID' : 'CODE') => array('?', $locationPrimary), '>=ref.LEFT_MARGIN' => 'this.L1.LEFT_MARGIN', '<=ref.RIGHT_MARGIN' => 'this.L1.RIGHT_MARGIN'), 'join_type' => 'inner'))->setSelect($select)->setFilter($filter)->setOrder($order);
     if (!$useGroups) {
         // emulate "select distinct"
         $query->setGroup($select);
         return $query->getQuery();
     } else {
         $sqls = array($query->getQuery());
         $query = new Entity\Query(static::getTargetEntityName());
         /*
         query example when working with delivery:
         
         select D.* from b_sale_delivery D
         	inner join b_sale_delivery2location DL on D.ID = DL.DELIVERY_ID and DL.LOCATION_TYPE = 'G'
         	inner join b_sale_location_group G on G.CODE = DL.LOCATION_ID (if this entity uses ID, skip this join)
         	inner join b_sale_grouplocation GL on GL.LOCATION_GROUP_ID = G.ID (if this entity uses ID, there will be DL.LOCATION_ID)
         	inner join b_sale_location L1 on L1.ID (there will be CODE, if grouplocation entity uses CODE) = GL.LOCATION_ID
         	inner join b_sale_location L2 on L2.ID (there will be CODE, if we seach by code) = 65683 and L2.LEFT_MARGIN >= L1.LEFT_MARGIN and L2.RIGHT_MARGIN <= L1.RIGHT_MARGIN;
         */
         $query->registerRuntimeField('DL', array('data_type' => get_called_class(), 'reference' => array('=this.' . $targetPrimaryFld => 'ref.' . $linkFld, '=ref.' . $typeFld => array('?', self::DB_GROUP_FLAG)), 'join_type' => 'inner'));
         if ($useCodes) {
             $query->registerRuntimeField('G', array('data_type' => '\\Bitrix\\Sale\\Location\\Group', 'reference' => array('=this.DL.' . $locationLinkFld => 'ref.CODE'), 'join_type' => 'inner'));
         }
         $query->registerRuntimeField('GL', array('data_type' => '\\Bitrix\\Sale\\Location\\GroupLocation', 'reference' => array($useCodes ? '=this.G.ID' : '=this.DL.' . $locationLinkFld => 'ref.' . $groupLinkFld), 'join_type' => 'inner'))->registerRuntimeField('L1', array('data_type' => '\\Bitrix\\Sale\\Location\\Location', 'reference' => array('=this.GL.' . $groupLocationLinkFld => 'ref.' . ($groupUseCodes ? 'CODE' : 'ID')), 'join_type' => 'inner'))->registerRuntimeField('L2', array('data_type' => '\\Bitrix\\Sale\\Location\\Location', 'reference' => array('=ref.' . ($seachById ? 'ID' : 'CODE') => array('?', $locationPrimary), '>=ref.LEFT_MARGIN' => 'this.L1.LEFT_MARGIN', '<=ref.RIGHT_MARGIN' => 'this.L1.RIGHT_MARGIN'), 'join_type' => 'inner'))->setSelect($select)->setFilter($filter)->setOrder($order);
         $sqls[] = $query->getQuery();
         return static::unionize($sqls);
     }
 }