fixed a bunch of bugs
This commit is contained in:
parent
1699e76dcc
commit
ed9e568d7d
|
|
@ -555,8 +555,6 @@ function generateReportFieldsFunction(report_fields) {
|
||||||
window.notifiedAboutRubIl = false;
|
window.notifiedAboutRubIl = false;
|
||||||
async function getReportFieldValue(frm, reportName, filters, fieldName, aggregation = 'sum') {
|
async function getReportFieldValue(frm, reportName, filters, fieldName, aggregation = 'sum') {
|
||||||
try {
|
try {
|
||||||
// Отладочное сообщение о начальных фильтрах
|
|
||||||
console.log(\`Запуск отчета \${reportName} с начальными фильтрами:\`, JSON.stringify(filters));
|
|
||||||
|
|
||||||
// Проверка необходимости полей сразу для всех фильтров
|
// Проверка необходимости полей сразу для всех фильтров
|
||||||
if (Object.values(filters).some(v => v === "$AyIlSpecial")) {
|
if (Object.values(filters).some(v => v === "$AyIlSpecial")) {
|
||||||
|
|
@ -726,9 +724,6 @@ async function getReportFieldValue(frm, reportName, filters, fieldName, aggregat
|
||||||
processedFilters[key] = value;
|
processedFilters[key] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Отладочное сообщение об обработанных фильтрах
|
|
||||||
console.log(\`ОТЧЕТ API - запуск отчета \${reportName} с фильтрами\`, JSON.stringify(processedFilters));
|
|
||||||
|
|
||||||
// Проверяем кеш для экономии запросов
|
// Проверяем кеш для экономии запросов
|
||||||
if (!window.reportCache) window.reportCache = {};
|
if (!window.reportCache) window.reportCache = {};
|
||||||
|
|
||||||
|
|
@ -756,7 +751,6 @@ async function getReportFieldValue(frm, reportName, filters, fieldName, aggregat
|
||||||
// Проверяем результат
|
// Проверяем результат
|
||||||
if (result && result.message) {
|
if (result && result.message) {
|
||||||
if (result.message.error) {
|
if (result.message.error) {
|
||||||
console.log(\`Ошибка при получении данных отчета: \${result.message.error}\`);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -764,8 +758,6 @@ async function getReportFieldValue(frm, reportName, filters, fieldName, aggregat
|
||||||
let value = parseFloat(result.message);
|
let value = parseFloat(result.message);
|
||||||
if (isNaN(value)) value = 0;
|
if (isNaN(value)) value = 0;
|
||||||
|
|
||||||
console.log(\`Результат отчета \${reportName}: \${value}\`);
|
|
||||||
|
|
||||||
// Сохраняем в кеш
|
// Сохраняем в кеш
|
||||||
window.reportCache[cacheKey] = {
|
window.reportCache[cacheKey] = {
|
||||||
value: value,
|
value: value,
|
||||||
|
|
@ -775,12 +767,10 @@ async function getReportFieldValue(frm, reportName, filters, fieldName, aggregat
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(\`Ошибка при вызове отчета \${reportName}:\`, err);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(\`Общая ошибка в getReportFieldValue:\`, error);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}`;
|
}`;
|
||||||
|
|
@ -1262,7 +1252,7 @@ function generateTransformExpressionFunction(universal_fields, report_fields) {
|
||||||
let reportCalls = [];
|
let reportCalls = [];
|
||||||
|
|
||||||
// === Обработка report(...) ===
|
// === Обработка report(...) ===
|
||||||
const reportRegex = /report\\(([^)]+)\\)/g;\n
|
const reportRegex = /report\\\\(([^)]+)\\\\)/g;
|
||||||
let match;
|
let match;
|
||||||
|
|
||||||
// Находим все вызовы report() в выражении
|
// Находим все вызовы report() в выражении
|
||||||
|
|
@ -1340,38 +1330,35 @@ function generateTransformExpressionFunction(universal_fields, report_fields) {
|
||||||
${Object.keys(universal_fields).map(fieldId => {
|
${Object.keys(universal_fields).map(fieldId => {
|
||||||
const field = universal_fields[fieldId];
|
const field = universal_fields[fieldId];
|
||||||
if (!field || !field.name) return '';
|
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')}
|
}).filter(Boolean).join('\n')}
|
||||||
|
|
||||||
// === Обработка val() и row() ===
|
// === Обработка 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) {
|
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) =>
|
transformed = transformed.replace(sumPattern, (m, f) =>
|
||||||
\`(frm.doc["\${prefix}"] && frm.doc["\${prefix}"].reduce((s, r) => s + (parseFloat(r["\${f}"]) || 0), 0) || 0)\`
|
\`(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) =>
|
transformed = transformed.replace(valPattern, (m, f) =>
|
||||||
\`(frm.doc["\${prefix}"] && frm.doc["\${prefix}"].reduce((s, r) => s + (parseFloat(r["\${f}"]) || 0), 0) || 0)\`
|
\`(frm.doc["\${prefix}"] && frm.doc["\${prefix}"].reduce((s, r) => s + (parseFloat(r["\${f}"]) || 0), 0) || 0)\`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (for_child_table) {
|
if (for_child_table) {
|
||||||
|
// ИСПРАВЛЕНО: корректная обработка row() в контексте табличной части
|
||||||
|
transformed = transformed.replace(/row\\\\(([^)]+)\\\\)/g, (m, f) =>
|
||||||
|
\`(parseFloat(row["\${f}"]) || 0)\`
|
||||||
|
);
|
||||||
|
|
||||||
transformed = transformed.replace(/val\\\\(([^)]+)\\\\)/g, (m, f) => {
|
transformed = transformed.replace(/val\\\\(([^)]+)\\\\)/g, (m, f) => {
|
||||||
if (f.startsWith(table_name + '_')) {
|
if (f.startsWith(table_name + '_')) {
|
||||||
return \`(parseFloat(row["\${f.slice(table_name.length + 1)}"]) || 0)\`;
|
return \`(parseFloat(row["\${f.slice(table_name.length + 1)}"]) || 0)\`;
|
||||||
}
|
}
|
||||||
return \`(parseFloat(frm.doc["\${f}"]) || 0)\`;
|
return \`(parseFloat(frm.doc["\${f}"]) || 0)\`;
|
||||||
});
|
});
|
||||||
|
|
||||||
transformed = transformed.replace(/row\\\\(([^)]+)\\\\)/g, (m, f) =>
|
|
||||||
\`(parseFloat(row["\${f}"]) || 0)\`
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
transformed = transformed.replace(/val\\\\(([^)]+)\\\\)/g, (m, f) =>
|
transformed = transformed.replace(/val\\\\(([^)]+)\\\\)/g, (m, f) =>
|
||||||
\`(parseFloat(frm.doc["\${f}"]) || 0)\`
|
\`(parseFloat(frm.doc["\${f}"]) || 0)\`
|
||||||
|
|
@ -5757,6 +5744,11 @@ function openTableRowFormulaModal(frm, formulaId = null) {
|
||||||
$triggerContainer.empty();
|
$triggerContainer.empty();
|
||||||
$modal.find(".field-groups-container").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.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');
|
$modal.modal('show');
|
||||||
|
|
@ -5894,6 +5886,11 @@ function openTableRowFormulaModal(frm, formulaId = null) {
|
||||||
initTriggerDragAndDrop($modal, $triggerContainer);
|
initTriggerDragAndDrop($modal, $triggerContainer);
|
||||||
setupTriggerEditableContainer($triggerContainer);
|
setupTriggerEditableContainer($triggerContainer);
|
||||||
|
|
||||||
|
// ИСПРАВЛЕНИЕ: Добавляем обработчик закрытия модального окна для очистки данных
|
||||||
|
$modal.off('hidden.bs.modal').on('hidden.bs.modal', function() {
|
||||||
|
$modal.removeData("formula-id");
|
||||||
|
});
|
||||||
|
|
||||||
// Удаляем блокирующий оверлей
|
// Удаляем блокирующий оверлей
|
||||||
$modal.find(".modal-overlay").remove();
|
$modal.find(".modal-overlay").remove();
|
||||||
})
|
})
|
||||||
|
|
@ -6946,7 +6943,6 @@ function generateTableRowFormulasHandlers(table_row_formulas, functions, target_
|
||||||
try {
|
try {
|
||||||
await calculate_table_row_field(frm, tableName, rowIdx, formula.field_name, formula.formula, "refresh");
|
await calculate_table_row_field(frm, tableName, rowIdx, formula.field_name, formula.formula, "refresh");
|
||||||
} catch (asyncError) {
|
} catch (asyncError) {
|
||||||
console.error("Ошибка при асинхронном расчете формулы (порядок " + (formula.order || 10) + "):", asyncError);
|
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
} else {
|
} 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");
|
calculate_table_row_field(frm, tableName, rowIdx, formula.field_name, formula.formula, "refresh");
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Ошибка расчета формулы для " + tableName + "[" + rowIdx + "]." + formula.field_name + " (порядок " + (formula.order || 10) + "):", error);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} catch (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) {
|
async function calculate_table_row_field(frm, tableName, rowIndex, fieldName, formula, triggerField) {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
if (!frm.doc[tableName] || !frm.doc[tableName][rowIndex]) {
|
if (!frm.doc[tableName] || !frm.doc[tableName][rowIndex]) {
|
||||||
return;
|
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 cdt = frm.fields_dict[tableName].grid.doctype;
|
||||||
const cdn = row.name;
|
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) {
|
const placeholder = \`__REPORT_PLACEHOLDER_\${reportPromises.length}__\`;
|
||||||
await calculate_universal_fields(frm);
|
|
||||||
|
// Ищем данные отчета в хранилище или используем предопределенный отчет
|
||||||
|
let reportName, reportFilters, reportField, reportAggregation;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Обработка вызовов report()
|
// Добавляем промис запроса к отчету
|
||||||
if (reportCalls && reportCalls.length > 0) {
|
reportPromises.push(
|
||||||
const reportResults = [];
|
getReportFieldValue(
|
||||||
|
|
||||||
for (const call of reportCalls) {
|
|
||||||
const result = await getReportFieldValue(
|
|
||||||
frm,
|
frm,
|
||||||
call.reportName,
|
reportName,
|
||||||
call.filters,
|
reportFilters,
|
||||||
call.fieldName,
|
reportField,
|
||||||
call.aggregation
|
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;
|
let result = 0;
|
||||||
try {
|
try {
|
||||||
result = eval(finalExpression);
|
// Создаем функцию с доступом к контексту row и frm
|
||||||
|
const evalFunc = new Function('row', 'frm', \`return \${finalFormula};\`);
|
||||||
|
result = evalFunc(row, frm);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -7019,14 +7080,14 @@ async function calculate_table_row_field(frm, tableName, rowIndex, fieldName, fo
|
||||||
result = 0;
|
result = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Устанавливаем вычисленное значение
|
||||||
frappe.model.set_value(cdt, cdn, fieldName, result);
|
frappe.model.set_value(cdt, cdn, fieldName, result);
|
||||||
|
|
||||||
// Обновляем таблицу
|
// Обновляем таблицу
|
||||||
frm.refresh_field(tableName);
|
frm.refresh_field(tableName);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
}
|
}
|
||||||
}
|
}`;
|
||||||
`;
|
|
||||||
|
|
||||||
|
|
||||||
functions.push(calculateFunction);
|
functions.push(calculateFunction);
|
||||||
|
|
@ -7429,7 +7490,6 @@ async function handle_predefined_events(frm) {
|
||||||
}
|
}
|
||||||
}).join('')}
|
}).join('')}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error in predefined events handler:", error);
|
|
||||||
}
|
}
|
||||||
}`;
|
}`;
|
||||||
|
|
||||||
|
|
@ -8300,7 +8360,6 @@ function restoreSpecialDateValues(d, current_filters) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} 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.filters_json = JSON.stringify(processedFilters);
|
||||||
fieldCopy.__has_special_dates = true; // Маркер для последующего восстановления
|
fieldCopy.__has_special_dates = true; // Маркер для последующего восстановления
|
||||||
} catch (e) {
|
} 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}");
|
${usesUniversal || usesReports ? 'await ' : ''}calculate_table_row_field(frm, "${tableName}", rowIndex, "${formula.field_name}", formula, "${trigger}");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Ошибка вычисления формулы для ${tableName}[${rowIndex - 1}].${formula.field_name}:", error);
|
|
||||||
}
|
}
|
||||||
}`;
|
}`;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue