Динамическое добавление свойств в ICML (#375)
This commit is contained in:
parent
1ec3bccd0c
commit
3162031b65
@ -1,3 +1,6 @@
|
|||||||
|
## 2024-12-09 v6.6.0
|
||||||
|
- Добавлено динамическое изменение свойств товаров при настройке экспорта
|
||||||
|
|
||||||
## 2024-12-08 v6.5.39
|
## 2024-12-08 v6.5.39
|
||||||
- Исправлена поломка заказов с промокодом Maxma при включенной передаче корзины в CRM
|
- Исправлена поломка заказов с промокодом Maxma при включенной передаче корзины в CRM
|
||||||
|
|
||||||
|
@ -1 +1 @@
|
|||||||
- Исправлена поломка заказов с промокодом Maxma при включенной передаче корзины в CRM
|
- Добавлено динамическое изменение свойств товаров при настройке экспорта
|
||||||
|
@ -38,7 +38,8 @@ if (file_exists($_SERVER['DOCUMENT_ROOT'] . '/bitrix/php_interface/retailcrm/exp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$settingService = SettingsService::getInstance([], '');
|
global $PROFILE_ID;
|
||||||
|
$settingService = SettingsService::getInstance([], '', $PROFILE_ID);
|
||||||
$iblockPropertySku = [];
|
$iblockPropertySku = [];
|
||||||
$iblockPropertySkuHl = [];
|
$iblockPropertySkuHl = [];
|
||||||
$iblockPropertyUnitSku = [];
|
$iblockPropertyUnitSku = [];
|
||||||
@ -46,7 +47,7 @@ if (file_exists($_SERVER['DOCUMENT_ROOT'] . '/bitrix/php_interface/retailcrm/exp
|
|||||||
$iblockPropertyProductHl = [];
|
$iblockPropertyProductHl = [];
|
||||||
$iblockPropertyUnitProduct = [];
|
$iblockPropertyUnitProduct = [];
|
||||||
|
|
||||||
foreach (array_keys($settingService->actrualPropList) as $prop) {
|
foreach (array_keys($settingService->actualPropList) as $prop) {
|
||||||
$skuUnitProps = ('iblockPropertyUnitSku_' . $prop);
|
$skuUnitProps = ('iblockPropertyUnitSku_' . $prop);
|
||||||
$skuUnitProps = $$skuUnitProps;
|
$skuUnitProps = $$skuUnitProps;
|
||||||
|
|
||||||
|
@ -26,7 +26,8 @@ CModule::IncludeModule('intaro.retailcrm');
|
|||||||
//TODO заменить вызов на сервис-локатор, когда он приедет
|
//TODO заменить вызов на сервис-локатор, когда он приедет
|
||||||
$settingsService = SettingsService::getInstance(
|
$settingsService = SettingsService::getInstance(
|
||||||
$arOldSetupVars ?? [],
|
$arOldSetupVars ?? [],
|
||||||
$ACTION
|
$ACTION,
|
||||||
|
$PROFILE_ID
|
||||||
);
|
);
|
||||||
|
|
||||||
$isSetupModulePage = $settingsService->isSetupModulePage();
|
$isSetupModulePage = $settingsService->isSetupModulePage();
|
||||||
@ -110,7 +111,7 @@ if ($STEP === 1) {
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<form method="post" action="<?=$APPLICATION->GetCurPage()?>">
|
<form method="post" id="submit-form" action="<?=$APPLICATION->GetCurPage()?>">
|
||||||
<?php
|
<?php
|
||||||
if ($ACTION === 'EXPORT_EDIT' || $ACTION === 'EXPORT_COPY') {
|
if ($ACTION === 'EXPORT_EDIT' || $ACTION === 'EXPORT_COPY') {
|
||||||
?>
|
?>
|
||||||
@ -190,8 +191,7 @@ if ($STEP === 1) {
|
|||||||
<tbody>
|
<tbody>
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
foreach ($settingsService->actrualPropList as $propertyKey => $property) {
|
foreach ($settingsService->defaultPropList as $propertyKey => $property) { ?>
|
||||||
$productSelected = false; ?>
|
|
||||||
|
|
||||||
<tr class="adm-list-table-row">
|
<tr class="adm-list-table-row">
|
||||||
<td class="adm-list-table-cell">
|
<td class="adm-list-table-cell">
|
||||||
@ -215,14 +215,14 @@ if ($STEP === 1) {
|
|||||||
if ($keyField === $propertyKey) { ?>
|
if ($keyField === $propertyKey) { ?>
|
||||||
<option value="<?=$field['CODE']?>"
|
<option value="<?=$field['CODE']?>"
|
||||||
<?php
|
<?php
|
||||||
$productSelected = $settingsService->isOptionSelected(
|
$isSelected = $settingsService->isOptionSelected(
|
||||||
$field,
|
$field,
|
||||||
$arIBlock['OLD_PROPERTY_PRODUCT_SELECT'],
|
$arIBlock['OLD_PROPERTY_PRODUCT_SELECT'],
|
||||||
$propertyKey
|
$propertyKey
|
||||||
);
|
);
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<?= $productSelected ? ' selected' : ''?>
|
<?= $isSelected ? ' selected' : ''?>
|
||||||
>
|
>
|
||||||
<?=$field['name']?>
|
<?=$field['name']?>
|
||||||
</option>
|
</option>
|
||||||
@ -241,7 +241,7 @@ if ($STEP === 1) {
|
|||||||
<?php
|
<?php
|
||||||
echo $settingsService->getOptionClass($prop, true);
|
echo $settingsService->getOptionClass($prop, true);
|
||||||
|
|
||||||
$productSelected = $settingsService->isOptionSelected(
|
$isSelected = $settingsService->isOptionSelected(
|
||||||
$prop,
|
$prop,
|
||||||
$arIBlock['OLD_PROPERTY_PRODUCT_SELECT'],
|
$arIBlock['OLD_PROPERTY_PRODUCT_SELECT'],
|
||||||
$propertyKey
|
$propertyKey
|
||||||
@ -251,7 +251,7 @@ if ($STEP === 1) {
|
|||||||
= $settingsService->getHlTableName($prop)
|
= $settingsService->getHlTableName($prop)
|
||||||
?? $productHlTableName;
|
?? $productHlTableName;
|
||||||
|
|
||||||
echo $productSelected ? ' selected' : '';
|
echo $isSelected ? ' selected' : '';
|
||||||
?>
|
?>
|
||||||
>
|
>
|
||||||
<?=$prop['NAME']?>
|
<?=$prop['NAME']?>
|
||||||
@ -376,7 +376,7 @@ if ($STEP === 1) {
|
|||||||
<option value="<?=$prop['CODE']?>"
|
<option value="<?=$prop['CODE']?>"
|
||||||
<?php
|
<?php
|
||||||
echo $settingsService->getOptionClass($prop, false);
|
echo $settingsService->getOptionClass($prop, false);
|
||||||
if (!$productSelected) {
|
|
||||||
$isSelected = $settingsService->isOptionSelected(
|
$isSelected = $settingsService->isOptionSelected(
|
||||||
$prop,
|
$prop,
|
||||||
$arIBlock['OLD_PROPERTY_SKU_SELECT'],
|
$arIBlock['OLD_PROPERTY_SKU_SELECT'],
|
||||||
@ -388,7 +388,6 @@ if ($STEP === 1) {
|
|||||||
?? $skuHlTableName;
|
?? $skuHlTableName;
|
||||||
|
|
||||||
echo $isSelected ? ' selected' : '';
|
echo $isSelected ? ' selected' : '';
|
||||||
}
|
|
||||||
?>
|
?>
|
||||||
>
|
>
|
||||||
<?=$prop['NAME']?>
|
<?=$prop['NAME']?>
|
||||||
@ -473,9 +472,97 @@ if ($STEP === 1) {
|
|||||||
</tr>
|
</tr>
|
||||||
<?php
|
<?php
|
||||||
} ?>
|
} ?>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
$catalogId = $arIBlock['ID'];
|
||||||
|
$catalogCustomProps = $settingsService->customPropList[$catalogId];
|
||||||
|
|
||||||
|
if (!empty($catalogCustomProps)) {
|
||||||
|
foreach ($catalogCustomProps as $catalogCustomPropCode => $catalogCustomPropValue) { ?>
|
||||||
|
<tr class="adm-list-table-row custom-property-row">
|
||||||
|
<td class="adm-list-table-cell custom-property-title">
|
||||||
|
<?=htmlspecialcharsex($catalogCustomPropValue)?>
|
||||||
|
</td>
|
||||||
|
<td class="adm-list-table-cell">
|
||||||
|
<select
|
||||||
|
name="iblockPropertyProduct_<?=$catalogCustomPropCode?>[<?= $catalogId ?>]"
|
||||||
|
id="iblockPropertyProduct_<?=$catalogCustomPropCode . $catalogId ?>"
|
||||||
|
class="property-export"
|
||||||
|
data-type="<?= $catalogCustomPropCode ?>"
|
||||||
|
onchange="propertyChange(this)"
|
||||||
|
style="width: 200px">
|
||||||
|
|
||||||
|
<option value=""></option>
|
||||||
|
<?php foreach ($arIBlock['PROPERTIES_PRODUCT'] as $prop) {
|
||||||
|
$productHlTableName = ''; ?>
|
||||||
|
<option value="<?=$prop['CODE']?>"
|
||||||
|
<?php
|
||||||
|
echo $settingsService->getOptionClass($prop, true);
|
||||||
|
|
||||||
|
$isSelected = $settingsService->isOptionSelected(
|
||||||
|
$prop,
|
||||||
|
$arIBlock['OLD_PROPERTY_PRODUCT_SELECT'],
|
||||||
|
$catalogCustomPropCode
|
||||||
|
);
|
||||||
|
|
||||||
|
$productHlTableName
|
||||||
|
= $settingsService->getHlTableName($prop)
|
||||||
|
?? $productHlTableName;
|
||||||
|
|
||||||
|
echo $isSelected ? ' selected' : '';
|
||||||
|
?>
|
||||||
|
>
|
||||||
|
<?=$prop['NAME']?>
|
||||||
|
</option>
|
||||||
|
<?php } ?>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<?php if ($arIBlock['PROPERTIES_SKU'] !== null) { ?>
|
||||||
|
<td class="adm-list-table-cell">
|
||||||
|
<select
|
||||||
|
name="iblockPropertySku_<?=$catalogCustomPropCode?>[<?= $catalogId ?>]"
|
||||||
|
id="iblockPropertySku_<?=$catalogCustomPropCode . $catalogId ?>"
|
||||||
|
class="property-export"
|
||||||
|
data-type="<?= $catalogCustomPropCode ?>"
|
||||||
|
onchange="propertyChange(this)"
|
||||||
|
style="width: 200px">
|
||||||
|
|
||||||
|
<option value=""></option>
|
||||||
|
<?php foreach ($arIBlock['PROPERTIES_SKU'] as $prop) {
|
||||||
|
$skuHlTableName = ''; ?>
|
||||||
|
<option value="<?=$prop['CODE']?>"
|
||||||
|
<?php
|
||||||
|
echo $settingsService->getOptionClass($prop, false);
|
||||||
|
|
||||||
|
$isSelected = $settingsService->isOptionSelected(
|
||||||
|
$prop,
|
||||||
|
$arIBlock['OLD_PROPERTY_SKU_SELECT'],
|
||||||
|
$catalogCustomPropCode
|
||||||
|
);
|
||||||
|
|
||||||
|
$skuHlTableName
|
||||||
|
= $settingsService->getHlTableName($prop)
|
||||||
|
?? $skuHlTableName;
|
||||||
|
|
||||||
|
echo $isSelected ? ' selected' : '';
|
||||||
|
?>
|
||||||
|
>
|
||||||
|
<?=$prop['NAME']?>
|
||||||
|
</option>
|
||||||
|
|
||||||
|
<?php } ?>
|
||||||
|
</select>
|
||||||
|
<button id="delete-custom-row" class="adm-btn-save" type="button" style="margin-left: 10px"><?= GetMessage('DELETE_PROPERTY');?></button>
|
||||||
|
</td>
|
||||||
|
<?php } ?>
|
||||||
|
</tr>
|
||||||
|
<?php }
|
||||||
|
}
|
||||||
|
?>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<br>
|
<button class="adm-btn-save add-custom-row" type="button" style="margin-top: 20px;"><?= GetMessage('ADD_PROPERTY');?></button>
|
||||||
<br>
|
<br>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -484,6 +571,20 @@ if ($STEP === 1) {
|
|||||||
</div>
|
</div>
|
||||||
<input type="hidden" name="count_checked" id="count_checked" value="<?=$intCountChecked?>">
|
<input type="hidden" name="count_checked" id="count_checked" value="<?=$intCountChecked?>">
|
||||||
<br>
|
<br>
|
||||||
|
<template id="custom-property-template-row">
|
||||||
|
<tr class="adm-list-table-row custom-property-row">
|
||||||
|
<td class="adm-list-table-cell">
|
||||||
|
<input type="text" title="Название нового свойства" name="custom-property-title" style="width: 200px">
|
||||||
|
</td>
|
||||||
|
<td class="adm-list-table-cell">
|
||||||
|
<select name="iblockPropertyProduct_" id="iblockPropertyProduct_" class="property-export" onchange="propertyChange(this)" style="width: 200px"></select>
|
||||||
|
</td>
|
||||||
|
<td class="adm-list-table-cell">
|
||||||
|
<select name="iblockPropertySku_" id="iiblockPropertySku_" class="property-export" onchange="propertyChange(this)" style="width: 200px"></select>
|
||||||
|
<button id="delete-new-custom-row" class="adm-btn-save" type="button" style="margin-left: 10px"><?= GetMessage('DELETE_PROPERTY');?></button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</template>
|
||||||
<h3><?=GetMessage('SETTINGS_EXPORT')?></h3>
|
<h3><?=GetMessage('SETTINGS_EXPORT')?></h3>
|
||||||
<span class="text"><?=GetMessage('FILENAME')?><br><br></span>
|
<span class="text"><?=GetMessage('FILENAME')?><br><br></span>
|
||||||
<input type="text" name="SETUP_FILE_NAME" value="<?=htmlspecialcharsbx(strlen($SETUP_FILE_NAME) > 0 ?
|
<input type="text" name="SETUP_FILE_NAME" value="<?=htmlspecialcharsbx(strlen($SETUP_FILE_NAME) > 0 ?
|
||||||
@ -566,7 +667,7 @@ if ($STEP === 1) {
|
|||||||
<input type="hidden" name="STEP" value="<?=$STEP + 1?>">
|
<input type="hidden" name="STEP" value="<?=$STEP + 1?>">
|
||||||
<input type="hidden" name="SETUP_FIELDS_LIST" value="<?=
|
<input type="hidden" name="SETUP_FIELDS_LIST" value="<?=
|
||||||
$settingsService->getSetupFieldsString(
|
$settingsService->getSetupFieldsString(
|
||||||
array_keys($settingsService->actrualPropList) ?? [],
|
array_keys($settingsService->actualPropList) ?? [],
|
||||||
$hlblockModule === true,
|
$hlblockModule === true,
|
||||||
$hlBlockList ?? []
|
$hlBlockList ?? []
|
||||||
)
|
)
|
||||||
@ -577,8 +678,109 @@ if ($STEP === 1) {
|
|||||||
</form>
|
</form>
|
||||||
|
|
||||||
<?php CJSCore::Init(['jquery']);?>
|
<?php CJSCore::Init(['jquery']);?>
|
||||||
|
<?php CUtil::InitJSCore(['intaro_custom_props']); ?>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
BX.ready(function() {
|
||||||
|
if (typeof createCustomPropsRaw !== 'function') {
|
||||||
|
$('.add-custom-row').hide();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.add-custom-row').click(function () {
|
||||||
|
if (typeof createCustomPropsRaw === 'function') {
|
||||||
|
createCustomPropsRaw($(this));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on('click', '#delete-new-custom-row', function () {
|
||||||
|
if (typeof deleteCustomPropRow === 'function') {
|
||||||
|
deleteCustomPropRow($(this));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on('click', '#delete-custom-row', function () {
|
||||||
|
let buttonElem = $(this);
|
||||||
|
|
||||||
|
if (typeof addCustomPropToDelete === 'function' && typeof deleteCustomPropRow === 'function') {
|
||||||
|
addCustomPropToDelete(buttonElem);
|
||||||
|
deleteCustomPropRow(buttonElem);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on('blur', 'input[name="custom-property-title"]', function () {
|
||||||
|
|
||||||
|
if (typeof getUniquePropertyCode === 'function' && typeof addCustomPropCodeToSelectAttributes === 'function') {
|
||||||
|
let inputElem = $(this);
|
||||||
|
let newPropertyTitle = inputElem.val();
|
||||||
|
|
||||||
|
if (!newPropertyTitle) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let newPropertyCode = getUniquePropertyCode(newPropertyTitle);
|
||||||
|
addCustomPropCodeToSelectAttributes(newPropertyCode, inputElem);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#submit-form').submit(function (formEvent) {
|
||||||
|
if (typeof setCustomProperties !== "function") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
formEvent.preventDefault();
|
||||||
|
let savePromise = null;
|
||||||
|
let deletePromise = null;
|
||||||
|
let formElem = formEvent.currentTarget;
|
||||||
|
let profileId = $($('input[name="PROFILE_ID"]')).val();
|
||||||
|
|
||||||
|
setCustomProperties();
|
||||||
|
|
||||||
|
if (Object.keys(customProps).length > 0) {
|
||||||
|
savePromise = BX.ajax.runAction('intaro:retailcrm.api.customexportprops.save', {
|
||||||
|
json: {
|
||||||
|
properties: customProps,
|
||||||
|
profileId: profileId
|
||||||
|
},
|
||||||
|
}).then(addParamsToSetupFieldsList());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Object.keys(customPropsToDelete).length > 0) {
|
||||||
|
deletePromise = BX.ajax.runAction('intaro:retailcrm.api.customexportprops.delete', {
|
||||||
|
json: {
|
||||||
|
properties: customPropsToDelete,
|
||||||
|
profileId: profileId
|
||||||
|
},
|
||||||
|
}).then(deleteParamsFromSetupFieldsList());
|
||||||
|
}
|
||||||
|
|
||||||
|
const promises = [savePromise, deletePromise].filter(Boolean);
|
||||||
|
|
||||||
|
if (promises.length > 0) {
|
||||||
|
Promise.all(promises)
|
||||||
|
.finally(() => {
|
||||||
|
formElem.submit();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
formElem.submit();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const setupFieldsListElement = $('input[name="SETUP_FIELDS_LIST"]');
|
||||||
|
let customProps = {};
|
||||||
|
let customPropsToDelete = {};
|
||||||
|
const setupFieldsParamsToFill = [
|
||||||
|
'iblockPropertySku_',
|
||||||
|
'iblockPropertyUnitSku_',
|
||||||
|
'iblockPropertyProduct_',
|
||||||
|
'iblockPropertyUnitProduct_',
|
||||||
|
'highloadblockb_hlsys_marking_code_group_',
|
||||||
|
'highloadblock_productb_hlsys_marking_code_group_',
|
||||||
|
'highloadblockeshop_color_reference_',
|
||||||
|
'highloadblock_producteshop_color_reference_',
|
||||||
|
'highloadblockeshop_brand_reference_',
|
||||||
|
'highloadblock_producteshop_brand_reference_'
|
||||||
|
];
|
||||||
|
|
||||||
function checkLoadStatus(object)
|
function checkLoadStatus(object)
|
||||||
{
|
{
|
||||||
if (object.checked) {
|
if (object.checked) {
|
||||||
|
@ -50,6 +50,10 @@ $arJsConfig = [
|
|||||||
'js' => '/bitrix/js/intaro/sms.js',
|
'js' => '/bitrix/js/intaro/sms.js',
|
||||||
'rel' => [],
|
'rel' => [],
|
||||||
],
|
],
|
||||||
|
'intaro_custom_props' => [
|
||||||
|
'js' => '/bitrix/js/intaro/export/custom-props-export.js',
|
||||||
|
'rel' => [],
|
||||||
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach ($arJsConfig as $ext => $arExt) {
|
foreach ($arJsConfig as $ext => $arExt) {
|
||||||
|
@ -0,0 +1,228 @@
|
|||||||
|
|
||||||
|
function deleteCustomPropRow(deleteButton)
|
||||||
|
{
|
||||||
|
deleteButton.closest('tr').remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
function addCustomPropToDelete(deleteButton)
|
||||||
|
{
|
||||||
|
let deletedPropTitle = deleteButton.closest('td').siblings().filter('.custom-property-title').text().trim();
|
||||||
|
let deletedPropCode = deleteButton.siblings().filter('select').first().data('type');
|
||||||
|
let customPropCatalogId = deleteButton.closest('.iblockExportTable').data('type');
|
||||||
|
|
||||||
|
let values = {
|
||||||
|
'code': deletedPropCode,
|
||||||
|
'title': deletedPropTitle,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (customPropsToDelete.hasOwnProperty(customPropCatalogId)) {
|
||||||
|
customPropsToDelete[customPropCatalogId].push(values);
|
||||||
|
} else {
|
||||||
|
customPropsToDelete[customPropCatalogId] = [values];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function addCustomPropCodeToSelectAttributes(customPropCode, customPropTitleElem)
|
||||||
|
{
|
||||||
|
let selectElements = customPropTitleElem.closest('.custom-property-row').find('td select');
|
||||||
|
let catalogId = customPropTitleElem.closest('.iblockExportTable').data('type');
|
||||||
|
|
||||||
|
selectElements.each(function (index, element) {
|
||||||
|
let selectElem = $(element);
|
||||||
|
let newSelectIdValue = selectElem.attr('id').match(/^[^_]*_/)[0] + customPropCode + catalogId;
|
||||||
|
let newSelectNameValue = selectElem.attr('name').match(/^[^_]*_/)[0] + customPropCode + `[${catalogId}]`;
|
||||||
|
|
||||||
|
selectElem.attr('id', newSelectIdValue);
|
||||||
|
selectElem.attr('name', newSelectNameValue);
|
||||||
|
selectElem.data('type', customPropCode);
|
||||||
|
triggerSelectChange(selectElem);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function triggerSelectChange(selectElem)
|
||||||
|
{
|
||||||
|
if (selectElem.val().length > 0) {
|
||||||
|
selectElem.trigger('change', [self]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setCustomProperties()
|
||||||
|
{
|
||||||
|
let customPropertiesRows = $('.custom-property-row');
|
||||||
|
|
||||||
|
if (customPropertiesRows.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let customPropertyCatalogId;
|
||||||
|
let customPropertyTitle = '';
|
||||||
|
let customPropertyCode = '';
|
||||||
|
let productPropertyMatch = '';
|
||||||
|
let offerPropertyMatch = '';
|
||||||
|
|
||||||
|
let catalogIds = [];
|
||||||
|
customPropertiesRows.each(function (index, propertyRow) {
|
||||||
|
let propertyRowObj = $(propertyRow);
|
||||||
|
customPropertyCatalogId = propertyRowObj.closest('.iblockExportTable').data('type');
|
||||||
|
customPropertyTitle = propertyRowObj.find('input[name="custom-property-title"]').val();
|
||||||
|
|
||||||
|
if (!customPropertyTitle) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
customPropertyCode = getUniquePropertyCode(customPropertyTitle);
|
||||||
|
productPropertyMatch = propertyRowObj.find('select[name=custom-product-property-select]').val();
|
||||||
|
offerPropertyMatch = propertyRowObj.find('select[name=custom-offer-property-select]').val();
|
||||||
|
|
||||||
|
let values = {
|
||||||
|
'title': customPropertyTitle,
|
||||||
|
'code': customPropertyCode,
|
||||||
|
'productProperty': productPropertyMatch,
|
||||||
|
'offerProperty': offerPropertyMatch
|
||||||
|
};
|
||||||
|
|
||||||
|
if (catalogIds.indexOf(customPropertyCatalogId) === -1) {
|
||||||
|
customProps[customPropertyCatalogId] = [values];
|
||||||
|
} else {
|
||||||
|
customProps[customPropertyCatalogId].push(values);
|
||||||
|
}
|
||||||
|
|
||||||
|
catalogIds.push(customPropertyCatalogId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getUniquePropertyCode(customPropertyTitle)
|
||||||
|
{
|
||||||
|
let uniqueValue = transliterate(customPropertyTitle).replace(/ /g, '_');
|
||||||
|
let counter = 0;
|
||||||
|
const setupFieldsListValues = setupFieldsListElement.val().split(',');
|
||||||
|
|
||||||
|
while (setupFieldsListValues.includes(uniqueValue)) {
|
||||||
|
uniqueValue = `${customPropertyTitle}${++counter}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return uniqueValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
function addParamsToSetupFieldsList()
|
||||||
|
{
|
||||||
|
let newParams = '';
|
||||||
|
|
||||||
|
if (Object.keys(customProps).length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let propertiesByCatalogId of Object.values(customProps)) {
|
||||||
|
propertiesByCatalogId.forEach(function (values) {
|
||||||
|
setupFieldsParamsToFill.forEach(function (param) {
|
||||||
|
newParams += ',' + param + values.code;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let newValue = setupFieldsListElement.val() + newParams;
|
||||||
|
setupFieldsListElement.val(newValue);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteParamsFromSetupFieldsList()
|
||||||
|
{
|
||||||
|
let setupFields = setupFieldsListElement.val();
|
||||||
|
|
||||||
|
if (Object.keys(customPropsToDelete).length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let propsByCatalogId of Object.values(customPropsToDelete)) {
|
||||||
|
propsByCatalogId.forEach(function (propValues) {
|
||||||
|
setupFieldsParamsToFill.forEach(function (param) {
|
||||||
|
let paramToDelete = ',' + param + propValues.code;
|
||||||
|
setupFields = setupFields.replace(paramToDelete, '');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
setupFieldsListElement.val(setupFields);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createCustomPropsRaw(addRowButton)
|
||||||
|
{
|
||||||
|
let templateRow = $($('#custom-property-template-row').html());
|
||||||
|
let templateSelectElements = templateRow.find('select');
|
||||||
|
|
||||||
|
let prevTableRow = $(addRowButton).prev('table').find('tbody tr:last-child');
|
||||||
|
let lastRawSelectElements = prevTableRow.find('td select');
|
||||||
|
|
||||||
|
lastRawSelectElements.each(function (index, element) {
|
||||||
|
let selectElement = $(element);
|
||||||
|
let templateSelectElement = templateSelectElements[index];
|
||||||
|
fillTemplateSelect(selectElement, templateSelectElement);
|
||||||
|
prevTableRow.after(templateRow);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function fillTemplateSelect(sourceSelectElement, templateSelectElement)
|
||||||
|
{
|
||||||
|
let selectOptions = sourceSelectElement.find('option');
|
||||||
|
|
||||||
|
selectOptions.each(function (index, element) {
|
||||||
|
let optionElem = $(element);
|
||||||
|
let value = $(optionElem).val();
|
||||||
|
let text = $(optionElem).text();
|
||||||
|
|
||||||
|
$('<option>', { value: value, text: text }).appendTo(templateSelectElement);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function transliterate(titleToTransliterate)
|
||||||
|
{
|
||||||
|
const hasCyrillicChars = /[\u0400-\u04FF]/.test(titleToTransliterate);
|
||||||
|
|
||||||
|
if (!hasCyrillicChars) {
|
||||||
|
return titleToTransliterate;
|
||||||
|
}
|
||||||
|
|
||||||
|
translitedText = '';
|
||||||
|
for (var i = 0; i < titleToTransliterate.length; i++) {
|
||||||
|
switch (titleToTransliterate[i]) {
|
||||||
|
case 'а': case 'А': translitedText += 'a'; break;
|
||||||
|
case 'б': case 'Б': translitedText += 'b'; break;
|
||||||
|
case 'в': case 'В': translitedText += 'v'; break;
|
||||||
|
case 'г': case 'Г': translitedText += 'g'; break;
|
||||||
|
case 'д': case 'Д': translitedText += 'd'; break;
|
||||||
|
case 'е': case 'Е': translitedText += 'e'; break;
|
||||||
|
case 'ё': case 'Ё': translitedText += 'yo'; break;
|
||||||
|
case 'ж': case 'Ж': translitedText += 'zh'; break;
|
||||||
|
case 'з': case 'З': translitedText += 'z'; break;
|
||||||
|
case 'и': case 'И': translitedText += 'i'; break;
|
||||||
|
case 'й': case 'Й': translitedText += 'y'; break;
|
||||||
|
case 'к': case 'К': translitedText += 'k'; break;
|
||||||
|
case 'л': case 'Л': translitedText += 'l'; break;
|
||||||
|
case 'м': case 'М': translitedText += 'm'; break;
|
||||||
|
case 'н': case 'Н': translitedText += 'n'; break;
|
||||||
|
case 'о': case 'О': translitedText += 'o'; break;
|
||||||
|
case 'п': case 'П': translitedText += 'p'; break;
|
||||||
|
case 'р': case 'Р': translitedText += 'r'; break;
|
||||||
|
case 'с': case 'С': translitedText += 's'; break;
|
||||||
|
case 'т': case 'Т': translitedText += 't'; break;
|
||||||
|
case 'у': case 'У': translitedText += 'u'; break;
|
||||||
|
case 'ф': case 'Ф': translitedText += 'f'; break;
|
||||||
|
case 'х': case 'Х': translitedText += 'h'; break;
|
||||||
|
case 'ц': case 'Ц': translitedText += 'c'; break;
|
||||||
|
case 'ч': case 'Ч': translitedText += 'ch'; break;
|
||||||
|
case 'ш': case 'Ш': translitedText += 'sh'; break;
|
||||||
|
case 'щ': case 'Щ': translitedText += 'sch'; break;
|
||||||
|
case 'ъ': case 'Ъ': translitedText += ''; break;
|
||||||
|
case 'ы': case 'Ы': translitedText += 'y'; break;
|
||||||
|
case 'ь': case 'Ь': translitedText += ''; break;
|
||||||
|
case 'э': case 'Э': translitedText += 'e'; break;
|
||||||
|
case 'ю': case 'Ю': translitedText += 'yu'; break;
|
||||||
|
case 'я': case 'Я': translitedText += 'ya'; break;
|
||||||
|
default: translitedText += titleToTransliterate[i]; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return translitedText;
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
$arModuleVersion = [
|
$arModuleVersion = [
|
||||||
'VERSION' => '6.5.39',
|
'VERSION' => '6.6.0',
|
||||||
'VERSION_DATE' => '2024-12-08 18:30:00'
|
'VERSION_DATE' => '2024-12-09 14:00:00'
|
||||||
];
|
];
|
||||||
|
@ -47,3 +47,5 @@ $MESS['BASE_PRICE'] = 'Base price';
|
|||||||
$MESS['WAIT'] = 'Loading...';
|
$MESS['WAIT'] = 'Loading...';
|
||||||
$MESS["OFFERS_VALUE"] = "Maximum number of trade offers for a product";
|
$MESS["OFFERS_VALUE"] = "Maximum number of trade offers for a product";
|
||||||
$MESS["LOAD_NON_ACTIVITY"] = "Unload inactive products, services and trade offers";
|
$MESS["LOAD_NON_ACTIVITY"] = "Unload inactive products, services and trade offers";
|
||||||
|
$MESS["ADD_PROPERTY"] = "Add property";
|
||||||
|
$MESS["DELETE_PROPERTY"] = "Delete";
|
||||||
|
@ -47,3 +47,5 @@ $MESS["UNIT_MEASUREMENT_KG"] = "кг.";
|
|||||||
$MESS['BASE_PRICE'] = 'Базовая цена';
|
$MESS['BASE_PRICE'] = 'Базовая цена';
|
||||||
$MESS['WAIT'] = 'Загрузка...';
|
$MESS['WAIT'] = 'Загрузка...';
|
||||||
$MESS["OFFERS_VALUE"] = "Максимальное количество торговых предложений у товара";
|
$MESS["OFFERS_VALUE"] = "Максимальное количество торговых предложений у товара";
|
||||||
|
$MESS["ADD_PROPERTY"] = "Добавить свойство";
|
||||||
|
$MESS["DELETE_PROPERTY"] = "Удалить";
|
||||||
|
@ -24,15 +24,19 @@ trait InstallerTrait
|
|||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
$path = $_SERVER['DOCUMENT_ROOT'] . '/local/';
|
$pathFrom = $_SERVER['DOCUMENT_ROOT'] .
|
||||||
|
'/bitrix/modules/' .
|
||||||
|
Constants::MODULE_ID .
|
||||||
|
'/install/export/bitrix/js/intaro/export'
|
||||||
|
;
|
||||||
|
|
||||||
CheckDirPath($path);
|
CopyDirFiles(
|
||||||
|
$pathFrom,
|
||||||
$file = new \Bitrix\Main\IO\File($path . 'icml_property_retailcrm.txt', $siteId = null);
|
$_SERVER['DOCUMENT_ROOT'] . '/bitrix/js/intaro/export/',
|
||||||
|
true,
|
||||||
if (!$file->isExists()) {
|
true,
|
||||||
$file->putContents("");
|
false
|
||||||
}
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function subscriptionSetup()
|
public function subscriptionSetup()
|
||||||
|
95
intaro.retailcrm/lib/controller/customexportprops.php
Normal file
95
intaro.retailcrm/lib/controller/customexportprops.php
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Intaro\RetailCrm\Controller;
|
||||||
|
|
||||||
|
use Bitrix\Main\Engine\Controller;
|
||||||
|
use Bitrix\Main\Result;
|
||||||
|
use Bitrix\Main\Error;
|
||||||
|
use Bitrix\Main\Application;
|
||||||
|
use Intaro\RetailCrm\Icml\SettingsService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @category Integration
|
||||||
|
* @package Intaro\RetailCrm\Controller
|
||||||
|
* @author RetailCRM <integration@retailcrm.ru>
|
||||||
|
* @license MIT
|
||||||
|
* @link http://retailcrm.ru
|
||||||
|
* @see http://retailcrm.ru/docs
|
||||||
|
*/
|
||||||
|
class CustomExportProps extends Controller
|
||||||
|
{
|
||||||
|
private function getRequestData(): array
|
||||||
|
{
|
||||||
|
$data = $this->getRequest()->getInput();
|
||||||
|
|
||||||
|
if ($data === null) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return json_decode($data, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function saveAction()
|
||||||
|
{
|
||||||
|
$requestData = $this->getRequestData();
|
||||||
|
$props = $requestData['properties'];
|
||||||
|
$profileId = $requestData['profileId'];
|
||||||
|
|
||||||
|
$settingsService = SettingsService::getInstance(
|
||||||
|
[],
|
||||||
|
null,
|
||||||
|
$profileId
|
||||||
|
);
|
||||||
|
|
||||||
|
$idCategories = array_keys($props);
|
||||||
|
|
||||||
|
if ($idCategories !== []) {
|
||||||
|
$settingsService->setProfileCatalogs($idCategories);//сразу заменяет и create и update
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($props as $catalogId => $propsArray) {
|
||||||
|
$catalogCustomProps = [];
|
||||||
|
|
||||||
|
foreach ($propsArray as $property) {
|
||||||
|
$catalogCustomProps[] = [
|
||||||
|
'code' => $property['code'],
|
||||||
|
'title' => $property['title']
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$settingsService
|
||||||
|
->setCatalogCustomPropsOptionName($catalogId)
|
||||||
|
->saveCustomProps($catalogCustomProps)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deleteAction()
|
||||||
|
{
|
||||||
|
$requestData = $this->getRequestData();
|
||||||
|
$props = $requestData['properties'];
|
||||||
|
$profileId = $requestData['profileId'];
|
||||||
|
|
||||||
|
$settingsService = SettingsService::getInstance(
|
||||||
|
[],
|
||||||
|
null,
|
||||||
|
$profileId
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($props as $catalogId => $propsArray) {
|
||||||
|
$catalogCustomProps = [];
|
||||||
|
|
||||||
|
foreach ($propsArray as $property) {
|
||||||
|
$catalogCustomProps[] = [
|
||||||
|
'code' => $property['code'],
|
||||||
|
'title' => $property['title']
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$settingsService
|
||||||
|
->setCatalogCustomPropsOptionName($catalogId)
|
||||||
|
->removeCustomProps($catalogCustomProps, $catalogId)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -8,14 +8,19 @@ use CCatalogGroup;
|
|||||||
use CCatalogSku;
|
use CCatalogSku;
|
||||||
use CCatalogVat;
|
use CCatalogVat;
|
||||||
use CIBlock;
|
use CIBlock;
|
||||||
|
use COption;
|
||||||
|
use Bitrix\Main\Config\Option;
|
||||||
use Intaro\RetailCrm\Service\Hl;
|
use Intaro\RetailCrm\Service\Hl;
|
||||||
use RetailcrmConfigProvider;
|
use RetailcrmConfigProvider;
|
||||||
|
use Bitrix\Main\Application;
|
||||||
|
use Bitrix\Main\Entity\Query;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Отвечает за управление настройками выгрузки icml каталога
|
* Отвечает за управление настройками выгрузки icml каталога
|
||||||
*
|
* @var $PROFILE_ID - зачем если получаем в в конструкторе инстансе
|
||||||
* Class SettingsService
|
* Class SettingsService
|
||||||
*
|
*
|
||||||
|
*
|
||||||
* @package Intaro\RetailCrm\Icml
|
* @package Intaro\RetailCrm\Icml
|
||||||
*/
|
*/
|
||||||
class SettingsService
|
class SettingsService
|
||||||
@ -32,6 +37,14 @@ class SettingsService
|
|||||||
*/
|
*/
|
||||||
public const INFOBLOCK_WITH_SKU = 'P';
|
public const INFOBLOCK_WITH_SKU = 'P';
|
||||||
|
|
||||||
|
private const MODULE_ID = 'intaro.retailcrm';
|
||||||
|
|
||||||
|
private string $catalogCustomPropsOptionName;
|
||||||
|
|
||||||
|
private string $profileCatalogsOptionName;
|
||||||
|
|
||||||
|
private string $exportProfileId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
@ -98,7 +111,13 @@ class SettingsService
|
|||||||
public $loadNonActivity;
|
public $loadNonActivity;
|
||||||
|
|
||||||
/** @var array */
|
/** @var array */
|
||||||
public $actrualPropList = [];
|
public $actualPropList = [];
|
||||||
|
|
||||||
|
/** @var array */
|
||||||
|
public $customPropList = [];
|
||||||
|
|
||||||
|
/** @var array */
|
||||||
|
public $defaultPropList = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \Intaro\RetailCrm\Icml\SettingsService|null
|
* @var \Intaro\RetailCrm\Icml\SettingsService|null
|
||||||
@ -112,7 +131,7 @@ class SettingsService
|
|||||||
* @param array $arOldSetupVars
|
* @param array $arOldSetupVars
|
||||||
* @param string|null $action
|
* @param string|null $action
|
||||||
*/
|
*/
|
||||||
private function __construct(array $arOldSetupVars, ?string $action)
|
private function __construct(array $arOldSetupVars, ?string $action, ?string $profileId)
|
||||||
{
|
{
|
||||||
$this->arOldSetupVars = $arOldSetupVars;
|
$this->arOldSetupVars = $arOldSetupVars;
|
||||||
$this->action = $action;
|
$this->action = $action;
|
||||||
@ -128,7 +147,15 @@ class SettingsService
|
|||||||
$this->getPriceTypes();
|
$this->getPriceTypes();
|
||||||
$this->getVatRates();
|
$this->getVatRates();
|
||||||
|
|
||||||
$this->actrualPropList = array_merge($this->getIblockPropsPreset(), $this->parseNewProps());
|
$this->exportProfileId = $profileId ?? '0';
|
||||||
|
$this->profileCatalogsOptionName = sprintf('exportProfileId_%s_catalogs', $this->exportProfileId);
|
||||||
|
|
||||||
|
$this->linkNewProfile();
|
||||||
|
$this->deleteEmptyProfileCatalogs();
|
||||||
|
|
||||||
|
$this->customPropList = $this->getNewProps();
|
||||||
|
$this->defaultPropList = $this->getIblockPropsPreset();
|
||||||
|
$this->actualPropList = $this->getActualPropList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -137,16 +164,30 @@ class SettingsService
|
|||||||
*
|
*
|
||||||
* @return \Intaro\RetailCrm\Icml\SettingsService|null
|
* @return \Intaro\RetailCrm\Icml\SettingsService|null
|
||||||
*/
|
*/
|
||||||
public static function getInstance(array $arOldSetupVars, ?string $action): ?SettingsService
|
public static function getInstance(array $arOldSetupVars, ?string $action, ?string $profileId): ?SettingsService
|
||||||
{
|
{
|
||||||
if (is_null(self::$instance)) {
|
if (is_null(self::$instance)) {
|
||||||
self::$instance = new self($arOldSetupVars, $action);
|
self::$instance = new self($arOldSetupVars, $action, $profileId);
|
||||||
}
|
}
|
||||||
|
|
||||||
return self::$instance;
|
return self::$instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPriceTypes()
|
private function getActualPropList(): array
|
||||||
|
{
|
||||||
|
$customProps = [];
|
||||||
|
|
||||||
|
foreach ($this->customPropList as $propsByCatalog) {
|
||||||
|
$customProps = array_merge($customProps, $propsByCatalog);
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
...$this->defaultPropList,
|
||||||
|
...$customProps
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getPriceTypes()
|
||||||
{
|
{
|
||||||
$dbPriceType = CCatalogGroup::GetList(['SORT' => 'ASC'], [], [], [], ['ID', 'NAME', 'BASE']);
|
$dbPriceType = CCatalogGroup::GetList(['SORT' => 'ASC'], [], [], [], ['ID', 'NAME', 'BASE']);
|
||||||
|
|
||||||
@ -155,7 +196,7 @@ class SettingsService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getVatRates()
|
private function getVatRates()
|
||||||
{
|
{
|
||||||
$dbVatRate = CCatalogVat::GetListEx(['SORT' => 'ASC'], ['ACTIVE' => 'Y'], false, false, ['ID', 'NAME', 'RATE']);
|
$dbVatRate = CCatalogVat::GetListEx(['SORT' => 'ASC'], ['ACTIVE' => 'Y'], false, false, ['ID', 'NAME', 'RATE']);
|
||||||
|
|
||||||
@ -230,9 +271,11 @@ class SettingsService
|
|||||||
private function setProperties(array &$properties, string $propName): void
|
private function setProperties(array &$properties, string $propName): void
|
||||||
{
|
{
|
||||||
foreach ($this->arOldSetupVars[$propName] as $iblock => $val) {
|
foreach ($this->arOldSetupVars[$propName] as $iblock => $val) {
|
||||||
|
if (!empty($val)) {
|
||||||
$properties[$iblock][$propName] = $val;
|
$properties[$iblock][$propName] = $val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return mixed|string
|
* @return mixed|string
|
||||||
@ -260,27 +303,22 @@ class SettingsService
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
private function parseNewProps(): array
|
private function getNewProps(): array
|
||||||
{
|
{
|
||||||
global $APPLICATION;
|
|
||||||
|
|
||||||
$result = [];
|
$result = [];
|
||||||
$text = $APPLICATION->GetFileContent($_SERVER["DOCUMENT_ROOT"] . "/local/icml_property_retailcrm.txt");
|
$currentProfileCatalogIds = $this->getProfileCatalogs();
|
||||||
|
|
||||||
if ($text === false) {
|
if (!is_null($currentProfileCatalogIds)) {
|
||||||
return $result;
|
foreach ($currentProfileCatalogIds as $catalogId) {
|
||||||
|
$catalogCustomProps = $this
|
||||||
|
->setCatalogCustomPropsOptionName($catalogId)
|
||||||
|
->getCustomProps()
|
||||||
|
;
|
||||||
|
|
||||||
|
foreach ($catalogCustomProps as $prop) {
|
||||||
|
$result[$catalogId][$prop['code']] = $prop['title'];
|
||||||
}
|
}
|
||||||
|
|
||||||
preg_match_all('/\w+\s*=\s*\w+[ *\w+]*/mu', $text, $matches);
|
|
||||||
|
|
||||||
foreach ($matches[0] as $newProp) {
|
|
||||||
$elements = explode("=", $newProp);
|
|
||||||
|
|
||||||
if (empty($elements[0]) || empty($elements[1])) {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$result[trim($elements[0])] = trim($elements[1]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
@ -289,7 +327,7 @@ class SettingsService
|
|||||||
/**
|
/**
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function getHintProps(): array
|
private function getHintProps(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'article' => ['ARTICLE', 'ART', 'ARTNUMBER', 'ARTICUL', 'ARTIKUL'],
|
'article' => ['ARTICLE', 'ART', 'ARTNUMBER', 'ARTICUL', 'ARTIKUL'],
|
||||||
@ -365,7 +403,7 @@ class SettingsService
|
|||||||
|
|
||||||
public function setProps(): void
|
public function setProps(): void
|
||||||
{
|
{
|
||||||
foreach (array_keys($this->actrualPropList) as $prop) {
|
foreach (array_keys($this->actualPropList) as $prop) {
|
||||||
$this->setProperties($this->iblockPropertySku, 'iblockPropertySku_' . $prop);
|
$this->setProperties($this->iblockPropertySku, 'iblockPropertySku_' . $prop);
|
||||||
$this->setProperties($this->iblockPropertyUnitSku, 'iblockPropertyUnitSku_' . $prop);
|
$this->setProperties($this->iblockPropertyUnitSku, 'iblockPropertyUnitSku_' . $prop);
|
||||||
$this->setProperties($this->iblockPropertyProduct, 'iblockPropertyProduct_' . $prop);
|
$this->setProperties($this->iblockPropertyProduct, 'iblockPropertyProduct_' . $prop);
|
||||||
@ -548,7 +586,7 @@ class SettingsService
|
|||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function getSiteList(int $iblockId): array
|
private function getSiteList(int $iblockId): array
|
||||||
{
|
{
|
||||||
$siteList = [];
|
$siteList = [];
|
||||||
|
|
||||||
@ -576,9 +614,11 @@ class SettingsService
|
|||||||
$dbSkuProperties = CIBlock::GetProperties($iblockOffer['IBLOCK_ID'], [], ['MULTIPLE' => 'N']);
|
$dbSkuProperties = CIBlock::GetProperties($iblockOffer['IBLOCK_ID'], [], ['MULTIPLE' => 'N']);
|
||||||
|
|
||||||
while ($prop = $dbSkuProperties->Fetch()) {
|
while ($prop = $dbSkuProperties->Fetch()) {
|
||||||
|
if ($prop['CODE'] !== '') {
|
||||||
$propertiesSKU[] = $prop;
|
$propertiesSKU[] = $prop;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return $propertiesSKU;
|
return $propertiesSKU;
|
||||||
}
|
}
|
||||||
@ -597,7 +637,7 @@ class SettingsService
|
|||||||
$props = [];
|
$props = [];
|
||||||
|
|
||||||
if (isset($oldValues[$iblockId])) {
|
if (isset($oldValues[$iblockId])) {
|
||||||
foreach (array_keys($this->actrualPropList) as $prop) {
|
foreach (array_keys($this->actualPropList) as $prop) {
|
||||||
$fullKey = $keyGroup . '_' . $prop;
|
$fullKey = $keyGroup . '_' . $prop;
|
||||||
$props[$prop] = $oldValues[$iblockId][$fullKey];
|
$props[$prop] = $oldValues[$iblockId][$fullKey];
|
||||||
}
|
}
|
||||||
@ -623,15 +663,17 @@ class SettingsService
|
|||||||
*
|
*
|
||||||
* @return array|null
|
* @return array|null
|
||||||
*/
|
*/
|
||||||
public function getProductProps(int $iblockId): ?array
|
private function getProductProps(int $iblockId): ?array
|
||||||
{
|
{
|
||||||
$propertiesProduct = null;
|
$propertiesProduct = null;
|
||||||
|
|
||||||
$iblockResult = CIBlock::GetProperties($iblockId, [], ['MULTIPLE' => 'N']);
|
$iblockResult = CIBlock::GetProperties($iblockId, [], ['MULTIPLE' => 'N']);
|
||||||
|
|
||||||
while ($prop = $iblockResult->Fetch()) {
|
while ($prop = $iblockResult->Fetch()) {
|
||||||
|
if ($prop['CODE'] !== '') {
|
||||||
$propertiesProduct[] = $prop;
|
$propertiesProduct[] = $prop;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return $propertiesProduct;
|
return $propertiesProduct;
|
||||||
}
|
}
|
||||||
@ -642,7 +684,7 @@ class SettingsService
|
|||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function isExport($iblockId, $iblockExport): bool
|
private function isExport($iblockId, $iblockExport): bool
|
||||||
{
|
{
|
||||||
if (is_array($iblockExport) && count($iblockExport) !== 0) {
|
if (is_array($iblockExport) && count($iblockExport) !== 0) {
|
||||||
return (in_array($iblockId, $iblockExport));
|
return (in_array($iblockId, $iblockExport));
|
||||||
@ -747,4 +789,152 @@ class SettingsService
|
|||||||
|
|
||||||
return [$arIBlockList, $intCountChecked, $intCountAvailIBlock, $arIBlockList['iblockExport'] ?? false];
|
return [$arIBlockList, $intCountChecked, $intCountAvailIBlock, $arIBlockList['iblockExport'] ?? false];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setCatalogCustomPropsOptionName(string $catalogId): self
|
||||||
|
{
|
||||||
|
$this->catalogCustomPropsOptionName = sprintf(
|
||||||
|
'exportCustomProps_ProfileId_%s_catalogId_%s',
|
||||||
|
$this->exportProfileId,
|
||||||
|
$catalogId
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getCustomProps(): ?array
|
||||||
|
{
|
||||||
|
$props = unserialize(COption::GetOptionString(self::MODULE_ID, $this->catalogCustomPropsOptionName));
|
||||||
|
|
||||||
|
if (!$props) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $props;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function removeCustomProps(array $propsToDelete, string $catalogId): void
|
||||||
|
{
|
||||||
|
$currentCatalogProps = $this->getCustomProps();
|
||||||
|
$updatedCatalogProps = array_values(
|
||||||
|
array_filter(
|
||||||
|
$currentCatalogProps,
|
||||||
|
fn ($currentProp) => !in_array($currentProp, $propsToDelete)
|
||||||
|
));
|
||||||
|
|
||||||
|
if (empty($updatedCatalogProps)) {
|
||||||
|
$this->deleteOptionEntry($this->catalogCustomPropsOptionName);
|
||||||
|
$this->deleteProfileCatalog($catalogId);
|
||||||
|
} else {
|
||||||
|
$this->updateCustomProps($updatedCatalogProps);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function updateCustomProps(array $updatedProps)
|
||||||
|
{
|
||||||
|
$serializedProps = serialize($updatedProps);
|
||||||
|
$this->updateOptionEntry($this->catalogCustomPropsOptionName, $serializedProps);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function setCustomProps(array $props)
|
||||||
|
{
|
||||||
|
$propsString = serialize($props);
|
||||||
|
$this->setOptionEntry($this->catalogCustomPropsOptionName, $propsString);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function saveCustomProps(array $newProps): void
|
||||||
|
{
|
||||||
|
$currentProps = $this->getCustomProps();
|
||||||
|
|
||||||
|
if (is_null($currentProps)) {
|
||||||
|
$this->setCustomProps($newProps);
|
||||||
|
} else {
|
||||||
|
$updatedProps = array_merge($currentProps, $newProps);
|
||||||
|
$this->updateCustomProps($updatedProps);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getProfileCatalogs(): ?array
|
||||||
|
{
|
||||||
|
$catalogs = unserialize(COption::GetOptionString(self::MODULE_ID, $this->profileCatalogsOptionName));
|
||||||
|
|
||||||
|
if (!$catalogs) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $catalogs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setProfileCatalogs(array $catalogsId): void
|
||||||
|
{
|
||||||
|
$catalogs = serialize($catalogsId);
|
||||||
|
$this->setOptionEntry($this->profileCatalogsOptionName, $catalogs);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function deleteProfileCatalog(string $catalogId): void
|
||||||
|
{
|
||||||
|
$currentCatalogs = $this->getProfileCatalogs();
|
||||||
|
$catalogIdIndex = array_search($catalogId, $currentCatalogs);
|
||||||
|
|
||||||
|
if ($catalogIdIndex !== false) {
|
||||||
|
unset($currentCatalogs[$catalogIdIndex]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$updatedCatalogs = serialize($currentCatalogs);
|
||||||
|
$this->updateOptionEntry($this->profileCatalogsOptionName, $updatedCatalogs);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function deleteEmptyProfileCatalogs(): void
|
||||||
|
{
|
||||||
|
$currentCatalogs = $this->getProfileCatalogs();
|
||||||
|
|
||||||
|
if (is_null($currentCatalogs)) {
|
||||||
|
$this->deleteOptionEntry($this->profileCatalogsOptionName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function setOptionEntry(string $name, string $value)
|
||||||
|
{
|
||||||
|
COption::SetOptionString(self::MODULE_ID, $name, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function updateOptionEntry(string $name, string $value)
|
||||||
|
{
|
||||||
|
COption::SetOptionString(self::MODULE_ID, $name, '');
|
||||||
|
COption::SetOptionString(self::MODULE_ID, $name, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function deleteOptionEntry(string $name)
|
||||||
|
{
|
||||||
|
COption::RemoveOption(self::MODULE_ID, $name);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function linkNewProfile(): void
|
||||||
|
{
|
||||||
|
$currentProfileCatalogs = unserialize(COption::GetOptionString(self::MODULE_ID, $this->profileCatalogsOptionName));
|
||||||
|
|
||||||
|
if (!$currentProfileCatalogs) {
|
||||||
|
$tmpProfileName = 'exportProfileId_0_catalogs';
|
||||||
|
$currentProfileCatalogs = unserialize(COption::GetOptionString(self::MODULE_ID, $tmpProfileName));
|
||||||
|
|
||||||
|
if ($currentProfileCatalogs) {
|
||||||
|
$this->setOptionEntry($this->profileCatalogsOptionName, serialize($currentProfileCatalogs));
|
||||||
|
$this->deleteOptionEntry($tmpProfileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($currentProfileCatalogs as $catalogId) {
|
||||||
|
$optionName = sprintf('exportCustomProps_ProfileId_%s_catalogId_%s', $this->exportProfileId, $catalogId);
|
||||||
|
$propsCatalog = unserialize(COption::GetOptionString(self::MODULE_ID, $optionName));
|
||||||
|
|
||||||
|
if (!$propsCatalog) {
|
||||||
|
$tmpOptionName = sprintf('exportCustomProps_ProfileId_%s_catalogId_%s', '0', $catalogId);
|
||||||
|
$propsCatalog = unserialize(COption::GetOptionString(self::MODULE_ID, $tmpOptionName));
|
||||||
|
|
||||||
|
if ($propsCatalog) {
|
||||||
|
$this->setOptionEntry($optionName, serialize($propsCatalog));
|
||||||
|
$this->deleteOptionEntry($tmpOptionName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -115,8 +115,8 @@ class XmlOfferBuilder
|
|||||||
public function __construct(XmlSetup $setup, array $measure, ?string $serverName)
|
public function __construct(XmlSetup $setup, array $measure, ?string $serverName)
|
||||||
{
|
{
|
||||||
$this->setup = $setup;
|
$this->setup = $setup;
|
||||||
|
$this->setSettingsService();
|
||||||
$this->purchasePriceNull = RetailcrmConfigProvider::getCrmPurchasePrice();
|
$this->purchasePriceNull = RetailcrmConfigProvider::getCrmPurchasePrice();
|
||||||
$this->settingsService = SettingsService::getInstance([], '');
|
|
||||||
$this->vatRates = $this->settingsService->vatRates;
|
$this->vatRates = $this->settingsService->vatRates;
|
||||||
$this->measures = $this->prepareMeasures($measure);
|
$this->measures = $this->prepareMeasures($measure);
|
||||||
$this->serverName = $serverName;
|
$this->serverName = $serverName;
|
||||||
@ -141,6 +141,12 @@ class XmlOfferBuilder
|
|||||||
return $this->xmlOffer;
|
return $this->xmlOffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function setSettingsService(): void
|
||||||
|
{
|
||||||
|
global $PROFILE_ID;
|
||||||
|
$this->settingsService = SettingsService::getInstance([], '', $PROFILE_ID);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $categories
|
* @param array $categories
|
||||||
*/
|
*/
|
||||||
@ -479,7 +485,7 @@ class XmlOfferBuilder
|
|||||||
private function createParamObject(array $params): array
|
private function createParamObject(array $params): array
|
||||||
{
|
{
|
||||||
$offerParams = [];
|
$offerParams = [];
|
||||||
$names = $this->settingsService->actrualPropList;
|
$names = $this->settingsService->actualPropList;
|
||||||
|
|
||||||
foreach ($params as $code => $value) {
|
foreach ($params as $code => $value) {
|
||||||
|
|
||||||
|
@ -1187,41 +1187,22 @@ function update()
|
|||||||
Loader::includeModule('highloadblock');
|
Loader::includeModule('highloadblock');
|
||||||
COption::SetOptionString('intaro.retailcrm', 'api_version', 'v5');
|
COption::SetOptionString('intaro.retailcrm', 'api_version', 'v5');
|
||||||
|
|
||||||
$orderDischarge = Option::get('intaro.retailcrm', 'order_discharge');
|
loadJsExport();
|
||||||
|
|
||||||
if ($orderDischarge === '0') {
|
|
||||||
$dateAgent = new DateTime();
|
|
||||||
|
|
||||||
$dateAgent->add('PT60S');
|
|
||||||
CAgent::AddAgent(
|
|
||||||
'RCrmActions::uploadOrdersAgent();',
|
|
||||||
'intaro.retailcrm',
|
|
||||||
'N',
|
|
||||||
180,
|
|
||||||
$dateAgent->format('d.m.Y H:i:s'),
|
|
||||||
'Y',
|
|
||||||
$dateAgent->format('d.m.Y H:i:s'),
|
|
||||||
30
|
|
||||||
);
|
|
||||||
|
|
||||||
COption::SetOptionString('intaro.retailcrm', 'order_discharge', '2');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function createCustomPropertyFile()
|
function loadJsExport()
|
||||||
{
|
{
|
||||||
$path = $_SERVER['DOCUMENT_ROOT'] . '/local/';
|
$pathFrom = $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/intaro.retailcrm/install/export/bitrix/js/intaro/export';
|
||||||
|
|
||||||
CheckDirPath($path);
|
CopyDirFiles(
|
||||||
|
$pathFrom,
|
||||||
$file = new \Bitrix\Main\IO\File($path . 'icml_property_retailcrm.txt', $siteId = null);
|
$_SERVER['DOCUMENT_ROOT'] . '/bitrix/js/intaro/export/',
|
||||||
|
true,
|
||||||
if (!$file->isExists()) {
|
true,
|
||||||
$file->putContents("");
|
false
|
||||||
}
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
update();
|
update();
|
||||||
} catch (Main\ObjectPropertyException | Main\ArgumentException | Main\SystemException $exception) {
|
} catch (Main\ObjectPropertyException | Main\ArgumentException | Main\SystemException $exception) {
|
||||||
|
@ -17,25 +17,6 @@ class SettingServiceTest extends \BitrixTestCase
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testConstruct(): SettingsService
|
|
||||||
{
|
|
||||||
$path = $_SERVER['DOCUMENT_ROOT'] . '/local/';
|
|
||||||
|
|
||||||
CheckDirPath($path);
|
|
||||||
|
|
||||||
$file = new \Bitrix\Main\IO\File($path . '/icml_property_retailcrm.txt', $siteId = null);
|
|
||||||
|
|
||||||
$file->putContents("property1 = test prop \n property2 = test prop 2");
|
|
||||||
|
|
||||||
$settingService = SettingsService::getInstance($this->getSetupVars(), "");
|
|
||||||
|
|
||||||
$this->assertInstanceOf(SettingsService::class, $settingService);
|
|
||||||
$this->assertArrayHasKey('property1', $settingService->actrualPropList);
|
|
||||||
$this->assertArrayHasKey('property2', $settingService->actrualPropList);
|
|
||||||
|
|
||||||
return $settingService;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function getSetupVars()
|
private function getSetupVars()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
|
Loading…
Reference in New Issue
Block a user