1
0
mirror of synced 2025-01-29 22:31:42 +03:00

Add mapping metadata fields in settings

This commit is contained in:
Dima Uryvskiy 2021-12-30 11:22:34 +03:00 committed by GitHub
parent c57cb099e5
commit 5a480f0b31
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 987 additions and 61 deletions

View File

@ -0,0 +1,20 @@
### Пользовательские поля
В настройках модуля есть возможность настроить передачу пользовательских полей из CMS в CRM и обратно. Для этого необходимо настроить соответствие между мета полями CMS и пользовательскими полями CRM.
Слева располагаются мета поля CMS, справа пользовательские поля CRM. В выпадающем списке слева нужно выбрать мета поля CMS, в выпадающем списке справа нужно выбрать пользовательское поле CRM и таким образом сопоставить их.
Пользовательские поля разбиты на две группы для заказов "Custom fields for order" и для клиентов "Custom fields for customer".
При нажатии на кнопку "Custom fields for order/customer" будет добавлены новые списки для выбора. Количество списков не может быть больше количества мета полей CMS или пользовательских полей CRM. Поэтому когда добавили максимальное число списков, кнопка добавления пропадает. Для каждой группы предусмотрена своя кнопка добавления.
Обратите внимание, что значения не должны повторяться, т.е. для двух мета полей CMS, не может быть выбрана одно и то же пользовательское поле CRM. Необходимо выбирать 1 к 1. Если вдруг выбрать значение которое уже используется, будет показано предупреждающее уведомление, выбранный список начнет мигать красным и в этом списке будет установленно значение по умолчанию "Select value".
Сопоставление можно удалить, если нажать на крестик справа от списка пользовательский полей CRM.
Для сохранения выбранных сопоставлений необходимо нажать на кнопку "Сохранить изменения" в конце страницы настроек.
Также в списке значений для сопоставления выводятся **только Активные в CRM пользовательские поля**.
На стороне CRM доступные пользовательские поля можно увидеть перейдя в **Настройки - Системные - Пользовательские поля.**

View File

@ -274,3 +274,36 @@ msgstr "Activar el modo de depuración en el módulo"
msgid "Is required to enable debug mode for advanced logs"
msgstr "Se requiere el modo de depuración para habilitar el registro avanzado de logs"
msgid "Custom fields"
msgstr "Campos personalizados"
msgid "Select value"
msgstr "Selecciona un valor"
msgid "Custom fields for order"
msgstr "Campos de pedido personalizados"
msgid "Custom fields for customer"
msgstr "Campos de clientes personalizados"
msgid "Add new select for order"
msgstr "Añadir"
msgid "Add new select for customer"
msgstr "Añadir"
msgid "This option is disabled"
msgstr "Opción desactivada"
msgid "Cron launches"
msgstr "Tareas de cron"
msgid "Generation ICML"
msgstr "Generación del catálogo"
msgid "Syncing history"
msgstr "Sincronización del historial"
msgid "Syncing inventories"
msgstr "Sincronización de inventario"

View File

@ -283,5 +283,38 @@ msgstr "Активировать режим отладки в модуле"
msgid "Is required to enable debug mode for advanced logs"
msgstr "Требуется включить режим отладки для расширенного логирования"
msgid "Custom fields"
msgstr "Пользовательские поля"
msgid "Select value"
msgstr "Выберите значение"
msgid "Custom fields for order"
msgstr "Пользовательские поля для заказа"
msgid "Custom fields for customer"
msgstr "Пользовательские поля для клиента"
msgid "Add new select for order"
msgstr "Добавить"
msgid "Add new select for customer"
msgstr "Добавить"
msgid "This option is disabled"
msgstr "Опция отключена"
msgid "Cron launches"
msgstr "Работающие крон задачи"
msgid "Generation ICML"
msgstr "Генерация каталога"
msgid "Syncing history"
msgstr "Синхронизация истории"
msgid "Syncing inventories"
msgstr "Синхронизация запасов"

View File

@ -0,0 +1,59 @@
.retailcrm-meta-select {
margin-right: 25px !important;
float:left !important;
width: 200px !important;
text-align-last: center;
border: 2px solid #2271b1;
}
.retailcrm-select-pair {
margin-bottom: 30px;
}
.retailcrm-order-label, .retailcrm-customer-label {
display: block;
font-size: 14px !important;
margin-top: 16px;
margin-bottom: 10px;
}
.add-new-select-retailcrm {
display:block;
width: 200px !important;
height: 34px;
color: #4169e1;
border-color: #4169e1;
background: #f6f7f7;
vertical-align: top;
margin-top: 16px;
margin-left: 128px;
margin-bottom: 10px;
}
.delete-select-retailcrm {
display: block;
width: 34px;
height: 34px;
--weight: 0.5px;
--aa: 0.5px; /* anti-aliasing */
--color: #4169e1;
border-color: #4169e1;
background: #f6f7f7;
padding: 0;
background:
linear-gradient(45deg, transparent calc(50% - var(--weight) - var(--aa)), var(--color) calc(50% - var(--weight)), var(--color) calc(50% + var(--weight)), transparent calc(50% + var(--weight) + var(--aa))),
linear-gradient(-45deg, transparent calc(50% - var(--weight) - var(--aa)), var(--color) calc(50% - var(--weight)), var(--color) calc(50% + var(--weight)), transparent calc(50% + var(--weight) + var(--aa)));
}
.red-selected-retailcrm {
border: solid 3px red !important;
animation: 2s blinker linear infinite;
#transition: border-width 0.6s linear;
}
@keyframes blinker {
0% { opacity: 1.0; }
50% { opacity: 0.3; }
100% { opacity: 1.0; }
}

1
src/assets/css/meta-fields.min.css vendored Normal file
View File

@ -0,0 +1 @@
.retailcrm-meta-select{margin-right:25px!important;float:left!important;width:200px!important;text-align-last:center;border:2px solid #2271b1}.retailcrm-select-pair{margin-bottom:30px}.retailcrm-customer-label,.retailcrm-order-label{display:block;font-size:14px!important;margin-top:16px;margin-bottom:10px}.add-new-select-retailcrm{display:block;width:200px!important;height:34px;color:#4169e1;border-color:#4169e1;background:#f6f7f7;vertical-align:top;margin-top:16px;margin-left:128px;margin-bottom:10px}.delete-select-retailcrm{display:block;width:34px;height:34px;--weight:0.5px;--aa:0.5px;--color:#4169e1;border-color:#4169e1;background:#f6f7f7;padding:0;background:linear-gradient(45deg,transparent calc(50% - var(--weight) - var(--aa)),var(--color) calc(50% - var(--weight)),var(--color) calc(50% + var(--weight)),transparent calc(50% + var(--weight) + var(--aa))),linear-gradient(-45deg,transparent calc(50% - var(--weight) - var(--aa)),var(--color) calc(50% - var(--weight)),var(--color) calc(50% + var(--weight)),transparent calc(50% + var(--weight) + var(--aa)))}.red-selected-retailcrm{border:solid 3px red!important;animation:2s blinker linear infinite}@keyframes blinker{0%{opacity:1}50%{opacity:.3}100%{opacity:1}}

View File

@ -21,7 +21,7 @@
box-sizing: border-box;
}
.retail-hidden {
.retailcrm-hidden {
display: none !important;
}

View File

@ -1 +1,5 @@
.retail-progress{border-radius:18px;border:1px solid rgba(122,122,122,.15);width:400px;height:18px;overflow:hidden;transition:height .25s ease}.retail-progress__loader{width:0;border-radius:18px;background:#4169e1;color:#fff;text-align:center;padding:0 30px;font-size:18px;font-weight:600;transition:width .4s ease-in;line-height:18px;box-sizing:border-box}.retail-hidden{display:none!important}.retail-count-data-upload{margin-bottom:20px;size:30px;color:#4169e1;font-weight:700}
<<<<<<< HEAD
.retail-progress{border-radius:18px;border:1px solid rgba(122,122,122,.15);width:400px;height:18px;overflow:hidden;transition:height .25s ease}.retail-progress__loader{width:0;border-radius:18px;background:#4169e1;color:#fff;text-align:center;padding:0 30px;font-size:18px;font-weight:600;transition:width .4s ease-in;line-height:18px;box-sizing:border-box}.retail-hidden{display:none!important}.retail-count-data-upload{margin-bottom:20px;size:30px;color:#4169e1;font-weight:700}
=======
.retail-progress{border-radius:18px;border:1px solid rgba(122,122,122,.15);width:400px;height:18px;overflow:hidden;transition:height .25s ease}.retail-progress__loader{width:0;border-radius:18px;background:#4169e1;color:#fff;text-align:center;padding:0 30px;font-size:18px;font-weight:600;transition:width .4s ease-in;line-height:18px;box-sizing:border-box}.retailcrm-hidden{display:none!important}.retail-count-data-upload{margin-bottom:20px;size:30px;color:#4169e1;font-weight:700}
>>>>>>> Add mapping metadata fields in settings

View File

@ -0,0 +1,180 @@
_backorders
_billing_address_1
_billing_address_2
_billing_address_index
_billing_city
_billing_company
_billing_country
_billing_email
_billing_first_name
_billing_last_name
_billing_phone
_billing_postcode
_billing_state
_button_text
_cart_discount
_cart_discount_tax
_cart_hash
_children
_completed_date
_created_via
_customer_ip_address
_customer_user
_customer_user_agent
_date_completed
_date_paid
_download_expiry
_download_limit
_download_permissions_granted
_downloadable
_downloadable_files
_edit_last
_edit_lock
_manage_stock
_new_order_email_sent
_order_currency
_order_key
_order_shipping
_order_shipping_tax
_order_stock_reduced
_order_tax
_order_total
_order_version
_paid_date
_payment_method
_payment_method_title
_price
_prices_include_tax
_product_attributes
_product_image_gallery
_product_url
_product_version
_recorded_coupon_usage_counts
_recorded_sales
_refund_amount
_refund_reason
_refunded_by
_refunded_payment
_regular_price
_sale_price
_shipping_address_1
_shipping_address_2
_shipping_address_index
_shipping_city
_shipping_company
_shipping_country
_shipping_first_name
_shipping_last_name
_shipping_postcode
_shipping_state
_sku
_sold_individually
_stock
_stock_status
_stripe_charge_captured
_stripe_currency
_stripe_customer_id
_stripe_fee
_stripe_intent_id
_stripe_net
_stripe_source_id
_tax_class
_tax_status
_thumbnail_id
_transaction_id
_variation_description
_virtual
_wc_attachment_source
_wc_average_rating
_wc_review_count
_wp_attached_file
_wp_attachment_metadata
_wp_desired_post_slug
_wp_old_slug
_wp_page_template
_wp_trash_meta_comments_status
_wp_trash_meta_status
_wp_trash_meta_time
_wpcom_is_markdown
_used_by
attribute_logo
attribute_pa_color
attribute_pa_size
is_vat_exempt
total_sales
coupon_amount
date_expires
discount_type
exclude_sale_items
free_shipping
individual_use
is_vat_exempt
limit_usage_to_x_items
usage_count
usage_limit
usage_limit_per_user
_shipping_phone
## Customer
_last_order
_order_count
_woocommerce_persistent_cart_1
_woocommerce_tracks_anon_id
admin_color
billing_address_1
billing_address_2
billing_city
billing_company
billing_country
billing_email
billing_first_name
billing_last_name
billing_phone
billing_postcode
billing_state
comment_shortcuts
community-events-location
default_password_nag
description
dismissed_maxmind_license_key_notice
dismissed_no_secure_connection_notice
dismissed_regenerating_thumbnails_notice
dismissed_update_notice
dismissed_wc_admin_notice
dismissed_wp_pointers
first_name
last_name
last_update
locale
nickname
paying_customer
rich_editing
session_tokens
shipping_address_1
shipping_address_2
shipping_city
shipping_company
shipping_country
shipping_first_name
shipping_last_name
shipping_method
shipping_phone
shipping_postcode
shipping_state
show_admin_bar_front
show_welcome_panel
syntax_highlighting
use_ssl
wc_last_active
woocommerce_admin_activity_panel_inbox_last_read
wp_capabilities
wp_dashboard_quick_press_last_post_id
wp_product_import_error_log
wp_user_level
wp_user-settings
wp_user-settings-time
wp_woocommerce_product_import_mapping
closedpostboxes_shop_order
metaboxhidden_shop_order
wp__stripe_customer_id

View File

@ -25,20 +25,24 @@ jQuery(function () {
_this.icml = response.icml;
_this.inventories = response.inventories;
_this.displayInfoAboutCron();
_this.displayInfoAboutCron(
response.translate.tr_td_cron,
response.translate.tr_td_icml,
response.translate.tr_td_history,
response.translate.tr_td_inventories
);
})
}
RetailcrmCronInfo.prototype.displayInfoAboutCron = function () {
RetailcrmCronInfo.prototype.displayInfoAboutCron = function (cron, icml, history, inventories) {
this.table = jQuery(this.title).next();
this.table.append('<tbody class="retail-debug-info"></tbody>');
this.infoTable = jQuery('tbody[class="retail-debug-info"]').get(0);
jQuery(this.infoTable).append("<tr><td class='retail-cron-info-title'>" + "Cron launches:" + "</td></tr>");
jQuery(this.infoTable).append("<tr><td class='retail-cron-info'>" + "History: " + this.history + "</td></tr>");
jQuery(this.infoTable).append("<tr><td class='retail-cron-info'>" + "Icml: " + this.icml + "</td></tr>");
jQuery(this.infoTable).append("<tr><td class='retail-cron-info'>" + "Inventories: " + this.inventories + "</td></tr>");
jQuery(this.infoTable).append("<tr><td class='retail-cron-info-title'>" + cron + " : " + "</td></tr>");
jQuery(this.infoTable).append("<tr><td class='retail-cron-info'>" + icml + " : " + this.icml + "</td></tr>");
jQuery(this.infoTable).append("<tr><td class='retail-cron-info'>" + history + " : " + this.history + "</td></tr>");
jQuery(this.infoTable).append("<tr><td class='retail-cron-info'>" + inventories + " : " + this.inventories + "</td></tr>");
}
window.RetailcrmCronInfo = RetailcrmCronInfo;

View File

@ -4,7 +4,7 @@ jQuery(function () {
this.submitButton = jQuery('button[id="export-orders-submit"]').get(0);
this.selectedOrdersButton = jQuery('button[id="export_selected_orders_btn"]').get(0);
jQuery(this.submitButton).after('<div id="export-orders-progress" class="retail-progress retail-hidden"></div');
jQuery(this.submitButton).after('<div id="export-orders-progress" class="retail-progress retailcrm-hidden"></div');
jQuery(this.submitButton).before('<div id="export-orders-count" class="retail-count-data-upload"></div');
this.progressBar = jQuery('div[id="export-orders-progress"]').get(0);
@ -21,7 +21,7 @@ jQuery(function () {
return false;
}
jQuery(this.submitButton).addClass('retail-hidden');
jQuery(this.submitButton).addClass('retailcrm-hidden');
this.ordersCount = 0;
this.customersCount = 0;
@ -37,7 +37,8 @@ jQuery(function () {
.done(function (response) {
_this.ordersCount = Number(response.count_orders);
_this.customersCount = Number(response.count_users);
jQuery(_this.submitButton).removeClass('retail-hidden');
jQuery(_this.submitButton).removeClass('retailcrm-hidden');
_this.messageEmtyField = response.translate.tr_empty_field;
_this.messageSuccessful = response.translate.tr_successful;
@ -65,6 +66,7 @@ jQuery(function () {
RetailcrmExportForm.prototype.displayCountUploadData = function (order, customer) {
this.counter = jQuery('div[id="export-orders-count"]').get(0);
jQuery(this.counter).text(`${customer}: ${this.customersCount} ${order}: ${this.ordersCount}`);
}
@ -115,9 +117,9 @@ jQuery(function () {
};
RetailcrmExportForm.prototype.initializeProgressBar = function () {
jQuery(this.submitButton).addClass('retail-hidden');
jQuery(this.submitButton).addClass('retailcrm-hidden');
jQuery(this.progressBar)
.removeClass('retail-hidden')
.removeClass('retailcrm-hidden')
.append(jQuery('<div/>', {class: 'retail-progress__loader', text: '0%'}))
window.addEventListener('beforeunload', this.confirmLeave);

View File

@ -0,0 +1,323 @@
jQuery(function () {
function RetailcrmMetaFields()
{
jQuery('.order-meta-data-retailcrm').closest('tr').addClass('retailcrm-hidden')
jQuery('.customer-meta-data-retailcrm').closest('tr').addClass('retailcrm-hidden')
jQuery('.customer-meta-data-retailcrm').closest('tr').after('<tr class="retailcrm-insert-select"></tr>')
this.insertSelects = jQuery('.retailcrm-insert-select').get(0);
this.orderTextArea = jQuery('.order-meta-data-retailcrm').get(0);
this.customerTextArea = jQuery('.customer-meta-data-retailcrm').get(0);
this.indexOrder = 1;
this.indexCustomer = 1;
if (typeof this.insertSelects === 'undefined'
|| this.orderTextArea === 'undefined'
|| this.customerTextArea === 'undefined'
) {
return false;
}
jQuery(this.insertSelects).append(
`<label class="retailcrm-order-label">Custom fields for order</label><div class="retailcrm-order-selects"></div>` +
`<label class="retailcrm-customer-label">Custom fields for customer</label><div class="retailcrm-customer-selects"></div>` +
`<button class="add-new-select-retailcrm" id="add-new-select-order-retailcrm">Add new select for order</button>` +
`<button class="add-new-select-retailcrm" id="add-new-select-customer-retailcrm">Add new select for customer</button>`
);
let _this = this;
if (this.orderTextArea.value === '') {
this.orderTextArea.value = JSON.stringify({});
}
if (this.customerTextArea.value === '') {
this.customerTextArea.value = JSON.stringify({});
}
jQuery.ajax({
url: window.location.origin + '/wp-admin/admin-ajax.php?action=set_meta_fields',
method: 'POST',
timeout: 0,
data: {ajax: 1},
dataType: 'json'
})
.done(function (response) {
_this.dataFields = response;
jQuery(".retailcrm-order-label").text(response.translate.tr_lb_order);
jQuery(".retailcrm-customer-label").text(response.translate.tr_lb_customer);
jQuery(".add-new-select-retailcrm").text(response.translate.tr_btn);
jQuery(".add-new-select-retailcrm").text(response.translate.tr_btn);
if (jQuery.isEmptyObject(JSON.parse(_this.orderTextArea.value)) && jQuery.isEmptyObject(JSON.parse(_this.customerTextArea.value))) {
_this.createSelects(_this.dataFields);
}
if (!jQuery.isEmptyObject(JSON.parse(_this.orderTextArea.value))) {
let objectJson = JSON.parse(_this.orderTextArea.value);
_this.indexOrder = _this.restoreSelectsData(
objectJson,
_this.dataFields.order,
'order',
1
);
}
if (!jQuery.isEmptyObject(JSON.parse(_this.customerTextArea.value))) {
let objectJson = JSON.parse(_this.customerTextArea.value);
_this.indexCustomer = _this.restoreSelectsData(
objectJson,
_this.dataFields.customer,
'customer',
1
);
}
})
jQuery(this.insertSelects).on('change', '.retailcrm-meta-select', function() {
let selectsData = {};
let typeSelect = this.id.split('-')[0]
let idChangeSelect = this.id.split('-')[2]
if (this.id.includes('order')) {
selectsData = _this.getSelectsData(
_this.orderTextArea.value,
'order',
idChangeSelect,
typeSelect
);
} else {
selectsData = _this.getSelectsData(
_this.customerTextArea.value,
'customer',
idChangeSelect,
typeSelect
);
}
if (Object.keys(selectsData).length != 0) {
if (this.id.includes('order')) {
_this.orderTextArea.value = JSON.stringify(selectsData);
} else {
_this.customerTextArea.value = JSON.stringify(selectsData);
}
}
});
jQuery(this.insertSelects).on('click', '.add-new-select-retailcrm', function(event) {
event.preventDefault();
if (this.id.includes('order')) {
_this.addPairSelects(
'.retailcrm-order-selects',
'order',
_this.dataFields.order,
_this.indexOrder
);
_this.indexOrder++;
} else {
_this.addPairSelects(
'.retailcrm-customer-selects',
'customer',
_this.dataFields.customer,
_this.indexCustomer
);
_this.indexCustomer++;
}
});
jQuery(this.insertSelects).on('click', '.delete-select-retailcrm', function(event) {
event.preventDefault();
let objectJson = {}
let entity = this.id.split('-')[0];
let index = this.id.split('-')[1];
if (entity === 'order') {
objectJson = JSON.parse(_this.orderTextArea.value);
} else {
objectJson = JSON.parse(_this.customerTextArea.value);
}
let metaFiled = jQuery(`#metaFields-${entity}-${index}`);
let valueMetaField = metaFiled.val();
for (let i = 1; i <= index; i++) {
jQuery(`#select-pair-${entity}-${i}`).remove();
}
delete objectJson[valueMetaField];
if (entity === 'order') {
_this.indexOrder = _this.restoreSelectsData(
objectJson,
_this.dataFields.order,
'order',
1
);
_this.orderTextArea.value = JSON.stringify(objectJson);
} else {
_this.indexCustomer = _this.restoreSelectsData(
objectJson,
_this.dataFields.customer,
'customer',
1
);
_this.customerTextArea.value = JSON.stringify(objectJson);
}
jQuery(`#add-new-select-${entity}-retailcrm`).removeClass('retailcrm-hidden')
});
}
RetailcrmMetaFields.prototype.restoreSelectsData = function (objectJson, dataEntity, entity, index) {
for (let key in objectJson) {
let getMetaSelect = `#metaFields-${entity}-${index} option[value=${key}]`;
let getCustomSelect = `#customFields-${entity}-${index} option[value=${objectJson[key]}]`;
this.addPairSelects(`.retailcrm-${entity}-selects`, entity, dataEntity, index);
jQuery(getMetaSelect).prop('selected', true);
jQuery(getCustomSelect).prop('selected', true);
index++;
}
return index;
}
RetailcrmMetaFields.prototype.getSelectsData = function (textarea, entity, idChangeSelect, typeSelect) {
let _this = this;
let selectsData = {};
if (!jQuery.isEmptyObject(textarea)) {
let objectJson = JSON.parse(textarea);
let field = jQuery(`#${typeSelect}-${entity}-${idChangeSelect}`);
let selectedField = jQuery(`#${typeSelect}-${entity}-${idChangeSelect} option:selected`);
let fieldValue = field.val();
if (Object.values(objectJson).includes(fieldValue) || fieldValue in objectJson) {
_this.addWarning(field, selectedField.text());
// Search key in object by id selects
let counter = 0;
for (let key in objectJson) {
counter++;
if (counter == idChangeSelect) {
delete objectJson[key];
}
}
if (entity === 'order') {
_this.orderTextArea.value = JSON.stringify(objectJson);
} else {
_this.customerTextArea.value = JSON.stringify(objectJson);
}
}
}
for (let i = 1; i <= jQuery(`.retailcrm-${entity}-selects div`).length; i++) {
let metaFiled = jQuery(`#metaFields-${entity}-${i}`);
let customField = jQuery(`#customFields-${entity}-${i}`);
let valueMetaField = metaFiled.val();
let valueCustomField = customField.val();
if (valueMetaField === 'default_retailcrm' || valueCustomField === 'default_retailcrm') {
continue;
}
_this.deleteWarning(metaFiled);
_this.deleteWarning(customField);
selectsData[valueMetaField] = valueCustomField;
}
return selectsData;
}
RetailcrmMetaFields.prototype.createSelects = function (dataFields) {
let orderData = dataFields.order;
let customerData = dataFields.customer;
//Create selects for order data
this.buildElements('.retailcrm-order-selects', 'order', this.indexOrder);
this.fillSelects(orderData, 'order', this.indexOrder);
//Create selects for customer data
this.buildElements('.retailcrm-customer-selects', 'customer', this.indexCustomer);
this.fillSelects(customerData, 'customer', this.indexCustomer);
this.indexOrder++;
this.indexCustomer++;
}
RetailcrmMetaFields.prototype.buildElements = function (element, entity, index) {
jQuery(element).append(
`<div class="retailcrm-select-pair" id="select-pair-${entity}-${index}">` +
`<select class="retailcrm-meta-select" id="metaFields-${entity}-${index}"></select>` +
`<select class="retailcrm-meta-select" id="customFields-${entity}-${index}"></select>` +
`<button class="delete-select-retailcrm" id="${entity}-${index}"></button></div>`
);
jQuery(`#add-new-select-${entity}-retailcrm`).insertAfter(`#select-pair-${entity}-${index}`);
}
RetailcrmMetaFields.prototype.fillSelects = function (data, entity, index) {
if (Object.keys(data.meta).length - 1 <= index || Object.keys(data.custom).length - 1 <= index) {
if (entity === 'order') {
jQuery('#add-new-select-order-retailcrm').addClass('retailcrm-hidden')
} else {
jQuery('#add-new-select-customer-retailcrm').addClass('retailcrm-hidden')
}
}
// Set meta fields in select
jQuery.each(data.meta, function(key, value) {
jQuery(`#metaFields-${entity}-${index}`)
.append(jQuery('<option></option>')
.attr('value', key)
.text(value));
});
// Set custom fields in select
jQuery.each(data.custom, function(key, value) {
jQuery(`#customFields-${entity}-${index}`)
.append(jQuery('<option></option>')
.attr('value', key)
.text(value));
});
}
RetailcrmMetaFields.prototype.addPairSelects = function (element, entity, data, index) {
this.buildElements(element, entity, index);
this.fillSelects(data, entity, index);
}
RetailcrmMetaFields.prototype.addWarning = function (field, fieldValue) {
alert(fieldValue + ' already been selected');
field.prop('value', 'default_retailcrm');
field.addClass('red-selected-retailcrm');
}
RetailcrmMetaFields.prototype.deleteWarning = function (field) {
if (field.css('border-color') === "rgb(255, 0, 0)") {
field.removeClass('red-selected-retailcrm')
}
}
window.RetailcrmMetaFields = RetailcrmMetaFields;
if (typeof RetailcrmMetaFields !== 'undefined') {
new window.RetailcrmMetaFields();
}
});

View File

@ -1,4 +1,5 @@
<?php
/**
* PHP version 5.6
*
@ -31,7 +32,8 @@ abstract class WC_Retailcrm_Abstracts_Settings extends WC_Integration
static::$option_key = $this->get_option_key();
if (isset($_GET['page']) && $_GET['page'] == 'wc-settings'
if (
isset($_GET['page']) && $_GET['page'] == 'wc-settings'
&& isset($_GET['tab']) && $_GET['tab'] == 'integration'
) {
add_action('init', array($this, 'init_settings_fields'), 99);
@ -66,19 +68,19 @@ abstract class WC_Retailcrm_Abstracts_Settings extends WC_Integration
public function init_form_fields()
{
$this->form_fields = array(
array( 'title' => __( 'Main settings', 'retailcrm' ), 'type' => 'title', 'desc' => '', 'id' => 'general_options' ),
array( 'title' => __('Main settings', 'retailcrm'), 'type' => 'title', 'desc' => '', 'id' => 'general_options' ),
'api_url' => array(
'title' => __( 'API of URL', 'retailcrm' ),
'title' => __('API of URL', 'retailcrm'),
'type' => 'text',
'description' => __( 'Enter API of URL (https://yourdomain.simla.com)', 'retailcrm' ),
'desc_tip' => true,
'default' => ''
),
'api_key' => array(
'title' => __( 'API key', 'retailcrm' ),
'title' => __('API key', 'retailcrm'),
'type' => 'text',
'description' => __( 'Enter your API key. You can find it in the administration section of Simla.com', 'retailcrm' ),
'description' => __('Enter your API key. You can find it in the administration section of Simla.com', 'retailcrm'),
'desc_tip' => true,
'default' => ''
)
@ -89,13 +91,14 @@ abstract class WC_Retailcrm_Abstracts_Settings extends WC_Integration
$apiKey = !empty($post[$this->plugin_id . $this->id . '_api_key']) ? $post[$this->plugin_id . $this->id . '_api_key'] : null;
if ($this->apiClient) {
if (isset($_GET['page']) && $_GET['page'] == 'wc-settings'
if (
isset($_GET['page']) && $_GET['page'] == 'wc-settings'
&& isset($_GET['tab']) && $_GET['tab'] == 'integration'
) {
add_action('admin_print_footer_scripts', array($this, 'show_blocks'), 99);
$this->form_fields[] = array(
'title' => __( 'API settings', 'retailcrm' ),
'title' => __('API settings', 'retailcrm'),
'type' => 'title',
'description' => '',
'id' => 'api_options'
@ -111,14 +114,14 @@ abstract class WC_Retailcrm_Abstracts_Settings extends WC_Integration
);
$this->form_fields['online_assistant'] = array(
'title' => __( 'Online assistant', 'retailcrm' ),
'title' => __('Online assistant', 'retailcrm'),
'type' => 'textarea',
'id' => 'online_assistant',
'placeholder' => __( 'Insert the Online consultant code here', 'retailcrm' )
'placeholder' => __('Insert the Online consultant code here', 'retailcrm')
);
$this->form_fields['catalog_options'] = array(
'title' => __( 'Catalog settings', 'retailcrm' ),
$this->form_fields[] = array(
'title' => __('Catalog settings', 'retailcrm'),
'type' => 'heading',
'description' => '',
'id' => 'catalog_options'
@ -193,7 +196,7 @@ abstract class WC_Retailcrm_Abstracts_Settings extends WC_Integration
'id' => 'shipping_options'
);
foreach ($wc_shipping_list as $shipping_code => $shipping) {
foreach ($wc_shipping_list as $shipping_code => $shipping) {
if (isset($shipping['enabled']) && $shipping['enabled'] == static::YES) {
$this->form_fields[$shipping_code] = array(
'title' => __($shipping['title'], 'woocommerce'),
@ -282,6 +285,26 @@ abstract class WC_Retailcrm_Abstracts_Settings extends WC_Integration
}
}
/**
* Meta data options
*/
$this->form_fields[] = array(
'title' => __('Custom fields', 'retailcrm'),
'type' => 'heading',
'description' => '',
'class' => 'meta-fields'
);
$this->form_fields['order-meta-data-retailcrm'] = array(
'type' => 'textarea',
'class' => 'order-meta-data-retailcrm',
);
$this->form_fields['customer-meta-data-retailcrm'] = array(
'type' => 'textarea',
'class' => 'customer-meta-data-retailcrm',
);
/**
* Inventories options
*/
@ -506,7 +529,7 @@ abstract class WC_Retailcrm_Abstracts_Settings extends WC_Integration
$response = $api->apiVersions();
if ($response->isSuccessful()) {
header("Refresh:0");
header("Refresh:0");
}
}
}
@ -533,20 +556,20 @@ abstract class WC_Retailcrm_Abstracts_Settings extends WC_Integration
'title' => '',
);
$data = wp_parse_args( $data, $defaults );
$data = wp_parse_args($data, $defaults);
ob_start();
?>
<tr valign="top">
<th scope="row" class="titledesc">
<label for="<?php echo esc_attr( $field ); ?>"><?php echo wp_kses_post( $data['title'] ); ?></label>
<?php echo $this->get_tooltip_html( $data ); ?>
<label for="<?php echo esc_attr($field); ?>"><?php echo wp_kses_post($data['title']); ?></label>
<?php echo $this->get_tooltip_html($data); ?>
</th>
<td class="forminp">
<fieldset>
<legend class="screen-reader-text"><span><?php echo wp_kses_post( $data['label'] ); ?></span></legend>
<button id="<?php echo $data['id']; ?>" class="<?php echo esc_attr( $data['class'] ); ?>" type="button" name="<?php echo esc_attr( $field ); ?>" id="<?php echo esc_attr( $field ); ?>" style="<?php echo esc_attr( $data['css'] ); ?>" <?php echo $this->get_custom_attribute_html( $data ); ?>><?php echo wp_kses_post( $data['label'] ); ?></button>
<?php echo $this->get_description_html( $data ); ?>
<legend class="screen-reader-text"><span><?php echo wp_kses_post($data['label']); ?></span></legend>
<button id="<?php echo $data['id']; ?>" class="<?php echo esc_attr($data['class']); ?>" type="button" name="<?php echo esc_attr($field); ?>" id="<?php echo esc_attr($field); ?>" style="<?php echo esc_attr($data['css']); ?>" <?php echo $this->get_custom_attribute_html($data); ?>><?php echo wp_kses_post($data['label']); ?></button>
<?php echo $this->get_description_html($data); ?>
</fieldset>
</td>
</tr>
@ -566,20 +589,20 @@ abstract class WC_Retailcrm_Abstracts_Settings extends WC_Integration
*/
public function generate_heading_html($key, $data)
{
$field_key = $this->get_field_key( $key );
$field_key = $this->get_field_key($key);
$defaults = array(
'title' => '',
'class' => '',
);
$data = wp_parse_args( $data, $defaults );
$data = wp_parse_args($data, $defaults);
ob_start();
?>
</table>
<h2 class="wc-settings-sub-title retailcrm_hidden <?php echo esc_attr( $data['class'] ); ?>" id="<?php echo esc_attr( $field_key ); ?>"><?php echo wp_kses_post( $data['title'] ); ?> <span style="opacity:0.5;float: right;">&#11015;</span></h2>
<?php if ( ! empty( $data['description'] ) ) : ?>
<p><?php echo wp_kses_post( $data['description'] ); ?></p>
<h2 class="wc-settings-sub-title retailcrm_hidden <?php echo esc_attr($data['class']); ?>" id="<?php echo esc_attr($field_key); ?>"><?php echo wp_kses_post($data['title']); ?> <span style="opacity:0.5;float: right;">&#11015;</span></h2>
<?php if (! empty($data['description'])) : ?>
<p><?php echo wp_kses_post($data['description']); ?></p>
<?php endif; ?>
<table class="form-table" style="display: none;">
<?php
@ -597,13 +620,13 @@ abstract class WC_Retailcrm_Abstracts_Settings extends WC_Integration
*/
public function validate_online_assistant_field($key, $value)
{
$onlineAssistant = $_POST['woocommerce_integration-retailcrm_online_assistant'];
$onlineAssistant = $_POST['woocommerce_integration-retailcrm_online_assistant'];
if (!empty($onlineAssistant) && is_string($onlineAssistant)) {
return wp_unslash($onlineAssistant);
}
if (!empty($onlineAssistant) && is_string($onlineAssistant)) {
return wp_unslash($onlineAssistant);
}
return '';
return '';
}
/**
@ -628,7 +651,7 @@ abstract class WC_Retailcrm_Abstracts_Settings extends WC_Integration
$response = $api->apiVersions();
if ($response == null) {
WC_Admin_Settings::add_error(esc_html__( 'Enter the correct URL of CRM', 'retailcrm'));
WC_Admin_Settings::add_error(esc_html__('Enter the correct URL of CRM', 'retailcrm'));
$value = '';
}
@ -661,7 +684,7 @@ abstract class WC_Retailcrm_Abstracts_Settings extends WC_Integration
}
if (empty($response) || !$response->isSuccessful()) {
WC_Admin_Settings::add_error( esc_html__( 'Enter the correct API key', 'retailcrm' ) );
WC_Admin_Settings::add_error(esc_html__('Enter the correct API key', 'retailcrm'));
$value = '';
}
@ -730,10 +753,12 @@ abstract class WC_Retailcrm_Abstracts_Settings extends WC_Integration
*
* @codeCoverageIgnore
*/
function add_retailcrm_button() {
function add_retailcrm_button()
{
global $wp_admin_bar;
if ( !is_super_admin() || !is_admin_bar_showing() || !is_admin())
if (!is_super_admin() || !is_admin_bar_showing() || !is_admin()) {
return;
}
$wp_admin_bar->add_menu(
array(
@ -756,7 +781,7 @@ abstract class WC_Retailcrm_Abstracts_Settings extends WC_Integration
array(
'id' => 'retailcrm_ajax_generate_setings',
'title' => __('Settings', 'retailcrm'),
'href'=> get_site_url().'/wp-admin/admin.php?page=wc-settings&tab=integration&section=integration-retailcrm',
'href' => get_site_url() . '/wp-admin/admin.php?page=wc-settings&tab=integration&section=integration-retailcrm',
'parent' => 'retailcrm_top_menu',
'class' => 'retailcrm_ajax_settings'
)

View File

@ -32,6 +32,7 @@ if (!class_exists('WC_Retailcrm_Base')) {
/**
* Init and hook in the integration.
*
* @param \WC_Retailcrm_Proxy|WC_Retailcrm_Client_V4|WC_Retailcrm_Client_V5|bool $retailcrm (default = false)
*/
public function __construct($retailcrm = false)
@ -77,6 +78,7 @@ if (!class_exists('WC_Retailcrm_Base')) {
add_action('retailcrm_inventories', array($this, 'load_stocks'));
add_action('wp_ajax_do_upload', array($this, 'upload_to_crm'));
add_action('wp_ajax_cron_info', array($this, 'get_cron_info'), 99);
add_action('wp_ajax_set_meta_fields', array($this, 'set_meta_fields'), 99);
add_action('wp_ajax_content_upload', array($this, 'count_upload_data'), 99);
add_action('wp_ajax_generate_icml', array($this, 'generate_icml'));
add_action('wp_ajax_upload_selected_orders', array($this, 'upload_selected_orders'));
@ -461,6 +463,10 @@ if (!class_exists('WC_Retailcrm_Base')) {
// Include style for debug info
wp_register_style('retailcrm-debug-info-style', $path . 'debug-info.min.css', false, '0.1');
wp_enqueue_style('retailcrm-debug-info-style');
// Include style for meta fields
wp_register_style('retailcrm-meta-fields-style', $path . 'meta-fields.min.css', false, '0.1');
wp_enqueue_style('retailcrm-meta-fields-style');
}
/**
@ -479,6 +485,9 @@ if (!class_exists('WC_Retailcrm_Base')) {
wp_register_script('retailcrm-cron-info', $path . 'retailcrm-cron-info.js', false, '0.1');
wp_enqueue_script('retailcrm-cron-info', $path . 'retailcrm-export.js', '', '', true);
wp_register_script('retailcrm-meta-fields', $path . 'retailcrm-meta-fields.js', false, '0.1');
wp_enqueue_script('retailcrm-meta-fields', $path . 'retailcrm-meta-fields.js', '', '', true);
}
/**
@ -545,33 +554,114 @@ if (!class_exists('WC_Retailcrm_Base')) {
* Return time work next cron
*/
public function get_cron_info() {
$icml = 'This option is disabled';
$history = 'This option is disabled';
$inventories = 'This option is disabled';
$defaultValue = __('This option is disabled', 'retailcrm');
$icml = $defaultValue;
$history = $defaultValue;
$inventories = $defaultValue;
$translate = array(
'tr_td_cron' => __('Cron launches', 'retailcrm'),
'tr_td_icml' => __('Generation ICML', 'retailcrm'),
'tr_td_history' => __('Syncing history', 'retailcrm'),
'tr_td_inventories' => __('Syncing inventories', 'retailcrm'),
);
if (isset($this->settings['history']) && $this->settings['history'] == static::YES) {
$history = date("H:i:s d-m-Y", wp_next_scheduled('retailcrm_history'));
$history = date( 'H:i:s d-m-Y', wp_next_scheduled('retailcrm_history'));
}
if (isset($this->settings['icml']) && $this->settings['icml'] == static::YES) {
$icml = date("H:i:s d-m-Y", wp_next_scheduled('retailcrm_icml'));
$icml = date( 'H:i:s d-m-Y', wp_next_scheduled('retailcrm_icml'));
}
if (isset($this->settings['sync']) && $this->settings['sync'] == static::YES) {
$inventories = date("H:i:s d-m-Y ", wp_next_scheduled('retailcrm_inventories'));
$inventories = date( 'H:i:s d-m-Y ', wp_next_scheduled('retailcrm_inventories'));
}
echo json_encode(
array(
'history' => $history,
'icml' => $icml,
'inventories' => $inventories
'inventories' => $inventories,
'translate' => $translate,
)
);
wp_die();
}
/**
* Set meta fields in settings
*/
public function set_meta_fields()
{
$orderMetaData = $this->getMetaData('order');
$customerMetaData = $this->getMetaData('user');
$orderCustomFields = $this->getCustomFields('order');
$customerCustomFields = $this->getCustomFields('customer');
$translate = array(
'tr_lb_order' => __('Custom fields for order', 'retailcrm'),
'tr_lb_customer' => __('Custom fields for customer', 'retailcrm'),
'tr_btn' => __('Add new select for order', 'retailcrm'),
);
echo json_encode(
array(
'order' => array('custom' => $orderCustomFields, 'meta' => $orderMetaData),
'customer' => array('custom' => $customerCustomFields, 'meta' => $customerMetaData),
'translate' => $translate,
)
);
wp_die();
}
/**
* Get custom fields with CRM
*
* @return array
*/
private function getCustomFields($entity)
{
$customFields = array('default_retailcrm' => __('Select value', 'retailcrm'));
$getCustomFields = $this->apiClient->customFieldsList(array('entity' => $entity), 100);
if (!empty($getCustomFields['customFields']) && $getCustomFields->isSuccessful()) {
foreach ($getCustomFields['customFields'] as $field) {
if (!empty($field['code']) && $field['name']) {
$customFields[$field['code']] = $field['name'];
}
}
}
return $customFields;
}
/**
* Get meta data with CMS
*
* @return array
*/
private function getMetaData($entity)
{
global $wpdb;
$table = $entity === 'order' ? $wpdb->postmeta : $wpdb->usermeta;
$metaData = array('default_retailcrm' => __('Select value', 'retailcrm'));
$sqlQuery = "SELECT DISTINCT `meta_key` FROM $table ORDER BY `meta_key`";
$defaultMetaFields = file(
__DIR__ . '/../assets/default/default_meta_fields.txt',
FILE_IGNORE_NEW_LINES
);
foreach ($wpdb->get_results($sqlQuery) as $metaValue) {
$metaData[$metaValue->meta_key] = $metaValue->meta_key;
}
return array_diff($metaData, $defaultMetaFields);
}
/**
* Get retailcrm api client
*
@ -604,7 +694,6 @@ if (!class_exists('WC_Retailcrm_Base')) {
delete_option('retailcrm_active_in_crm');
}
/**
* @param $settings
*

View File

@ -36,6 +36,9 @@ if (!class_exists('WC_Retailcrm_Customers')) :
/** @var array */
private $customerCorporateAddress = array();
/**@var array */
private $customFields = array();
/**
* WC_Retailcrm_Customers constructor.
*
@ -48,6 +51,10 @@ if (!class_exists('WC_Retailcrm_Customers')) :
$this->retailcrm = $retailcrm;
$this->retailcrm_settings = $retailcrm_settings;
$this->customer_address = $customer_address;
if (!empty($retailcrm_settings['customer-meta-data-retailcrm'])) {
$this->customFields = json_decode($retailcrm_settings['customer-meta-data-retailcrm'], true);
}
}
/**
@ -370,6 +377,16 @@ if (!class_exists('WC_Retailcrm_Customers')) :
}
}
if (!empty($this->customFields)) {
foreach ($this->customFields as $metaKey => $customKey) {
$metaValue = $customer->get_meta($metaKey);
if (!empty($metaValue)) {
$data_customer['customFields'][$customKey] = $metaValue;
}
}
}
$this->customer = apply_filters(
'retailcrm_process_customer',
WC_Retailcrm_Plugin::clearArray($data_customer),

View File

@ -161,6 +161,10 @@ if ( ! class_exists( 'WC_Retailcrm_History' ) ) :
if ($wcCustomer instanceof WC_Customer) {
$wcCustomer->save();
$customerCustomFields = $this->getCustomData('customer');
$this->updateMetaData($customerCustomFields, $crmCustomer, $wcCustomer->get_id());
}
WC_Retailcrm_Logger::debug(__METHOD__, array('Updated WC_Customer:', $wcCustomer));
@ -235,6 +239,9 @@ if ( ! class_exists( 'WC_Retailcrm_History' ) ) :
}
$wcOrder = wc_get_order($wcOrderId);
$orderCustomFields = $this->getCustomData('order');
$this->updateMetaData($orderCustomFields, $order, $wcOrderId, 'order');
if ($wcOrder instanceof WC_Order) {
$wcOrder->calculate_totals();
@ -1076,6 +1083,48 @@ if ( ! class_exists( 'WC_Retailcrm_History' ) ) :
return $handled;
}
/**
* Get custom fields mapping with settings.
*
* @param string $dataType This data type which we get.
*
* @return mixed|void
*/
private function getCustomData($dataType)
{
if (!empty($this->retailcrmSettings["$dataType-meta-data-retailcrm"])) {
return json_decode(
$this->retailcrmSettings["$dataType-meta-data-retailcrm"],
true
);
}
}
/**
* Update meta data in CMS.
*
* @param array $customFields Custom fields witch settings mapping.
* @param array $data Data witch CRM.
* @param int $idPost ID post in which we update the metadata.
* @param string $dataType Data type which to update the metadata.
*
* @return void
*/
private function updateMetaData($customFields, $data, $idPost, $dataType = 'customer')
{
if (!empty($customFields)) {
foreach ($customFields as $metaKey => $customKey) {
if (!empty($data['customFields'][$customKey])) {
if ($dataType === 'order') {
update_post_meta($idPost, $metaKey, $data['customFields'][$customKey]);
} else {
update_user_meta($idPost, $metaKey, $data['customFields'][$customKey]);
}
}
}
}
}
/**
* Returns retailCRM order by id or by externalId.
* It returns only order data, not ApiResponse or something.

View File

@ -44,6 +44,9 @@ if ( ! class_exists( 'WC_Retailcrm_Orders' ) ) :
/** @var array */
private $payment = array();
/**@var array */
private $customFields = array();
public function __construct(
$retailcrm,
$retailcrm_settings,
@ -60,6 +63,10 @@ if ( ! class_exists( 'WC_Retailcrm_Orders' ) ) :
$this->customers = $customers;
$this->orders = $orders;
$this->order_payment = $order_payment;
if (!empty($retailcrm_settings['order-meta-data-retailcrm'])) {
$this->customFields = json_decode($retailcrm_settings['order-meta-data-retailcrm'], true);
}
}
/**
@ -402,6 +409,16 @@ if ( ! class_exists( 'WC_Retailcrm_Orders' ) ) :
$order_data['payments'][] = $this->order_payment->build($order)->get_data();
}
if (!empty($this->customFields)) {
foreach ($this->customFields as $metaKey => $customKey) {
$metaValue = $order->get_meta($metaKey);
if (!empty($metaValue)) {
$order_data['customFields'][$customKey] = $metaValue;
}
}
}
$this->order = WC_Retailcrm_Plugin::clearArray($order_data);
$this->processOrderCustomerInfo($order, $update);

View File

@ -171,6 +171,10 @@ class WC_Retailcrm_History_Assembler
] = self::newValue($change['newValue']);
}
if (strripos($change['field'], 'custom_') !== false) {
$customers[$change['customer']['id']]['customFields'][str_replace( 'custom_', '', $change['field'])] = self::newValue($change['newValue']);
}
// email_marketing_unsubscribed_at old value will be null and new value will be datetime in
// `Y-m-d H:i:s` format if customer was marked as unsubscribed in retailCRM
if (isset($change['customer']['id']) && $change['field'] == 'email_marketing_unsubscribed_at') {

Binary file not shown.

Binary file not shown.

View File

@ -19,7 +19,6 @@ class WC_Retailcrm_Test_Case_Helper extends WC_Unit_Test_Case
'p_pending' => 'no',
'p_private' => 'no',
'p_publish' => 'no',
'catalog_options' => 'no',
'order_methods' => array(0 => 'phone'),
'flat_rate_shipping' => 'delivery',
'free_shipping' => 'delivery2',

View File

@ -17,12 +17,13 @@ class WC_Retailcrm_Base_Test extends WC_Retailcrm_Test_Case_Helper
$this->apiMock = $this->getMockBuilder('\WC_Retailcrm_Proxy')
->disableOriginalConstructor()
->setMethods(
array(
[
'orderMethodsList',
'deliveryTypesList',
'paymentTypesList',
'statusesList'
)
'statusesList',
'customFieldsList',
]
)
->getMock();
@ -71,7 +72,6 @@ class WC_Retailcrm_Base_Test extends WC_Retailcrm_Test_Case_Helper
$this->assertArrayHasKey('corporate_enabled', $this->baseRetailcrm->form_fields);
$this->assertArrayHasKey('online_assistant', $this->baseRetailcrm->form_fields);
$this->assertArrayHasKey('catalog_options', $this->baseRetailcrm->form_fields);
$this->assertArrayHasKey('order_methods', $this->baseRetailcrm->form_fields);
$this->assertInternalType('array', $this->baseRetailcrm->form_fields['order_methods']);
@ -278,6 +278,73 @@ class WC_Retailcrm_Base_Test extends WC_Retailcrm_Test_Case_Helper
ob_end_clean();
}
public function test_set_meta_fields()
{
$responseApiMock = $this->getMockBuilder('\WC_Retailcrm_Response_Helper')
->disableOriginalConstructor()
->setMethods(['isSuccessful'])
->getMock();
$this->setMockResponse($responseApiMock, 'isSuccessful', true);
$responseApiMock->setResponse(
[
'success' => true,
'customFields' => [
[
'name' => 'Test_Upload',
'code' => 'test_upload',
],
[
'name' => 'test123',
'code' => 'test',
],
]
]
);
$this->setMockResponse($this->apiMock, 'customFieldsList', $responseApiMock);
ob_start();
$this->baseRetailcrm->set_meta_fields();
$jsonData = $this->getJsonData(ob_get_contents());
$this->assertArrayHasKey('order', $jsonData);
$this->assertArrayHasKey('customer', $jsonData);
$this->assertArrayHasKey('translate', $jsonData);
$this->assertArrayHasKey('custom', $jsonData['order']);
$this->assertArrayHasKey('meta', $jsonData['order']);
$this->assertArrayHasKey('custom', $jsonData['customer']);
$this->assertArrayHasKey('meta', $jsonData['customer']);
$this->assertArrayHasKey('tr_lb_order', $jsonData['translate']);
$this->assertArrayHasKey('tr_lb_customer', $jsonData['translate']);
$this->assertArrayHasKey('tr_btn', $jsonData['translate']);
$this->assertArrayHasKey('default_retailcrm', $jsonData['order']['meta']);
$this->assertArrayHasKey('default_retailcrm', $jsonData['order']['custom']);
$this->assertArrayHasKey('test_upload', $jsonData['order']['custom']);
$this->assertArrayHasKey('test', $jsonData['order']['custom']);
$this->assertArrayHasKey('default_retailcrm', $jsonData['customer']['meta']);
$this->assertArrayHasKey('default_retailcrm', $jsonData['customer']['custom']);
$this->assertArrayHasKey('test_upload', $jsonData['customer']['custom']);
$this->assertArrayHasKey('test', $jsonData['customer']['custom']);
$this->assertEquals('Select value', $jsonData['order']['meta']['default_retailcrm']);
$this->assertEquals('Select value', $jsonData['order']['custom']['default_retailcrm']);
$this->assertEquals('Test_Upload', $jsonData['order']['custom']['test_upload']);
$this->assertEquals('test123', $jsonData['order']['custom']['test']);
$this->assertEquals('Select value', $jsonData['customer']['meta']['default_retailcrm']);
$this->assertEquals('Select value', $jsonData['customer']['custom']['default_retailcrm']);
$this->assertEquals('Test_Upload', $jsonData['customer']['custom']['test_upload']);
$this->assertEquals('test123', $jsonData['customer']['custom']['test']);
ob_end_clean();
}
private function getJsonData($text)
{