From 5a480f0b31da46ad60a469d0a696b0bc20bd5ba0 Mon Sep 17 00:00:00 2001 From: Dima Uryvskiy Date: Thu, 30 Dec 2021 11:22:34 +0300 Subject: [PATCH] Add mapping metadata fields in settings --- doc/1.Setup/Custom fields settings.md | 20 ++ resources/pot/retailcrm-es_ES.pot | 33 ++ resources/pot/retailcrm-ru_RU.pot | 33 ++ src/assets/css/meta-fields.css | 59 ++++ src/assets/css/meta-fields.min.css | 1 + src/assets/css/progress-bar.css | 2 +- src/assets/css/progress-bar.min.css | 6 +- src/assets/default/default_meta_fields.txt | 180 ++++++++++ src/assets/js/retailcrm-cron-info.js | 18 +- src/assets/js/retailcrm-export.js | 12 +- src/assets/js/retailcrm-meta-fields.js | 323 ++++++++++++++++++ .../class-wc-retailcrm-abstracts-settings.php | 93 +++-- src/include/class-wc-retailcrm-base.php | 105 +++++- src/include/class-wc-retailcrm-customers.php | 17 + src/include/class-wc-retailcrm-history.php | 49 +++ src/include/class-wc-retailcrm-orders.php | 17 + .../class-wc-retailcrm-history-assembler.php | 4 + src/languages/retailcrm-es_ES.mo | Bin 8295 -> 8953 bytes src/languages/retailcrm-ru_RU.mo | Bin 10151 -> 11017 bytes .../class-wc-retailcrm-test-case-helper.php | 1 - tests/test-wc-retailcrm-base.php | 75 +++- 21 files changed, 987 insertions(+), 61 deletions(-) create mode 100644 doc/1.Setup/Custom fields settings.md create mode 100644 src/assets/css/meta-fields.css create mode 100644 src/assets/css/meta-fields.min.css create mode 100644 src/assets/default/default_meta_fields.txt create mode 100644 src/assets/js/retailcrm-meta-fields.js diff --git a/doc/1.Setup/Custom fields settings.md b/doc/1.Setup/Custom fields settings.md new file mode 100644 index 0000000..7b22957 --- /dev/null +++ b/doc/1.Setup/Custom fields settings.md @@ -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 доступные пользовательские поля можно увидеть перейдя в **Настройки - Системные - Пользовательские поля.** + diff --git a/resources/pot/retailcrm-es_ES.pot b/resources/pot/retailcrm-es_ES.pot index b2e7d42..79328cd 100644 --- a/resources/pot/retailcrm-es_ES.pot +++ b/resources/pot/retailcrm-es_ES.pot @@ -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" + diff --git a/resources/pot/retailcrm-ru_RU.pot b/resources/pot/retailcrm-ru_RU.pot index 2c4e3f7..99e428e 100644 --- a/resources/pot/retailcrm-ru_RU.pot +++ b/resources/pot/retailcrm-ru_RU.pot @@ -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 "Синхронизация запасов" + diff --git a/src/assets/css/meta-fields.css b/src/assets/css/meta-fields.css new file mode 100644 index 0000000..f4e7e4b --- /dev/null +++ b/src/assets/css/meta-fields.css @@ -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; } +} \ No newline at end of file diff --git a/src/assets/css/meta-fields.min.css b/src/assets/css/meta-fields.min.css new file mode 100644 index 0000000..856d60b --- /dev/null +++ b/src/assets/css/meta-fields.min.css @@ -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}} \ No newline at end of file diff --git a/src/assets/css/progress-bar.css b/src/assets/css/progress-bar.css index 5b05629..12534e8 100644 --- a/src/assets/css/progress-bar.css +++ b/src/assets/css/progress-bar.css @@ -21,7 +21,7 @@ box-sizing: border-box; } -.retail-hidden { +.retailcrm-hidden { display: none !important; } diff --git a/src/assets/css/progress-bar.min.css b/src/assets/css/progress-bar.min.css index b8539e1..d109360 100644 --- a/src/assets/css/progress-bar.min.css +++ b/src/assets/css/progress-bar.min.css @@ -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} \ No newline at end of file +<<<<<<< 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 diff --git a/src/assets/default/default_meta_fields.txt b/src/assets/default/default_meta_fields.txt new file mode 100644 index 0000000..f237e8f --- /dev/null +++ b/src/assets/default/default_meta_fields.txt @@ -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 diff --git a/src/assets/js/retailcrm-cron-info.js b/src/assets/js/retailcrm-cron-info.js index 44d10d0..40c6bbe 100644 --- a/src/assets/js/retailcrm-cron-info.js +++ b/src/assets/js/retailcrm-cron-info.js @@ -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(''); this.infoTable = jQuery('tbody[class="retail-debug-info"]').get(0); - jQuery(this.infoTable).append("" + "Cron launches:" + ""); - jQuery(this.infoTable).append("" + "History: " + this.history + ""); - jQuery(this.infoTable).append("" + "Icml: " + this.icml + ""); - jQuery(this.infoTable).append("" + "Inventories: " + this.inventories + ""); + jQuery(this.infoTable).append("" + cron + " : " + ""); + jQuery(this.infoTable).append("" + icml + " : " + this.icml + ""); + jQuery(this.infoTable).append("" + history + " : " + this.history + ""); + jQuery(this.infoTable).append("" + inventories + " : " + this.inventories + ""); } window.RetailcrmCronInfo = RetailcrmCronInfo; diff --git a/src/assets/js/retailcrm-export.js b/src/assets/js/retailcrm-export.js index 31d856d..4f44c8e 100644 --- a/src/assets/js/retailcrm-export.js +++ b/src/assets/js/retailcrm-export.js @@ -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('
', {class: 'retail-progress__loader', text: '0%'})) window.addEventListener('beforeunload', this.confirmLeave); diff --git a/src/assets/js/retailcrm-meta-fields.js b/src/assets/js/retailcrm-meta-fields.js new file mode 100644 index 0000000..4504d54 --- /dev/null +++ b/src/assets/js/retailcrm-meta-fields.js @@ -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('') + 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( + `
` + + `
` + + `` + + `` + ); + + 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( + `
` + + `` + + `` + + `
` + ); + + 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('') + .attr('value', key) + .text(value)); + }); + + // Set custom fields in select + jQuery.each(data.custom, function(key, value) { + jQuery(`#customFields-${entity}-${index}`) + .append(jQuery('') + .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(); + } +}); diff --git a/src/include/abstracts/class-wc-retailcrm-abstracts-settings.php b/src/include/abstracts/class-wc-retailcrm-abstracts-settings.php index 464d60e..a487577 100644 --- a/src/include/abstracts/class-wc-retailcrm-abstracts-settings.php +++ b/src/include/abstracts/class-wc-retailcrm-abstracts-settings.php @@ -1,4 +1,5 @@ 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(); ?> - - get_tooltip_html( $data ); ?> + + get_tooltip_html($data); ?>
- - - get_description_html( $data ); ?> + + + get_description_html($data); ?>
@@ -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(); ?> -

- -

+

+ +

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§ion=integration-retailcrm', + 'href' => get_site_url() . '/wp-admin/admin.php?page=wc-settings&tab=integration§ion=integration-retailcrm', 'parent' => 'retailcrm_top_menu', 'class' => 'retailcrm_ajax_settings' ) diff --git a/src/include/class-wc-retailcrm-base.php b/src/include/class-wc-retailcrm-base.php index 19b4f0b..065299e 100644 --- a/src/include/class-wc-retailcrm-base.php +++ b/src/include/class-wc-retailcrm-base.php @@ -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 * diff --git a/src/include/class-wc-retailcrm-customers.php b/src/include/class-wc-retailcrm-customers.php index 8e02727..b72f526 100644 --- a/src/include/class-wc-retailcrm-customers.php +++ b/src/include/class-wc-retailcrm-customers.php @@ -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), diff --git a/src/include/class-wc-retailcrm-history.php b/src/include/class-wc-retailcrm-history.php index 597b4d8..8cf6b5d 100644 --- a/src/include/class-wc-retailcrm-history.php +++ b/src/include/class-wc-retailcrm-history.php @@ -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. diff --git a/src/include/class-wc-retailcrm-orders.php b/src/include/class-wc-retailcrm-orders.php index 1348bde..572750a 100644 --- a/src/include/class-wc-retailcrm-orders.php +++ b/src/include/class-wc-retailcrm-orders.php @@ -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); diff --git a/src/include/components/class-wc-retailcrm-history-assembler.php b/src/include/components/class-wc-retailcrm-history-assembler.php index 82d1b62..9628ca2 100644 --- a/src/include/components/class-wc-retailcrm-history-assembler.php +++ b/src/include/components/class-wc-retailcrm-history-assembler.php @@ -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') { diff --git a/src/languages/retailcrm-es_ES.mo b/src/languages/retailcrm-es_ES.mo index 88c78bea40e8f348573908c174c34d1582173fc9..5d48b5fbe8e65e8f7c23b6a0752b5641271e7fa7 100644 GIT binary patch delta 2669 zcmaLY4QN$m9LMozQ`=^`&ACmdGmrVQ%$KQcrKwZ5)Xg@R&S|Ez&h9TD6)tMGr}$kmJwz~IWt%gT451{pcE8kFZA~P-FvQJMGyPm&vRbx^YVY5 z=kD_2Uzf%&6%BsMP}+%dV)`Is9>WDU@jBd>Zk(M z&I;5(HlW_`#Syp<`7_=tdXRO4(uof#x zhdT681KEo!@paTd|3nR}l-X!P6?_z6H4dYHvoyG|8uf+t;Ceew;rel$iAQldeue62 zIMbMevyfXRgzBg}xbDL$uJ@r<^9&Z@IV{F6F|IHENM$BwGb}YQ8}(u>Hef3<3G+N^ zj~qdk(|m|(XaKczmr+adNANs{#`Inxs-H5f#0s2*>k7#~@0uOl7>Rpv1|Gr+JdbPf z8ZN^o7E&2HfaCB8X5(38HOxoItL7qV##d08`X0w)F|(SBRmhx8XA$|=%y)336kkQn zc0(cWHH>STof<-vvD0;Uo+c-cj5tT#(va*#&QO4$N9J# zJ5U2Yfn+LfKBuBoUPaC97gS1f7_P2Mkja`!NSkIpR$?ov!<{%6Pog^d30I=UPE`gy z)C6~;CUg+*$M-Qu=YKpq=@xEOAbp!HZQaGB0A$w*OF2GLIS{>#?sXT|D;@7Cn zbAncs(sP)FwM3?@qoO0Ml1*$R8VTl>8YFA45>JgtwFcroRf1B7)r5WzRt5Jm(Es%^ zjhY6l--i}L8BtN@w2UhHEm%V+?U}NkN~P9cMd?*hHfji^?Lk6Cn~4dgmS_oT4R0e< zn$n~`b?hD@?j^KLtd40T783cyB0^cy@tZ^NkJgj~{ijZVcJn-93bB}2L8vSzELAAl zXtM|{lZy6BrZiL8K^5(dK)A&~enh(J8r`m`~^gv?q4vyjQg(9JZp)BUa3bIH4Y^!}G0BZ>-1bbbRw4 z&pbcu_=)=5{Y}0XwIX(JG_=KunYz?htPaY5sp)x$<-=cR_V)sFNg8uAAwwrq=r+~{U&i^~}OZ6J zDbFphE7cUWup6`6BThJ(U)VReV9DvDcGzWlX%kNtACIrGeaGfS#|kkqQ)hQ}c`>WY z@nc@pj=0*x;EIt2_dpa3q zBoQlQ_ndwq;%)YlQ_8Mpk8IHrg~*O=^+qjH;`xcf@^=!u%ZsK)f{eI!#I(3kO@cvZ jnzGXAv3=J|o-ZGfHL|%Y^C)JAdfcsc*iK#=wMic#QZl9zqrmmT_PVmWRM!c%8#oJcQ%$Fg}DwFo~z|5gdu`|AJGw z{vF#fQ4vBP_M*?fhYvf|=bY4W;|x~f74(NU(FezH(-+s^qc|6<1i=H!*>C z(agj+cwL1)-+-zR8##GC-d+c`oaVUC#XlSTRF_fP8@?7oPc|A626K2 zg&_`3a2);pPv~=hVlT!>lOXlAmPIWZ--&>G*1 zu48-x%oUP28=KLI(zp=cMkhFj1Nb+xhp?P))Sac#jqJqd@B`#uLAZ+z_yGCKhFbDt zs@m{r?2fMYq0RFazKlna@`h?!*cVMhCu%|OFGZVoJ(7g*0@`f5(9&el%nc&d3&Ys$ z_y0X7rg##wZNe_>!4J_|UPrsPjAfgl3gjmtg=N@=Hg7vx!Yycq4j^j|XR#Bnq9v%M zK4z)|FEM{u$B9kR+*nLm2gbPeWvu@Y1Y|tgd=;(6AHcKsG zGuhFpTu;R}xh0i{@(p9Rl;qzSUlY$APkfgfO8%2SR=vM8w>Whw|9s7jlKiH++wt5` UYFutx!^wRA))D&_;q5ri@y5i=iA!SGppD9vYqd(@lPOI^TpmN)n#WIiO^ ztlXM&<#H|mz%D3*iM8BZTXW|!o7v3PnwzWTA8qd0HYN$1upgep0eA-c<9Qs8m%Q=~%%J=`4#WGH zgJ~(o%)|m5iMx^KVbefnIX6z@K>Q0c@e!)x5PD6;DV{|*g7R{F4tF9|O&HZtBdVQq z=nf23{|0Jce1LdOAE6(=!|^zg>1#zc;AAYvVr)Wn zcpWv6d$7Y+38&)( zv{Ch%aVoYURn1*ghY!4R5{*xzoQc}qr5GMWW;K~1=tI4@A17f0s(}lrdRK7?{)`&% zSRU%k6d>DdR-)QjkJ`cjYHRAf=SMtGp!zvAkoBKT<{UT1;w_|YlfXs|#tfW@dH6i8 z#dUZ9OR*cZQo|YDC@jEUScdGDS%WlbwxVWSg*pp+Q7hIoi1p7V)5?t*cpX_SlS=Pe zfh-(~%TP0_zz*DpR5gW6S6fhuH3`O4qgLiFm32n$quzgr8psd|<1i0(*2=;~ynsNklF^O+T109b=xDj8(lcvgUKtKsr%p;YaWOLwtd9CZk)8MW~4!$Hmy{ z`4AUTF16w-atv$q{a+)aEhyol7j0x@rV%x>4%D9Jb7ID0A*#b|$Ry1ndP8+CS4Iq@Uu-&kbS@f_6WvK={J<_*+d9rQekn$f4If!slDQAS?e z*|>wUjatzk@G$ntXIrodSzI%i<ilmW)H|u1G)c zfjZ~>xZk*Ll@hNL3soS|znivk)gfiP?ts+!cETc*w#4D8^(X0IJ)Ra(SV`y{tRglM znyHq%j95%)CQ8|H+-ninxkPX89y{P}VYyd+8Ffgt4N6PB{@tHd-B?3t>6GRZ+UHba zCZVKd=fJzaQtA@Z7ui8OR9@q!!s`-7GK;7)6opD~8^o1U^ixYrJH$8T3h8qyyO<+)Y$rrQ)bpTD}i zB4GQX2L=}Ru|9OVobyhL^R?3+tB)Nq&Qmv{oteoA<4#lKyweq{cUoe{VvSC_(`Gpx zvG;iSlI2|FX)8|}oc747JgXniF7u=__JNAl|3!;x+~rlLQ*Ahx)S@blenurV+d*LT z+oAb=b0T`fX`|bg*!zsvZKy>}&|H@jrQV&aM~PN*>@cHMJ?5m5UgR|mPp{K$^fzlk zLgc}ik^S3ab=2rm&B&KyvQyOMWvbRivvOJ!vQ9addpgqG88x$yH`5ZmmU}btKg2KG A6aWAK delta 2054 zcmZYAS!_&E9LMqhbgwF1P)n<=wuhJo}}j&-Pxw{p-xd%g2xIGppd7>8j@!?)N2zaSq=W;;r-AL{vO zsQVUS9j?KkVt$1NyKhfW9fVOK`H1YEC9*7ipYEB78lV76(U1AK42y9$7UE@W!Z1$8 z3TBaoTQLgTQrLfX(~fgNGd#;dD{4o@xC6B#FEJZ`;z-OU@XXBuSc1*i3y+{CejeNL zHfqJ&IcSGlalOy%2C~`a@4@~n_SGy~9ZW^Wuq8Mc*P@cB4V6@vu^ykJAM+V)83u42 zUdKEvqccrxE{?-ps0rV~D(pm!(=|wD=z%QM0~6347?pf&sFh#DIrtcBa1ifS3%1}Q ze1<2`&qKBN5H&zAwy^>WaWyW+GQ5l0$>4Vy+h|m<%pvF?mn@8oWnWPfNhMJf(<0RM zIXDPga26iIsrb&blt546d=rkxo46jWe`F^&APW!LQ5u@jHPnjUqhb?a*+sY3zZX{s1Eh3(dZ+ls1BQnhdSJhTy`g+q~vY0N~%h91RH^LWAmt!shXG;8Jx|5 z1-b*5qheo5<;`*9HWyWfQ?>d8DiLyj!<7#zO3dFy@4t#-ucA<@G*Pwc2C5dTkWN$l zwe>TpEXw^=0{72oq8eVAfJ(9?s z@&C6FHn*g6tfkJU2B=CRm6!E10PD&$YOA1X-wMtR-m~I diff --git a/tests/helpers/class-wc-retailcrm-test-case-helper.php b/tests/helpers/class-wc-retailcrm-test-case-helper.php index e48539f..0520e11 100644 --- a/tests/helpers/class-wc-retailcrm-test-case-helper.php +++ b/tests/helpers/class-wc-retailcrm-test-case-helper.php @@ -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', diff --git a/tests/test-wc-retailcrm-base.php b/tests/test-wc-retailcrm-base.php index e5fb277..e23dcad 100644 --- a/tests/test-wc-retailcrm-base.php +++ b/tests/test-wc-retailcrm-base.php @@ -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) {