Added order in row formulas
This commit is contained in:
parent
022c809acc
commit
1699e76dcc
|
|
@ -5598,18 +5598,22 @@ function createTableRowFormulaModal() {
|
|||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="row mb-3">
|
||||
<div class="col-md-4">
|
||||
<div class="col-md-3">
|
||||
<label for="table_row_table">Табличная часть:</label>
|
||||
<select id="table_row_table" class="form-control"></select>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="col-md-3">
|
||||
<label for="table_row_field">Поле:</label>
|
||||
<select id="table_row_field" class="form-control" disabled></select>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="col-md-3">
|
||||
<label for="table_row_index">Номер строки:</label>
|
||||
<input type="number" id="table_row_index" class="form-control" min="1" value="1">
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label for="table_row_order">Порядок выполнения:</label>
|
||||
<input type="number" id="table_row_order" class="form-control" min="0" value="10">
|
||||
</div>
|
||||
</div>
|
||||
<div class="formula-workspace">
|
||||
<div class="formula-result-container">
|
||||
|
|
@ -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('<option value="">Выберите поле</option>');
|
||||
|
|
@ -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,
|
||||
|
|
@ -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) {
|
|||
<th>Табличная часть</th>
|
||||
<th>Поле</th>
|
||||
<th>Строка</th>
|
||||
<th>Порядок</th>
|
||||
<th>Формула</th>
|
||||
<th>Обновлять при изменении</th>
|
||||
<th>Действия</th>
|
||||
|
|
@ -6403,6 +6417,7 @@ function renderTableRowFormulas(frm) {
|
|||
<td>${formula.table_name}</td>
|
||||
<td>${formula.field_name}</td>
|
||||
<td>${formula.row_index}</td>
|
||||
<td>${formula.order || 10}</td>
|
||||
<td>${formula.formula}</td>
|
||||
<td>${formula.triggers || '-'}</td>
|
||||
<td>
|
||||
|
|
@ -6874,64 +6889,79 @@ function generateTableRowFormulasHandlers(table_row_formulas, functions, target_
|
|||
let initFunction = `
|
||||
// Функция для инициализации формул строк табличных частей
|
||||
function initialize_table_row_formulas(frm) {
|
||||
|
||||
try {
|
||||
// Получаем информацию о формулах для строк табличных частей
|
||||
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;
|
||||
// ВАЖНО: Преобразуем объект в массив и сортируем его по порядку выполнения
|
||||
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;
|
||||
});
|
||||
|
||||
if (!formulasByTable[tableName]) {
|
||||
formulasByTable[tableName] = [];
|
||||
// Группируем формулы по табличным частям и строкам
|
||||
const formulasByTableAndRow = {};
|
||||
|
||||
sortedFormulas.forEach(formula => {
|
||||
const tableName = formula.table_name;
|
||||
const rowIndex = parseInt(formula.row_index);
|
||||
|
||||
if (!formulasByTableAndRow[tableName]) {
|
||||
formulasByTableAndRow[tableName] = {};
|
||||
}
|
||||
|
||||
formulasByTable[tableName].push(formula);
|
||||
if (!formulasByTableAndRow[tableName][rowIndex]) {
|
||||
formulasByTableAndRow[tableName][rowIndex] = [];
|
||||
}
|
||||
|
||||
formulasByTableAndRow[tableName][rowIndex].push(formula);
|
||||
});
|
||||
|
||||
// Устанавливаем обработчики для каждой табличной части
|
||||
Object.keys(formulasByTable).forEach(tableName => {
|
||||
Object.keys(formulasByTableAndRow).forEach(tableName => {
|
||||
if (!frm.doc[tableName]) {
|
||||
return;
|
||||
}
|
||||
|
||||
rowFormulas.forEach(async formula => {
|
||||
// Для каждой строки таблицы
|
||||
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(");
|
||||
|
||||
// Всегда используем явный вызов calculate_table_row_field
|
||||
await calculate_table_row_field(frm, tableName, rowIndex, formula.field_name, formula.formula, "refresh");
|
||||
} catch (error) {
|
||||
}
|
||||
});
|
||||
|
||||
// Вычисляем формулы для строки только если у них есть триггер "При открытии документа"
|
||||
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 () => {
|
||||
// Для асинхронных вызовов используем await в асинхронной IIFE
|
||||
(async () => {
|
||||
try {
|
||||
await calculate_table_row_field(frm, tableName, rowIndex, formula.field_name, formula.formula, "refresh");
|
||||
} catch (error) {
|
||||
await calculate_table_row_field(frm, tableName, rowIdx, formula.field_name, formula.formula, "refresh");
|
||||
} catch (asyncError) {
|
||||
console.error("Ошибка при асинхронном расчете формулы (порядок " + (formula.order || 10) + "):", asyncError);
|
||||
}
|
||||
}, 0);
|
||||
})();
|
||||
} else {
|
||||
// Синхронный вызов для обычных формул
|
||||
calculate_table_row_field(frm, tableName, rowIndex, formula.field_name, formula.formula, "refresh");
|
||||
// Для синхронных вызовов выполняем напрямую
|
||||
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) {
|
||||
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);
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue