uawdijnntqw1x1x1
IP : 52.14.115.102
Hostname : axolotl
Kernel : Linux axolotl 4.9.0-13-amd64 #1 SMP Debian 4.9.228-1 (2020-07-05) x86_64
Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,
OS : Linux
PATH:
/
var
/
www
/
axolotl
/
data
/
www
/
arhangelsk.axolotls.ru
/
a537b
/
binding.tar
/
/
dealcontact.php000066400000037060150044450540007547 0ustar00<?php /** * Bitrix Framework * @package bitrix * @subpackage crm * @copyright 2001-2016 Bitrix */ namespace Bitrix\Crm\Binding; use Bitrix\Main; use Bitrix\Main\Entity; use Bitrix\Crm; class DealContactTable extends Entity\DataManager { /** * Get table name. * @return string */ public static function getTableName() { return 'b_crm_deal_contact'; } /** * Get table fields map. * @return array */ public static function getMap() { return array( 'DEAL_ID' => array('primary' => true, 'data_type' => 'integer'), 'CONTACT_ID' => array('primary' => true, 'data_type' => 'integer'), 'SORT' => array('data_type' => 'integer', 'default_value' => 0), 'ROLE_ID' => array('data_type' => 'integer', 'default_value' => 0), 'IS_PRIMARY' => array('data_type' => 'boolean', 'values' => array('N', 'Y'), 'default_value' => 'N') ); } /** * Execute UPSERT operation. * @param array $data Field data. * @return void */ public static function upsert(array $data) { $dealID = isset($data['DEAL_ID']) ? (int)$data['DEAL_ID'] : 0; if($dealID <= 0) { throw new Main\ArgumentException('Must contains DEAL_ID field.', 'data'); } $contactID = isset($data['CONTACT_ID']) ? (int)$data['CONTACT_ID'] : 0; if($contactID <= 0) { throw new Main\ArgumentException('Must contains CONTACT_ID field.', 'data'); } $sort = isset($data['SORT']) ? (int)$data['SORT'] : 0; $roleID = isset($data['ROLE_ID']) ? (int)$data['ROLE_ID'] : 0; $primary = isset($data['IS_PRIMARY']) && strtoupper($data['IS_PRIMARY']) === 'Y' ? 'Y' : 'N'; $connection = Main\Application::getConnection(); $queries = $connection->getSqlHelper()->prepareMerge( 'b_crm_deal_contact', array('DEAL_ID', 'CONTACT_ID'), array('DEAL_ID' => $dealID, 'CONTACT_ID' => $contactID, 'SORT' => $sort, 'ROLE_ID' => $roleID, 'IS_PRIMARY' => $primary), array('SORT' => $sort, 'ROLE_ID' => $roleID, 'IS_PRIMARY' => $primary) ); foreach($queries as $query) { $connection->queryExecute($query); } } /** * Get deal IDs are bound to specified contact. * @param int $contactID Contact ID. * @return array * @throws Main\ArgumentException */ public static function getContactDealIDs($contactID) { $contactID = (int)$contactID; if($contactID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'contactID'); } $dbResult = Main\Application::getConnection()->query( /** @lang text*/ "SELECT DEAL_ID FROM b_crm_deal_contact WHERE CONTACT_ID = {$contactID}" ); $results = array(); while($ary = $dbResult->fetch()) { $results[] = (int)$ary['DEAL_ID']; } return $results; } /** * Get contact IDs are bound to specified deal. * @param int $dealID Deal ID. * @return array * @throws Main\ArgumentException */ public static function getDealContactIDs($dealID) { $dealID = (int)$dealID; if($dealID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'dealID'); } $dbResult = Main\Application::getConnection()->query( /** @lang text*/ "SELECT CONTACT_ID FROM b_crm_deal_contact WHERE DEAL_ID = {$dealID} ORDER BY SORT ASC" ); $results = array(); while($ary = $dbResult->fetch()) { $results[] = (int)$ary['CONTACT_ID']; } return $results; } /** * Get deal's bindings. * @param int $dealID Deal ID. * @return array * @throws Main\ArgumentException */ public static function getDealBindings($dealID) { $dealID = (int)$dealID; if($dealID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'dealID'); } $dbResult = Main\Application::getConnection()->query( /** @lang text*/ "SELECT CONTACT_ID, SORT, ROLE_ID, IS_PRIMARY FROM b_crm_deal_contact WHERE DEAL_ID = {$dealID} ORDER BY SORT" ); $results = array(); while($ary = $dbResult->fetch()) { $results[] = array( 'CONTACT_ID' => (int)$ary['CONTACT_ID'], 'SORT' => (int)$ary['SORT'], 'ROLE_ID' => (int)$ary['ROLE_ID'], 'IS_PRIMARY' => $ary['IS_PRIMARY'] ); } return $results; } /** * Get binding map for deal's collection. * @param array $dealIDs Array of Deal IDs. * @return array * @throws Main\ArgumentException * @throws Main\ObjectPropertyException * @throws Main\SystemException */ public static function getBulkDealBindings(array $dealIDs) { $bindingMap = array(); foreach($dealIDs as $dealID) { $bindingMap[$dealID] = array(); } $dbResult = self::getList( array( 'filter' => array('@DEAL_ID' => $dealIDs), 'select' => array('DEAL_ID', 'CONTACT_ID', 'SORT', 'ROLE_ID', 'IS_PRIMARY'), 'order' => array('DEAL_ID' => 'ASC', 'SORT' => 'ASC') ) ); while($ary = $dbResult->fetch()) { $bindingMap[$ary['DEAL_ID']][] = array( 'CONTACT_ID' => (int)$ary['CONTACT_ID'], 'SORT' => (int)$ary['SORT'], 'ROLE_ID' => (int)$ary['ROLE_ID'], 'IS_PRIMARY' => $ary['IS_PRIMARY'] ); } return $bindingMap; } /** * Get deal's binding count. * @param $dealID * @return int * @throws Main\ArgumentException */ public static function getDealBindingCount($dealID) { $dealID = (int)$dealID; if($dealID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'dealID'); } $dbResult = Main\Application::getConnection()->query( /** @lang text*/ "SELECT COUNT(*) CNT FROM b_crm_deal_contact WHERE DEAL_ID = {$dealID}" ); $ary = $dbResult->fetch(); return is_array($ary) ? (int)$ary['CNT'] : 0; } /** * Check if deal has contacts. * @param int $dealID Deal ID. * @return bool * @throws Main\ArgumentException */ public static function hasContacts($dealID) { $dealID = (int)$dealID; if($dealID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'dealID'); } $result = self::getList( array( 'select' => array('DEAL_ID'), 'filter' => array('=DEAL_ID' => $dealID), 'limit' => 1 ) ); return is_array($result->fetch()); } /** * Bind deal to contacts are specified by ID. * @param int $dealID Deal ID. * @param array $contactIDs Array of contact IDs. * @return void */ public static function bindContactIDs($dealID, array $contactIDs) { $bindings = EntityBinding::prepareEntityBindings(\CCrmOwnerType::Contact, $contactIDs); $qty = count($bindings); if($qty > 0) { for($i = 0; $i < $qty; $i++) { if($i === 0) { $bindings[$i]['IS_PRIMARY'] = 'Y'; } $bindings[$i]['SORT'] = 10 * ($i + 1); } self::bindContacts($dealID, $bindings); } } /** * Bind deal to contacts. * @param int $dealID Deal ID. * @param array $bindings Array of contact bindings. * @return void * @throws Main\ArgumentException */ public static function bindContacts($dealID, array $bindings) { $dealID = (int)$dealID; if($dealID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'dealID'); } $qty = count($bindings); if($qty === 0) { return; } $processed = 0; for($i = 0; $i < $qty; $i++) { $binding = $bindings[$i]; if(!is_array($binding)) { continue; } $contactID = isset($binding['CONTACT_ID']) ? (int)$binding['CONTACT_ID'] : 0; if($contactID <= 0) { continue; } self::upsert( array( 'DEAL_ID' => $dealID, 'CONTACT_ID' => $contactID, 'SORT' => isset($binding['SORT']) ? (int)$binding['SORT'] : (10 * ($i + 1)), 'ROLE_ID' => isset($binding['ROLE_ID']) ? (int)$binding['ROLE_ID'] : EntityBinding::ROLE_UNDEFINED, 'IS_PRIMARY' => isset($binding['IS_PRIMARY']) ? $binding['IS_PRIMARY'] : '' ) ); $processed++; } if($processed > 0) { Main\Application::getConnection()->queryExecute( /** @lang text*/ "UPDATE b_crm_deal SET CONTACT_ID = (SELECT MIN(CONTACT_ID) FROM b_crm_deal_contact WHERE IS_PRIMARY = 'Y' AND DEAL_ID = {$dealID}) WHERE ID = {$dealID}" ); } } /** * Unbind specified deal from specified contacts. * @param int $dealID Deal ID. * @param array $contactIDs Array of contact IDs. * @return void * @throws Main\ArgumentException */ public static function unbindContactIDs($dealID, array $contactIDs) { $dealID = (int)$dealID; if($dealID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'dealID'); } $contactIDs = array_filter($contactIDs); if(empty($contactIDs)) { return; } $connection = Main\Application::getConnection(); $values = implode(',', $contactIDs); $connection->queryExecute( /** @lang text */ "DELETE FROM b_crm_deal_contact WHERE DEAL_ID = {$dealID} AND CONTACT_ID IN({$values})" ); $connection->queryExecute( /** @lang text*/ "UPDATE b_crm_deal SET CONTACT_ID = (SELECT MIN(CONTACT_ID) FROM b_crm_deal_contact WHERE IS_PRIMARY = 'Y' AND DEAL_ID = {$dealID}) WHERE ID = {$dealID}" ); } /** * Unbind specified deal from specified contacts. * @param int $dealID Deal ID. * @param array $bindings Array of bindings. * @return void * @throws Main\ArgumentException */ public static function unbindContacts($dealID, array $bindings) { $dealID = (int)$dealID; if($dealID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'dealID'); } self::unbindContactIDs($dealID, EntityBinding::prepareEntityIDs(\CCrmOwnerType::Contact, $bindings)); } /** * Unbind specified deal from all contacts. * @param int $dealID Deal ID. * @return void * @throws Main\ArgumentException */ public static function unbindAllContacts($dealID) { $dealID = (int)$dealID; if($dealID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'dealID'); } $connection = Main\Application::getConnection(); $connection->queryExecute( /** @lang text */ "DELETE FROM b_crm_deal_contact WHERE DEAL_ID = {$dealID}" ); $connection->queryExecute( /** @lang text */ "UPDATE b_crm_deal SET CONTACT_ID = NULL WHERE ID = {$dealID}" ); } /** * Unbind specified contact from all deals. * @param int $contactID Contact ID. * @return void * @throws Main\ArgumentException */ public static function unbindAllDeals($contactID) { $contactID = (int)$contactID; if($contactID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'contactID'); } $connection = Main\Application::getConnection(); $connection->queryExecute( /** @lang text */ "DELETE FROM b_crm_deal_contact WHERE CONTACT_ID = {$contactID}" ); $connection->queryExecute( /** @lang text */ "UPDATE b_crm_deal SET CONTACT_ID = (SELECT MIN(CONTACT_ID) FROM b_crm_deal_contact t WHERE t.DEAL_ID = b_crm_deal.ID) WHERE CONTACT_ID = {$contactID}" ); } /** * Prepage SQL join filter condition for specified entity. * @param int $entityTypeID Entity type ID for filter. * @param int $entityID Entity ID for filter. * @param string $tableAlias Alias of primary table. * @return string * @throws Main\ArgumentException * @throws Main\ArgumentOutOfRangeException * @throws Main\NotSupportedException */ public static function prepareFilterJoinSql($entityTypeID, $entityID, $tableAlias) { if(!is_int($entityTypeID)) { $entityTypeID = (int)$entityTypeID; } if(!\CCrmOwnerType::IsDefined($entityTypeID)) { throw new Main\ArgumentOutOfRangeException('entityTypeID', \CCrmOwnerType::FirstOwnerType, \CCrmOwnerType::LastOwnerType ); } if($entityTypeID !== \CCrmOwnerType::Contact && $entityTypeID !== \CCrmOwnerType::Deal) { $entityTypeName = \CCrmOwnerType::ResolveName($entityTypeID); throw new Main\NotSupportedException("Entity type: '{$entityTypeName}' is not supported in current context"); } $entityIDs = is_array($entityID) ? $entityID : array($entityID); $effectiveIDs = array(); foreach($entityIDs as $ID) { $ID = (int)$ID; if($ID > 0) { $effectiveIDs[] = $ID; } } $qty = count($effectiveIDs); if($qty > 1) { $slug = implode(',', $effectiveIDs); if($entityTypeID === \CCrmOwnerType::Contact) { return "INNER JOIN b_crm_deal_contact DC ON DC.CONTACT_ID IN({$slug}) AND DC.DEAL_ID = {$tableAlias}.ID"; } else//if($entityTypeID === \CCrmOwnerType::Deal) { return "INNER JOIN b_crm_deal_contact DC ON DC.DEAL_ID IN({$slug}) AND DC.CONTACT_ID = {$tableAlias}.ID"; } } elseif($qty === 1) { if($entityTypeID === \CCrmOwnerType::Contact) { return "INNER JOIN b_crm_deal_contact DC ON DC.CONTACT_ID = {$effectiveIDs[0]} AND DC.DEAL_ID = {$tableAlias}.ID"; } else//if($entityTypeID === \CCrmOwnerType::Deal) { return "INNER JOIN b_crm_deal_contact DC ON DC.DEAL_ID = {$effectiveIDs[0]} AND DC.CONTACT_ID = {$tableAlias}.ID"; } } return ""; } /** * Unbind all contacts from seed deal and bind to target deal * @param int $seedDealID Seed deal ID. * @param int $targDealID Target deal ID. * @throws Main\ArgumentException */ public static function rebindAllContacts($seedDealID, $targDealID) { $seedDealID = (int)$seedDealID; if($seedDealID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'seedDealID'); } $targDealID = (int)$targDealID; if($targDealID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'targDealID'); } //Combine contacts from seed and target and bind to target. $connection = Main\Application::getConnection(); $dbResult = $connection->query( /** @lang text */ "SELECT CONTACT_ID FROM b_crm_deal_contact WHERE DEAL_ID IN ({$seedDealID}, {$targDealID}) GROUP BY CONTACT_ID" ); $contactIDs = array(); while($fields = $dbResult->fetch()) { $contactIDs[] = (int)$fields['CONTACT_ID']; } if(!empty($contactIDs)) { self::bindContactIDs($targDealID, $contactIDs); } //Clear seed bindings $connection->queryExecute( /** @lang text */ "DELETE FROM b_crm_deal_contact WHERE DEAL_ID = {$seedDealID}" ); } /** * Unbind all deals from seed contact and bind to target contact * @param int $seedContactID Seed contact ID. * @param int $targContactID Target contact ID. * @throws Main\ArgumentException */ public static function rebindAllDeals($seedContactID, $targContactID) { $seedContactID = (int)$seedContactID; if($seedContactID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'seedContactID'); } $targContactID = (int)$targContactID; if($targContactID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'targContactID'); } if($seedContactID === $targContactID) { return; } $connection = Main\Application::getConnection(); $dbResult = $connection->query( /** @lang text */ "SELECT DEAL_ID FROM b_crm_deal_contact WHERE CONTACT_ID = {$seedContactID}" ); while($fields = $dbResult->fetch()) { $dealID = (int)$fields['DEAL_ID']; $bindings = self::getDealBindings($dealID); $seedIndex = $targIndex = -1; for($i = 0, $l = count($bindings); $i < $l; $i++) { $binding = $bindings[$i]; $contactID = (int)$binding['CONTACT_ID']; if($contactID === $seedContactID) { $seedIndex = $i; } elseif($contactID === $targContactID) { $targIndex = $i; } if($seedIndex >= 0 && $targIndex >= 0) { break; } } $seedBinding = $seedIndex >= 0 ? $bindings[$seedIndex] : null; $targBinding = $targIndex >= 0 ? $bindings[$targIndex] : null; if(!is_array($seedBinding)) { continue; } self::unbindContactIDs($dealID, array($seedContactID)); $isPrimary = isset($seedBinding['IS_PRIMARY']) && $seedBinding['IS_PRIMARY'] === 'Y'; if(!is_array($targBinding)) { $seedBinding['CONTACT_ID'] = $targContactID; self::bindContacts($dealID, array($seedBinding)); } elseif($isPrimary) { $targBinding['IS_PRIMARY'] = 'Y'; self::bindContacts($dealID, array($targBinding)); } } } }quotecontact.php000066400000034757150044450540010011 0ustar00<?php /** * Bitrix Framework * @package bitrix * @subpackage crm * @copyright 2001-2016 Bitrix */ namespace Bitrix\Crm\Binding; use Bitrix\Main; use Bitrix\Main\Entity; class QuoteContactTable extends Entity\DataManager { /** * Get table name. * @return string */ public static function getTableName() { return 'b_crm_quote_contact'; } /** * Get table fields map. * @return array */ public static function getMap() { return array( 'QUOTE_ID' => array('primary' => true, 'data_type' => 'integer'), 'CONTACT_ID' => array('primary' => true, 'data_type' => 'integer'), 'SORT' => array('data_type' => 'integer', 'default_value' => 0), 'ROLE_ID' => array('data_type' => 'integer', 'default_value' => 0), 'IS_PRIMARY' => array('data_type' => 'boolean', 'values' => array('N', 'Y'), 'default_value' => 'N') ); } /** * Execute UPSERT operation. * @param array $data Field data. * @return void */ public static function upsert(array $data) { $quoteID = isset($data['QUOTE_ID']) ? (int)$data['QUOTE_ID'] : 0; if($quoteID <= 0) { throw new Main\ArgumentException('Must contains QUOTE_ID field.', 'data'); } $contactID = isset($data['CONTACT_ID']) ? (int)$data['CONTACT_ID'] : 0; if($contactID <= 0) { throw new Main\ArgumentException('Must contains CONTACT_ID field.', 'data'); } $sort = isset($data['SORT']) ? (int)$data['SORT'] : 0; $roleID = isset($data['ROLE_ID']) ? (int)$data['ROLE_ID'] : 0; $primary = isset($data['IS_PRIMARY']) && strtoupper($data['IS_PRIMARY']) === 'Y' ? 'Y' : 'N'; $connection = Main\Application::getConnection(); $queries = $connection->getSqlHelper()->prepareMerge( 'b_crm_quote_contact', array('QUOTE_ID', 'CONTACT_ID'), array('QUOTE_ID' => $quoteID, 'CONTACT_ID' => $contactID, 'SORT' => $sort, 'ROLE_ID' => $roleID, 'IS_PRIMARY' => $primary), array('SORT' => $sort, 'ROLE_ID' => $roleID, 'IS_PRIMARY' => $primary) ); foreach($queries as $query) { $connection->queryExecute($query); } } /** * Get quote IDs are bound to specified contact. * @param int $contactID Contact ID. * @return array * @throws Main\ArgumentException */ public static function getContactQuotesIDs($contactID) { $contactID = (int)$contactID; if($contactID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'contactID'); } $dbResult = Main\Application::getConnection()->query( /** @lang text*/ "SELECT QUOTE_ID FROM b_crm_quote_contact WHERE CONTACT_ID = {$contactID}" ); $results = array(); while($ary = $dbResult->fetch()) { $results[] = (int)$ary['QUOTE_ID']; } return $results; } /** * Get contact IDs are bound to specified quote. * @param int $quoteID Quote ID. * @return array * @throws Main\ArgumentException */ public static function getQuoteContactIDs($quoteID) { $quoteID = (int)$quoteID; if($quoteID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'quoteID'); } $dbResult = Main\Application::getConnection()->query( /** @lang text*/ "SELECT CONTACT_ID FROM b_crm_quote_contact WHERE QUOTE_ID = {$quoteID} ORDER BY SORT ASC" ); $results = array(); while($ary = $dbResult->fetch()) { $results[] = (int)$ary['CONTACT_ID']; } return $results; } /** * Get quote's bindings. * @param int $quoteID Quote ID. * @return array * @throws Main\ArgumentException */ public static function getQuoteBindings($quoteID) { $quoteID = (int)$quoteID; if($quoteID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'quoteID'); } $dbResult = Main\Application::getConnection()->query( /** @lang text*/ "SELECT CONTACT_ID, SORT, ROLE_ID, IS_PRIMARY FROM b_crm_quote_contact WHERE QUOTE_ID = {$quoteID} ORDER BY SORT" ); $results = array(); while($ary = $dbResult->fetch()) { $results[] = array( 'CONTACT_ID' => (int)$ary['CONTACT_ID'], 'SORT' => (int)$ary['SORT'], 'ROLE_ID' => (int)$ary['ROLE_ID'], 'IS_PRIMARY' => $ary['IS_PRIMARY'] ); } return $results; } /** * Get binding map for quote's collection. * @param array $quoteIDs Array of Quote IDs. * @return array * @throws Main\ArgumentException * @throws Main\ObjectPropertyException * @throws Main\SystemException */ public static function getBulkQuoteBindings(array $quoteIDs) { $bindingMap = array(); foreach($quoteIDs as $quoteID) { $bindingMap[$quoteID] = array(); } $dbResult = self::getList( array( 'filter' => array('@QUOTE_ID' => $quoteIDs), 'select' => array('QUOTE_ID', 'CONTACT_ID', 'SORT', 'ROLE_ID', 'IS_PRIMARY'), 'order' => array('QUOTE_ID' => 'ASC', 'SORT' => 'ASC') ) ); while($ary = $dbResult->fetch()) { $bindingMap[$ary['QUOTE_ID']][] = array( 'CONTACT_ID' => (int)$ary['CONTACT_ID'], 'SORT' => (int)$ary['SORT'], 'ROLE_ID' => (int)$ary['ROLE_ID'], 'IS_PRIMARY' => $ary['IS_PRIMARY'] ); } return $bindingMap; } /** * Get quote's binding count. * @param int $quoteID Quote ID. * @return int * @throws Main\ArgumentException */ public static function getQuoteBindingCount($quoteID) { $quoteID = (int)$quoteID; if($quoteID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'quoteID'); } $dbResult = Main\Application::getConnection()->query( /** @lang text*/ "SELECT COUNT(*) CNT FROM b_crm_quote_contact WHERE QUOTE_ID = {$quoteID}" ); $ary = $dbResult->fetch(); return is_array($ary) ? (int)$ary['CNT'] : 0; } /** * Check if quote has contacts. * @param int $quoteID Quote ID. * @return bool * @throws Main\ArgumentException */ public static function hasContacts($quoteID) { $quoteID = (int)$quoteID; if($quoteID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'quoteID'); } $result = self::getList( array( 'select' => array('QUOTE_ID'), 'filter' => array('=QUOTE_ID' => $quoteID), 'limit' => 1 ) ); return is_array($result->fetch()); } /** * Bind quote to contacts are specified by ID. * @param int $quoteID Quote ID. * @param array $contactIDs Array of contact IDs. * @return void */ public static function bindContactIDs($quoteID, array $contactIDs) { $bindings = EntityBinding::prepareEntityBindings(\CCrmOwnerType::Contact, $contactIDs); $qty = count($bindings); if($qty > 0) { for($i = 0; $i < $qty; $i++) { if($i === 0) { $bindings[$i]['IS_PRIMARY'] = 'Y'; } $bindings[$i]['SORT'] = 10 * ($i + 1); } self::bindContacts($quoteID, $bindings); } } /** * Bind quote to contacts. * @param int $quoteID Quote ID. * @param array $bindings Array of contact bindings. * @return void * @throws Main\ArgumentException */ public static function bindContacts($quoteID, array $bindings) { $quoteID = (int)$quoteID; if($quoteID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'quoteID'); } $qty = count($bindings); if($qty === 0) { return; } $processed = 0; for($i = 0; $i < $qty; $i++) { $binding = $bindings[$i]; $contactID = isset($binding['CONTACT_ID']) ? (int)$binding['CONTACT_ID'] : 0; if($contactID <= 0) { continue; } self::upsert( array( 'QUOTE_ID' => $quoteID, 'CONTACT_ID' => $contactID, 'SORT' => isset($binding['SORT']) ? (int)$binding['SORT'] : (10 * ($i + 1)), 'ROLE_ID' => isset($binding['ROLE_ID']) ? (int)$binding['ROLE_ID'] : EntityBinding::ROLE_UNDEFINED, 'IS_PRIMARY' => isset($binding['IS_PRIMARY']) ? $binding['IS_PRIMARY'] : '' ) ); $processed++; } if($processed > 0) { Main\Application::getConnection()->queryExecute( /** @lang text*/ "UPDATE b_crm_quote SET CONTACT_ID = (SELECT MIN(CONTACT_ID) FROM b_crm_quote_contact WHERE IS_PRIMARY = 'Y' AND QUOTE_ID = {$quoteID}) WHERE ID = {$quoteID}" ); } } /** * Unbind specified quote from specified contacts. * @param int $quoteID Quote ID. * @param array $contactIDs Array of contact IDs. * @return void * @throws Main\ArgumentException */ public static function unbindContactIDs($quoteID, array $contactIDs) { $quoteID = (int)$quoteID; if($quoteID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'quoteID'); } $contactIDs = array_filter($contactIDs); if(empty($contactIDs)) { return; } $connection = Main\Application::getConnection(); $values = implode(',', $contactIDs); $connection->queryExecute( /** @lang text */ "DELETE FROM b_crm_quote_contact WHERE QUOTE_ID = {$quoteID} AND CONTACT_ID IN({$values})" ); $connection->queryExecute( /** @lang text*/ "UPDATE b_crm_quote SET CONTACT_ID = (SELECT MIN(CONTACT_ID) FROM b_crm_quote_contact WHERE IS_PRIMARY = 'Y' AND QUOTE_ID = {$quoteID}) WHERE ID = {$quoteID}" ); } /** * Unbind specified quote from specified contacts. * @param int $quoteID Quote ID. * @param array $bindings Array of bindings. * @return void * @throws Main\ArgumentException */ public static function unbindContacts($quoteID, array $bindings) { $quoteID = (int)$quoteID; if($quoteID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'quoteID'); } self::unbindContactIDs($quoteID, EntityBinding::prepareEntityIDs(\CCrmOwnerType::Contact, $bindings)); } /** * Unbind specified quote from all contacts. * @param int $quoteID Quote ID. * @return void * @throws Main\ArgumentException */ public static function unbindAllContacts($quoteID) { $quoteID = (int)$quoteID; if($quoteID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'quoteID'); } $connection = Main\Application::getConnection(); $connection->queryExecute( /** @lang text */ "DELETE FROM b_crm_quote_contact WHERE QUOTE_ID = {$quoteID}" ); $connection->queryExecute( /** @lang text */ "UPDATE b_crm_quote SET CONTACT_ID = NULL WHERE ID = {$quoteID}" ); } /** * Unbind specified contact from all quotes. * @param int $contactID Contact ID. * @return void * @throws Main\ArgumentException */ public static function unbindAllQuotes($contactID) { $contactID = (int)$contactID; if($contactID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'contactID'); } $connection = Main\Application::getConnection(); $connection->queryExecute( /** @lang text */ "DELETE FROM b_crm_quote_contact WHERE CONTACT_ID = {$contactID}" ); $connection->queryExecute( /** @lang text */ "UPDATE b_crm_quote SET CONTACT_ID = (SELECT MIN(CONTACT_ID) FROM b_crm_quote_contact t WHERE t.QUOTE_ID = b_crm_quote.ID) WHERE CONTACT_ID = {$contactID}" ); } /** * Prepage SQL join filter condition for specified entity. * @param int $entityTypeID Entity type ID for filter. * @param int $entityID Entity ID for filter. * @param string $tableAlias Alias of primary table. * @return string * @throws Main\ArgumentException * @throws Main\ArgumentOutOfRangeException * @throws Main\NotSupportedException */ public static function prepareFilterJoinSql($entityTypeID, $entityID, $tableAlias) { if(!is_int($entityTypeID)) { $entityTypeID = (int)$entityTypeID; } if(!\CCrmOwnerType::IsDefined($entityTypeID)) { throw new Main\ArgumentOutOfRangeException('entityTypeID', \CCrmOwnerType::FirstOwnerType, \CCrmOwnerType::LastOwnerType ); } if($entityTypeID !== \CCrmOwnerType::Contact && $entityTypeID !== \CCrmOwnerType::Quote) { $entityTypeName = \CCrmOwnerType::ResolveName($entityTypeID); throw new Main\NotSupportedException("Entity type: '{$entityTypeName}' is not supported in current context"); } $entityIDs = is_array($entityID) ? $entityID : array($entityID); $effectiveIDs = array(); foreach($entityIDs as $ID) { $ID = (int)$ID; if($ID > 0) { $effectiveIDs[] = $ID; } } $qty = count($effectiveIDs); if($qty > 1) { $slug = implode(',', $effectiveIDs); if($entityTypeID === \CCrmOwnerType::Contact) { return "INNER JOIN b_crm_quote_contact QC ON QC.CONTACT_ID IN({$slug}) AND QC.QUOTE_ID = {$tableAlias}.ID"; } else//if($entityTypeID === \CCrmOwnerType::Quote) { return "INNER JOIN b_crm_quote_contact QC ON QC.QUOTE_ID IN({$slug}) AND QC.CONTACT_ID = {$tableAlias}.ID"; } } elseif($qty === 1) { if($entityTypeID === \CCrmOwnerType::Contact) { return "INNER JOIN b_crm_quote_contact QC ON QC.CONTACT_ID = {$effectiveIDs[0]} AND QC.QUOTE_ID = {$tableAlias}.ID"; } else//if($entityTypeID === \CCrmOwnerType::Quote) { return "INNER JOIN b_crm_quote_contact QC ON QC.QUOTE_ID = {$effectiveIDs[0]} AND QC.CONTACT_ID = {$tableAlias}.ID"; } } return ""; } /** * Unbind all quotes from seed contact and bind to target contact * @param int $seedContactID Seed contact ID. * @param int $targContactID Target contact ID. * @throws Main\ArgumentException */ public static function rebindAllQuotes($seedContactID, $targContactID) { $seedContactID = (int)$seedContactID; if($seedContactID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'seedContactID'); } $targContactID = (int)$targContactID; if($targContactID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'targContactID'); } if($seedContactID === $targContactID) { return; } $connection = Main\Application::getConnection(); $dbResult = $connection->query( /** @lang text */ "SELECT QUOTE_ID FROM b_crm_quote_contact WHERE CONTACT_ID = {$seedContactID}" ); while($fields = $dbResult->fetch()) { $quoteID = (int)$fields['QUOTE_ID']; $bindings = self::getQuoteBindings($quoteID); $seedIndex = $targIndex = -1; for($i = 0, $l = count($bindings); $i < $l; $i++) { $binding = $bindings[$i]; $contactID = (int)$binding['CONTACT_ID']; if($contactID === $seedContactID) { $seedIndex = $i; } elseif($contactID === $targContactID) { $targIndex = $i; } if($seedIndex >= 0 && $targIndex >= 0) { break; } } $seedBinding = $seedIndex >= 0 ? $bindings[$seedIndex] : null; $targBinding = $targIndex >= 0 ? $bindings[$targIndex] : null; if(!is_array($seedBinding)) { continue; } self::unbindContactIDs($quoteID, array($seedContactID)); $isPrimary = isset($seedBinding['IS_PRIMARY']) && $seedBinding['IS_PRIMARY'] === 'Y'; if(!is_array($targBinding)) { $seedBinding['CONTACT_ID'] = $targContactID; self::bindContacts($quoteID, array($seedBinding)); } elseif($isPrimary) { $targBinding['IS_PRIMARY'] = 'Y'; self::bindContacts($quoteID, array($targBinding)); } } } }bindinghelper.php000066400000017362150044450540010103 0ustar00<?php /** * Bitrix Framework * @package bitrix * @subpackage crm * @copyright 2001-2016 Bitrix */ namespace Bitrix\Crm\Binding; use Bitrix\Main; use Bitrix\Main\Localization\Loc; class BindingHelper { public static function prepareBindingInfos($ownerTypeID, $ownerID, $entityTypeID, $formID) { Loc::loadMessages(__FILE__); $userPermissions = \CCrmPerms::GetCurrentUserPermissions(); $formFieldNames = \CCrmViewHelper::getFormFieldNames($formID); $entityIDs = null; if($ownerTypeID === \CCrmOwnerType::Contact && $entityTypeID === \CCrmOwnerType::Company) { $entityIDs = ContactCompanyTable::getContactCompanyIDs($ownerID); } elseif($ownerTypeID === \CCrmOwnerType::Deal && $entityTypeID === \CCrmOwnerType::Contact) { $entityIDs = DealContactTable::getDealContactIDs($ownerID); } elseif($ownerTypeID === \CCrmOwnerType::Quote && $entityTypeID === \CCrmOwnerType::Contact) { $entityIDs = QuoteContactTable::getQuoteContactIDs($ownerID); } if(empty($entityIDs)) { return array(); } $prefix = \CCrmOwnerTypeAbbr::ResolveByTypeID($entityTypeID); $map = array(); if($entityTypeID === \CCrmOwnerType::Company) { $dbRes = \CCrmCompany::GetListEx( array(), array('@ID' => $entityIDs, 'CHECK_PERMISSIONS' => 'N'), false, false, array('ID', 'TITLE', 'LOGO') ); if(is_object($dbRes)) { $file = new \CFile(); while($fields = $dbRes->Fetch()) { $entityID = (int)$fields['ID']; $isEntityReadPermitted = \CCrmCompany::CheckReadPermission($entityID, $userPermissions); if(!$isEntityReadPermitted) { $info = array( 'ENTITY_TYPE_NAME' => \CCrmOwnerType::CompanyName, 'ENTITY_ID' => $entityID, 'ENABLE_MULTIFIELDS' => false, 'NAME' => Loc::getMessage('BINDING_HLP_HIDDEN_COMPANY') ); } else { $info = array( 'ENTITY_TYPE_NAME' => \CCrmOwnerType::CompanyName, 'ENTITY_ID' => $entityID, 'NAME' => isset($fields['TITLE']) ? $fields['TITLE'] : '', 'DESCRIPTION' => '', 'SHOW_URL' => \CCrmOwnerType::GetEntityShowPath(\CCrmOwnerType::Company, $fields['ID'], false), ); $imageID = isset($fields['LOGO']) ? (int)$fields['LOGO'] : 0; if($imageID <= 0) { $info['IMAGE_URL'] = ''; } else { $fileInfo = $file->ResizeImageGet( $imageID, array('width' => 48, 'height' => 31), BX_RESIZE_IMAGE_PROPORTIONAL ); $info['IMAGE_URL'] = is_array($fileInfo) && isset($fileInfo['src']) ? $fileInfo['src'] : ''; } $multiFieldDbRes = \CCrmFieldMulti::GetList( array('ID' => 'asc'), array('ENTITY_ID' => \CCrmOwnerType::CompanyName, 'ELEMENT_ID' => $entityID) ); $multiFieldData = array(); while($multiFields = $multiFieldDbRes->Fetch()) { $multiFieldData[$multiFields['TYPE_ID']][$multiFields['ID']] = array('VALUE' => $multiFields['VALUE'], 'VALUE_TYPE' => $multiFields['VALUE_TYPE']); } if(isset($multiFieldData['PHONE'])) { $info['PHONE'] = self::prepareMultiFields( $multiFieldData['PHONE'], \CCrmOwnerType::CompanyName, $entityID, 'PHONE', $formFieldNames ); } if(isset($multiFieldData['EMAIL'])) { $info['EMAIL'] = self::prepareMultiFields( $multiFieldData['EMAIL'], \CCrmOwnerType::CompanyName, $entityID, 'EMAIL', $formFieldNames ); } } $map["{$prefix}_{$entityID}"] = array('type' => 'client', 'data' => $info); } } } elseif($entityTypeID === \CCrmOwnerType::Contact) { $dbRes = \CCrmContact::GetListEx( array(), array('@ID' => $entityIDs, 'CHECK_PERMISSIONS' => 'N'), false, false, array('ID', 'HONORIFIC', 'NAME', 'SECOND_NAME', 'LAST_NAME', 'POST', 'PHOTO') ); if(is_object($dbRes)) { $file = new \CFile(); while($fields = $dbRes->Fetch()) { $entityID = (int)$fields['ID']; $isEntityReadPermitted = \CCrmContact::CheckReadPermission($entityID, $userPermissions); if(!$isEntityReadPermitted) { $info = array( 'ENTITY_TYPE_NAME' => \CCrmOwnerType::ContactName, 'ENTITY_ID' => $entityID, 'ENABLE_MULTIFIELDS' => false, 'NAME' => Loc::getMessage('BINDING_HLP_HIDDEN_CONTACT') ); } else { $info = array( 'ENTITY_TYPE_NAME' => \CCrmOwnerType::ContactName, 'ENTITY_ID' => $entityID, 'NAME' => \CCrmContact::PrepareFormattedName($fields), 'DESCRIPTION' => isset($fields['POST']) ? $fields['POST'] : '', 'SHOW_URL' => \CCrmOwnerType::GetEntityShowPath(\CCrmOwnerType::Contact, $fields['ID'], false), ); $imageID = isset($fields['PHOTO']) ? (int)$fields['PHOTO'] : 0; if($imageID <= 0) { $info['IMAGE_URL'] = ''; } else { $fileInfo = $file->ResizeImageGet( $imageID, array('width' => 38, 'height' => 38), BX_RESIZE_IMAGE_EXACT ); $info['IMAGE_URL'] = is_array($fileInfo) && isset($fileInfo['src']) ? $fileInfo['src'] : ''; } $multiFieldDbRes = \CCrmFieldMulti::GetList( array('ID' => 'asc'), array('ENTITY_ID' => \CCrmOwnerType::ContactName, 'ELEMENT_ID' => $entityID) ); $multiFieldData = array(); while($multiFields = $multiFieldDbRes->Fetch()) { $multiFieldData[$multiFields['TYPE_ID']][$multiFields['ID']] = array('VALUE' => $multiFields['VALUE'], 'VALUE_TYPE' => $multiFields['VALUE_TYPE']); } if(isset($multiFieldData['PHONE'])) { $info['PHONE'] = self::prepareMultiFields( $multiFieldData['PHONE'], \CCrmOwnerType::ContactName, $entityID, 'PHONE', $formFieldNames ); } if(isset($multiFieldData['EMAIL'])) { $info['EMAIL'] = self::prepareMultiFields( $multiFieldData['EMAIL'], \CCrmOwnerType::ContactName, $entityID, 'EMAIL', $formFieldNames ); } } $map["{$prefix}_{$entityID}"] = array('type' => 'client', 'data' => $info); } } } $results = array(); foreach($entityIDs as $entityID) { $key = "{$prefix}_{$entityID}"; if(isset($map[$key])) { $results[] = $map[$key]; } } return $results; } private static function prepareMultiFields(array $multiFields, $entityTypeName, $entityID, $typeID, array $formFieldNames = null) { if(empty($multiFields)) { return null; } $arEntityTypeInfos = \CCrmFieldMulti::GetEntityTypeInfos(); $arEntityTypes = \CCrmFieldMulti::GetEntityTypes(); $sipConfig = array( 'STUB' => GetMessage('CRM_ENTITY_QPV_MULTI_FIELD_NOT_ASSIGNED'), 'ENABLE_SIP' => true, 'SIP_PARAMS' => array( 'ENTITY_TYPE' => 'CRM_'.$entityTypeName, 'ENTITY_ID' => $entityID) ); $typeInfo = isset($arEntityTypeInfos[$typeID]) ? $arEntityTypeInfos[$typeID] : array(); $caption = isset($typeInfo['NAME']) ? $typeInfo['NAME'] : $typeID; if(is_array($formFieldNames) && isset($formFieldNames[$typeID])) { $caption = $formFieldNames[$typeID]; } $result = array( 'type' => 'multiField', 'caption' => $caption, 'data' => array('type'=> $typeID, 'items'=> array()) ); foreach($multiFields as $multiField) { $value = isset($multiField['VALUE']) ? $multiField['VALUE'] : ''; $valueType = isset($multiField['VALUE_TYPE']) ? $multiField['VALUE_TYPE'] : ''; $entityType = $arEntityTypes[$typeID]; $valueTypeInfo = isset($entityType[$valueType]) ? $entityType[$valueType] : null; $params = array('VALUE' => $value, 'VALUE_TYPE_ID' => $valueType, 'VALUE_TYPE' => $valueTypeInfo); $result['data']['items'][] = \CCrmViewHelper::PrepareMultiFieldValueItemData($typeID, $params, $sipConfig); } return $result; } }entitybinding.php000066400000036662150044450540010144 0ustar00<?php /** * Bitrix Framework * @package bitrix * @subpackage crm * @copyright 2001-2016 Bitrix */ namespace Bitrix\Crm\Binding; use Bitrix\Main; class EntityBinding { const ROLE_UNDEFINED = 0; /** * Verify binding structure. * @param int $entityTypeID Entity Type ID. * @param array $binding Source binding. * @return bool */ public static function verifyEntityBinding($entityTypeID, array $binding) { if(!is_int($entityTypeID)) { $entityTypeID = (int)$entityTypeID; } if(!\CCrmOwnerType::IsDefined($entityTypeID)) { return false; } if($entityTypeID === \CCrmOwnerType::Company) { $fieldName = 'COMPANY_ID'; } elseif($entityTypeID === \CCrmOwnerType::Contact) { $fieldName = 'CONTACT_ID'; } else { return false; } return is_array($binding) && isset($binding[$fieldName]) && $binding[$fieldName] > 0; } public static function normalizeEntityBindings($entityTypeID, array &$bindings) { if(!is_int($entityTypeID)) { $entityTypeID = (int)$entityTypeID; } if(!\CCrmOwnerType::IsDefined($entityTypeID)) { throw new Main\ArgumentOutOfRangeException('entityTypeID', \CCrmOwnerType::FirstOwnerType, \CCrmOwnerType::LastOwnerType ); } if($entityTypeID === \CCrmOwnerType::Company) { $fieldName = 'COMPANY_ID'; } elseif($entityTypeID === \CCrmOwnerType::Contact) { $fieldName = 'CONTACT_ID'; } else { $entityTypeName = \CCrmOwnerType::ResolveName($entityTypeID); throw new Main\NotSupportedException("Entity type: '{$entityTypeName}' is not supported in current context"); } $effectiveBindings = array(); $primaryBindingIndex = -1; for($i = 0, $l = count($bindings); $i < $l; $i++) { $binding = $bindings[$i]; if(!is_array($binding)) { continue; } $entityID = isset($binding[$fieldName]) ? (int)$binding[$fieldName] : 0; if($entityID <= 0) { continue; } if(!(isset($binding['SORT']) && $binding['SORT'] > 0)) { $binding['SORT'] = ($i + 1) * 10; } if(isset($binding['IS_PRIMARY'])) { if($binding['IS_PRIMARY'] === 'Y' && $primaryBindingIndex < 0) { $primaryBindingIndex = $i; } else { unset($binding['IS_PRIMARY']); } } $effectiveBindings[] = $binding; } if($primaryBindingIndex < 0 && count($effectiveBindings) > 0) { $effectiveBindings[0]['IS_PRIMARY'] = 'Y'; } $bindings = $effectiveBindings; } public static function addEntityBinding($entityTypeID, $entityID, array &$bindings) { if(!is_int($entityTypeID)) { $entityTypeID = (int)$entityTypeID; } if(!\CCrmOwnerType::IsDefined($entityTypeID)) { throw new Main\ArgumentOutOfRangeException('entityTypeID', \CCrmOwnerType::FirstOwnerType, \CCrmOwnerType::LastOwnerType ); } if($entityTypeID === \CCrmOwnerType::Company) { $fieldName = 'COMPANY_ID'; } elseif($entityTypeID === \CCrmOwnerType::Contact) { $fieldName = 'CONTACT_ID'; } else { $entityTypeName = \CCrmOwnerType::ResolveName($entityTypeID); throw new Main\NotSupportedException("Entity type: '{$entityTypeName}' is not supported in current context"); } $bindings[] = array($fieldName => (int)$entityID); $maxSort = 0; foreach($bindings as $binding) { $sort = isset($binding['SORT']) ? (int)$binding['SORT'] : 0; if($sort > $maxSort) { $maxSort = $sort; } elseif($sort <= 0) { $maxSort += 10; $binding['SORT'] = $maxSort; } } } public static function removeEntityBinding($entityTypeID, $entityID, array &$bindings) { if(!is_int($entityTypeID)) { $entityTypeID = (int)$entityTypeID; } if(!\CCrmOwnerType::IsDefined($entityTypeID)) { throw new Main\ArgumentOutOfRangeException('entityTypeID', \CCrmOwnerType::FirstOwnerType, \CCrmOwnerType::LastOwnerType ); } $index = self::findBindingIndexByEntityID($entityTypeID, $entityID, $bindings); if($index >= 0) { unset($bindings[$index]); $bindings = array_values($bindings); } } /** * Prepare entity bindings from array of entity IDs. * @param int $entityTypeID Entity Type ID. * @param array $entityIDs Entity IDs. * @return array * @throws Main\ArgumentOutOfRangeException * @throws Main\NotSupportedException */ public static function prepareEntityBindings($entityTypeID, array $entityIDs) { if(!is_int($entityTypeID)) { $entityTypeID = (int)$entityTypeID; } if(!\CCrmOwnerType::IsDefined($entityTypeID)) { throw new Main\ArgumentOutOfRangeException('entityTypeID', \CCrmOwnerType::FirstOwnerType, \CCrmOwnerType::LastOwnerType ); } if($entityTypeID === \CCrmOwnerType::Company) { $fieldName = 'COMPANY_ID'; } elseif($entityTypeID === \CCrmOwnerType::Contact) { $fieldName = 'CONTACT_ID'; } else { $entityTypeName = \CCrmOwnerType::ResolveName($entityTypeID); throw new Main\NotSupportedException("Entity type: '{$entityTypeName}' is not supported in current context"); } $bindings = array(); $entityIDs = array_filter($entityIDs); $sort = 0; foreach($entityIDs as $entityID) { if($entityID > 0) { $sort += 10; $bindings[] = array($fieldName => (int)$entityID, 'SORT' => $sort); } } return $bindings; } /** * Extract entity IDs from bindings. * @param int $entityTypeID Entity Type ID. * @param array $bindings Bindings. * @return array * @throws Main\ArgumentOutOfRangeException * @throws Main\NotSupportedException */ public static function prepareEntityIDs($entityTypeID, array $bindings) { if(!is_int($entityTypeID)) { $entityTypeID = (int)$entityTypeID; } if(!\CCrmOwnerType::IsDefined($entityTypeID)) { throw new Main\ArgumentOutOfRangeException('entityTypeID', \CCrmOwnerType::FirstOwnerType, \CCrmOwnerType::LastOwnerType ); } if($entityTypeID === \CCrmOwnerType::Company) { $fieldName = 'COMPANY_ID'; } elseif($entityTypeID === \CCrmOwnerType::Contact) { $fieldName = 'CONTACT_ID'; } else { $entityTypeName = \CCrmOwnerType::ResolveName($entityTypeID); throw new Main\NotSupportedException("Entity type: '{$entityTypeName}' is not supported in current context"); } $entityIDs = array(); foreach($bindings as $binding) { if(!is_array($binding)) { continue; } $entityID = is_array($binding) && isset($binding[$fieldName]) ? (int)$binding[$fieldName] : 0; if($entityID > 0) { $entityIDs[] = $entityID; } } return $entityIDs; } /** * Extract entity ID from binding. * @param int $entityTypeID Entity Type ID. * @param array $binding Bindings. * @return int * @throws Main\ArgumentOutOfRangeException * @throws Main\NotSupportedException */ public static function prepareEntityID($entityTypeID, array $binding) { if(!is_int($entityTypeID)) { $entityTypeID = (int)$entityTypeID; } if(!\CCrmOwnerType::IsDefined($entityTypeID)) { throw new Main\ArgumentOutOfRangeException('entityTypeID', \CCrmOwnerType::FirstOwnerType, \CCrmOwnerType::LastOwnerType ); } if($entityTypeID === \CCrmOwnerType::Company) { $fieldName = 'COMPANY_ID'; } elseif($entityTypeID === \CCrmOwnerType::Contact) { $fieldName = 'CONTACT_ID'; } else { $entityTypeName = \CCrmOwnerType::ResolveName($entityTypeID); throw new Main\NotSupportedException("Entity type: '{$entityTypeName}' is not supported in current context"); } return isset($binding[$fieldName]) ? (int)$binding[$fieldName] : 0; } /** * Extract entity ID from first binding. * @param int $entityTypeID Entity Type ID. * @param array $bindings Bindings. * @return array|int * @throws Main\ArgumentOutOfRangeException * @throws Main\NotSupportedException */ public static function getFirstEntityID($entityTypeID, array $bindings) { if(!(isset($bindings[0]) && is_array($bindings[0]))) { return 0; } return self::prepareEntityID($entityTypeID, $bindings[0]); } /** * Extract entity ID from last binding. * @param int $entityTypeID Entity Type ID. * @param array $bindings Bindings. * @return array|int * @throws Main\ArgumentOutOfRangeException * @throws Main\NotSupportedException */ public static function getLastEntityID($entityTypeID, array $bindings) { if(empty($bindings)) { return 0; } $index = count($bindings) - 1; return is_array($bindings[$index]) ? self::prepareEntityID($entityTypeID, $bindings[$index]) : 0; } /** * Mark first binding as primary. * @param array &$bindings Bindings. */ public static function markFirstAsPrimary(array &$bindings) { $qty = count($bindings); if($qty === 0) { return; } if(is_array($bindings[0])) { $bindings[0]['IS_PRIMARY'] = 'Y'; } for($i = 1; $i < $qty; $i++) { if(is_array($bindings[$i])) { unset($bindings[$i]['IS_PRIMARY']); } } } /** * Mark binding as primary. * @param array &$bindings Bindings. * @param int $entityTypeID Entity Type ID. * @param int $entityID Entity ID. */ public static function markAsPrimary(array &$bindings, $entityTypeID, $entityID) { if($entityTypeID === \CCrmOwnerType::Company) { $fieldName = 'COMPANY_ID'; } elseif($entityTypeID === \CCrmOwnerType::Contact) { $fieldName = 'CONTACT_ID'; } else { $entityTypeName = \CCrmOwnerType::ResolveName($entityTypeID); throw new Main\NotSupportedException("Entity type: '{$entityTypeName}' is not supported in current context"); } $qty = count($bindings); for($i = 0; $i < $qty; $i++) { if(!is_array($bindings[$i])) { continue; } if(isset($bindings[$i][$fieldName]) && $bindings[$i][$fieldName] == $entityID) { $bindings[$i]['IS_PRIMARY'] = 'Y'; } else { unset($bindings[$i]['IS_PRIMARY']); } } } public static function isPrimary(array $binding) { return isset($binding['IS_PRIMARY']) && $binding['IS_PRIMARY'] === 'Y'; } /** * Try find primary binding. * @param array $bindings Bindings. * @return array|null */ public static function findPrimaryBinding(array $bindings) { foreach($bindings as $binding) { if(!is_array($binding)) { continue; } if(isset($binding['IS_PRIMARY']) && $binding['IS_PRIMARY'] === 'Y') { return $binding; } } return null; } public static function findBindingIndexByEntityID($entityTypeID, $entityID, array $bindings) { $fieldName = self::resolveEntityFieldName($entityTypeID); if($fieldName === '') { return -1; } for($i = 0, $l = count($bindings); $i < $l; $i++) { if(!is_array($bindings[$i])) { continue; } if(isset($bindings[$i][$fieldName]) && $bindings[$i][$fieldName] == $entityID) { return $i; } } return -1; } public static function findBindingByEntityID($entityTypeID, $entityID, array $bindings) { $index = self::findBindingIndexByEntityID($entityTypeID, $entityID, $bindings); return $index >= 0 ? $bindings[$index] : null; } /** * Prepare binding changes. * @param int $entityTypeID Entity Type ID. * @param array $origin Origin bindings. * @param array $current Current bindings. * @param array &$added Added bindings (output parameter). * @param array &$removed Removed bindings (output parameter). * @return void * @throws Main\ArgumentOutOfRangeException * @throws Main\NotSupportedException */ public static function prepareBindingChanges($entityTypeID, array $origin, array $current, array &$added, array &$removed) { if(!is_int($entityTypeID)) { $entityTypeID = (int)$entityTypeID; } if(!\CCrmOwnerType::IsDefined($entityTypeID)) { throw new Main\ArgumentOutOfRangeException('entityTypeID', \CCrmOwnerType::FirstOwnerType, \CCrmOwnerType::LastOwnerType ); } if($entityTypeID === \CCrmOwnerType::Company) { $fieldName = 'COMPANY_ID'; } elseif($entityTypeID === \CCrmOwnerType::Contact) { $fieldName = 'CONTACT_ID'; } else { $entityTypeName = \CCrmOwnerType::ResolveName($entityTypeID); throw new Main\NotSupportedException("Entity type: '{$entityTypeName}' is not supported in current context"); } $maxSort = 0; $originMap = array(); $originPrimaryID = 0; foreach($origin as $binding) { $ID = isset($binding[$fieldName]) ? (int)$binding[$fieldName] : 0; if($ID > 0) { $originMap[$ID] = $binding; if(isset($binding['SORT']) && $binding['SORT'] > $maxSort) { $maxSort = (int)$binding['SORT']; } if(isset($binding['IS_PRIMARY']) && $binding['IS_PRIMARY'] === 'Y') { $originPrimaryID = $ID; } } } $currentMap = array(); $currentPrimaryID = 0; foreach($current as $binding) { $ID = isset($binding[$fieldName]) ? (int)$binding[$fieldName] : 0; if($ID <= 0) { continue; } $currentMap[$ID] = $binding; if(isset($binding['IS_PRIMARY']) && $binding['IS_PRIMARY'] === 'Y') { $currentPrimaryID = $ID; } } $originIDs = array_keys($originMap); $currentIDs = array_keys($currentMap); if(!empty($removed)) { $removed = array(); } foreach(array_diff($originIDs, $currentIDs) as $ID) { $removed[$ID] = $originMap[$ID]; } if(!empty($added)) { $added = array(); } foreach(array_diff($currentIDs, $originIDs) as $ID) { $binding = $currentMap[$ID]; if($maxSort > 0 && !isset($binding['SORT'])) { $maxSort += 10; $binding['SORT'] = $maxSort; } $added[$ID] = $binding; } foreach($current as $currentBinding) { $ID = isset($currentBinding[$fieldName]) ? (int)$currentBinding[$fieldName] : 0; if($ID <= 0) { continue; } if(isset($added[$ID]) || isset($removed[$ID])) { continue; } $originBinding = isset($originMap[$ID]) ? $originMap[$ID] : null; if(!is_array($originBinding)) { continue; } $originSort = isset($originBinding["SORT"]) ? (int)$originBinding["SORT"] : 0; $currentSort = isset($currentBinding["SORT"]) ? (int)$currentBinding["SORT"] : 0; if($originSort !== $currentSort) { $added[$ID] = $currentBinding; } } if(($originPrimaryID > 0 || $currentPrimaryID > 0) && $originPrimaryID !== $currentPrimaryID) { if($currentPrimaryID > 0 && !isset($added[$currentPrimaryID])) { $added[$currentPrimaryID] = array_merge( $currentMap[$currentPrimaryID], array('IS_PRIMARY' => 'Y') ); } if($originPrimaryID > 0 && !isset($removed[$originPrimaryID])) { $added[$originPrimaryID] = array_merge( $currentMap[$originPrimaryID], array('IS_PRIMARY' => 'N') ); } } $removed = array_values($removed); $added = array_values($added); } /** * Resolve field name for specified entity type. * @param int $entityTypeID Entity type ID. * @return string */ public static function resolveEntityFieldName($entityTypeID) { if($entityTypeID === \CCrmOwnerType::Company) { return 'COMPANY_ID'; } elseif($entityTypeID === \CCrmOwnerType::Contact) { return 'CONTACT_ID'; } return ''; } public static function resolveEntityID($entityTypeID, array $binding) { $fieldName = self::resolveEntityFieldName($entityTypeID); if($fieldName === '') { return 0; } return isset($binding[$fieldName]) ? (int)$binding[$fieldName] : 0; } public static function getPrimaryOrDefault(array $bindings) { if(empty($bindings)) { return null; } $binding = self::findPrimaryBinding($bindings); if(!is_array($binding)) { $binding = $bindings[0]; } return $binding; } public static function getPrimaryEntityID($entityTypeID, array $bindings) { $primaryBinding = self::getPrimaryOrDefault($bindings); return is_array($primaryBinding) ? self::prepareEntityID($entityTypeID, $primaryBinding) : 0; } }contactcompany.php000066400000052650150044450540010312 0ustar00<?php /** * Bitrix Framework * @package bitrix * @subpackage crm * @copyright 2001-2016 Bitrix */ namespace Bitrix\Crm\Binding; use Bitrix\Main; use Bitrix\Main\Entity; class ContactCompanyTable extends Entity\DataManager { /** * Get table name. * @return string */ public static function getTableName() { return 'b_crm_contact_company'; } /** * Get table fields map. * @return array */ public static function getMap() { return array( 'CONTACT_ID' => array('primary' => true, 'data_type' => 'integer'), 'COMPANY_ID' => array('primary' => true, 'data_type' => 'integer'), 'SORT' => array('data_type' => 'integer', 'default_value' => 0), 'ROLE_ID' => array('data_type' => 'integer', 'default_value' => 0), 'IS_PRIMARY' => array('data_type' => 'boolean', 'values' => array('N', 'Y'), 'default_value' => 'N') ); } /** * Execute UPSERT operation. * @param array $data Field data. * @return void */ public static function upsert(array $data) { $contactID = isset($data['CONTACT_ID']) ? (int)$data['CONTACT_ID'] : 0; if($contactID <= 0) { throw new Main\ArgumentException('Must contains CONTACT_ID field.', 'data'); } $companyID = isset($data['COMPANY_ID']) ? (int)$data['COMPANY_ID'] : 0; if($contactID <= 0) { throw new Main\ArgumentException('Must contains COMPANY_ID field.', 'data'); } $sort = isset($data['SORT']) ? (int)$data['SORT'] : 0; $roleID = isset($data['ROLE_ID']) ? (int)$data['ROLE_ID'] : 0; $primary = isset($data['IS_PRIMARY']) && strtoupper($data['IS_PRIMARY']) === 'Y' ? 'Y' : 'N'; $connection = Main\Application::getConnection(); $queries = $connection->getSqlHelper()->prepareMerge( 'b_crm_contact_company', array('CONTACT_ID', 'COMPANY_ID'), array('CONTACT_ID' => $contactID, 'COMPANY_ID' => $companyID, 'SORT' => $sort, 'ROLE_ID' => $roleID, 'IS_PRIMARY' => $primary), array('SORT' => $sort, 'ROLE_ID' => $roleID, 'IS_PRIMARY' => $primary) ); foreach($queries as $query) { $connection->queryExecute($query); } } /** * Get company IDs are bound to specified contact. * @param int $contactID Contact ID. * @return array * @throws Main\ArgumentException */ public static function getContactCompanyIDs($contactID) { $contactID = (int)$contactID; if($contactID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'contactID'); } $dbResult = Main\Application::getConnection()->query( /** @lang text*/ "SELECT COMPANY_ID FROM b_crm_contact_company WHERE CONTACT_ID = {$contactID} ORDER BY SORT ASC" ); $results = array(); while($ary = $dbResult->fetch()) { $results[] = (int)$ary['COMPANY_ID']; } return $results; } /** * Get contact IDs are bound to specified company. * @param int $companyID Company ID. * @return array * @throws Main\ArgumentException */ public static function getCompanyContactIDs($companyID) { $companyID = (int)$companyID; if($companyID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'companyID'); } $dbResult = Main\Application::getConnection()->query( /** @lang text*/ "SELECT CONTACT_ID FROM b_crm_contact_company WHERE COMPANY_ID = {$companyID} ORDER BY CONTACT_ID ASC" ); $results = array(); while($ary = $dbResult->fetch()) { $results[] = (int)$ary['CONTACT_ID']; } return $results; } /** * Get contacts's bindings. * @param int $contactID Contact ID. * @return array * @throws Main\ArgumentException */ public static function getContactBindings($contactID) { $contactID = (int)$contactID; if($contactID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'dealID'); } $dbResult = Main\Application::getConnection()->query( /** @lang text*/ "SELECT COMPANY_ID, SORT, ROLE_ID, IS_PRIMARY FROM b_crm_contact_company WHERE CONTACT_ID = {$contactID} ORDER BY SORT" ); $results = array(); while($ary = $dbResult->fetch()) { $results[] = array( 'COMPANY_ID' => (int)$ary['COMPANY_ID'], 'SORT' => (int)$ary['SORT'], 'ROLE_ID' => (int)$ary['ROLE_ID'], 'IS_PRIMARY' => $ary['IS_PRIMARY'] ); } return $results; } /** * Get binding map for contact's collection. * @param array $contactIDs Array of Contact IDs. * @return array * @throws Main\ArgumentException * @throws Main\ObjectPropertyException * @throws Main\SystemException */ public static function getBulkContactBindings(array $contactIDs) { $bindingMap = array(); foreach($contactIDs as $contactID) { $bindingMap[$contactID] = array(); } $dbResult = self::getList( array( 'filter' => array('@CONTACT_ID' => $contactIDs), 'select' => array('COMPANY_ID', 'CONTACT_ID', 'SORT', 'ROLE_ID', 'IS_PRIMARY'), 'order' => array('CONTACT_ID' => 'ASC', 'SORT' => 'ASC') ) ); while($ary = $dbResult->fetch()) { $bindingMap[$ary['CONTACT_ID']][] = array( 'COMPANY_ID' => (int)$ary['COMPANY_ID'], 'SORT' => (int)$ary['SORT'], 'ROLE_ID' => (int)$ary['ROLE_ID'], 'IS_PRIMARY' => $ary['IS_PRIMARY'] ); } return $bindingMap; } /** * Get contact's binding count. * @param int $contactID Contact ID. * @return int * @throws Main\ArgumentException */ public static function getContactBindingCount($contactID) { $contactID = (int)$contactID; if($contactID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'contactID'); } $dbResult = Main\Application::getConnection()->query( /** @lang text*/ "SELECT COUNT(*) CNT FROM b_crm_contact_company WHERE CONTACT_ID = {$contactID}" ); $ary = $dbResult->fetch(); return is_array($ary) ? (int)$ary['CNT'] : 0; } /** * Get company's bindings. * @param int $companyID Company ID. * @return array * @throws Main\ArgumentException */ public static function getCompanyBindings($companyID) { $contactID = (int)$companyID; if($contactID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'companyID'); } $dbResult = Main\Application::getConnection()->query( /** @lang text*/ "SELECT CONTACT_ID, SORT, ROLE_ID, IS_PRIMARY FROM b_crm_contact_company WHERE COMPANY_ID = {$companyID} ORDER BY SORT" ); $results = array(); while($ary = $dbResult->fetch()) { $results[] = array( 'CONTACT_ID' => (int)$ary['CONTACT_ID'], 'SORT' => (int)$ary['SORT'], 'ROLE_ID' => (int)$ary['ROLE_ID'], 'IS_PRIMARY' => $ary['IS_PRIMARY'] ); } return $results; } /** * Check if contact has companies. * @param int $contactID Contact ID. * @return bool * @throws Main\ArgumentException */ public static function hasCompanies($contactID) { $contactID = (int)$contactID; if($contactID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'contactID'); } $result = self::getList( array( 'select' => array('CONTACT_ID'), 'filter' => array('=CONTACT_ID' => $contactID), 'limit' => 1 ) ); return is_array($result->fetch()); } /** * Bind contact to companies are specified by ID. * @param int $contactID Contact ID. * @param array $companyIDs Array of company IDs. * @return void */ public static function bindCompanyIDs($contactID, array $companyIDs) { $bindings = EntityBinding::prepareEntityBindings(\CCrmOwnerType::Company, $companyIDs); $qty = count($bindings); if($qty > 0) { for($i = 0; $i < $qty; $i++) { if($i === 0) { $bindings[$i]['IS_PRIMARY'] = 'Y'; } $bindings[$i]['SORT'] = 10 * ($i + 1); } self::bindCompanies($contactID, $bindings); } } /** * Bind company to contacts specified by ID. * @param int $companyID Company ID. * @param array $contactIDs Array of contact IDs. * @return void */ public static function bindContactIDs($companyID, array $contactIDs) { $bindings = EntityBinding::prepareEntityBindings(\CCrmOwnerType::Contact, $contactIDs); $qty = count($bindings); if($qty > 0) { for($i = 0; $i < $qty; $i++) { $bindings[$i]['IS_PRIMARY'] = 'Y'; $bindings[$i]['SORT'] = 10; } self::bindContacts($companyID, $bindings); } } /** * Bind contact to companies. * @param int $contactID Contact ID. * @param array $bindings Array of company bindings. * @return void * @throws Main\ArgumentException */ public static function bindCompanies($contactID, array $bindings) { $contactID = (int)$contactID; if($contactID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'contactID'); } $qty = count($bindings); if($qty === 0) { return; } $processed = 0; for($i = 0; $i < $qty; $i++) { $binding = $bindings[$i]; $companyID = isset($binding['COMPANY_ID']) ? (int)$binding['COMPANY_ID'] : 0; if($companyID <= 0) { continue; } self::upsert( array( 'CONTACT_ID' => $contactID, 'COMPANY_ID' => $companyID, 'SORT' => isset($binding['SORT']) ? (int)$binding['SORT'] : (10 * ($i + 1)), 'ROLE_ID' => isset($binding['ROLE_ID']) ? (int)$binding['ROLE_ID'] : EntityBinding::ROLE_UNDEFINED, 'IS_PRIMARY' => isset($binding['IS_PRIMARY']) ? $binding['IS_PRIMARY'] : '' ) ); $processed++; } if($processed > 0) { Main\Application::getConnection()->queryExecute( /** @lang text*/ "UPDATE b_crm_contact SET COMPANY_ID = (SELECT MIN(COMPANY_ID) FROM b_crm_contact_company WHERE IS_PRIMARY = 'Y' AND CONTACT_ID = {$contactID}) WHERE ID = {$contactID}" ); } } /** * Bind company to contacts. * @param int $companyID Company ID. * @param array $bindings Array of company bindings. * @return void * @throws Main\ArgumentException */ public static function bindContacts($companyID, array $bindings) { $companyID = (int)$companyID; if($companyID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'companyID'); } $qty = count($bindings); if($qty === 0) { return; } $affectedIDs = array(); for($i = 0; $i < $qty; $i++) { $binding = $bindings[$i]; $contactID = isset($binding['CONTACT_ID']) ? (int)$binding['CONTACT_ID'] : 0; if($contactID <= 0) { continue; } self::upsert( array( 'CONTACT_ID' => $contactID, 'COMPANY_ID' => $companyID, 'SORT' => isset($binding['SORT']) ? (int)$binding['SORT'] : (10 * ($i + 1)), 'ROLE_ID' => isset($binding['ROLE_ID']) ? (int)$binding['ROLE_ID'] : EntityBinding::ROLE_UNDEFINED, 'IS_PRIMARY' => isset($binding['IS_PRIMARY']) ? $binding['IS_PRIMARY'] : '' ) ); $affectedIDs[] = $contactID; } if(!empty($affectedIDs)) { $values = implode(',', $affectedIDs); Main\Application::getConnection()->queryExecute( /** @lang text*/ "UPDATE b_crm_contact_company SET IS_PRIMARY = (CASE WHEN COMPANY_ID = {$companyID} THEN 'Y' ELSE 'N' END) WHERE CONTACT_ID IN({$values})" ); Main\Application::getConnection()->queryExecute( /** @lang text*/ "UPDATE b_crm_contact SET COMPANY_ID = (SELECT MIN(COMPANY_ID) FROM b_crm_contact_company t WHERE t.IS_PRIMARY = 'Y' AND t.CONTACT_ID = b_crm_contact.ID) WHERE ID IN({$values})" ); } } /** * Unbind specified contact from specified companies. * @param int $contactID Contact ID. * @param array $companyIDs Array of company IDs. * @return void * @throws Main\ArgumentException */ public static function unbindCompanyIDs($contactID, array $companyIDs) { $contactID = (int)$contactID; if($contactID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'contactID'); } $companyIDs = array_filter($companyIDs); if(empty($companyIDs)) { return; } $connection = Main\Application::getConnection(); $values = implode(',', $companyIDs); $connection->queryExecute( /** @lang text */ "DELETE FROM b_crm_contact_company WHERE CONTACT_ID = {$contactID} AND COMPANY_ID IN({$values})" ); $connection->queryExecute( /** @lang text */ "UPDATE b_crm_contact SET COMPANY_ID = (SELECT MIN(COMPANY_ID) FROM b_crm_contact_company t WHERE t.IS_PRIMARY = 'Y' AND t.CONTACT_ID = b_crm_contact.ID) WHERE ID = {$contactID}" ); } /** * Unbind specified contact from specified companies. * @param int $contactID Contact ID. * @param array $bindings Array of bindings. * @return void * @throws Main\ArgumentException */ public static function unbindCompanies($contactID, array $bindings) { $contactID = (int)$contactID; if($contactID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'contactID'); } self::unbindCompanyIDs($contactID, EntityBinding::prepareEntityIDs(\CCrmOwnerType::Company, $bindings)); } /** * Unbind specified contact from all companies. * @param int $contactID Contact ID. * @throws Main\ArgumentException * @throws Main\NotSupportedException */ public static function unbindAllCompanies($contactID) { $contactID = (int)$contactID; if($contactID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'ID'); } $connection = Main\Application::getConnection(); $connection->queryExecute( /** @lang text */ "DELETE FROM b_crm_contact_company WHERE CONTACT_ID = {$contactID}" ); $connection->queryExecute( /** @lang text */ "UPDATE b_crm_contact SET COMPANY_ID = NULL WHERE ID = {$contactID}" ); } /** * Unbind specified company from specified contacts. * @param int $companyID Company ID. * @param array $contactIDs Array of contact IDs. * @return void * @throws Main\ArgumentException */ public static function unbindContactIDs($companyID, array $contactIDs) { $companyID = (int)$companyID; if($companyID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'companyID'); } $contactIDs = array_filter($contactIDs); if(empty($contactIDs)) { return; } $connection = Main\Application::getConnection(); $values = implode(',', $contactIDs); $connection->queryExecute( /** @lang text */ "DELETE FROM b_crm_contact_company WHERE COMPANY_ID = {$companyID} AND CONTACT_ID IN({$values})" ); $connection->queryExecute( /** @lang text */ "UPDATE b_crm_contact SET COMPANY_ID = (SELECT MIN(COMPANY_ID) FROM b_crm_contact_company t WHERE t.CONTACT_ID = b_crm_contact.ID) WHERE COMPANY_ID = {$companyID} AND ID IN({$values})" ); } /** * Unbind specified company from specified contacts. * @param int $companyID Company ID. * @param array $bindings Array of bindings. * @return void * @throws Main\ArgumentException */ public static function unbindContacts($companyID, array $bindings) { $companyID = (int)$companyID; if($companyID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'quoteID'); } self::unbindContactIDs($companyID, EntityBinding::prepareEntityIDs(\CCrmOwnerType::Contact, $bindings)); } /** * Unbind specified company from all contacts. * @param int $companyID Company ID. * @return void * @throws Main\ArgumentException */ public static function unbindAllContacts($companyID) { $companyID = (int)$companyID; if($companyID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'companyID'); } $connection = Main\Application::getConnection(); $connection->queryExecute( /** @lang text */ "DELETE FROM b_crm_contact_company WHERE COMPANY_ID = {$companyID}" ); $connection->queryExecute( /** @lang text */ "UPDATE b_crm_contact SET COMPANY_ID = (SELECT MIN(COMPANY_ID) FROM b_crm_contact_company t WHERE t.CONTACT_ID = b_crm_contact.ID) WHERE COMPANY_ID = {$companyID}" ); } /** * Prepare SQL join filter condition for specified entity. * @param int $entityTypeID Entity type ID for filter. * @param int $entityID Entity ID for filter. * @param string $tableAlias Alias of primary table. * @return string * @throws Main\ArgumentException * @throws Main\ArgumentOutOfRangeException * @throws Main\NotSupportedException */ public static function prepareFilterJoinSql($entityTypeID, $entityID, $tableAlias) { if(!is_int($entityTypeID)) { $entityTypeID = (int)$entityTypeID; } if(!\CCrmOwnerType::IsDefined($entityTypeID)) { throw new Main\ArgumentOutOfRangeException('entityTypeID', \CCrmOwnerType::FirstOwnerType, \CCrmOwnerType::LastOwnerType ); } if(!is_int($entityID)) { $entityID = (int)$entityID; } if($entityID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'entityID'); } if($entityTypeID === \CCrmOwnerType::Company) { return "INNER JOIN b_crm_contact_company CC ON CC.COMPANY_ID = {$entityID} AND CC.CONTACT_ID = {$tableAlias}.ID"; } elseif($entityTypeID === \CCrmOwnerType::Contact) { return "INNER JOIN b_crm_contact_company CC ON CC.CONTACT_ID = {$entityID} AND CC.COMPANY_ID = {$tableAlias}.ID"; } $entityTypeName = \CCrmOwnerType::ResolveName($entityTypeID); throw new Main\NotSupportedException("Entity type: '{$entityTypeName}' is not supported in current context"); } /** * Prepare SQL join filter condition for specified entity by entity title. * @param int $entityTypeID Entity type ID for filter. * @param string $entityTitle Entity Title for filter. * @param string $tableAlias Alias of primary table. * @return string * @throws Main\ArgumentOutOfRangeException * @throws Main\NotSupportedException */ public static function prepareFilterJoinSqlByTitle($entityTypeID, $entityTitle, $tableAlias) { if(!is_int($entityTypeID)) { $entityTypeID = (int)$entityTypeID; } if(!\CCrmOwnerType::IsDefined($entityTypeID)) { throw new Main\ArgumentOutOfRangeException('entityTypeID', \CCrmOwnerType::FirstOwnerType, \CCrmOwnerType::LastOwnerType ); } if(!is_string($entityTitle)) { $entityTitle = (string)$entityTitle; } if($entityTitle === '') { return ''; } $entityTitle = \CSQLWhere::ForLIKE($entityTitle); if($entityTypeID === \CCrmOwnerType::Company) { return "INNER JOIN ( SELECT CC.CONTACT_ID FROM b_crm_contact_company CC INNER JOIN b_crm_company C ON C.ID = CC.COMPANY_ID AND C.TITLE LIKE '{$entityTitle}%' ESCAPE '!' GROUP BY CC.CONTACT_ID ) CC ON {$tableAlias}.ID = CC.CONTACT_ID"; } $entityTypeName = \CCrmOwnerType::ResolveName($entityTypeID); throw new Main\NotSupportedException("Entity type: '{$entityTypeName}' is not supported in current context"); } /** * Unbind all contacts from seed company and bind to target company * @param int $seedCompanyID Seed company ID. * @param int $targCompanyID Target company ID. * @throws Main\ArgumentException */ public static function rebindAllContacts($seedCompanyID, $targCompanyID) { $seedCompanyID = (int)$seedCompanyID; if($seedCompanyID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'seedCompanyID'); } $targCompanyID = (int)$targCompanyID; if($targCompanyID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'targCompanyID'); } //Combine contacts from seed and target and bind to target. $connection = Main\Application::getConnection(); $dbResult = $connection->query( /** @lang text */ "SELECT CONTACT_ID FROM b_crm_contact_company WHERE COMPANY_ID IN ({$seedCompanyID}, {$targCompanyID}) GROUP BY CONTACT_ID" ); $contactIDs = array(); while($fields = $dbResult->fetch()) { $contactIDs[] = (int)$fields['CONTACT_ID']; } if(!empty($contactIDs)) { self::bindContactIDs($targCompanyID, $contactIDs); } //Clear seed bindings $connection->queryExecute( /** @lang text */ "DELETE FROM b_crm_contact_company WHERE COMPANY_ID = {$seedCompanyID}" ); $connection->queryExecute( /** @lang text */ "UPDATE b_crm_contact SET COMPANY_ID = {$targCompanyID} WHERE COMPANY_ID = {$seedCompanyID}" ); } /** * Unbind all companies from seed contact and bind to target contact * @param int $seedContactID Seed contact ID. * @param int $targContactID Target contact ID. * @throws Main\ArgumentException */ public static function rebindAllCompanies($seedContactID, $targContactID) { $seedContactID = (int)$seedContactID; if($seedContactID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'seedContactID'); } $targContactID = (int)$targContactID; if($targContactID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'targContactID'); } if($seedContactID === $targContactID) { return; } $connection = Main\Application::getConnection(); $dbResult = $connection->query( /** @lang text */ "SELECT COMPANY_ID FROM b_crm_contact_company WHERE CONTACT_ID = {$seedContactID}" ); while($fields = $dbResult->fetch()) { $companyID = (int)$fields['COMPANY_ID']; $bindings = self::getCompanyBindings($companyID); $seedIndex = $targIndex = -1; for($i = 0, $l = count($bindings); $i < $l; $i++) { $binding = $bindings[$i]; $contactID = (int)$binding['CONTACT_ID']; if($contactID === $seedContactID) { $seedIndex = $i; } elseif($contactID === $targContactID) { $targIndex = $i; } if($seedIndex >= 0 && $targIndex >= 0) { break; } } $seedBinding = $seedIndex >= 0 ? $bindings[$seedIndex] : null; $targBinding = $targIndex >= 0 ? $bindings[$targIndex] : null; if(!is_array($seedBinding)) { continue; } self::unbindContactIDs($companyID, array($seedContactID)); $isPrimary = isset($seedBinding['IS_PRIMARY']) && $seedBinding['IS_PRIMARY'] === 'Y'; if(!is_array($targBinding)) { $seedBinding['CONTACT_ID'] = $targContactID; self::bindContacts($companyID, array($seedBinding)); } elseif($isPrimary) { $targBinding['IS_PRIMARY'] = 'Y'; self::bindContacts($companyID, array($targBinding)); } } } }orderdealtable.php000066400000005355150044450540010241 0ustar00<?php /** * Bitrix Framework * @package bitrix * @subpackage crm * @copyright 2001-2018 Bitrix */ namespace Bitrix\Crm\Binding; use Bitrix\Main; use Bitrix\Main\ORM\Fields\IntegerField; use Bitrix\Main\ORM\Fields\Relations\Reference; /** * Class OrderContactCompanyTable * @package Bitrix\Crm\Binding */ class OrderDealTable extends Main\ORM\Data\DataManager { /** * Get table name. * @return string */ public static function getTableName() { return 'b_crm_order_deal'; } /** * Get table fields map. * @return array */ public static function getMap() { return [ new IntegerField('DEAL_ID', [ 'primary' => true, 'unique' => true, ]), new IntegerField('ORDER_ID', [ 'primary' => true, ]), new Reference('ORDER', '\Bitrix\Sale\Internals\Order', ['=this.ORDER_ID' => 'ref.ID'] ), new Reference('DEAL', '\Bitrix\Crm\Deal', ['=this.DEAL_ID' => 'ref.ID'] ), ]; } /** * @param $orderId * @return int|false * @throws Main\ArgumentException * @throws Main\ObjectPropertyException * @throws Main\SystemException */ public static function getDealIdByOrderId($orderId) { $orderId = intval($orderId); if($orderId > 0) { $item = static::getList([ 'select' => ['DEAL_ID'], 'filter' => [ '=ORDER_ID' => $orderId, ], ])->fetch(); if($item) { return $item['DEAL_ID']; } } return false; } /** * @param $dealId * @return array * @throws Main\ArgumentException * @throws Main\ObjectPropertyException * @throws Main\SystemException */ public static function getDealOrders($dealId) { $result = []; $dealId = intval($dealId); if($dealId > 0) { $items = static::getList([ 'select' => ['ORDER_ID'], 'filter' => [ '=DEAL_ID' => $dealId, ], ]); while($item = $items->fetch()) { $result[] = $item['ORDER_ID']; } } return $result; } /** * @param $orderId * @return Main\ORM\Data\DeleteResult * @throws Main\ArgumentException * @throws Main\ObjectPropertyException * @throws Main\SystemException */ public static function deleteByOrderId($orderId) { $dealId = static::getDealIdByOrderId($orderId); if($dealId) { return static::delete([ 'ORDER_ID' => $orderId, 'DEAL_ID' => $dealId, ]); } return new Main\ORM\Data\DeleteResult(); } /** * @param $dealId * @return Main\ORM\Data\DeleteResult * @throws Main\ArgumentException * @throws Main\ObjectPropertyException * @throws Main\SystemException */ public static function deleteByDealId($dealId) { $orderIds = static::getDealOrders($dealId); foreach($orderIds as $orderId) { static::delete([ 'ORDER_ID' => $orderId, 'DEAL_ID' => $dealId, ]); } return new Main\ORM\Data\DeleteResult(); } }ordercontactcompany.php000066400000042336150044450540011346 0ustar00<?php /** * Bitrix Framework * @package bitrix * @subpackage crm * @copyright 2001-2018 Bitrix */ namespace Bitrix\Crm\Binding; use Bitrix\Main; use Bitrix\Main\Entity; use Bitrix\Crm\Order; /** * Class OrderContactCompanyTable * @package Bitrix\Crm\Binding */ class OrderContactCompanyTable extends Entity\DataManager { /** * Get table name. * @return string */ public static function getTableName() { return 'b_crm_order_contact_company'; } /** * Get table fields map. * @return array */ public static function getMap() { return array( 'ID' => array( 'primary' => true, 'data_type' => 'integer' ), 'ORDER_ID' => array( 'data_type' => 'integer' ), 'ORDER' => array( 'data_type' => '\Bitrix\Sale\Order', 'reference' => array( '=this.ORDER_ID' => 'ref.ID' ) ), 'ENTITY_ID' => array( 'data_type' => 'integer' ), 'ENTITY_TYPE_ID' => array( 'data_type' => 'integer' ), 'SORT' => array( 'data_type' => 'integer', 'default_value' => 0 ), 'ROLE_ID' => array( 'data_type' => 'integer', 'default_value' => 0 ), 'IS_PRIMARY' => array( 'data_type' => 'boolean', 'values' => array('N', 'Y'), 'default_value' => 'N' ) ); } /** * Execute UPSERT operation. * @param array $data Field data. * @return void * @throws Main\ArgumentException * @throws Main\Db\SqlQueryException */ public static function upsert(array $data) { $orderId = isset($data['ORDER_ID']) ? (int)$data['ORDER_ID'] : 0; if($orderId <= 0) { throw new Main\ArgumentException('Must contains ORDER_ID field.', 'data'); } $contactID = isset($data['ENTITY_ID']) ? (int)$data['ENTITY_ID'] : 0; if($contactID <= 0) { throw new Main\ArgumentException('Must contains ENTITY_ID field.', 'data'); } $sort = isset($data['SORT']) ? (int)$data['SORT'] : 0; $roleID = isset($data['ROLE_ID']) ? (int)$data['ROLE_ID'] : 0; $primary = isset($data['IS_PRIMARY']) && strtoupper($data['IS_PRIMARY']) === 'Y' ? 'Y' : 'N'; $connection = Main\Application::getConnection(); $queries = $connection->getSqlHelper()->prepareMerge( 'b_crm_order_contact', array('ORDER_ID', 'ENTITY_ID'), array('ORDER_ID' => $orderId, 'ENTITY_ID' => $contactID, 'SORT' => $sort, 'ROLE_ID' => $roleID, 'IS_PRIMARY' => $primary), array('SORT' => $sort, 'ROLE_ID' => $roleID, 'IS_PRIMARY' => $primary) ); foreach($queries as $query) { $connection->queryExecute($query); } } /** * Get order IDs are bound to specified contact. * @param int $contactID Contact ID. * @return array * @throws Main\ArgumentException * @throws Main\Db\SqlQueryException */ public static function getContactOrderIDs($contactID) { $contactID = (int)$contactID; if($contactID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'contactID'); } $dbResult = Main\Application::getConnection()->query( /** @lang text*/ "SELECT ORDER_ID FROM b_crm_order_contact_company WHERE ENTITY_ID = {$contactID}" ); $results = array(); while($ary = $dbResult->fetch()) { $results[] = (int)$ary['ORDER_ID']; } return $results; } /** * Get contact IDs are bound to specified order. * @param int $orderId order ID. * @return array * @throws Main\ArgumentException * @throws Main\Db\SqlQueryException */ public static function getOrderContactIDs($orderId) { $orderId = (int)$orderId; if($orderId <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'orderId'); } $dbResult = Main\Application::getConnection()->query( /** @lang text*/ "SELECT ENTITY_ID FROM b_crm_order_contact_company WHERE ORDER_ID = {$orderId} ORDER BY SORT ASC" ); $results = array(); while($ary = $dbResult->fetch()) { $results[] = (int)$ary['ENTITY_ID']; } return $results; } /** * Get order's bindings. * @param int $orderId Order ID. * @return array * @throws Main\ArgumentException * @throws Main\Db\SqlQueryException */ public static function getOrderBindings($orderId) { $orderId = (int)$orderId; if($orderId <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'order'); } $dbResult = Main\Application::getConnection()->query( /** @lang text*/ "SELECT ENTITY_ID, SORT, ROLE_ID, IS_PRIMARY FROM b_crm_order_contact_company WHERE ORDER_ID = ".$orderId." AND ENTITY_TYPE_ID = ".\CCrmOwnerType::Contact." ORDER BY SORT" ); $results = array(); while($ary = $dbResult->fetch()) { $results[] = array( 'CONTACT_ID' => (int)$ary['ENTITY_ID'], 'SORT' => (int)$ary['SORT'], 'ROLE_ID' => (int)$ary['ROLE_ID'], 'IS_PRIMARY' => $ary['IS_PRIMARY'] ); } return $results; } /** * Get order's binding count. * @param int $orderId order ID. * @return int * @throws Main\ArgumentException * @throws Main\Db\SqlQueryException */ public static function getOrderBindingCount($orderId) { $orderId = (int)$orderId; if($orderId <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'orderId'); } $dbResult = Main\Application::getConnection()->query( /** @lang text*/ "SELECT COUNT(*) CNT FROM b_crm_order_contact_company WHERE ORDER_ID = {$orderId}" ); $ary = $dbResult->fetch(); return is_array($ary) ? (int)$ary['CNT'] : 0; } /** * Check if order has contacts. * @param int $orderId Order ID. * @return bool * @throws Main\ArgumentException * @throws Main\ObjectPropertyException * @throws Main\SystemException */ public static function hasContacts($orderId) { $orderId = (int)$orderId; if($orderId <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'orderId'); } $result = self::getList( array( 'select' => array('ORDER_ID'), 'filter' => array('=ORDER_ID' => $orderId), 'limit' => 1 ) ); return is_array($result->fetch()); } /** * Bind order to contacts are specified by ID. * @param int $orderId Order ID. * @param array $contactIDs Array of contact IDs. * @return void * @throws Main\ArgumentException * @throws Main\ArgumentOutOfRangeException * @throws Main\Db\SqlQueryException * @throws Main\LoaderException * @throws Main\NotSupportedException * @throws Main\SystemException */ public static function bindContactIDs($orderId, array $contactIDs) { $bindings = EntityBinding::prepareEntityBindings(\CCrmOwnerType::Contact, $contactIDs); $qty = count($bindings); if($qty > 0) { for($i = 0; $i < $qty; $i++) { if($i === 0) { $bindings[$i]['IS_PRIMARY'] = 'Y'; } $bindings[$i]['SORT'] = 10 * ($i + 1); } self::bindContacts($orderId, $bindings); } } /** * Bind order to contacts. * @param int $orderId order id. * @param array $bindings Array of contact bindings. * @return void * @throws Main\ArgumentException * @throws Main\Db\SqlQueryException * @throws Main\SystemException * @throws Main\LoaderException */ public static function bindContacts($orderId, array $bindings) { if(!Main\Loader::includeModule('sale')) throw new Main\SystemException('Can\'t include module "sale"'); $orderId = (int)$orderId; if($orderId <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'orderId'); } $qty = count($bindings); if($qty === 0) { return; } $processed = 0; for($i = 0; $i < $qty; $i++) { $binding = $bindings[$i]; $contactID = isset($binding['ENTITY_ID']) ? (int)$binding['ENTITY_ID'] : 0; if($contactID <= 0) { continue; } self::upsert( array( 'ORDER_ID' => $orderId, 'ENTITY_ID' => $contactID, 'SORT' => isset($binding['SORT']) ? (int)$binding['SORT'] : (10 * ($i + 1)), 'ROLE_ID' => isset($binding['ROLE_ID']) ? (int)$binding['ROLE_ID'] : EntityBinding::ROLE_UNDEFINED, 'IS_PRIMARY' => isset($binding['IS_PRIMARY']) ? $binding['IS_PRIMARY'] : '' ) ); $processed++; } if($processed > 0) { Main\Application::getConnection()->queryExecute( /** @lang text*/ "UPDATE b_sale_order SET ENTITY_ID = (SELECT MIN(ENTITY_ID) FROM b_crm_order_contact_company WHERE IS_PRIMARY = 'Y' AND ORDER_ID = {$orderId}) WHERE ID = {$orderId}" ); } } /** * Unbind specified order from specified contacts. * @param int $orderId order id. * @param array $contactIDs Array of contact IDs. * @return void * @throws Main\ArgumentException * @throws Main\Db\SqlQueryException * @throws Main\LoaderException * @throws Main\SystemException */ public static function unbindContactIDs($orderId, array $contactIDs) { if(!Main\Loader::includeModule('sale')) throw new Main\SystemException('Can\'t include module "sale"'); $orderId = (int)$orderId; if($orderId <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'orderId'); } $contactIDs = array_filter($contactIDs); if(empty($contactIDs)) { return; } $connection = Main\Application::getConnection(); $values = implode(',', $contactIDs); $connection->queryExecute( /** @lang text */ "DELETE FROM b_crm_order_contact_company WHERE ORDER_ID = {$orderId} AND ENTITY_ID IN({$values})" ); $connection->queryExecute( /** @lang text*/ "UPDATE b_sale_order SET ENTITY_ID = (SELECT MIN(ENTITY_ID) FROM b_crm_order_contact_company WHERE IS_PRIMARY = 'Y' AND ORDER_ID = {$orderId}) WHERE ID = {$orderId}" ); } /** * Unbind specified order from specified contacts. * @param int $orderId Order ID. * @param array $bindings Array of bindings. * @return void * @throws Main\ArgumentException * @throws Main\ArgumentOutOfRangeException * @throws Main\Db\SqlQueryException * @throws Main\LoaderException * @throws Main\NotSupportedException * @throws Main\SystemException */ public static function unbindContacts($orderId, array $bindings) { $orderId = (int)$orderId; if($orderId <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'orderId'); } self::unbindContactIDs($orderId, EntityBinding::prepareEntityIDs(\CCrmOwnerType::Contact, $bindings)); } /** * Unbind specified order from all contacts. * @param int $orderId Order ID. * @return void * @throws Main\ArgumentException * @throws Main\Db\SqlQueryException * @throws Main\LoaderException * @throws Main\SystemException */ public static function unbindAllContacts($orderId) { if(!Main\Loader::includeModule('sale')) throw new Main\SystemException('Can\'t include module "sale"'); $orderId = (int)$orderId; if($orderId <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'orderId'); } $connection = Main\Application::getConnection(); $connection->queryExecute( /** @lang text */ "DELETE FROM b_crm_order_contact_company WHERE ORDER_ID = {$orderId}" ); $connection->queryExecute( /** @lang text */ "UPDATE b_sale_order SET ENTITY_ID = NULL WHERE ID = {$orderId}" ); } /** * Unbind specified contact from all orders. * @param int $contactID Contact ID. * @return void * @throws Main\ArgumentException * @throws Main\Db\SqlQueryException * @throws Main\LoaderException * @throws Main\SystemException */ public static function unbindAllOrders($contactID) { if(!Main\Loader::includeModule('sale')) throw new Main\SystemException('Can\'t include module "sale"'); $contactID = (int)$contactID; if($contactID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'contactID'); } $connection = Main\Application::getConnection(); $connection->queryExecute( /** @lang text */ "DELETE FROM b_crm_order_contact_company WHERE ENTITY_ID = {$contactID}" ); $connection->queryExecute( /** @lang text */ "UPDATE b_sale_order SET ENTITY_ID = (SELECT MIN(ENTITY_ID) FROM b_crm_order_contact_company t WHERE t.ORDER_ID = b_sale_order.ID) WHERE ENTITY_ID = {$contactID}" ); } /** * Prepage SQL join filter condition for specified entity. * @param int $entityTypeID Entity type ID for filter. * @param int $entityID Entity ID for filter. * @param string $tableAlias Alias of primary table. * @return string * @throws Main\ArgumentException * @throws Main\ArgumentOutOfRangeException * @throws Main\NotSupportedException */ public static function prepareFilterJoinSql($entityTypeID, $entityID, $tableAlias) { if(!is_int($entityTypeID)) { $entityTypeID = (int)$entityTypeID; } if(!\CCrmOwnerType::IsDefined($entityTypeID)) { throw new Main\ArgumentOutOfRangeException('entityTypeID', \CCrmOwnerType::FirstOwnerType, \CCrmOwnerType::LastOwnerType ); } if($entityTypeID !== \CCrmOwnerType::Contact && $entityTypeID !== \CCrmOwnerType::Order) { $entityTypeName = \CCrmOwnerType::ResolveName($entityTypeID); throw new Main\NotSupportedException("Entity type: '{$entityTypeName}' is not supported in current context"); } $entityIDs = is_array($entityID) ? $entityID : array($entityID); $effectiveIDs = array(); foreach($entityIDs as $ID) { $ID = (int)$ID; if($ID > 0) { $effectiveIDs[] = $ID; } } $qty = count($effectiveIDs); if($qty > 1) { $slug = implode(',', $effectiveIDs); if($entityTypeID === \CCrmOwnerType::Contact) { return "INNER JOIN b_crm_order_contact_company QC ON QC.ENTITY_ID IN({$slug}) AND QC.ORDER_ID = {$tableAlias}.ID"; } else//if($entityTypeID === \CCrmOwnerType::Order) { return "INNER JOIN b_crm_order_contact_company QC ON QC.ORDER_ID IN({$slug}) AND QC.ENTITY_ID = {$tableAlias}.ID"; } } elseif($qty === 1) { if($entityTypeID === \CCrmOwnerType::Contact) { return "INNER JOIN b_crm_order_contact_company QC ON QC.ENTITY_ID = {$effectiveIDs[0]} AND QC.ORDER_ID = {$tableAlias}.ID"; } else//if($entityTypeID === \CCrmOwnerType::Order) { return "INNER JOIN b_crm_order_contact_company QC ON QC.ORDER_ID = {$effectiveIDs[0]} AND QC.ENTITY_ID = {$tableAlias}.ID"; } } return ""; } /** * Unbind all orders from seed contact and bind to target contact * @param int $seedContactID Seed contact ID. * @param int $targContactID Target contact ID. * @throws Main\ArgumentException * @throws Main\Db\SqlQueryException * @throws Main\LoaderException * @throws Main\SystemException */ public static function rebindAllOrders($seedContactID, $targContactID) { $seedContactID = (int)$seedContactID; if($seedContactID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'seedContactID'); } $targContactID = (int)$targContactID; if($targContactID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'targContactID'); } if($seedContactID === $targContactID) { return; } $connection = Main\Application::getConnection(); $dbResult = $connection->query( /** @lang text */ "SELECT ORDER_ID FROM b_crm_order_contact_company WHERE ENTITY_ID = {$seedContactID}" ); while($fields = $dbResult->fetch()) { $orderId = (int)$fields['ORDER_ID']; $bindings = self::getOrderBindings($orderId); $seedIndex = $targIndex = -1; for($i = 0, $l = count($bindings); $i < $l; $i++) { $binding = $bindings[$i]; $contactID = (int)$binding['ENTITY_ID']; if($contactID === $seedContactID) { $seedIndex = $i; } elseif($contactID === $targContactID) { $targIndex = $i; } if($seedIndex >= 0 && $targIndex >= 0) { break; } } $seedBinding = $seedIndex >= 0 ? $bindings[$seedIndex] : null; $targBinding = $targIndex >= 0 ? $bindings[$targIndex] : null; if(!is_array($seedBinding)) { continue; } self::unbindContactIDs($orderId, array($seedContactID)); $isPrimary = isset($seedBinding['IS_PRIMARY']) && $seedBinding['IS_PRIMARY'] === 'Y'; if(!is_array($targBinding)) { $seedBinding['ENTITY_ID'] = $targContactID; self::bindContacts($orderId, array($seedBinding)); } elseif($isPrimary) { $targBinding['IS_PRIMARY'] = 'Y'; self::bindContacts($orderId, array($targBinding)); } } } /** * Get orders by entities. * <p>$entities: * [ * ['TYPE_ID' => \CCrmOwnerType::Contact, 'ID' => 123], * ['TYPE_ID' => \CCrmOwnerType::Company, 'ID' => 321], * ] * </p> * * @param array $entities Entity list with type ID and entity ID. * @param bool $isPrimary Return only primary results. * @return int[] */ public static function getOrdersByEntities(array $entities, $isPrimary = true) { $list = []; foreach ($entities as $entity) { $typeId = isset($entity['TYPE_ID']) ? (int) $entity['TYPE_ID'] : null; $id = isset($entity['ID']) ? (int) $entity['ID'] : null; if (!$typeId || !$id) { continue; } if (!isset($list[$typeId])) { $list[$typeId] = []; } $list[$typeId][] = $id; } if (empty($list)) { return []; } $result = []; $filter = [ '=ENTITY_TYPE_ID' => array_keys($list), '=ENTITY_ID' => array_unique(array_reduce(array_values($list), 'array_merge', [])), '=ORDER.STATUS_ID' => Order\OrderStatus::getSemanticProcessStatuses(), ]; if ($isPrimary) { $filter['=IS_PRIMARY'] = 'Y'; } $orders = static::getList([ 'select' => ['ORDER_ID', 'ENTITY_TYPE_ID', 'ENTITY_ID'], 'filter' => $filter ])->fetchAll(); foreach ($orders as $item) { $typeId = (int) $item['ENTITY_TYPE_ID']; $id = (int) $item['ENTITY_ID']; if (!in_array($id, $list[$typeId])) { continue; } $result[] = (int) $item['ORDER_ID']; } return $result; } }leadcontact.php000066400000034553150044450540007553 0ustar00<?php /** * Bitrix Framework * @package bitrix * @subpackage crm * @copyright 2001-2018 Bitrix */ namespace Bitrix\Crm\Binding; use Bitrix\Main; use Bitrix\Main\Entity; class LeadContactTable extends Entity\DataManager { /** * Get table name. * @return string */ public static function getTableName() { return 'b_crm_lead_contact'; } /** * Get table fields map. * @return array */ public static function getMap() { return array( 'LEAD_ID' => array('primary' => true, 'data_type' => 'integer'), 'CONTACT_ID' => array('primary' => true, 'data_type' => 'integer'), 'SORT' => array('data_type' => 'integer', 'default_value' => 0), 'ROLE_ID' => array('data_type' => 'integer', 'default_value' => 0), 'IS_PRIMARY' => array('data_type' => 'boolean', 'values' => array('N', 'Y'), 'default_value' => 'N') ); } /** * Execute UPSERT operation. * @param array $data Field data. * @return void */ public static function upsert(array $data) { $leadID = isset($data['LEAD_ID']) ? (int)$data['LEAD_ID'] : 0; if($leadID <= 0) { throw new Main\ArgumentException('Must contains LEAD_ID field.', 'data'); } $contactID = isset($data['CONTACT_ID']) ? (int)$data['CONTACT_ID'] : 0; if($contactID <= 0) { throw new Main\ArgumentException('Must contains CONTACT_ID field.', 'data'); } $sort = isset($data['SORT']) ? (int)$data['SORT'] : 0; $roleID = isset($data['ROLE_ID']) ? (int)$data['ROLE_ID'] : 0; $primary = isset($data['IS_PRIMARY']) && strtoupper($data['IS_PRIMARY']) === 'Y' ? 'Y' : 'N'; $connection = Main\Application::getConnection(); $queries = $connection->getSqlHelper()->prepareMerge( 'b_crm_lead_contact', array('LEAD_ID', 'CONTACT_ID'), array('LEAD_ID' => $leadID, 'CONTACT_ID' => $contactID, 'SORT' => $sort, 'ROLE_ID' => $roleID, 'IS_PRIMARY' => $primary), array('SORT' => $sort, 'ROLE_ID' => $roleID, 'IS_PRIMARY' => $primary) ); foreach($queries as $query) { $connection->queryExecute($query); } } /** * Get Lead IDs are bound to specified contact. * @param int $contactID Contact ID. * @return array * @throws Main\ArgumentException */ public static function getContactLeadIDs($contactID) { $contactID = (int)$contactID; if($contactID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'contactID'); } $dbResult = Main\Application::getConnection()->query( /** @lang text*/ "SELECT LEAD_ID FROM b_crm_lead_contact WHERE CONTACT_ID = {$contactID}" ); $results = array(); while($ary = $dbResult->fetch()) { $results[] = (int)$ary['LEAD_ID']; } return $results; } /** * Get Contact IDs are bound to specified Lead. * @param int $leadID Lead ID. * @return array * @throws Main\ArgumentException */ public static function getLeadContactIDs($leadID) { $leadID = (int)$leadID; if($leadID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'leadID'); } $dbResult = Main\Application::getConnection()->query( /** @lang text*/ "SELECT CONTACT_ID FROM b_crm_lead_contact WHERE LEAD_ID = {$leadID} ORDER BY SORT ASC" ); $results = array(); while($ary = $dbResult->fetch()) { $results[] = (int)$ary['CONTACT_ID']; } return $results; } /** * Get Lead's bindings. * @param int $leadID Lead ID. * @return array * @throws Main\ArgumentException */ public static function getLeadBindings($leadID) { $leadID = (int)$leadID; if($leadID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'leadID'); } $dbResult = Main\Application::getConnection()->query( /** @lang text*/ "SELECT CONTACT_ID, SORT, ROLE_ID, IS_PRIMARY FROM b_crm_lead_contact WHERE LEAD_ID = {$leadID} ORDER BY SORT" ); $results = array(); while($ary = $dbResult->fetch()) { $results[] = array( 'CONTACT_ID' => (int)$ary['CONTACT_ID'], 'SORT' => (int)$ary['SORT'], 'ROLE_ID' => (int)$ary['ROLE_ID'], 'IS_PRIMARY' => $ary['IS_PRIMARY'] ); } return $results; } /** * Get binding map for lead's collection. * @param array $leadsIDs Array of Lead IDs. * @return array * @throws Main\ArgumentException * @throws Main\ObjectPropertyException * @throws Main\SystemException */ public static function getBulkLeadBindings(array $leadsIDs) { $bindingMap = array(); foreach($leadsIDs as $leadID) { $bindingMap[$leadID] = array(); } $dbResult = self::getList( array( 'filter' => array('@LEAD_ID' => $leadsIDs), 'select' => array('LEAD_ID', 'CONTACT_ID', 'SORT', 'ROLE_ID', 'IS_PRIMARY'), 'order' => array('LEAD_ID' => 'ASC', 'SORT' => 'ASC') ) ); while($ary = $dbResult->fetch()) { $bindingMap[$ary['LEAD_ID']][] = array( 'CONTACT_ID' => (int)$ary['CONTACT_ID'], 'SORT' => (int)$ary['SORT'], 'ROLE_ID' => (int)$ary['ROLE_ID'], 'IS_PRIMARY' => $ary['IS_PRIMARY'] ); } return $bindingMap; } /** * Get Lead's binding count. * @param $leadID * @return int * @throws Main\ArgumentException */ public static function getLeadBindingCount($leadID) { $leadID = (int)$leadID; if($leadID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'leadID'); } $dbResult = Main\Application::getConnection()->query( /** @lang text*/ "SELECT COUNT(*) CNT FROM b_crm_lead_contact WHERE LEAD_ID = {$leadID}" ); $ary = $dbResult->fetch(); return is_array($ary) ? (int)$ary['CNT'] : 0; } /** * Check if Lead has Contacts. * @param int $leadID Lead ID. * @return bool * @throws Main\ArgumentException */ public static function hasContacts($leadID) { $leadID = (int)$leadID; if($leadID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'leadID'); } $result = self::getList( array( 'select' => array('LEAD_ID'), 'filter' => array('=LEAD_ID' => $leadID), 'limit' => 1 ) ); return is_array($result->fetch()); } /** * Bind Lead to Contacts are specified by ID. * @param int $leadID Lead ID. * @param array $contactIDs Array of contact IDs. * @return void */ public static function bindContactIDs($leadID, array $contactIDs) { $bindings = EntityBinding::prepareEntityBindings(\CCrmOwnerType::Contact, $contactIDs); $qty = count($bindings); if($qty > 0) { for($i = 0; $i < $qty; $i++) { if($i === 0) { $bindings[$i]['IS_PRIMARY'] = 'Y'; } $bindings[$i]['SORT'] = 10 * ($i + 1); } self::bindContacts($leadID, $bindings); } } /** * Bind Lead to Contacts. * @param int $leadID Lead ID. * @param array $bindings Array of contact bindings. * @return void * @throws Main\ArgumentException */ public static function bindContacts($leadID, array $bindings) { $leadID = (int)$leadID; if($leadID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'leadID'); } $qty = count($bindings); if($qty === 0) { return; } $processed = 0; for($i = 0; $i < $qty; $i++) { $binding = $bindings[$i]; if(!is_array($binding)) { continue; } $contactID = isset($binding['CONTACT_ID']) ? (int)$binding['CONTACT_ID'] : 0; if($contactID <= 0) { continue; } self::upsert( array( 'LEAD_ID' => $leadID, 'CONTACT_ID' => $contactID, 'SORT' => isset($binding['SORT']) ? (int)$binding['SORT'] : (10 * ($i + 1)), 'ROLE_ID' => isset($binding['ROLE_ID']) ? (int)$binding['ROLE_ID'] : EntityBinding::ROLE_UNDEFINED, 'IS_PRIMARY' => isset($binding['IS_PRIMARY']) ? $binding['IS_PRIMARY'] : '' ) ); $processed++; } if($processed > 0) { Main\Application::getConnection()->queryExecute( /** @lang text*/ "UPDATE b_crm_lead SET CONTACT_ID = (SELECT MIN(CONTACT_ID) FROM b_crm_lead_contact WHERE IS_PRIMARY = 'Y' AND LEAD_ID = {$leadID}) WHERE ID = {$leadID}" ); } } /** * Unbind specified Lead from specified contacts. * @param int $leadID Lead ID. * @param array $contactIDs Array of contact IDs. * @return void * @throws Main\ArgumentException */ public static function unbindContactIDs($leadID, array $contactIDs) { $leadID = (int)$leadID; if($leadID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'leadID'); } $contactIDs = array_filter($contactIDs); if(empty($contactIDs)) { return; } $connection = Main\Application::getConnection(); $values = implode(',', $contactIDs); $connection->queryExecute( /** @lang text */ "DELETE FROM b_crm_lead_contact WHERE LEAD_ID = {$leadID} AND CONTACT_ID IN({$values})" ); $connection->queryExecute( /** @lang text*/ "UPDATE b_crm_lead SET CONTACT_ID = (SELECT MIN(CONTACT_ID) FROM b_crm_lead_contact WHERE IS_PRIMARY = 'Y' AND LEAD_ID = {$leadID}) WHERE ID = {$leadID}" ); } /** * Unbind specified Lead from specified Contacts. * @param int $leadID Lead ID. * @param array $bindings Array of bindings. * @return void * @throws Main\ArgumentException */ public static function unbindContacts($leadID, array $bindings) { $leadID = (int)$leadID; if($leadID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'leadID'); } self::unbindContactIDs($leadID, EntityBinding::prepareEntityIDs(\CCrmOwnerType::Contact, $bindings)); } /** * Unbind specified Lead from all contacts. * @param int $leadID Lead ID. * @return void * @throws Main\ArgumentException */ public static function unbindAllContacts($leadID) { $leadID = (int)$leadID; if($leadID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'leadID'); } $connection = Main\Application::getConnection(); $connection->queryExecute( /** @lang text */ "DELETE FROM b_crm_lead_contact WHERE LEAD_ID = {$leadID}" ); $connection->queryExecute( /** @lang text */ "UPDATE b_crm_lead SET CONTACT_ID = NULL WHERE ID = {$leadID}" ); } /** * Unbind specified Contact from all Leads. * @param int $contactID Contact ID. * @return void * @throws Main\ArgumentException */ public static function unbindAllLeads($contactID) { $contactID = (int)$contactID; if($contactID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'contactID'); } $connection = Main\Application::getConnection(); $connection->queryExecute( /** @lang text */ "DELETE FROM b_crm_lead_contact WHERE CONTACT_ID = {$contactID}" ); $connection->queryExecute( /** @lang text */ "UPDATE b_crm_lead SET CONTACT_ID = (SELECT MIN(CONTACT_ID) FROM b_crm_lead_contact t WHERE t.LEAD_ID = b_crm_lead.ID) WHERE CONTACT_ID = {$contactID}" ); } /** * Prepare SQL join filter condition for specified entity. * @param int $entityTypeID Entity type ID for filter. * @param int $entityID Entity ID for filter. * @param string $tableAlias Alias of primary table. * @return string * @throws Main\ArgumentException * @throws Main\ArgumentOutOfRangeException * @throws Main\NotSupportedException */ public static function prepareFilterJoinSql($entityTypeID, $entityID, $tableAlias) { if(!is_int($entityTypeID)) { $entityTypeID = (int)$entityTypeID; } if(!\CCrmOwnerType::IsDefined($entityTypeID)) { throw new Main\ArgumentOutOfRangeException('entityTypeID', \CCrmOwnerType::FirstOwnerType, \CCrmOwnerType::LastOwnerType ); } if($entityTypeID !== \CCrmOwnerType::Contact && $entityTypeID !== \CCrmOwnerType::Lead) { $entityTypeName = \CCrmOwnerType::ResolveName($entityTypeID); throw new Main\NotSupportedException("Entity type: '{$entityTypeName}' is not supported in current context"); } $entityIDs = is_array($entityID) ? $entityID : array($entityID); $effectiveIDs = array(); foreach($entityIDs as $ID) { $ID = (int)$ID; if($ID > 0) { $effectiveIDs[] = $ID; } } $qty = count($effectiveIDs); if($qty > 1) { $slug = implode(',', $effectiveIDs); if($entityTypeID === \CCrmOwnerType::Contact) { return "INNER JOIN b_crm_lead_contact DC ON DC.CONTACT_ID IN({$slug}) AND DC.LEAD_ID = {$tableAlias}.ID"; } else//if($entityTypeID === \CCrmOwnerType::Lead) { return "INNER JOIN b_crm_lead_contact DC ON DC.LEAD_ID IN({$slug}) AND DC.CONTACT_ID = {$tableAlias}.ID"; } } elseif($qty === 1) { if($entityTypeID === \CCrmOwnerType::Contact) { return "INNER JOIN b_crm_lead_contact DC ON DC.CONTACT_ID = {$effectiveIDs[0]} AND DC.LEAD_ID = {$tableAlias}.ID"; } else//if($entityTypeID === \CCrmOwnerType::Lead) { return "INNER JOIN b_crm_lead_contact DC ON DC.LEAD_ID = {$effectiveIDs[0]} AND DC.CONTACT_ID = {$tableAlias}.ID"; } } return ""; } /** * Unbind all Leads from seed Contact and bind to target Contact * @param int $seedContactID Seed contact ID. * @param int $targContactID Target contact ID. * @throws Main\ArgumentException */ public static function rebindAllLeads($seedContactID, $targContactID) { $seedContactID = (int)$seedContactID; if($seedContactID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'seedContactID'); } $targContactID = (int)$targContactID; if($targContactID <= 0) { throw new Main\ArgumentException('Must be greater than zero', 'targContactID'); } if($seedContactID === $targContactID) { return; } $connection = Main\Application::getConnection(); $dbResult = $connection->query( /** @lang text */ "SELECT LEAD_ID FROM b_crm_lead_contact WHERE CONTACT_ID = {$seedContactID}" ); while($fields = $dbResult->fetch()) { $leadID = (int)$fields['LEAD_ID']; $bindings = self::getLeadBindings($leadID); $seedIndex = $targIndex = -1; for($i = 0, $l = count($bindings); $i < $l; $i++) { $binding = $bindings[$i]; $contactID = (int)$binding['CONTACT_ID']; if($contactID === $seedContactID) { $seedIndex = $i; } elseif($contactID === $targContactID) { $targIndex = $i; } if($seedIndex >= 0 && $targIndex >= 0) { break; } } $seedBinding = $seedIndex >= 0 ? $bindings[$seedIndex] : null; $targBinding = $targIndex >= 0 ? $bindings[$targIndex] : null; if(!is_array($seedBinding)) { continue; } self::unbindContactIDs($leadID, array($seedContactID)); $isPrimary = isset($seedBinding['IS_PRIMARY']) && $seedBinding['IS_PRIMARY'] === 'Y'; if(!is_array($targBinding)) { $seedBinding['CONTACT_ID'] = $targContactID; self::bindContacts($leadID, array($seedBinding)); } elseif($isPrimary) { $targBinding['IS_PRIMARY'] = 'Y'; self::bindContacts($leadID, array($targBinding)); } } } }
/var/www/axolotl/data/www/arhangelsk.axolotls.ru/a537b/binding.tar