fixed a bunch of bugs

This commit is contained in:
Ali 2025-04-23 17:12:38 +04:00
parent 1699e76dcc
commit ed9e568d7d
1 changed files with 117 additions and 60 deletions

View File

@ -555,8 +555,6 @@ function generateReportFieldsFunction(report_fields) {
window.notifiedAboutRubIl = false;
async function getReportFieldValue(frm, reportName, filters, fieldName, aggregation = 'sum') {
try {
// Отладочное сообщение о начальных фильтрах
console.log(\`Запуск отчета \${reportName} с начальными фильтрами:\`, JSON.stringify(filters));
// Проверка необходимости полей сразу для всех фильтров
if (Object.values(filters).some(v => v === "$AyIlSpecial")) {
@ -726,9 +724,6 @@ async function getReportFieldValue(frm, reportName, filters, fieldName, aggregat
processedFilters[key] = value;
}
// Отладочное сообщение об обработанных фильтрах
console.log(\`ОТЧЕТ API - запуск отчета \${reportName} с фильтрами\`, JSON.stringify(processedFilters));
// Проверяем кеш для экономии запросов
if (!window.reportCache) window.reportCache = {};
@ -756,7 +751,6 @@ async function getReportFieldValue(frm, reportName, filters, fieldName, aggregat
// Проверяем результат
if (result && result.message) {
if (result.message.error) {
console.log(\`Ошибка при получении данных отчета: \${result.message.error}\`);
return 0;
}
@ -764,8 +758,6 @@ async function getReportFieldValue(frm, reportName, filters, fieldName, aggregat
let value = parseFloat(result.message);
if (isNaN(value)) value = 0;
console.log(\`Результат отчета \${reportName}: \${value}\`);
// Сохраняем в кеш
window.reportCache[cacheKey] = {
value: value,
@ -775,12 +767,10 @@ async function getReportFieldValue(frm, reportName, filters, fieldName, aggregat
return value;
}
} catch (err) {
console.error(\`Ошибка при вызове отчета \${reportName}:\`, err);
}
return 0;
} catch (error) {
console.error(\`Общая ошибка в getReportFieldValue:\`, error);
return 0;
}
}`;
@ -1262,7 +1252,7 @@ function generateTransformExpressionFunction(universal_fields, report_fields) {
let reportCalls = [];
// === Обработка report(...) ===
const reportRegex = /report\\(([^)]+)\\)/g;\n
const reportRegex = /report\\\\(([^)]+)\\\\)/g;
let match;
// Находим все вызовы report() в выражении
@ -1340,38 +1330,35 @@ function generateTransformExpressionFunction(universal_fields, report_fields) {
${Object.keys(universal_fields).map(fieldId => {
const field = universal_fields[fieldId];
if (!field || !field.name) return '';
return `transformed = transformed.replace(/univ\\(${field.name}\\)/g, "(frm.doc.__universalFields && frm.doc.__universalFields['${fieldId}'] || 0)");`;
return `transformed = transformed.replace(/univ\\\\(${field.name}\\\\)/g, "(frm.doc.__universalFields && frm.doc.__universalFields['${fieldId}'] || 0)");`;
}).filter(Boolean).join('\n')}
// === Обработка val() и row() ===
const tablePrefixes = ${JSON.stringify([
"items", "taxes", "packed_items", "payments", "advances", "timesheets",
"payment_schedule", "sales_team", "aksiz_test_table"
])};
for (const prefix of tablePrefixes) {
const sumPattern = new RegExp(\`sum\\\\(\${prefix}_([^)]+)\\\\)\`, 'g');
const sumPattern = new RegExp(\`sum\\\\\\\\(\${prefix}_([^)]+)\\\\\\\\)\`, 'g');
transformed = transformed.replace(sumPattern, (m, f) =>
\`(frm.doc["\${prefix}"] && frm.doc["\${prefix}"].reduce((s, r) => s + (parseFloat(r["\${f}"]) || 0), 0) || 0)\`
);
const valPattern = new RegExp(\`val\\\\(\${prefix}_([^)]+)\\\\)\`, 'g');
const valPattern = new RegExp(\`val\\\\\\\\(\${prefix}_([^)]+)\\\\\\\\)\`, 'g');
transformed = transformed.replace(valPattern, (m, f) =>
\`(frm.doc["\${prefix}"] && frm.doc["\${prefix}"].reduce((s, r) => s + (parseFloat(r["\${f}"]) || 0), 0) || 0)\`
);
}
if (for_child_table) {
// ИСПРАВЛЕНО: корректная обработка row() в контексте табличной части
transformed = transformed.replace(/row\\\\(([^)]+)\\\\)/g, (m, f) =>
\`(parseFloat(row["\${f}"]) || 0)\`
);
transformed = transformed.replace(/val\\\\(([^)]+)\\\\)/g, (m, f) => {
if (f.startsWith(table_name + '_')) {
return \`(parseFloat(row["\${f.slice(table_name.length + 1)}"]) || 0)\`;
}
return \`(parseFloat(frm.doc["\${f}"]) || 0)\`;
});
transformed = transformed.replace(/row\\\\(([^)]+)\\\\)/g, (m, f) =>
\`(parseFloat(row["\${f}"]) || 0)\`
);
} else {
transformed = transformed.replace(/val\\\\(([^)]+)\\\\)/g, (m, f) =>
\`(parseFloat(frm.doc["\${f}"]) || 0)\`
@ -5757,6 +5744,11 @@ function openTableRowFormulaModal(frm, formulaId = null) {
$triggerContainer.empty();
$modal.find(".field-groups-container").empty();
// ИСПРАВЛЕНИЕ: явно очищаем ID формулы, если это новая формула
if (!formulaId) {
$modal.removeData("formula-id");
}
// Показываем модальное окно с блокировкой контента
$modal.find(".modal-content").append('<div class="modal-overlay" style="position:absolute;top:0;left:0;right:0;bottom:0;background:rgba(255,255,255,0.8);z-index:1000;display:flex;align-items:center;justify-content:center;"><div class="text-center"><div class="spinner-border text-primary" role="status"></div><div class="mt-2">Загрузка данных...</div></div></div>');
$modal.modal('show');
@ -5894,6 +5886,11 @@ function openTableRowFormulaModal(frm, formulaId = null) {
initTriggerDragAndDrop($modal, $triggerContainer);
setupTriggerEditableContainer($triggerContainer);
// ИСПРАВЛЕНИЕ: Добавляем обработчик закрытия модального окна для очистки данных
$modal.off('hidden.bs.modal').on('hidden.bs.modal', function() {
$modal.removeData("formula-id");
});
// Удаляем блокирующий оверлей
$modal.find(".modal-overlay").remove();
})
@ -6946,7 +6943,6 @@ function generateTableRowFormulasHandlers(table_row_formulas, functions, target_
try {
await calculate_table_row_field(frm, tableName, rowIdx, formula.field_name, formula.formula, "refresh");
} catch (asyncError) {
console.error("Ошибка при асинхронном расчете формулы (порядок " + (formula.order || 10) + "):", asyncError);
}
})();
} else {
@ -6954,13 +6950,11 @@ function generateTableRowFormulasHandlers(table_row_formulas, functions, target_
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);
}
}`;
@ -6971,6 +6965,7 @@ function generateTableRowFormulasHandlers(table_row_formulas, functions, target_
// Функция для расчета значения поля в строке табличной части
async function calculate_table_row_field(frm, tableName, rowIndex, fieldName, formula, triggerField) {
try {
if (!frm.doc[tableName] || !frm.doc[tableName][rowIndex]) {
return;
}
@ -6979,39 +6974,105 @@ async function calculate_table_row_field(frm, tableName, rowIndex, fieldName, fo
const cdt = frm.fields_dict[tableName].grid.doctype;
const cdn = row.name;
const { transformed, needsAsync, reportCalls } = transform_expression(formula, true, tableName);
// === Обработка report() ===
let processedFormula = formula;
if (formula.includes("report(")) {
// Регулярное выражение для поиска вызовов report()
const reportRegex = /report\\(([^)]+)\\)/g;
let match;
const reportPromises = [];
const reportPlaceholders = [];
let finalExpression = transformed;
// Находим все вызовы report() и заменяем их на плейсхолдеры
while ((match = reportRegex.exec(formula)) !== null) {
const fullMatch = match[0]; // report(fieldName)
const fieldName = match[1]; // fieldName
// Загрузка универсальных полей при необходимости
if (formula.includes("univ(") && !frm.doc.__universalFields) {
await calculate_universal_fields(frm);
}
// Создаем уникальный плейсхолдер
const placeholder = \`__REPORT_PLACEHOLDER_\${reportPromises.length}__\`;
// Обработка вызовов report()
if (reportCalls && reportCalls.length > 0) {
const reportResults = [];
// Ищем данные отчета в хранилище или используем предопределенный отчет
let reportName, reportFilters, reportField, reportAggregation;
for (const call of reportCalls) {
const result = await getReportFieldValue(
frm,
call.reportName,
call.filters,
call.fieldName,
call.aggregation
if (fieldName === "testt") {
reportName = "General Ledger";
reportFilters = {"company":"$DefaultCompany","from_date":"$AyIlSpecial","to_date":"$AyIlSpecial"};
reportField = "debit";
reportAggregation = "sum";
} else {
// Ищем в хранилище полей отчетов
const reportFields = JSON.parse(frm.doc.report_fields_storage || "{}");
const reportObj = Object.values(reportFields).find(f => f.name === fieldName);
if (reportObj) {
reportName = reportObj.report;
reportFilters = JSON.parse(reportObj.filters_json || "{}");
reportField = reportObj.field_name;
reportAggregation = reportObj.aggregation || 'sum';
} else {
processedFormula = processedFormula.replace(fullMatch, "0");
continue;
}
}
// Добавляем промис запроса к отчету
reportPromises.push(
getReportFieldValue(
frm,
reportName,
reportFilters,
reportField,
reportAggregation
)
);
reportResults.push({ placeholder: call.placeholder, value: result });
// Запоминаем соответствие плейсхолдера и вызова
reportPlaceholders.push({
placeholder: placeholder,
original: fullMatch
});
// Заменяем вызов отчета на плейсхолдер
processedFormula = processedFormula.replace(fullMatch, placeholder);
}
for (const result of reportResults) {
finalExpression = finalExpression.replace(result.placeholder, result.value);
// Если нашли вызовы отчетов, ждем выполнения всех запросов
if (reportPromises.length > 0) {
const reportResults = await Promise.all(reportPromises);
// Заменяем плейсхолдеры на результаты
for (let i = 0; i < reportPlaceholders.length; i++) {
// Убедимся, что результат - числовое значение
const reportValue = reportResults[i] !== undefined ? Number(reportResults[i]) : 0;
processedFormula = processedFormula.replace(
reportPlaceholders[i].placeholder,
reportValue
);
}
}
}
// Вычисление выражения
// === Обработка row() ===
// Заменяем все вызовы row() на доступ к полям текущей строки
let finalFormula = processedFormula;
const rowRegex = /row\\(([^)]+)\\)/g;
finalFormula = finalFormula.replace(rowRegex, (match, fieldName) => {
return \`(parseFloat(row["\${fieldName}"]) || 0)\`;
});
// === Обработка val() ===
// Заменяем все вызовы val() на доступ к полям документа
const valRegex = /val\\(([^)]+)\\)/g;
finalFormula = finalFormula.replace(valRegex, (match, fieldName) => {
return \`(parseFloat(frm.doc["\${fieldName}"]) || 0)\`;
});
// Вычисление выражения с доступом к объекту row
let result = 0;
try {
result = eval(finalExpression);
// Создаем функцию с доступом к контексту row и frm
const evalFunc = new Function('row', 'frm', \`return \${finalFormula};\`);
result = evalFunc(row, frm);
} catch (e) {
}
@ -7019,14 +7080,14 @@ async function calculate_table_row_field(frm, tableName, rowIndex, fieldName, fo
result = 0;
}
// Устанавливаем вычисленное значение
frappe.model.set_value(cdt, cdn, fieldName, result);
// Обновляем таблицу
frm.refresh_field(tableName);
} catch (err) {
}
}
`;
}`;
functions.push(calculateFunction);
@ -7429,7 +7490,6 @@ async function handle_predefined_events(frm) {
}
}).join('')}
} catch (error) {
console.error("Error in predefined events handler:", error);
}
}`;
@ -8300,7 +8360,6 @@ function restoreSpecialDateValues(d, current_filters) {
}
});
} catch (e) {
console.error("Error restoring special date values:", e);
}
}
@ -9030,7 +9089,6 @@ function editReportField(frm, fieldId) {
fieldCopy.filters_json = JSON.stringify(processedFilters);
fieldCopy.__has_special_dates = true; // Маркер для последующего восстановления
} catch (e) {
console.error("Error processing filters:", e);
}
}
@ -9132,7 +9190,6 @@ 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);
}
}`;