@@ -5660,11 +5664,11 @@ function createTableRowFormulaModal() {
$('body').append(modalHtml);
- // Добавляем обработчики для селектов
+ // Обработчики для селекторов
$("#table_row_table").on('change', function() {
const selectedTable = $(this).val();
if (selectedTable) {
- loadTableFields(selectedTable);
+ loadTableFieldsForSelector(selectedTable);
$("#table_row_field").prop('disabled', false);
} else {
$("#table_row_field").prop('disabled', true).empty().append('');
@@ -5791,6 +5795,9 @@ function openTableRowFormulaModal(frm, formulaId = null) {
$("#table_row_field").val(formula.field_name);
$("#table_row_index").val(formula.row_index);
+ // Загружаем порядок выполнения (если существует, иначе значение по умолчанию 10)
+ $("#table_row_order").val(formula.order || 10);
+
// Заполняем формулу и триггеры
parseAndRenderFormula($resultContainer, formula.formula, true);
parseAndRenderTriggers($triggerContainer, formula.triggers);
@@ -5839,7 +5846,7 @@ function openTableRowFormulaModal(frm, formulaId = null) {
const formula = getFormulaText($resultContainer);
const triggers = getTriggerFieldsText($triggerContainer);
- // Сохраняем формулу
+ // Сохраняем формулу со всеми необходимыми данными, включая порядок
saveTableRowFormula(frm, {
table_name: tableName,
field_name: fieldName,
@@ -5850,7 +5857,7 @@ function openTableRowFormulaModal(frm, formulaId = null) {
$modal.modal('hide');
});
-
+
// Обработчик для кнопки "При открытии документа"
$modal.find('.add-predefined-event').off('click').on('click', function() {
addTokenToTriggers("При открытии документа", $triggerContainer, 'event');
@@ -6341,7 +6348,13 @@ function saveTableRowFormula(frm, formulaData, formulaId = null) {
try {
let tableRowFormulas = JSON.parse(frm.doc.table_row_formulas_storage || "{}");
- // Сохраняем формулу
+ // Получаем значение порядка из интерфейса
+ const order = parseInt($("#table_row_order").val()) || 10;
+
+ // Добавляем порядок в данные формулы
+ formulaData.order = order;
+
+ // Сохраняем новую или обновленную формулу
tableRowFormulas[newFormulaId] = formulaData;
// Обновляем значение в форме
@@ -6383,6 +6396,7 @@ function renderTableRowFormulas(frm) {
Табличная часть |
Поле |
Строка |
+ Порядок |
Формула |
Обновлять при изменении |
Действия |
@@ -6403,6 +6417,7 @@ function renderTableRowFormulas(frm) {
${formula.table_name} |
${formula.field_name} |
${formula.row_index} |
+ ${formula.order || 10} |
${formula.formula} |
${formula.triggers || '-'} |
@@ -6874,64 +6889,79 @@ function generateTableRowFormulasHandlers(table_row_formulas, functions, target_
let initFunction = `
// Функция для инициализации формул строк табличных частей
function initialize_table_row_formulas(frm) {
-
- // Получаем информацию о формулах для строк табличных частей
- const formulas = JSON.parse(frm.doc.table_row_formulas_storage || "{}");
-
- // Группируем формулы по табличным частям
- const formulasByTable = {};
- Object.keys(formulas).forEach(formulaId => {
- const formula = formulas[formulaId];
- const tableName = formula.table_name;
+ try {
+ // Получаем информацию о формулах для строк табличных частей
+ const formulas = JSON.parse(frm.doc.table_row_formulas_storage || "{}");
- if (!formulasByTable[tableName]) {
- formulasByTable[tableName] = [];
- }
+ // ВАЖНО: Преобразуем объект в массив и сортируем его по порядку выполнения
+ const sortedFormulas = Object.entries(formulas).map(([id, formula]) => {
+ return { id, ...formula };
+ }).sort((a, b) => {
+ // Сортировка по значению поля order (если порядок не задан, используем 10 по умолчанию)
+ const orderA = a.order !== undefined ? parseInt(a.order) : 10;
+ const orderB = b.order !== undefined ? parseInt(b.order) : 10;
+ return orderA - orderB;
+ });
- formulasByTable[tableName].push(formula);
- });
-
- // Устанавливаем обработчики для каждой табличной части
- Object.keys(formulasByTable).forEach(tableName => {
- if (!frm.doc[tableName]) {
- return;
- }
+ // Группируем формулы по табличным частям и строкам
+ const formulasByTableAndRow = {};
- rowFormulas.forEach(async formula => {
- try {
- // Проверяем, нужен ли асинхронный вызов
- const usesUniversal = formula.formula && formula.formula.includes("univ(");
- const usesReports = formula.formula && formula.formula.includes("report(");
-
- // Всегда используем явный вызов calculate_table_row_field
- await calculate_table_row_field(frm, tableName, rowIndex, formula.field_name, formula.formula, "refresh");
- } catch (error) {
- }
- });
+ sortedFormulas.forEach(formula => {
+ const tableName = formula.table_name;
+ const rowIndex = parseInt(formula.row_index);
- // Вычисляем формулы для строки только если у них есть триггер "При открытии документа"
- rowFormulas.forEach(formula => {
- try {
- // Проверяем, нужен ли асинхронный вызов
- const usesUniversal = formula.formula && formula.formula.includes("univ(");
- const usesReports = formula.formula && formula.formula.includes("report(");
-
- if (usesUniversal || usesReports) {
- // Используем setTimeout для асинхронных вызовов, чтобы не блокировать процесс
- setTimeout(async () => {
- try {
- await calculate_table_row_field(frm, tableName, rowIndex, formula.field_name, formula.formula, "refresh");
- } catch (error) {
- }
- }, 0);
- } else {
- // Синхронный вызов для обычных формул
- calculate_table_row_field(frm, tableName, rowIndex, formula.field_name, formula.formula, "refresh");
+ if (!formulasByTableAndRow[tableName]) {
+ formulasByTableAndRow[tableName] = {};
+ }
+
+ if (!formulasByTableAndRow[tableName][rowIndex]) {
+ formulasByTableAndRow[tableName][rowIndex] = [];
+ }
+
+ formulasByTableAndRow[tableName][rowIndex].push(formula);
+ });
+
+ // Устанавливаем обработчики для каждой табличной части
+ Object.keys(formulasByTableAndRow).forEach(tableName => {
+ if (!frm.doc[tableName]) {
+ return;
+ }
+
+ // Для каждой строки таблицы
+ frm.doc[tableName].forEach((row, rowIdx) => {
+ // Получаем отсортированные формулы для текущей строки (строки нумеруются с 1, а индексы с 0)
+ const rowFormulas = formulasByTableAndRow[tableName][rowIdx + 1] || [];
+
+ // Выполняем формулы в порядке сортировки (по полю order)
+ for (const formula of rowFormulas) {
+ try {
+ // Определяем необходимость асинхронного вызова
+ const usesUniversal = formula.formula && formula.formula.includes("univ(");
+ const usesReports = formula.formula && formula.formula.includes("report(");
+
+ // Вызываем расчет формулы согласно установленному порядку
+ if (usesUniversal || usesReports) {
+ // Для асинхронных вызовов используем await в асинхронной IIFE
+ (async () => {
+ try {
+ await calculate_table_row_field(frm, tableName, rowIdx, formula.field_name, formula.formula, "refresh");
+ } catch (asyncError) {
+ console.error("Ошибка при асинхронном расчете формулы (порядок " + (formula.order || 10) + "):", asyncError);
+ }
+ })();
+ } else {
+ // Для синхронных вызовов выполняем напрямую
+ calculate_table_row_field(frm, tableName, rowIdx, formula.field_name, formula.formula, "refresh");
+ }
+ } catch (error) {
+ console.error("Ошибка расчета формулы для " + tableName + "[" + rowIdx + "]." + formula.field_name + " (порядок " + (formula.order || 10) + "):", error);
}
- } catch (error) {
}
});
});
+ } catch (error) {
+ console.error("Ошибка инициализации формул строк табличных частей:", error);
+ }
}`;
functions.push(initFunction);
@@ -9042,12 +9072,28 @@ function deleteReportField(frm, fieldId) {
);
}
+// Обработка формул строк таблиц для генерации клиентского скрипта
function processTableRowFormulas(table_row_formulas, table_doctypes) {
// Хранилище для объединенных обработчиков
const triggerHandlers = {};
+ // Проверяем, что объект table_row_formulas не пустой
+ if (!table_row_formulas || Object.keys(table_row_formulas).length === 0) {
+ return triggerHandlers;
+ }
+
+ // Получаем отсортированные формулы по порядку выполнения
+ const sortedFormulas = Object.entries(table_row_formulas).map(([id, formula]) => {
+ return { id, ...formula };
+ }).sort((a, b) => {
+ // Сортировка по значению поля order (если порядок не задан, используем 10 по умолчанию)
+ const orderA = a.order !== undefined ? parseInt(a.order) : 10;
+ const orderB = b.order !== undefined ? parseInt(b.order) : 10;
+ return orderA - orderB;
+ });
+
// Группируем формулы по триггерам
- Object.values(table_row_formulas).forEach(formula => {
+ sortedFormulas.forEach(formula => {
const tableName = formula.table_name;
const rowIndex = parseInt(formula.row_index);
const usesUniversal = formula.formula && formula.formula.includes("univ(");
@@ -9075,9 +9121,9 @@ function processTableRowFormulas(table_row_formulas, table_doctypes) {
triggerHandlers[trigger].isAsync = true;
}
- // Код для вычисления формулы
+ // Код для вычисления формулы, с учетом порядка выполнения
const handlerCode = `
- // Проверяем строку ${rowIndex} в таблице ${tableName}
+ // Формула строки ${rowIndex} в таблице ${tableName} (порядок: ${formula.order || 10})
if (frm.doc.${tableName} && frm.doc.${tableName}.length >= ${rowIndex}) {
try {
// Индекс строки на 1 меньше номера строки
@@ -9086,6 +9132,7 @@ function processTableRowFormulas(table_row_formulas, table_doctypes) {
${usesUniversal || usesReports ? 'await ' : ''}calculate_table_row_field(frm, "${tableName}", rowIndex, "${formula.field_name}", formula, "${trigger}");
} catch (error) {
+ console.error("Ошибка вычисления формулы для ${tableName}[${rowIndex - 1}].${formula.field_name}:", error);
}
}`;
@@ -9096,7 +9143,7 @@ function processTableRowFormulas(table_row_formulas, table_doctypes) {
// Добавляем обработчики для событий add_row и remove_row для каждой таблицы
const tables = new Set();
- Object.values(table_row_formulas).forEach(formula => {
+ sortedFormulas.forEach(formula => {
tables.add(formula.table_name);
});
|