From 0d6841402d4c3a99e204d234f16546c7028ceec6 Mon Sep 17 00:00:00 2001 From: Ali <010109ali@gmail.com> Date: Thu, 28 Aug 2025 15:54:01 +0400 Subject: [PATCH] New order column (test) --- .../doctype/formula_editor/formula_editor.js | 65 +++++++++++++++---- formula_editor/hooks.py | 6 ++ formula_editor/public/js/formula_editor_ui.js | 16 ++++- 3 files changed, 72 insertions(+), 15 deletions(-) diff --git a/formula_editor/formula_editor/doctype/formula_editor/formula_editor.js b/formula_editor/formula_editor/doctype/formula_editor/formula_editor.js index 99971d6..a96b0c5 100644 --- a/formula_editor/formula_editor/doctype/formula_editor/formula_editor.js +++ b/formula_editor/formula_editor/doctype/formula_editor/formula_editor.js @@ -109,20 +109,31 @@ frappe.require([ function restore_formulas(frm) { let stored_formulas = JSON.parse(frm.doc.formula_storage || "{}"); - $(frm.fields_dict.formula_fields.wrapper).find('.formula-input, .trigger-input').each(function() { + $(frm.fields_dict.formula_fields.wrapper).find('.formula-input, .trigger-input, .order-input').each(function() { let fieldname = $(this).attr("data-fieldname"); if (!fieldname) { return; } let isTriggerField = fieldname.endsWith("_triggers"); - let baseFieldname = isTriggerField ? fieldname.replace("_triggers", "") : fieldname; + let isOrderField = fieldname.endsWith("_order"); + let baseFieldname = isTriggerField ? fieldname.replace("_triggers", "") : + isOrderField ? fieldname.replace("_order", "") : fieldname; if (stored_formulas[baseFieldname] !== undefined) { - let value = isTriggerField ? stored_formulas[baseFieldname].triggers : stored_formulas[baseFieldname].formula; + let value; + if (isTriggerField) { + value = stored_formulas[baseFieldname].triggers; + } else if (isOrderField) { + value = stored_formulas[baseFieldname].order || 10; + } else { + value = stored_formulas[baseFieldname].formula; + } - if (typeof value !== "string") { - return; + if (isTriggerField || (!isTriggerField && !isOrderField)) { + if (typeof value !== "string") { + return; + } } $(this).val(value); } @@ -163,6 +174,10 @@ frappe.require([ // Получаем триггерное поле let triggers = $(frm.fields_dict.formula_fields.wrapper) .find(`[data-fieldname="${fieldname}_triggers"] input`).val(); + + // Получаем поле порядка + let order = $(frm.fields_dict.formula_fields.wrapper) + .find(`[data-fieldname="${fieldname}_order"] input`).val(); // Проверяем, что формула или триггеры не пустые if (formula.trim() !== "" || (triggers && triggers.trim() !== "")) { @@ -170,13 +185,24 @@ frappe.require([ formula_data[fieldname] = { formula: formula || "", triggers: triggers || "", - is_table_field: is_table_field + is_table_field: is_table_field, + order: order ? parseInt(order) : 10 }; } }); frm.set_value("formula_storage", JSON.stringify(formula_data)); } + // Вспомогательная функция для извлечения порядка из строки обработчика + function extractOrderFromHandler(handlerCode) { + // Ищем комментарий с порядком в строке обработчика + const orderMatch = handlerCode.match(/\/\/ order: (\d+)/); + if (orderMatch) { + return parseInt(orderMatch[1]); + } + return 10; // значение по умолчанию + } + // Генерация клиентского скрипта function generate_client_script(frm) { if (!frm.doc.target_doctype) { @@ -504,8 +530,8 @@ frappe.require([ triggerHandlers[trigger].isAsync = true; } - // Добавляем вызов функции расчета - triggerHandlers[trigger].handlers.push(`await calculate_${fieldname}(frm);`); + // Добавляем вызов функции расчета с информацией о порядке + triggerHandlers[trigger].handlers.push(`await calculate_${fieldname}(frm); // order: ${field_info.order || 10}`); } }); } @@ -540,8 +566,15 @@ frappe.require([ refreshHandlerBody += ` await calculate_universal_fields(frm);\n`; } + // Сортируем обработчики refresh по порядку + const sortedRefreshHandlers = refreshHandlers.slice().sort((a, b) => { + const orderA = formula_data[a.field] ? (formula_data[a.field].order || 10) : 10; + const orderB = formula_data[b.field] ? (formula_data[b.field].order || 10) : 10; + return orderA - orderB; + }); + // Добавляем вызовы для каждого поля с триггером "При открытии документа" - refreshHandlers.forEach(handler => { + sortedRefreshHandlers.forEach(handler => { if (!handler.type || handler.type !== 'table_row') { refreshHandlerBody += ` ${needsAsync && handler.uses_universal ? 'await ' : ''}calculate_${handler.field}(frm);\n`; } @@ -616,7 +649,7 @@ frappe.require([ ); if (!hasUniversalCall) { - triggerHandlers[field].handlers.unshift('await calculate_universal_fields(frm);'); + triggerHandlers[field].handlers.unshift('await calculate_universal_fields(frm); // order: 0'); } }); } @@ -633,8 +666,16 @@ frappe.require([ } } - // Добавляем все обработчики - handler.handlers.forEach(handlerCode => { + // Сортируем обработчики по порядку выполнения + const sortedHandlers = handler.handlers.slice().sort((a, b) => { + // Извлекаем порядок из строки обработчика + const orderA = extractOrderFromHandler(a) || 10; + const orderB = extractOrderFromHandler(b) || 10; + return orderA - orderB; + }); + + // Добавляем отсортированные обработчики + sortedHandlers.forEach(handlerCode => { main_script += ` ${handlerCode}\n`; }); diff --git a/formula_editor/hooks.py b/formula_editor/hooks.py index 932f951..09c738d 100644 --- a/formula_editor/hooks.py +++ b/formula_editor/hooks.py @@ -28,6 +28,12 @@ doctype_js = { "Formula Editor": "formula_editor/doctype/formula_editor/formula_editor_main.js", } +fixtures = [ + { + "doctype": "Formula Editor" + } +] + # include js in doctype list views # doctype_list_js = {"doctype" : "public/js/doctype_list.js"} diff --git a/formula_editor/public/js/formula_editor_ui.js b/formula_editor/public/js/formula_editor_ui.js index 945e603..8f237bf 100644 --- a/formula_editor/public/js/formula_editor_ui.js +++ b/formula_editor/public/js/formula_editor_ui.js @@ -139,8 +139,8 @@ function addTokenStyles() { } function createFormulaFieldHtml(field, dataAttr) { - return $('