From ac0c185bf35a228e31c4fd738d5e4a3744fff2a5 Mon Sep 17 00:00:00 2001 From: danila Date: Wed, 1 Jul 2026 16:44:51 +0500 Subject: [PATCH 1/4] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=BF=D0=BE=D0=B4=D0=B4=D0=B5=D1=80=D0=B6=D0=BA?= =?UTF-8?q?=D0=B0=20=D0=BC=D1=83=D0=BB=D1=8C=D1=82=D0=B8=D1=81=D0=B0=D0=B9?= =?UTF-8?q?=D1=82=D0=BE=D0=B2=D0=BE=D1=81=D1=82=D0=B8=20=D0=B4=D0=BB=D1=8F?= =?UTF-8?q?=20=D1=82=D0=B8=D0=BF=D0=B0=20=D0=BA=D0=BE=D0=BD=D1=82=D1=80?= =?UTF-8?q?=D0=B0=D0=B3=D0=B5=D0=BD=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 3 + .../classes/general/events/RetailCrmEvent.php | 8 +-- .../general/history/RetailCrmHistory_v5.php | 11 ++- .../general/order/RetailCrmOrder_v5.php | 12 ++-- intaro.retailcrm/description.ru | 2 +- intaro.retailcrm/install/index.php | 13 +++- intaro.retailcrm/install/step3.php | 41 ++++++----- intaro.retailcrm/install/version.php | 4 +- .../builder/api/corporatecustomerbuilder.php | 20 ++++-- .../component/builder/api/customerbuilder.php | 25 +++++-- .../lib/component/configprovider.php | 72 ++++++++++++++----- intaro.retailcrm/lib/component/constants.php | 3 +- intaro.retailcrm/options.php | 66 +++++++++++++---- intaro.retailcrm/updater.php | 59 +++++++++++++++ .../general/order/RetailCrmOrder_v5Test.php | 10 ++- .../api/CorporateCustomerBuilderTest.php | 12 ++-- .../builder/api/CustomerBuilderTest.php | 8 ++- 17 files changed, 286 insertions(+), 83 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b10c6751..4b9a27182 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## 2026-07-01 v6.8.3 +- Добавлена поддержка мультисайтовости для типа контрагента + ## 2026-06-18 v6.8.2 - Исправлены замечания по безопасности модуля. Уточнены защитные проверки и обработка данных после повторной проверки приложения на Маркетплейсе. diff --git a/intaro.retailcrm/classes/general/events/RetailCrmEvent.php b/intaro.retailcrm/classes/general/events/RetailCrmEvent.php index b6dfc45a4..9d028efd0 100644 --- a/intaro.retailcrm/classes/general/events/RetailCrmEvent.php +++ b/intaro.retailcrm/classes/general/events/RetailCrmEvent.php @@ -171,7 +171,7 @@ public static function orderSave($event) $optionsSitesList = RetailcrmConfigProvider::getSitesList(); $optionsOrderProps = RetailcrmConfigProvider::getOrderProps(); $optionsLegalDetails = RetailcrmConfigProvider::getLegalDetails(); - $optionsContragentType = RetailcrmConfigProvider::getContragentTypes(); + $optionsContragentType = RetailcrmConfigProvider::getContragentTypesBySite(); $optionsCustomFields = RetailcrmConfigProvider::getCustomFields(); //corp cliente swich @@ -224,7 +224,7 @@ public static function orderSave($event) //TODO эта управляющая конструкция по функционалу дублирует RetailCrmOrder::createCustomerForOrder. // Необходимо устранить дублирование, вынеся логику в обособленный класс-сервис - if ('Y' === $optionCorpClient && in_array($optionsContragentType[$arOrder['PERSON_TYPE_ID']], ['legal-entity', 'enterpreneur'])) { + if ('Y' === $optionCorpClient && in_array($optionsContragentType[$arOrder['LID']][$arOrder['PERSON_TYPE_ID']] ?? null, ['legal-entity', 'enterpreneur'])) { //corparate cliente $nickName = ''; $address = ''; @@ -325,7 +325,7 @@ function ($carry, $item) use ($nickName) { $resultUserCorp = RetailCrmCorporateClient::clientSend( $arOrder, $api, - $optionsContragentType[$arOrder['PERSON_TYPE_ID']], + $optionsContragentType[$arOrder['LID']][$arOrder['PERSON_TYPE_ID']] ?? null, true, false, $site @@ -430,7 +430,7 @@ function ($carry, $item) use ($nickName) { $resultUser = RetailCrmUser::customerSend( $arUser, $api, - $optionsContragentType[$arOrder['PERSON_TYPE_ID']], + $optionsContragentType[$arOrder['LID']][$arOrder['PERSON_TYPE_ID']] ?? null, true, $site ); diff --git a/intaro.retailcrm/classes/general/history/RetailCrmHistory_v5.php b/intaro.retailcrm/classes/general/history/RetailCrmHistory_v5.php index 3e734aa05..dae39897b 100644 --- a/intaro.retailcrm/classes/general/history/RetailCrmHistory_v5.php +++ b/intaro.retailcrm/classes/general/history/RetailCrmHistory_v5.php @@ -12,8 +12,13 @@ use Bitrix\Main\ArgumentException; use Bitrix\Main\ArgumentNullException; use Bitrix\Main\ArgumentOutOfRangeException; +use Bitrix\Main\ArgumentTypeException; use Bitrix\Main\Context; +use Bitrix\Main\NotImplementedException; use Bitrix\Main\NotSupportedException; +use Bitrix\Main\ObjectException; +use Bitrix\Main\ObjectNotFoundException; +use Bitrix\Main\ObjectPropertyException; use Bitrix\Main\SystemException; use Bitrix\Sale\Basket; use Bitrix\Sale\Delivery\Services\EmptyDeliveryService; @@ -294,7 +299,7 @@ public static function orderHistory(): bool $optionsOrderNumbers = RetailcrmConfigProvider::getOrderNumbers(); $optionsCanselOrder = RetailcrmConfigProvider::getCancellableOrderPaymentStatuses(); $currency = RetailcrmConfigProvider::getCurrencyOrDefault(); - $contragentTypes = array_flip(RetailcrmConfigProvider::getContragentTypes()); + $contragentTypesBySite = RetailcrmConfigProvider::getContragentTypesBySite(); $shipmentDeducted = RetailcrmConfigProvider::getShipmentDeducted(); $optionsPayment = [ @@ -410,6 +415,8 @@ public static function orderHistory(): bool continue; } + $contragentTypes = array_flip($contragentTypesBySite[$site] ?? []); + if (isset($order['customer']['externalId']) && !is_numeric($order['customer']['externalId'])) { unset($order['customer']['externalId']); } @@ -665,6 +672,8 @@ public static function orderHistory(): bool continue; } + $contragentTypes = array_flip($contragentTypesBySite[$site] ?? []); + self::setManager($newOrder, $order); //delivery diff --git a/intaro.retailcrm/classes/general/order/RetailCrmOrder_v5.php b/intaro.retailcrm/classes/general/order/RetailCrmOrder_v5.php index a1404088a..be6d36a9c 100644 --- a/intaro.retailcrm/classes/general/order/RetailCrmOrder_v5.php +++ b/intaro.retailcrm/classes/general/order/RetailCrmOrder_v5.php @@ -134,7 +134,7 @@ public static function orderSend( $order['customer']['browserId'] = $_COOKIE['_rc']; } - $order['contragent']['contragentType'] = $arParams['optionsContragentType'][$arOrder['PERSON_TYPE_ID']]; + $order['contragent']['contragentType'] = $arParams['optionsContragentType'][$arOrder['LID']][$arOrder['PERSON_TYPE_ID']] ?? null; $countryList = BitrixOrderService::getCountryList(); $isSendCustomFields = 'N'; @@ -615,7 +615,7 @@ public static function uploadOrders(int $pSize = 50, bool $failed = false, array $optionsPayment = RetailcrmConfigProvider::getPayment(); $optionsOrderProps = RetailcrmConfigProvider::getOrderProps(); $optionsLegalDetails = RetailcrmConfigProvider::getLegalDetails(); - $optionsContragentType = RetailcrmConfigProvider::getContragentTypes(); + $optionsContragentType = RetailcrmConfigProvider::getContragentTypesBySite(); $optionsCustomFields = RetailcrmConfigProvider::getCustomFields(); $api = new ApiClient(RetailcrmConfigProvider::getApiUrl(), RetailcrmConfigProvider::getApiKey()); @@ -772,7 +772,7 @@ public static function createCustomerForOrder( array $order, $site ): void { - $optionsContragentType = RetailcrmConfigProvider::getContragentTypes(); + $optionsContragentType = RetailcrmConfigProvider::getContragentTypesBySite(); $user = UserTable::getById($order['USER_ID'])->fetch(); if (!$user) { @@ -793,7 +793,7 @@ public static function createCustomerForOrder( if ( 'Y' === RetailcrmConfigProvider::getCorporateClientStatus() - && in_array($optionsContragentType[$order['PERSON_TYPE_ID']], ['legal-entity', 'enterpreneur']) + && in_array($optionsContragentType[$order['LID']][$order['PERSON_TYPE_ID']] ?? null, ['legal-entity', 'enterpreneur']) ) { // TODO check if order is corporate, and if it IS - make corporate order $arCustomer = RetailCrmUser::customerSend( @@ -807,7 +807,7 @@ public static function createCustomerForOrder( $arCustomerCorporate = RetailCrmCorporateClient::clientSend( $order, $api, - $optionsContragentType[$order['PERSON_TYPE_ID']], + $optionsContragentType[$order['LID']][$order['PERSON_TYPE_ID']] ?? null, false, true, $site @@ -824,7 +824,7 @@ public static function createCustomerForOrder( $arCustomer = RetailCrmUser::customerSend( $user, $api, - $optionsContragentType[$order['PERSON_TYPE_ID']], + $optionsContragentType[$order['LID']][$order['PERSON_TYPE_ID']] ?? null, false, $site ); diff --git a/intaro.retailcrm/description.ru b/intaro.retailcrm/description.ru index 3b3ab2635..bb46b064f 100644 --- a/intaro.retailcrm/description.ru +++ b/intaro.retailcrm/description.ru @@ -1 +1 @@ -- Исправлены замечания по безопасности модуля. Уточнены защитные проверки и обработка данных после повторной проверки приложения на Маркетплейсе. +- Добавлена поддержка мультисайтовости для типа контрагента \ No newline at end of file diff --git a/intaro.retailcrm/install/index.php b/intaro.retailcrm/install/index.php index 408568498..b2c502b63 100644 --- a/intaro.retailcrm/install/index.php +++ b/intaro.retailcrm/install/index.php @@ -769,14 +769,20 @@ function DoInstall() //contragents type list $contragentTypeArr = []; - foreach ($orderTypesList as $orderType) { - $contragentTypeArr[$orderType['ID']] = htmlspecialchars(trim($_POST['contragent-type-' . $orderType['ID']])); + $arSites = RCrmActions::getSitesList(); + + foreach ($arSites as $site) { + foreach ($orderTypesList as $orderType) { + $contragentTypeArr[$site['LID']][$orderType['ID']] = htmlspecialchars( + trim($_POST['contragent-type-' . $site['LID'] . '-' . $orderType['ID']]) + ); + } } COption::SetOptionString($this->MODULE_ID, Constants::CRM_ADDRESS_OPTIONS, serialize($addressDetailOptions)); COption::SetOptionString($this->MODULE_ID, Constants::CRM_ORDER_PROPS, serialize(RCrmActions::clearArr($orderPropsArr))); COption::SetOptionString($this->MODULE_ID, Constants::CRM_LEGAL_DETAILS, serialize(RCrmActions::clearArr($legalDetailsArr))); - COption::SetOptionString($this->MODULE_ID, Constants::CRM_CONTRAGENT_TYPE, serialize(RCrmActions::clearArr($contragentTypeArr))); + COption::SetOptionString($this->MODULE_ID, Constants::CRM_CONTRAGENT_TYPE_SITE, serialize(RCrmActions::clearArr($contragentTypeArr))); $APPLICATION->IncludeAdminFile( GetMessage('MODULE_INSTALL_TITLE'), $this->INSTALL_PATH . '/step4.php' @@ -1191,6 +1197,7 @@ public function DoUninstall() COption::RemoveOption($this->MODULE_ID, Constants::CRM_ORDER_TYPES_ARR); COption::RemoveOption($this->MODULE_ID, Constants::CRM_LEGAL_DETAILS); COption::RemoveOption($this->MODULE_ID, Constants::CRM_CONTRAGENT_TYPE); + COption::RemoveOption($this->MODULE_ID, Constants::CRM_CONTRAGENT_TYPE_SITE); COption::RemoveOption($this->MODULE_ID, Constants::CRM_SITES_LIST); COption::RemoveOption($this->MODULE_ID, Constants::CRM_ORDER_DISCHARGE); COption::RemoveOption($this->MODULE_ID, Constants::CRM_ORDER_FAILED_IDS); diff --git a/intaro.retailcrm/install/step3.php b/intaro.retailcrm/install/step3.php index b4bc52e74..572f7a61c 100644 --- a/intaro.retailcrm/install/step3.php +++ b/intaro.retailcrm/install/step3.php @@ -47,14 +47,20 @@ ['allowed_classes' => false] ); - if ($arResult['CONTRAGENT_TYPES'] === false) { - foreach ($arResult['contragentType'] as $crmContrAgentType) { - if ($crmContrAgentType['ID'] === 'individual') { - $arResult['CONTRAGENT_TYPES']['1'] = 'individual'; - } + if ($arResult['CONTRAGENT_TYPES'] === false || empty($arResult['CONTRAGENT_TYPES'])) { + $arResult['CONTRAGENT_TYPES'] = []; + + foreach ($arResult['arSites'] as $site) { + $arResult['CONTRAGENT_TYPES'][$site['LID']] = []; + + foreach ($arResult['contragentType'] as $crmContrAgentType) { + if ($crmContrAgentType['ID'] === 'individual') { + $arResult['CONTRAGENT_TYPES'][$site['LID']]['1'] = 'individual'; + } - if ($crmContrAgentType['ID'] === 'legal-entity') { - $arResult['CONTRAGENT_TYPES']['2'] = 'legal-entity'; + if ($crmContrAgentType['ID'] === 'legal-entity') { + $arResult['CONTRAGENT_TYPES'][$site['LID']]['2'] = 'legal-entity'; + } } } } @@ -122,34 +128,37 @@ function updateAddressList() } $(document).ready(function() { - const individual = $("[name='contragent-type-1']").val(); - const legalEntity = $("[name='contragent-type-2']").val(); - $('input:checked[name^="address-detail-"]').each(updateAddressList); + + const individual_ = $("[name='contragent-type--1']").val(); + const legalEntity_ = $("[name='contragent-type--2']").val(); - if (legalEntity !== 'individual') { + if (legalEntity_ !== 'individual') { $('tr.legal-detail-2').each(function(){ - if($(this).hasClass(legalEntity)){ + if($(this).hasClass(legalEntity_)){ $(this).show(); $('.legal-detail-title-2').show(); } }); } - if (individual !== 'individual') { + if (individual_ !== 'individual') { $('tr.legal-detail-1').each(function(){ - if($(this).hasClass(individual)){ + if($(this).hasClass(individual_)){ $(this).show(); $('.legal-detail-title-1').show(); } }); } + $('input[name^="address-detail-"]').change(updateAddressList); - + $('input:checked[name^="address-detail-"]').each(updateAddressList); + $('tr.contragent-type select').change(function(){ const splitName = $(this).attr('name').split('-'); const contragentType = $(this).val(); - const orderType = splitName[2]; + const siteLid = splitName[2]; + const orderType = splitName[3]; let legalDetailOrderType = $('tr.legal-detail-' + orderType); legalDetailOrderType.hide(); diff --git a/intaro.retailcrm/install/version.php b/intaro.retailcrm/install/version.php index 995e10875..99ef41995 100644 --- a/intaro.retailcrm/install/version.php +++ b/intaro.retailcrm/install/version.php @@ -1,6 +1,6 @@ '6.8.2', - 'VERSION_DATE' => '2026-06-18 12:00:00' + 'VERSION' => '6.8.3', + 'VERSION_DATE' => '2026-07-01 12:00:00' ]; diff --git a/intaro.retailcrm/lib/component/builder/api/corporatecustomerbuilder.php b/intaro.retailcrm/lib/component/builder/api/corporatecustomerbuilder.php index d84395a69..ddc350ac6 100644 --- a/intaro.retailcrm/lib/component/builder/api/corporatecustomerbuilder.php +++ b/intaro.retailcrm/lib/component/builder/api/corporatecustomerbuilder.php @@ -86,7 +86,6 @@ public function __construct() $this->cookieExtractor = ServiceLocator::get(CookieService::class); $this->sites = ConfigProvider::getSitesList(); $this->legalDetails = ConfigProvider::getLegalDetails(); - $this->contragentTypes = ConfigProvider::getContragentTypes(); } /** @@ -103,12 +102,16 @@ public function build(): BuilderInterface throw new BuilderException('Order should be provided for building corporate customer!'); } - $contragentType = ConfigProvider::getContragentTypeForPersonType($this->order->getPersonTypeId()); + $contragentType = ConfigProvider::getContragentTypeForPersonType( + $this->order->getPersonTypeId(), + $this->order->getSiteId() + ); if (null === $contragentType) { throw new BuilderException(sprintf( - 'Cannot find corresponding contragent type for PERSON_TYPE_ID `%s`', - $this->order->getPersonTypeId() + 'Cannot find corresponding contragent type for PERSON_TYPE_ID `%s` and site `%s`', + $this->order->getPersonTypeId(), + $this->order->getSiteId() )); } @@ -269,8 +272,13 @@ protected function buildLegalDetails(): void } } - if (array_key_exists($this->order->getPersonTypeId(), $this->contragentTypes)) { - $this->customer->contragent->contragentType = $this->contragentTypes[$this->order->getPersonTypeId()]; + $contragentType = ConfigProvider::getContragentTypeForPersonType( + $this->order->getPersonTypeId(), + $this->order->getSiteId() + ); + + if (null !== $contragentType) { + $this->customer->contragent->contragentType = $contragentType; } if (empty($this->customer->nickName)) { diff --git a/intaro.retailcrm/lib/component/builder/api/customerbuilder.php b/intaro.retailcrm/lib/component/builder/api/customerbuilder.php index 5d2ecfb3f..d5443989c 100644 --- a/intaro.retailcrm/lib/component/builder/api/customerbuilder.php +++ b/intaro.retailcrm/lib/component/builder/api/customerbuilder.php @@ -44,6 +44,9 @@ class CustomerBuilder implements BuilderInterface /** @var string $personTypeId */ private $personTypeId; + /** @var string|null $siteId */ + private $siteId; + /** @var bool */ private $attachDaemonCollectorId = false; @@ -63,10 +66,12 @@ public function __construct() */ public function build(): BuilderInterface { - $this->buildBase( - ConfigProvider::getContragentTypeForPersonType($this->personTypeId ?? '') - ?? 'individual' - ); + $contragentType = ConfigProvider::getContragentTypeForPersonType( + $this->personTypeId ?? '', + $this->siteId + ) ?? 'individual'; + + $this->buildBase($contragentType); $this->buildNames(); $this->buildPhones(); $this->buildAddress(); @@ -88,6 +93,7 @@ public function reset(): BuilderInterface $this->user = null; $this->customer = null; $this->personTypeId = null; + $this->siteId = null; return $this; } @@ -124,6 +130,17 @@ public function setPersonTypeId(string $personTypeId): CustomerBuilder return $this; } + /** + * @param string|null $siteId + * + * @return CustomerBuilder + */ + public function setSiteId(?string $siteId): CustomerBuilder + { + $this->siteId = $siteId; + return $this; + } + /** * @param bool $attachDaemonCollectorId * diff --git a/intaro.retailcrm/lib/component/configprovider.php b/intaro.retailcrm/lib/component/configprovider.php index b480a7d23..a81958de2 100644 --- a/intaro.retailcrm/lib/component/configprovider.php +++ b/intaro.retailcrm/lib/component/configprovider.php @@ -94,6 +94,9 @@ class ConfigProvider /** @var array $contragentTypes */ protected static $contragentTypes; + /** @var array $contragentTypesBySite */ + protected static $contragentTypesBySite; + /** @var array $cancellableOrderPaymentStatuses */ protected static $cancellableOrderPaymentStatuses; @@ -464,6 +467,7 @@ public static function getLegalDetails() /** * getContragentTypes * + * @deprecated Use getContragentTypesBySite() instead * @return array */ public static function getContragentTypes() @@ -476,19 +480,66 @@ public static function getContragentTypes() } /** - * Returns contragent type for provided person type (PERSON_TYPE_ID in the Bitrix order). + * setContragentTypes + * + * @deprecated Use setContragentTypesBySite() instead + * @param array $contragentTypeArr + */ + public static function setContragentTypes($contragentTypeArr) + { + static::setOption(Constants::CRM_CONTRAGENT_TYPE, serialize(self::getUtils() + ->clearArray(is_array($contragentTypeArr)?$contragentTypeArr:[]))); + } + + /** + * getContragentTypesBySite + * + * @return array + */ + public static function getContragentTypesBySite() + { + if (self::isEmptyNotZero(static::$contragentTypesBySite)) { + static::$contragentTypesBySite = static::getUnserializedOption(Constants::CRM_CONTRAGENT_TYPE_SITE); + } + + return is_array(static::$contragentTypesBySite) ? static::$contragentTypesBySite : []; + } + + /** + * setContragentTypesBySite + * + * @param array $contragentTypeArr + */ + public static function setContragentTypesBySite($contragentTypeArr) + { + static::setOption(Constants::CRM_CONTRAGENT_TYPE_SITE, serialize(self::getUtils() + ->clearArray(is_array($contragentTypeArr)?$contragentTypeArr:[]))); + } + + /** + * Returns contragent type for provided person type (PERSON_TYPE_ID in the Bitrix order) and site ID. * Returns null if nothing was found. * * @param string $personTypeId + * @param string|null $siteId * * @return string|null */ - public static function getContragentTypeForPersonType(string $personTypeId): ?string + public static function getContragentTypeForPersonType(string $personTypeId, ?string $siteId = null): ?string { - $personTypes = static::getContragentTypes(); + $contragentTypesBySite = static::getContragentTypesBySite(); - if (!empty($personTypes[$personTypeId])) { - return $personTypes[$personTypeId]; + if ($siteId !== null) { + if (!empty($contragentTypesBySite[$siteId][$personTypeId])) { + return $contragentTypesBySite[$siteId][$personTypeId]; + } + return null; + } + + foreach ($contragentTypesBySite as $siteContragentTypes) { + if (!empty($siteContragentTypes[$personTypeId])) { + return $siteContragentTypes[$personTypeId]; + } } return null; @@ -1145,17 +1196,6 @@ public static function setPaymentStatuses($paymentStatusesArr) ->clearArray(is_array($paymentStatusesArr)?$paymentStatusesArr:[]))); } - /** - * setContragentTypes - * - * @param array $contragentTypeArr - */ - public static function setContragentTypes($contragentTypeArr) - { - static::setOption(Constants::CRM_CONTRAGENT_TYPE, serialize(self::getUtils() - ->clearArray(is_array($contragentTypeArr)?$contragentTypeArr:[]))); - } - /** * @return \Intaro\RetailCrm\Service\Utils */ diff --git a/intaro.retailcrm/lib/component/constants.php b/intaro.retailcrm/lib/component/constants.php index 806fd4611..5970a2bbf 100644 --- a/intaro.retailcrm/lib/component/constants.php +++ b/intaro.retailcrm/lib/component/constants.php @@ -18,7 +18,7 @@ */ class Constants { - public const MODULE_VERSION = '6.8.2'; + public const MODULE_VERSION = '6.8.3'; public const CRM_PURCHASE_PRICE_NULL = 'purchasePrice_null'; public const BITRIX_USER_ID_PREFIX = 'bitrixUserId-'; public const CRM_USERS_MAP = 'crm_users_map'; @@ -38,6 +38,7 @@ class Constants public const CRM_LEGAL_DETAILS = 'legal_details'; public const CRM_CUSTOM_FIELDS = 'custom_fields'; public const CRM_CONTRAGENT_TYPE = 'contragent_type'; + public const CRM_CONTRAGENT_TYPE_SITE = 'contragent_type_site'; public const CRM_SITES_LIST_CORPORATE = 'shops-corporate'; public const CRM_ORDER_NUMBERS = 'order_numbers'; public const CRM_ORDER_VAT = 'order_vat'; diff --git a/intaro.retailcrm/options.php b/intaro.retailcrm/options.php index 09c1b306a..73a70ff2b 100644 --- a/intaro.retailcrm/options.php +++ b/intaro.retailcrm/options.php @@ -468,8 +468,12 @@ //contragents type list $contragentTypeArr = []; - foreach ($orderTypesList as $orderType) { - $contragentTypeArr[$orderType['ID']] = htmlspecialchars(trim($_POST['contragent-type-' . $orderType['ID']])); + foreach ($arResult['arSites'] as $site) { + foreach ($orderTypesList as $orderType) { + $contragentTypeArr[$site['LID']][$orderType['ID']] = htmlspecialchars( + trim($_POST['contragent-type-' . $site['LID'] . '-' . $orderType['ID']]) + ); + } } //stores @@ -909,6 +913,20 @@ function maskCorp($var) { Constants::CRM_CONTRAGENT_TYPE, serialize(RCrmActions::clearArr(is_array($contragentTypeArr) ? $contragentTypeArr : [])) ); + $legacyContragentTypes = []; + if (!empty($contragentTypeArr)) { + $firstSite = reset($arResult['arSites']); + foreach ($orderTypesList as $orderType) { + $legacyContragentTypes[$orderType['ID']] = + $contragentTypeArr[$firstSite['LID']][$orderType['ID']] ?? 'individual'; + } + } + + COption::SetOptionString( + $mid, + Constants::CRM_CONTRAGENT_TYPE, + serialize(RCrmActions::clearArr(is_array($legacyContragentTypes) ? $legacyContragentTypes : [])) + ); COption::SetOptionString( $mid, Constants::CRM_LEGAL_DETAILS, @@ -1339,7 +1357,7 @@ function ($payment) { $optionsSitesList = unserialize(COption::GetOptionString($mid, Constants::CRM_SITES_LIST, 0), ['allowed_classes' => false]); $optionsDischarge = (int) COption::GetOptionString($mid, Constants::CRM_ORDER_DISCHARGE, 0); $optionsOrderProps = unserialize(COption::GetOptionString($mid, Constants::CRM_ORDER_PROPS, 0), ['allowed_classes' => false]); - $optionsContragentType = unserialize(COption::GetOptionString($mid, Constants::CRM_CONTRAGENT_TYPE, 0), ['allowed_classes' => false]); + $optionsContragentType = unserialize(COption::GetOptionString($mid, Constants::CRM_CONTRAGENT_TYPE_SITE, 0), ['allowed_classes' => false]); $optionsLegalDetails = unserialize(COption::GetOptionString($mid, Constants::CRM_LEGAL_DETAILS, 0), ['allowed_classes' => false]); $optionsCustomFields = unserialize(COption::GetOptionString($mid, Constants::CRM_CUSTOM_FIELDS, 0), ['allowed_classes' => false]); $optionsOrderNumbers = COption::GetOptionString($mid, Constants::CRM_ORDER_NUMBERS, 0); @@ -1811,9 +1829,9 @@ function updateAddressList() $('input:checked[name^="address-detail-"]').each(updateAddressList); $('tr.contragent-type select').change(function() { - splitName = $(this).attr('name').split('-'); - contragentType = $(this).val(); - orderType = splitName[2]; + const splitName = $(this).attr('name').split('-'); + const contragentType = $(this).val(); + const orderType = splitName[3]; $('tr.legal-detail-' + orderType).hide(); $('.legal-detail-title-' + orderType).hide(); @@ -2285,22 +2303,29 @@ function updateAddressList() + + - + - - + + @@ -2399,9 +2424,22 @@ function updateAddressList() > + } ?>" + + > diff --git a/intaro.retailcrm/updater.php b/intaro.retailcrm/updater.php index 17dec4ed0..50b152b45 100755 --- a/intaro.retailcrm/updater.php +++ b/intaro.retailcrm/updater.php @@ -3,6 +3,7 @@ use Bitrix\Main\Loader; use Bitrix\Main\Config\Option; use Bitrix\Main\Application; +use Intaro\RetailCrm\Component\Constants; function update() { @@ -13,6 +14,8 @@ function update() customFieldsCheck(); addEventSaveOrder(); loadJsExport(); + + migrateContragentTypes(); } function loadJsExport() @@ -93,6 +96,62 @@ function addEventSaveOrder() } } +/** + * Миграция данных contragent type из старого формата в новый + */ +function migrateContragentTypes() +{ + $newOptionValue = Option::get('intaro.retailcrm', Constants::CRM_CONTRAGENT_TYPE_SITE, null); + + if ($newOptionValue !== null && $newOptionValue !== '') { + return; + } + + $oldContragentTypes = Option::get('intaro.retailcrm', Constants::CRM_CONTRAGENT_TYPE, null); + + if (empty($oldContragentTypes)) { + $oldContragentTypes = []; + } else { + $oldContragentTypes = unserialize($oldContragentTypes, ['allowed_classes' => false]); + + if (!is_array($oldContragentTypes)) { + $oldContragentTypes = []; + } + } + + $sites = \CSite::GetList( + $by = 'sort', + $order = 'asc', + ['ACTIVE' => 'Y'] + ); + + $newContragentTypes = []; + + while ($site = $sites->Fetch()) { + $siteId = $site['LID']; + $newContragentTypes[$siteId] = []; + + $personTypes = \CSalePersonType::GetList( + ['SORT' => 'ASC'], + ['LID' => $siteId, 'ACTIVE' => 'Y'] + ); + + while ($personType = $personTypes->Fetch()) { + $personTypeId = $personType['ID']; + + if (isset($oldContragentTypes[$personTypeId])) { + $newContragentTypes[$siteId][$personTypeId] = $oldContragentTypes[$personTypeId]; + } else { + $newContragentTypes[$siteId][$personTypeId] = 'individual'; + } + } + } + + if (!empty($newContragentTypes)) { + Option::set('intaro.retailcrm', Constants::CRM_CONTRAGENT_TYPE_SITE, serialize($newContragentTypes)); + } +} + try { update(); } catch (\Throwable $exception) { diff --git a/tests/classes/general/order/RetailCrmOrder_v5Test.php b/tests/classes/general/order/RetailCrmOrder_v5Test.php index 87baabbeb..621f14180 100644 --- a/tests/classes/general/order/RetailCrmOrder_v5Test.php +++ b/tests/classes/general/order/RetailCrmOrder_v5Test.php @@ -114,7 +114,7 @@ public function testFieldExists(): void public function initSystemData(): void { RetailcrmConfigProvider::setOrderTypes(['bitrixType' => 'crmType']); - RetailcrmConfigProvider::setContragentTypes(['bitrixType' => 'individual']); + RetailcrmConfigProvider::setContragentTypesBySite(['s1' => ['bitrixType' => 'individual']]); RetailcrmConfigProvider::setPaymentStatuses([1 => 'paymentStatus']); RetailcrmConfigProvider::setPaymentTypes([1 => 'testPayment']); RetailcrmConfigProvider::setDeliveryTypes(['test' => 'test']); @@ -129,10 +129,12 @@ public function orderSendProvider() $arFields = $this->getArFields(); $this->initSystemData(); + $contragentTypes = RetailcrmConfigProvider::getContragentTypesBySite(); + $arParams = [ 'optionsOrderTypes' => RetailcrmConfigProvider::getOrderTypes(), 'optionsPayStatuses' => RetailcrmConfigProvider::getPaymentStatuses(), - 'optionsContragentType' => RetailcrmConfigProvider::getContragentTypes(), + 'optionsContragentType' => $contragentTypes, 'optionsDelivTypes' => RetailcrmConfigProvider::getDeliveryTypes(), 'optionsPayTypes' => RetailcrmConfigProvider::getPaymentTypes(), 'optionsOrderProps' => ['bitrixType' => ['fio' => 'FIO']], @@ -140,6 +142,8 @@ public function orderSendProvider() 'customOrderProps' => ['1#TEST_PROP_1' => 'custom_first', '2#TEST_PROP_2' => 'custom_second'] ]; + $contragentType = $contragentTypes['s1'][$arFields['PERSON_TYPE_ID']] ?? null; + return [[ 'arFields' => $arFields, 'arParams' => $arParams, @@ -159,7 +163,7 @@ public function orderSendProvider() 'service' => ['code' => $arFields['DELIVERYS'][0]['service']] ], 'contragent' => [ - 'contragentType' => $arParams['optionsContragentType'][$arFields['PERSON_TYPE_ID']] + 'contragentType' => $contragentType ], 'payments' => [[ 'type' => $arParams['optionsPayTypes'][$arFields['PAYMENTS'][0]['PAY_SYSTEM_ID']], diff --git a/tests/lib/component/builder/api/CorporateCustomerBuilderTest.php b/tests/lib/component/builder/api/CorporateCustomerBuilderTest.php index aad60061d..4c2d36a2f 100755 --- a/tests/lib/component/builder/api/CorporateCustomerBuilderTest.php +++ b/tests/lib/component/builder/api/CorporateCustomerBuilderTest.php @@ -20,9 +20,11 @@ protected function setUp(): void Helpers::setConfigProperty('sitesList', ['s1' => 's1']); Helpers::setConfigProperty('corporateClientName', 'COMPANY'); Helpers::setConfigProperty('corporateClientAddress', 'COMPANY_ADR'); - Helpers::setConfigProperty('contragentTypes', [ - 'individual', - 'legal-entity' + Helpers::setConfigProperty('contragentTypesBySite', [ + 's1' => [ + 'individual' => 'individual', + 'legal-entity' => 'legal-entity' + ] ]); Helpers::setConfigProperty('legalDetails', [ 'individual', @@ -75,7 +77,9 @@ public function testBuild() $order = Order::create('s1', $user->getId()); $order->setField('DATE_INSERT', new DateTime()); - $order->setPersonTypeId(array_flip(ConfigProvider::getContragentTypes())['legal-entity']); + $contragentTypes = ConfigProvider::getContragentTypesBySite(); + $personTypeId = array_flip($contragentTypes['s1'] ?? [])['legal-entity'] ?? null; + $order->setPersonTypeId($personTypeId); $saveResult = $order->save(); self::assertTrue($saveResult->isSuccess(), implode(', ', $saveResult->getErrorMessages())); self::assertNotNull($order->getId(), implode(', ', $saveResult->getErrorMessages())); diff --git a/tests/lib/component/builder/api/CustomerBuilderTest.php b/tests/lib/component/builder/api/CustomerBuilderTest.php index 9515a863d..6eb62e5c4 100755 --- a/tests/lib/component/builder/api/CustomerBuilderTest.php +++ b/tests/lib/component/builder/api/CustomerBuilderTest.php @@ -19,8 +19,10 @@ class CustomerBuilderTest extends TestCase { public function setUp(): void { - Helpers::setConfigProperty('contragentTypes', [ - 'individual' => 'individual' + Helpers::setConfigProperty('contragentTypesBySite', [ + 's1' => [ + 'individual' => 'individual' + ] ]); } @@ -52,6 +54,7 @@ public function testBuild($entity): void ->reset() ->setAttachDaemonCollectorId(true) ->setPersonTypeId('individual') + ->setSiteId('s1') ->setUser($entity) ->build() ->getResult(); @@ -97,6 +100,7 @@ static function (Event $event) { $builder = new CustomerBuilder(); $result = $builder ->setPersonTypeId('individual') + ->setSiteId('s1') ->setUser($entity) ->build() ->getResult(); From 5279393c2cdbe685e6f9267cb96fc4279c3eb3aa Mon Sep 17 00:00:00 2001 From: danila Date: Wed, 1 Jul 2026 16:44:51 +0500 Subject: [PATCH 2/4] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=BF=D0=BE=D0=B4=D0=B4=D0=B5=D1=80=D0=B6=D0=BA?= =?UTF-8?q?=D0=B0=20=D0=BC=D1=83=D0=BB=D1=8C=D1=82=D0=B8=D1=81=D0=B0=D0=B9?= =?UTF-8?q?=D1=82=D0=BE=D0=B2=D0=BE=D1=81=D1=82=D0=B8=20=D0=B4=D0=BB=D1=8F?= =?UTF-8?q?=20=D1=82=D0=B8=D0=BF=D0=B0=20=D0=BA=D0=BE=D0=BD=D1=82=D1=80?= =?UTF-8?q?=D0=B0=D0=B3=D0=B5=D0=BD=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 3 + .../classes/general/events/RetailCrmEvent.php | 8 +-- .../general/history/RetailCrmHistory_v5.php | 11 ++- .../general/order/RetailCrmOrder_v5.php | 12 ++-- intaro.retailcrm/description.ru | 2 +- intaro.retailcrm/install/index.php | 13 +++- intaro.retailcrm/install/step3.php | 41 ++++++----- intaro.retailcrm/install/version.php | 4 +- .../builder/api/corporatecustomerbuilder.php | 20 ++++-- .../component/builder/api/customerbuilder.php | 25 +++++-- .../lib/component/configprovider.php | 72 ++++++++++++++----- intaro.retailcrm/lib/component/constants.php | 1 + intaro.retailcrm/options.php | 66 +++++++++++++---- intaro.retailcrm/updater.php | 59 +++++++++++++++ .../general/order/RetailCrmOrder_v5Test.php | 10 ++- .../api/CorporateCustomerBuilderTest.php | 12 ++-- .../builder/api/CustomerBuilderTest.php | 8 ++- 17 files changed, 285 insertions(+), 82 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ebd9a3450..bb357a294 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## 2026-07-01 v6.8.4 +- Добавлена поддержка мультисайтовости для типа контрагента + ## 2026-06-30 v6.8.3 - Исправлено присвоение PERSON_TYPE_ID для $newOrder diff --git a/intaro.retailcrm/classes/general/events/RetailCrmEvent.php b/intaro.retailcrm/classes/general/events/RetailCrmEvent.php index b6dfc45a4..9d028efd0 100644 --- a/intaro.retailcrm/classes/general/events/RetailCrmEvent.php +++ b/intaro.retailcrm/classes/general/events/RetailCrmEvent.php @@ -171,7 +171,7 @@ public static function orderSave($event) $optionsSitesList = RetailcrmConfigProvider::getSitesList(); $optionsOrderProps = RetailcrmConfigProvider::getOrderProps(); $optionsLegalDetails = RetailcrmConfigProvider::getLegalDetails(); - $optionsContragentType = RetailcrmConfigProvider::getContragentTypes(); + $optionsContragentType = RetailcrmConfigProvider::getContragentTypesBySite(); $optionsCustomFields = RetailcrmConfigProvider::getCustomFields(); //corp cliente swich @@ -224,7 +224,7 @@ public static function orderSave($event) //TODO эта управляющая конструкция по функционалу дублирует RetailCrmOrder::createCustomerForOrder. // Необходимо устранить дублирование, вынеся логику в обособленный класс-сервис - if ('Y' === $optionCorpClient && in_array($optionsContragentType[$arOrder['PERSON_TYPE_ID']], ['legal-entity', 'enterpreneur'])) { + if ('Y' === $optionCorpClient && in_array($optionsContragentType[$arOrder['LID']][$arOrder['PERSON_TYPE_ID']] ?? null, ['legal-entity', 'enterpreneur'])) { //corparate cliente $nickName = ''; $address = ''; @@ -325,7 +325,7 @@ function ($carry, $item) use ($nickName) { $resultUserCorp = RetailCrmCorporateClient::clientSend( $arOrder, $api, - $optionsContragentType[$arOrder['PERSON_TYPE_ID']], + $optionsContragentType[$arOrder['LID']][$arOrder['PERSON_TYPE_ID']] ?? null, true, false, $site @@ -430,7 +430,7 @@ function ($carry, $item) use ($nickName) { $resultUser = RetailCrmUser::customerSend( $arUser, $api, - $optionsContragentType[$arOrder['PERSON_TYPE_ID']], + $optionsContragentType[$arOrder['LID']][$arOrder['PERSON_TYPE_ID']] ?? null, true, $site ); diff --git a/intaro.retailcrm/classes/general/history/RetailCrmHistory_v5.php b/intaro.retailcrm/classes/general/history/RetailCrmHistory_v5.php index dc6ee9681..13bd7b439 100644 --- a/intaro.retailcrm/classes/general/history/RetailCrmHistory_v5.php +++ b/intaro.retailcrm/classes/general/history/RetailCrmHistory_v5.php @@ -12,8 +12,13 @@ use Bitrix\Main\ArgumentException; use Bitrix\Main\ArgumentNullException; use Bitrix\Main\ArgumentOutOfRangeException; +use Bitrix\Main\ArgumentTypeException; use Bitrix\Main\Context; +use Bitrix\Main\NotImplementedException; use Bitrix\Main\NotSupportedException; +use Bitrix\Main\ObjectException; +use Bitrix\Main\ObjectNotFoundException; +use Bitrix\Main\ObjectPropertyException; use Bitrix\Main\SystemException; use Bitrix\Sale\Basket; use Bitrix\Sale\Delivery\Services\EmptyDeliveryService; @@ -295,7 +300,7 @@ public static function orderHistory(): bool $optionsOrderNumbers = RetailcrmConfigProvider::getOrderNumbers(); $optionsCanselOrder = RetailcrmConfigProvider::getCancellableOrderPaymentStatuses(); $currency = RetailcrmConfigProvider::getCurrencyOrDefault(); - $contragentTypes = array_flip(RetailcrmConfigProvider::getContragentTypes()); + $contragentTypesBySite = RetailcrmConfigProvider::getContragentTypesBySite(); $shipmentDeducted = RetailcrmConfigProvider::getShipmentDeducted(); $optionsPayment = [ @@ -411,6 +416,8 @@ public static function orderHistory(): bool continue; } + $contragentTypes = array_flip($contragentTypesBySite[$site] ?? []); + if (isset($order['customer']['externalId']) && !is_numeric($order['customer']['externalId'])) { unset($order['customer']['externalId']); } @@ -666,6 +673,8 @@ public static function orderHistory(): bool continue; } + $contragentTypes = array_flip($contragentTypesBySite[$site] ?? []); + self::setManager($newOrder, $order); //delivery diff --git a/intaro.retailcrm/classes/general/order/RetailCrmOrder_v5.php b/intaro.retailcrm/classes/general/order/RetailCrmOrder_v5.php index a1404088a..be6d36a9c 100644 --- a/intaro.retailcrm/classes/general/order/RetailCrmOrder_v5.php +++ b/intaro.retailcrm/classes/general/order/RetailCrmOrder_v5.php @@ -134,7 +134,7 @@ public static function orderSend( $order['customer']['browserId'] = $_COOKIE['_rc']; } - $order['contragent']['contragentType'] = $arParams['optionsContragentType'][$arOrder['PERSON_TYPE_ID']]; + $order['contragent']['contragentType'] = $arParams['optionsContragentType'][$arOrder['LID']][$arOrder['PERSON_TYPE_ID']] ?? null; $countryList = BitrixOrderService::getCountryList(); $isSendCustomFields = 'N'; @@ -615,7 +615,7 @@ public static function uploadOrders(int $pSize = 50, bool $failed = false, array $optionsPayment = RetailcrmConfigProvider::getPayment(); $optionsOrderProps = RetailcrmConfigProvider::getOrderProps(); $optionsLegalDetails = RetailcrmConfigProvider::getLegalDetails(); - $optionsContragentType = RetailcrmConfigProvider::getContragentTypes(); + $optionsContragentType = RetailcrmConfigProvider::getContragentTypesBySite(); $optionsCustomFields = RetailcrmConfigProvider::getCustomFields(); $api = new ApiClient(RetailcrmConfigProvider::getApiUrl(), RetailcrmConfigProvider::getApiKey()); @@ -772,7 +772,7 @@ public static function createCustomerForOrder( array $order, $site ): void { - $optionsContragentType = RetailcrmConfigProvider::getContragentTypes(); + $optionsContragentType = RetailcrmConfigProvider::getContragentTypesBySite(); $user = UserTable::getById($order['USER_ID'])->fetch(); if (!$user) { @@ -793,7 +793,7 @@ public static function createCustomerForOrder( if ( 'Y' === RetailcrmConfigProvider::getCorporateClientStatus() - && in_array($optionsContragentType[$order['PERSON_TYPE_ID']], ['legal-entity', 'enterpreneur']) + && in_array($optionsContragentType[$order['LID']][$order['PERSON_TYPE_ID']] ?? null, ['legal-entity', 'enterpreneur']) ) { // TODO check if order is corporate, and if it IS - make corporate order $arCustomer = RetailCrmUser::customerSend( @@ -807,7 +807,7 @@ public static function createCustomerForOrder( $arCustomerCorporate = RetailCrmCorporateClient::clientSend( $order, $api, - $optionsContragentType[$order['PERSON_TYPE_ID']], + $optionsContragentType[$order['LID']][$order['PERSON_TYPE_ID']] ?? null, false, true, $site @@ -824,7 +824,7 @@ public static function createCustomerForOrder( $arCustomer = RetailCrmUser::customerSend( $user, $api, - $optionsContragentType[$order['PERSON_TYPE_ID']], + $optionsContragentType[$order['LID']][$order['PERSON_TYPE_ID']] ?? null, false, $site ); diff --git a/intaro.retailcrm/description.ru b/intaro.retailcrm/description.ru index b5f2d6f7b..bb46b064f 100644 --- a/intaro.retailcrm/description.ru +++ b/intaro.retailcrm/description.ru @@ -1 +1 @@ -- Исправлено присвоение PERSON_TYPE_ID для $newOrder +- Добавлена поддержка мультисайтовости для типа контрагента \ No newline at end of file diff --git a/intaro.retailcrm/install/index.php b/intaro.retailcrm/install/index.php index 408568498..b2c502b63 100644 --- a/intaro.retailcrm/install/index.php +++ b/intaro.retailcrm/install/index.php @@ -769,14 +769,20 @@ function DoInstall() //contragents type list $contragentTypeArr = []; - foreach ($orderTypesList as $orderType) { - $contragentTypeArr[$orderType['ID']] = htmlspecialchars(trim($_POST['contragent-type-' . $orderType['ID']])); + $arSites = RCrmActions::getSitesList(); + + foreach ($arSites as $site) { + foreach ($orderTypesList as $orderType) { + $contragentTypeArr[$site['LID']][$orderType['ID']] = htmlspecialchars( + trim($_POST['contragent-type-' . $site['LID'] . '-' . $orderType['ID']]) + ); + } } COption::SetOptionString($this->MODULE_ID, Constants::CRM_ADDRESS_OPTIONS, serialize($addressDetailOptions)); COption::SetOptionString($this->MODULE_ID, Constants::CRM_ORDER_PROPS, serialize(RCrmActions::clearArr($orderPropsArr))); COption::SetOptionString($this->MODULE_ID, Constants::CRM_LEGAL_DETAILS, serialize(RCrmActions::clearArr($legalDetailsArr))); - COption::SetOptionString($this->MODULE_ID, Constants::CRM_CONTRAGENT_TYPE, serialize(RCrmActions::clearArr($contragentTypeArr))); + COption::SetOptionString($this->MODULE_ID, Constants::CRM_CONTRAGENT_TYPE_SITE, serialize(RCrmActions::clearArr($contragentTypeArr))); $APPLICATION->IncludeAdminFile( GetMessage('MODULE_INSTALL_TITLE'), $this->INSTALL_PATH . '/step4.php' @@ -1191,6 +1197,7 @@ public function DoUninstall() COption::RemoveOption($this->MODULE_ID, Constants::CRM_ORDER_TYPES_ARR); COption::RemoveOption($this->MODULE_ID, Constants::CRM_LEGAL_DETAILS); COption::RemoveOption($this->MODULE_ID, Constants::CRM_CONTRAGENT_TYPE); + COption::RemoveOption($this->MODULE_ID, Constants::CRM_CONTRAGENT_TYPE_SITE); COption::RemoveOption($this->MODULE_ID, Constants::CRM_SITES_LIST); COption::RemoveOption($this->MODULE_ID, Constants::CRM_ORDER_DISCHARGE); COption::RemoveOption($this->MODULE_ID, Constants::CRM_ORDER_FAILED_IDS); diff --git a/intaro.retailcrm/install/step3.php b/intaro.retailcrm/install/step3.php index b4bc52e74..572f7a61c 100644 --- a/intaro.retailcrm/install/step3.php +++ b/intaro.retailcrm/install/step3.php @@ -47,14 +47,20 @@ ['allowed_classes' => false] ); - if ($arResult['CONTRAGENT_TYPES'] === false) { - foreach ($arResult['contragentType'] as $crmContrAgentType) { - if ($crmContrAgentType['ID'] === 'individual') { - $arResult['CONTRAGENT_TYPES']['1'] = 'individual'; - } + if ($arResult['CONTRAGENT_TYPES'] === false || empty($arResult['CONTRAGENT_TYPES'])) { + $arResult['CONTRAGENT_TYPES'] = []; + + foreach ($arResult['arSites'] as $site) { + $arResult['CONTRAGENT_TYPES'][$site['LID']] = []; + + foreach ($arResult['contragentType'] as $crmContrAgentType) { + if ($crmContrAgentType['ID'] === 'individual') { + $arResult['CONTRAGENT_TYPES'][$site['LID']]['1'] = 'individual'; + } - if ($crmContrAgentType['ID'] === 'legal-entity') { - $arResult['CONTRAGENT_TYPES']['2'] = 'legal-entity'; + if ($crmContrAgentType['ID'] === 'legal-entity') { + $arResult['CONTRAGENT_TYPES'][$site['LID']]['2'] = 'legal-entity'; + } } } } @@ -122,34 +128,37 @@ function updateAddressList() } $(document).ready(function() { - const individual = $("[name='contragent-type-1']").val(); - const legalEntity = $("[name='contragent-type-2']").val(); - $('input:checked[name^="address-detail-"]').each(updateAddressList); + + const individual_ = $("[name='contragent-type--1']").val(); + const legalEntity_ = $("[name='contragent-type--2']").val(); - if (legalEntity !== 'individual') { + if (legalEntity_ !== 'individual') { $('tr.legal-detail-2').each(function(){ - if($(this).hasClass(legalEntity)){ + if($(this).hasClass(legalEntity_)){ $(this).show(); $('.legal-detail-title-2').show(); } }); } - if (individual !== 'individual') { + if (individual_ !== 'individual') { $('tr.legal-detail-1').each(function(){ - if($(this).hasClass(individual)){ + if($(this).hasClass(individual_)){ $(this).show(); $('.legal-detail-title-1').show(); } }); } + $('input[name^="address-detail-"]').change(updateAddressList); - + $('input:checked[name^="address-detail-"]').each(updateAddressList); + $('tr.contragent-type select').change(function(){ const splitName = $(this).attr('name').split('-'); const contragentType = $(this).val(); - const orderType = splitName[2]; + const siteLid = splitName[2]; + const orderType = splitName[3]; let legalDetailOrderType = $('tr.legal-detail-' + orderType); legalDetailOrderType.hide(); diff --git a/intaro.retailcrm/install/version.php b/intaro.retailcrm/install/version.php index f1a5af790..daca68744 100644 --- a/intaro.retailcrm/install/version.php +++ b/intaro.retailcrm/install/version.php @@ -1,6 +1,6 @@ '6.8.3', - 'VERSION_DATE' => '2026-06-30 12:00:00' + 'VERSION' => '6.8.4', + 'VERSION_DATE' => '2026-07-01 12:00:00' ]; diff --git a/intaro.retailcrm/lib/component/builder/api/corporatecustomerbuilder.php b/intaro.retailcrm/lib/component/builder/api/corporatecustomerbuilder.php index d84395a69..ddc350ac6 100644 --- a/intaro.retailcrm/lib/component/builder/api/corporatecustomerbuilder.php +++ b/intaro.retailcrm/lib/component/builder/api/corporatecustomerbuilder.php @@ -86,7 +86,6 @@ public function __construct() $this->cookieExtractor = ServiceLocator::get(CookieService::class); $this->sites = ConfigProvider::getSitesList(); $this->legalDetails = ConfigProvider::getLegalDetails(); - $this->contragentTypes = ConfigProvider::getContragentTypes(); } /** @@ -103,12 +102,16 @@ public function build(): BuilderInterface throw new BuilderException('Order should be provided for building corporate customer!'); } - $contragentType = ConfigProvider::getContragentTypeForPersonType($this->order->getPersonTypeId()); + $contragentType = ConfigProvider::getContragentTypeForPersonType( + $this->order->getPersonTypeId(), + $this->order->getSiteId() + ); if (null === $contragentType) { throw new BuilderException(sprintf( - 'Cannot find corresponding contragent type for PERSON_TYPE_ID `%s`', - $this->order->getPersonTypeId() + 'Cannot find corresponding contragent type for PERSON_TYPE_ID `%s` and site `%s`', + $this->order->getPersonTypeId(), + $this->order->getSiteId() )); } @@ -269,8 +272,13 @@ protected function buildLegalDetails(): void } } - if (array_key_exists($this->order->getPersonTypeId(), $this->contragentTypes)) { - $this->customer->contragent->contragentType = $this->contragentTypes[$this->order->getPersonTypeId()]; + $contragentType = ConfigProvider::getContragentTypeForPersonType( + $this->order->getPersonTypeId(), + $this->order->getSiteId() + ); + + if (null !== $contragentType) { + $this->customer->contragent->contragentType = $contragentType; } if (empty($this->customer->nickName)) { diff --git a/intaro.retailcrm/lib/component/builder/api/customerbuilder.php b/intaro.retailcrm/lib/component/builder/api/customerbuilder.php index 5d2ecfb3f..d5443989c 100644 --- a/intaro.retailcrm/lib/component/builder/api/customerbuilder.php +++ b/intaro.retailcrm/lib/component/builder/api/customerbuilder.php @@ -44,6 +44,9 @@ class CustomerBuilder implements BuilderInterface /** @var string $personTypeId */ private $personTypeId; + /** @var string|null $siteId */ + private $siteId; + /** @var bool */ private $attachDaemonCollectorId = false; @@ -63,10 +66,12 @@ public function __construct() */ public function build(): BuilderInterface { - $this->buildBase( - ConfigProvider::getContragentTypeForPersonType($this->personTypeId ?? '') - ?? 'individual' - ); + $contragentType = ConfigProvider::getContragentTypeForPersonType( + $this->personTypeId ?? '', + $this->siteId + ) ?? 'individual'; + + $this->buildBase($contragentType); $this->buildNames(); $this->buildPhones(); $this->buildAddress(); @@ -88,6 +93,7 @@ public function reset(): BuilderInterface $this->user = null; $this->customer = null; $this->personTypeId = null; + $this->siteId = null; return $this; } @@ -124,6 +130,17 @@ public function setPersonTypeId(string $personTypeId): CustomerBuilder return $this; } + /** + * @param string|null $siteId + * + * @return CustomerBuilder + */ + public function setSiteId(?string $siteId): CustomerBuilder + { + $this->siteId = $siteId; + return $this; + } + /** * @param bool $attachDaemonCollectorId * diff --git a/intaro.retailcrm/lib/component/configprovider.php b/intaro.retailcrm/lib/component/configprovider.php index b480a7d23..a81958de2 100644 --- a/intaro.retailcrm/lib/component/configprovider.php +++ b/intaro.retailcrm/lib/component/configprovider.php @@ -94,6 +94,9 @@ class ConfigProvider /** @var array $contragentTypes */ protected static $contragentTypes; + /** @var array $contragentTypesBySite */ + protected static $contragentTypesBySite; + /** @var array $cancellableOrderPaymentStatuses */ protected static $cancellableOrderPaymentStatuses; @@ -464,6 +467,7 @@ public static function getLegalDetails() /** * getContragentTypes * + * @deprecated Use getContragentTypesBySite() instead * @return array */ public static function getContragentTypes() @@ -476,19 +480,66 @@ public static function getContragentTypes() } /** - * Returns contragent type for provided person type (PERSON_TYPE_ID in the Bitrix order). + * setContragentTypes + * + * @deprecated Use setContragentTypesBySite() instead + * @param array $contragentTypeArr + */ + public static function setContragentTypes($contragentTypeArr) + { + static::setOption(Constants::CRM_CONTRAGENT_TYPE, serialize(self::getUtils() + ->clearArray(is_array($contragentTypeArr)?$contragentTypeArr:[]))); + } + + /** + * getContragentTypesBySite + * + * @return array + */ + public static function getContragentTypesBySite() + { + if (self::isEmptyNotZero(static::$contragentTypesBySite)) { + static::$contragentTypesBySite = static::getUnserializedOption(Constants::CRM_CONTRAGENT_TYPE_SITE); + } + + return is_array(static::$contragentTypesBySite) ? static::$contragentTypesBySite : []; + } + + /** + * setContragentTypesBySite + * + * @param array $contragentTypeArr + */ + public static function setContragentTypesBySite($contragentTypeArr) + { + static::setOption(Constants::CRM_CONTRAGENT_TYPE_SITE, serialize(self::getUtils() + ->clearArray(is_array($contragentTypeArr)?$contragentTypeArr:[]))); + } + + /** + * Returns contragent type for provided person type (PERSON_TYPE_ID in the Bitrix order) and site ID. * Returns null if nothing was found. * * @param string $personTypeId + * @param string|null $siteId * * @return string|null */ - public static function getContragentTypeForPersonType(string $personTypeId): ?string + public static function getContragentTypeForPersonType(string $personTypeId, ?string $siteId = null): ?string { - $personTypes = static::getContragentTypes(); + $contragentTypesBySite = static::getContragentTypesBySite(); - if (!empty($personTypes[$personTypeId])) { - return $personTypes[$personTypeId]; + if ($siteId !== null) { + if (!empty($contragentTypesBySite[$siteId][$personTypeId])) { + return $contragentTypesBySite[$siteId][$personTypeId]; + } + return null; + } + + foreach ($contragentTypesBySite as $siteContragentTypes) { + if (!empty($siteContragentTypes[$personTypeId])) { + return $siteContragentTypes[$personTypeId]; + } } return null; @@ -1145,17 +1196,6 @@ public static function setPaymentStatuses($paymentStatusesArr) ->clearArray(is_array($paymentStatusesArr)?$paymentStatusesArr:[]))); } - /** - * setContragentTypes - * - * @param array $contragentTypeArr - */ - public static function setContragentTypes($contragentTypeArr) - { - static::setOption(Constants::CRM_CONTRAGENT_TYPE, serialize(self::getUtils() - ->clearArray(is_array($contragentTypeArr)?$contragentTypeArr:[]))); - } - /** * @return \Intaro\RetailCrm\Service\Utils */ diff --git a/intaro.retailcrm/lib/component/constants.php b/intaro.retailcrm/lib/component/constants.php index 1476a436d..5970a2bbf 100644 --- a/intaro.retailcrm/lib/component/constants.php +++ b/intaro.retailcrm/lib/component/constants.php @@ -38,6 +38,7 @@ class Constants public const CRM_LEGAL_DETAILS = 'legal_details'; public const CRM_CUSTOM_FIELDS = 'custom_fields'; public const CRM_CONTRAGENT_TYPE = 'contragent_type'; + public const CRM_CONTRAGENT_TYPE_SITE = 'contragent_type_site'; public const CRM_SITES_LIST_CORPORATE = 'shops-corporate'; public const CRM_ORDER_NUMBERS = 'order_numbers'; public const CRM_ORDER_VAT = 'order_vat'; diff --git a/intaro.retailcrm/options.php b/intaro.retailcrm/options.php index 09c1b306a..73a70ff2b 100644 --- a/intaro.retailcrm/options.php +++ b/intaro.retailcrm/options.php @@ -468,8 +468,12 @@ //contragents type list $contragentTypeArr = []; - foreach ($orderTypesList as $orderType) { - $contragentTypeArr[$orderType['ID']] = htmlspecialchars(trim($_POST['contragent-type-' . $orderType['ID']])); + foreach ($arResult['arSites'] as $site) { + foreach ($orderTypesList as $orderType) { + $contragentTypeArr[$site['LID']][$orderType['ID']] = htmlspecialchars( + trim($_POST['contragent-type-' . $site['LID'] . '-' . $orderType['ID']]) + ); + } } //stores @@ -909,6 +913,20 @@ function maskCorp($var) { Constants::CRM_CONTRAGENT_TYPE, serialize(RCrmActions::clearArr(is_array($contragentTypeArr) ? $contragentTypeArr : [])) ); + $legacyContragentTypes = []; + if (!empty($contragentTypeArr)) { + $firstSite = reset($arResult['arSites']); + foreach ($orderTypesList as $orderType) { + $legacyContragentTypes[$orderType['ID']] = + $contragentTypeArr[$firstSite['LID']][$orderType['ID']] ?? 'individual'; + } + } + + COption::SetOptionString( + $mid, + Constants::CRM_CONTRAGENT_TYPE, + serialize(RCrmActions::clearArr(is_array($legacyContragentTypes) ? $legacyContragentTypes : [])) + ); COption::SetOptionString( $mid, Constants::CRM_LEGAL_DETAILS, @@ -1339,7 +1357,7 @@ function ($payment) { $optionsSitesList = unserialize(COption::GetOptionString($mid, Constants::CRM_SITES_LIST, 0), ['allowed_classes' => false]); $optionsDischarge = (int) COption::GetOptionString($mid, Constants::CRM_ORDER_DISCHARGE, 0); $optionsOrderProps = unserialize(COption::GetOptionString($mid, Constants::CRM_ORDER_PROPS, 0), ['allowed_classes' => false]); - $optionsContragentType = unserialize(COption::GetOptionString($mid, Constants::CRM_CONTRAGENT_TYPE, 0), ['allowed_classes' => false]); + $optionsContragentType = unserialize(COption::GetOptionString($mid, Constants::CRM_CONTRAGENT_TYPE_SITE, 0), ['allowed_classes' => false]); $optionsLegalDetails = unserialize(COption::GetOptionString($mid, Constants::CRM_LEGAL_DETAILS, 0), ['allowed_classes' => false]); $optionsCustomFields = unserialize(COption::GetOptionString($mid, Constants::CRM_CUSTOM_FIELDS, 0), ['allowed_classes' => false]); $optionsOrderNumbers = COption::GetOptionString($mid, Constants::CRM_ORDER_NUMBERS, 0); @@ -1811,9 +1829,9 @@ function updateAddressList() $('input:checked[name^="address-detail-"]').each(updateAddressList); $('tr.contragent-type select').change(function() { - splitName = $(this).attr('name').split('-'); - contragentType = $(this).val(); - orderType = splitName[2]; + const splitName = $(this).attr('name').split('-'); + const contragentType = $(this).val(); + const orderType = splitName[3]; $('tr.legal-detail-' + orderType).hide(); $('.legal-detail-title-' + orderType).hide(); @@ -2285,22 +2303,29 @@ function updateAddressList() + + - + - - + + @@ -2399,9 +2424,22 @@ function updateAddressList() > + } ?>" + + > diff --git a/intaro.retailcrm/updater.php b/intaro.retailcrm/updater.php index 17dec4ed0..50b152b45 100755 --- a/intaro.retailcrm/updater.php +++ b/intaro.retailcrm/updater.php @@ -3,6 +3,7 @@ use Bitrix\Main\Loader; use Bitrix\Main\Config\Option; use Bitrix\Main\Application; +use Intaro\RetailCrm\Component\Constants; function update() { @@ -13,6 +14,8 @@ function update() customFieldsCheck(); addEventSaveOrder(); loadJsExport(); + + migrateContragentTypes(); } function loadJsExport() @@ -93,6 +96,62 @@ function addEventSaveOrder() } } +/** + * Миграция данных contragent type из старого формата в новый + */ +function migrateContragentTypes() +{ + $newOptionValue = Option::get('intaro.retailcrm', Constants::CRM_CONTRAGENT_TYPE_SITE, null); + + if ($newOptionValue !== null && $newOptionValue !== '') { + return; + } + + $oldContragentTypes = Option::get('intaro.retailcrm', Constants::CRM_CONTRAGENT_TYPE, null); + + if (empty($oldContragentTypes)) { + $oldContragentTypes = []; + } else { + $oldContragentTypes = unserialize($oldContragentTypes, ['allowed_classes' => false]); + + if (!is_array($oldContragentTypes)) { + $oldContragentTypes = []; + } + } + + $sites = \CSite::GetList( + $by = 'sort', + $order = 'asc', + ['ACTIVE' => 'Y'] + ); + + $newContragentTypes = []; + + while ($site = $sites->Fetch()) { + $siteId = $site['LID']; + $newContragentTypes[$siteId] = []; + + $personTypes = \CSalePersonType::GetList( + ['SORT' => 'ASC'], + ['LID' => $siteId, 'ACTIVE' => 'Y'] + ); + + while ($personType = $personTypes->Fetch()) { + $personTypeId = $personType['ID']; + + if (isset($oldContragentTypes[$personTypeId])) { + $newContragentTypes[$siteId][$personTypeId] = $oldContragentTypes[$personTypeId]; + } else { + $newContragentTypes[$siteId][$personTypeId] = 'individual'; + } + } + } + + if (!empty($newContragentTypes)) { + Option::set('intaro.retailcrm', Constants::CRM_CONTRAGENT_TYPE_SITE, serialize($newContragentTypes)); + } +} + try { update(); } catch (\Throwable $exception) { diff --git a/tests/classes/general/order/RetailCrmOrder_v5Test.php b/tests/classes/general/order/RetailCrmOrder_v5Test.php index 87baabbeb..621f14180 100644 --- a/tests/classes/general/order/RetailCrmOrder_v5Test.php +++ b/tests/classes/general/order/RetailCrmOrder_v5Test.php @@ -114,7 +114,7 @@ public function testFieldExists(): void public function initSystemData(): void { RetailcrmConfigProvider::setOrderTypes(['bitrixType' => 'crmType']); - RetailcrmConfigProvider::setContragentTypes(['bitrixType' => 'individual']); + RetailcrmConfigProvider::setContragentTypesBySite(['s1' => ['bitrixType' => 'individual']]); RetailcrmConfigProvider::setPaymentStatuses([1 => 'paymentStatus']); RetailcrmConfigProvider::setPaymentTypes([1 => 'testPayment']); RetailcrmConfigProvider::setDeliveryTypes(['test' => 'test']); @@ -129,10 +129,12 @@ public function orderSendProvider() $arFields = $this->getArFields(); $this->initSystemData(); + $contragentTypes = RetailcrmConfigProvider::getContragentTypesBySite(); + $arParams = [ 'optionsOrderTypes' => RetailcrmConfigProvider::getOrderTypes(), 'optionsPayStatuses' => RetailcrmConfigProvider::getPaymentStatuses(), - 'optionsContragentType' => RetailcrmConfigProvider::getContragentTypes(), + 'optionsContragentType' => $contragentTypes, 'optionsDelivTypes' => RetailcrmConfigProvider::getDeliveryTypes(), 'optionsPayTypes' => RetailcrmConfigProvider::getPaymentTypes(), 'optionsOrderProps' => ['bitrixType' => ['fio' => 'FIO']], @@ -140,6 +142,8 @@ public function orderSendProvider() 'customOrderProps' => ['1#TEST_PROP_1' => 'custom_first', '2#TEST_PROP_2' => 'custom_second'] ]; + $contragentType = $contragentTypes['s1'][$arFields['PERSON_TYPE_ID']] ?? null; + return [[ 'arFields' => $arFields, 'arParams' => $arParams, @@ -159,7 +163,7 @@ public function orderSendProvider() 'service' => ['code' => $arFields['DELIVERYS'][0]['service']] ], 'contragent' => [ - 'contragentType' => $arParams['optionsContragentType'][$arFields['PERSON_TYPE_ID']] + 'contragentType' => $contragentType ], 'payments' => [[ 'type' => $arParams['optionsPayTypes'][$arFields['PAYMENTS'][0]['PAY_SYSTEM_ID']], diff --git a/tests/lib/component/builder/api/CorporateCustomerBuilderTest.php b/tests/lib/component/builder/api/CorporateCustomerBuilderTest.php index aad60061d..4c2d36a2f 100755 --- a/tests/lib/component/builder/api/CorporateCustomerBuilderTest.php +++ b/tests/lib/component/builder/api/CorporateCustomerBuilderTest.php @@ -20,9 +20,11 @@ protected function setUp(): void Helpers::setConfigProperty('sitesList', ['s1' => 's1']); Helpers::setConfigProperty('corporateClientName', 'COMPANY'); Helpers::setConfigProperty('corporateClientAddress', 'COMPANY_ADR'); - Helpers::setConfigProperty('contragentTypes', [ - 'individual', - 'legal-entity' + Helpers::setConfigProperty('contragentTypesBySite', [ + 's1' => [ + 'individual' => 'individual', + 'legal-entity' => 'legal-entity' + ] ]); Helpers::setConfigProperty('legalDetails', [ 'individual', @@ -75,7 +77,9 @@ public function testBuild() $order = Order::create('s1', $user->getId()); $order->setField('DATE_INSERT', new DateTime()); - $order->setPersonTypeId(array_flip(ConfigProvider::getContragentTypes())['legal-entity']); + $contragentTypes = ConfigProvider::getContragentTypesBySite(); + $personTypeId = array_flip($contragentTypes['s1'] ?? [])['legal-entity'] ?? null; + $order->setPersonTypeId($personTypeId); $saveResult = $order->save(); self::assertTrue($saveResult->isSuccess(), implode(', ', $saveResult->getErrorMessages())); self::assertNotNull($order->getId(), implode(', ', $saveResult->getErrorMessages())); diff --git a/tests/lib/component/builder/api/CustomerBuilderTest.php b/tests/lib/component/builder/api/CustomerBuilderTest.php index 9515a863d..6eb62e5c4 100755 --- a/tests/lib/component/builder/api/CustomerBuilderTest.php +++ b/tests/lib/component/builder/api/CustomerBuilderTest.php @@ -19,8 +19,10 @@ class CustomerBuilderTest extends TestCase { public function setUp(): void { - Helpers::setConfigProperty('contragentTypes', [ - 'individual' => 'individual' + Helpers::setConfigProperty('contragentTypesBySite', [ + 's1' => [ + 'individual' => 'individual' + ] ]); } @@ -52,6 +54,7 @@ public function testBuild($entity): void ->reset() ->setAttachDaemonCollectorId(true) ->setPersonTypeId('individual') + ->setSiteId('s1') ->setUser($entity) ->build() ->getResult(); @@ -97,6 +100,7 @@ static function (Event $event) { $builder = new CustomerBuilder(); $result = $builder ->setPersonTypeId('individual') + ->setSiteId('s1') ->setUser($entity) ->build() ->getResult(); From 55d0753b49d70fdda2c814284e9fcb481e49e869 Mon Sep 17 00:00:00 2001 From: danila Date: Thu, 2 Jul 2026 15:56:35 +0500 Subject: [PATCH 3/4] fix MR --- intaro.retailcrm/install/step3.php | 36 +++++++++++-------- intaro.retailcrm/lib/component/constants.php | 2 +- .../lib/service/customerservice.php | 22 +++++++++++- intaro.retailcrm/lib/service/utils.php | 6 ++-- intaro.retailcrm/options.php | 2 +- 5 files changed, 48 insertions(+), 20 deletions(-) diff --git a/intaro.retailcrm/install/step3.php b/intaro.retailcrm/install/step3.php index 572f7a61c..9fff6b158 100644 --- a/intaro.retailcrm/install/step3.php +++ b/intaro.retailcrm/install/step3.php @@ -43,7 +43,7 @@ if (!isset($arResult['CONTRAGENT_TYPES'])) { $arResult['CONTRAGENT_TYPES'] = unserialize( - (string) COption::GetOptionString(Constants::MODULE_ID, Constants::CRM_CONTRAGENT_TYPE, 0), + (string) COption::GetOptionString(Constants::MODULE_ID, Constants::CRM_CONTRAGENT_TYPE_SITE, 0), ['allowed_classes' => false] ); @@ -203,20 +203,26 @@ function updateAddressList() - + + + + + + + + + + diff --git a/intaro.retailcrm/lib/component/constants.php b/intaro.retailcrm/lib/component/constants.php index 5970a2bbf..9c7d36c2e 100644 --- a/intaro.retailcrm/lib/component/constants.php +++ b/intaro.retailcrm/lib/component/constants.php @@ -18,7 +18,7 @@ */ class Constants { - public const MODULE_VERSION = '6.8.3'; + public const MODULE_VERSION = '6.8.4'; public const CRM_PURCHASE_PRICE_NULL = 'purchasePrice_null'; public const BITRIX_USER_ID_PREFIX = 'bitrixUserId-'; public const CRM_USERS_MAP = 'crm_users_map'; diff --git a/intaro.retailcrm/lib/service/customerservice.php b/intaro.retailcrm/lib/service/customerservice.php index b976b236f..59e941799 100644 --- a/intaro.retailcrm/lib/service/customerservice.php +++ b/intaro.retailcrm/lib/service/customerservice.php @@ -152,7 +152,7 @@ public function getCustomer(string $externalId): ?Customer */ public function createModel(int $userId) { - $key = array_search('individual', ConfigProvider::getContragentTypes(), true); + $key = $this->findIndividualPersonTypeId(); $builder = new CustomerBuilder(); try { @@ -167,4 +167,24 @@ public function createModel(int $userId) Logger::getInstance()->write($exception->getMessage(), Constants::LOYALTY_ERROR); } } + + /** + * Находит ID типа плательщика, соответствующего 'individual' + * Перебирает все сайты в поиске первого individual + * + * @return string|null + */ + private function findIndividualPersonTypeId(): ?string + { + $contragentTypesBySite = ConfigProvider::getContragentTypesBySite(); + + foreach ($contragentTypesBySite as $siteContragentTypes) { + $found = array_search('individual', $siteContragentTypes, true); + if ($found !== false) { + return (string) $found; + } + } + + return null; + } } diff --git a/intaro.retailcrm/lib/service/utils.php b/intaro.retailcrm/lib/service/utils.php index 6b519cca1..a33ab4d1f 100644 --- a/intaro.retailcrm/lib/service/utils.php +++ b/intaro.retailcrm/lib/service/utils.php @@ -86,12 +86,14 @@ public function fromUTF8($string) * Returns true if provided PERSON_TYPE_ID is corporate customer * * @param string $personTypeId + * @param string|null $siteId * * @return bool */ - public function isPersonCorporate(string $personTypeId): bool + public function isPersonCorporate(string $personTypeId, ?string $siteId = null): bool { - return ConfigProvider::getContragentTypeForPersonType($personTypeId) === Constants::CORPORATE_CONTRAGENT_TYPE; + $contragentType = ConfigProvider::getContragentTypeForPersonType($personTypeId, $siteId); + return $contragentType === Constants::CORPORATE_CONTRAGENT_TYPE; } /** diff --git a/intaro.retailcrm/options.php b/intaro.retailcrm/options.php index 73a70ff2b..e0082c6c5 100644 --- a/intaro.retailcrm/options.php +++ b/intaro.retailcrm/options.php @@ -910,7 +910,7 @@ function maskCorp($var) { ); COption::SetOptionString( $mid, - Constants::CRM_CONTRAGENT_TYPE, + Constants::CRM_CONTRAGENT_TYPE_SITE, serialize(RCrmActions::clearArr(is_array($contragentTypeArr) ? $contragentTypeArr : [])) ); $legacyContragentTypes = []; From d5d9f2423d0a45ddbec8c4c09b5a8521b22c7234 Mon Sep 17 00:00:00 2001 From: danila Date: Fri, 3 Jul 2026 11:48:24 +0500 Subject: [PATCH 4/4] fix MR --- intaro.retailcrm/install/index.php | 13 ++++++++++++- intaro.retailcrm/install/step3.php | 7 ------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/intaro.retailcrm/install/index.php b/intaro.retailcrm/install/index.php index b2c502b63..3fb1f378e 100644 --- a/intaro.retailcrm/install/index.php +++ b/intaro.retailcrm/install/index.php @@ -674,7 +674,18 @@ function DoInstall() $arResult['LEGAL_DETAILS'] = unserialize($legalDetails, ['allowed_classes' => false]); } if ($contragentType = COption::GetOptionString($this->OLD_MODULE_ID, Constants::CRM_CONTRAGENT_TYPE, 0)) { - $arResult['CONTRAGENT_TYPES'] = unserialize($contragentType, ['allowed_classes' => false]); + $oldContragentTypes = unserialize($contragentType, ['allowed_classes' => false]); + + $arResult['CONTRAGENT_TYPES'] = []; + $arSites = RCrmActions::getSitesList(); + + if (is_array($oldContragentTypes)) { + foreach ($arSites as $site) { + foreach ($oldContragentTypes as $personTypeId => $contragentTypeValue) { + $arResult['CONTRAGENT_TYPES'][$site['LID']][$personTypeId] = $contragentTypeValue; + } + } + } } $APPLICATION->IncludeAdminFile( diff --git a/intaro.retailcrm/install/step3.php b/intaro.retailcrm/install/step3.php index 9fff6b158..660dd8a52 100644 --- a/intaro.retailcrm/install/step3.php +++ b/intaro.retailcrm/install/step3.php @@ -198,11 +198,6 @@ function updateAddressList() - - - - - @@ -223,8 +218,6 @@ function updateAddressList() - -