table sums are now available in table row formulas

This commit is contained in:
Ali 2025-10-28 14:43:48 +04:00
parent 2dd18c4143
commit d72ce0b06b
1 changed files with 206 additions and 107 deletions

View File

@ -114,7 +114,29 @@ function createTableRowFormulaModal() {
</div> </div>
`; `;
// Стили для модального окна
const modalStyles = `
<style id="table-row-formula-modal-styles">
/* Стили для кнопок полей табличных частей (суммы) */
.table-sum-field-btn {
background-color: #fff3e0 !important;
border-color: #ffb74d !important;
}
.table-sum-field-btn:hover {
background-color: #ffe0b2 !important;
}
/* Остальные стили уже есть в основных стилях */
</style>
`;
$('body').append(modalHtml); $('body').append(modalHtml);
// Добавляем стили только если их еще нет
if (!$('#table-row-formula-modal-styles').length) {
$('head').append(modalStyles);
}
// Обработчики для селекторов // Обработчики для селекторов
$("#table_row_table").on('change', function() { $("#table_row_table").on('change', function() {
@ -525,125 +547,202 @@ function populateTableRowFormulaFieldsAsync(frm, $modal, callback) {
$container.append($documentFieldsGroup); $container.append($documentFieldsGroup);
// 2. Добавляем раздел с полями текущей строки таблицы // === НОВЫЙ КОД: Добавляем поля из табличных частей ===
const $rowFieldsGroup = $(` // 2. Добавляем раздел с полями табличных частей (суммы)
const $tableFieldsGroup = $(`
<div class="field-group"> <div class="field-group">
<div class="field-group-title">Поля текущей строки</div> <div class="field-group-title">Поля табличных частей (суммы)</div>
<div class="field-buttons-container row-fields-container" data-group="row-fields"></div> <div class="field-buttons-container" data-group="table-fields"></div>
</div> </div>
`); `);
$container.append($rowFieldsGroup); const $tableFieldsContainer = $tableFieldsGroup.find('.field-buttons-container');
// 3. Добавляем раздел с универсальными полями // Счетчик для отслеживания загруженных таблиц
if (frm.doc.universal_fields_storage) { let tablesToLoad = 0;
const universalFields = JSON.parse(frm.doc.universal_fields_storage || "{}"); let tablesLoaded = 0;
if (Object.keys(universalFields).length > 0) { // Подсчитываем количество таблиц
const $universalFieldGroup = $(` if (meta && meta.fields) {
<div class="field-group"> meta.fields.forEach(tableField => {
<div class="field-group-title">Универсальные поля</div> if (tableField.fieldtype === 'Table' && tableField.options) {
<div class="field-buttons-container" data-group="universal-fields"></div> tablesToLoad++;
</div> }
`); });
const $universalButtonsContainer = $universalFieldGroup.find('.field-buttons-container');
Object.keys(universalFields).forEach(fieldId => {
const field = universalFields[fieldId];
if (!field || !field.name) return;
const $fieldBtn = $(`
<button class="btn btn-sm universal-field-btn draggable-item"
data-fieldname="univ(${field.name})"
data-label="${field.name}"
data-group="universal-fields"
data-field-id="${fieldId}"
draggable="true">
univ(${field.name})
</button>
`);
$universalButtonsContainer.append($fieldBtn);
});
$container.append($universalFieldGroup);
}
} }
// 4. Добавляем раздел с полями отчетов // Если нет табличных частей, сразу продолжаем
if (frm.doc.report_fields_storage) { if (tablesToLoad === 0) {
const reportFields = JSON.parse(frm.doc.report_fields_storage || "{}"); continueWithOtherGroups();
return;
if (Object.keys(reportFields).length > 0) {
const $reportFieldGroup = $(`
<div class="field-group">
<div class="field-group-title">Поля отчетов</div>
<div class="field-buttons-container" data-group="report-fields"></div>
</div>
`);
const $reportButtonsContainer = $reportFieldGroup.find('.field-buttons-container');
Object.keys(reportFields).forEach(fieldId => {
const field = reportFields[fieldId];
if (!field || !field.name) return;
const $fieldBtn = $(`
<button class="btn btn-sm report-field-btn draggable-item"
data-fieldname="report(${field.name})"
data-label="${field.name}"
data-group="report-fields"
data-field-id="${fieldId}"
draggable="true">
report(${field.name})
</button>
`);
$reportButtonsContainer.append($fieldBtn);
});
$container.append($reportFieldGroup);
}
} }
// НОВОЕ: 5. Добавляем группу для полей из конкретных строк табличных частей // Проходим по всем табличным частям
const $tableFieldGroup = $(` if (meta && meta.fields) {
<div class="field-group"> meta.fields.forEach(tableField => {
<div class="field-group-title">Поля из строк табличных частей</div> if (tableField.fieldtype === 'Table' && tableField.options) {
<div class="field-buttons-container table-field-container"> // Получаем meta дочерней таблицы
<button class="btn btn-info btn-sm select-table-field-in-row"> frappe.model.with_doctype(tableField.options, function() {
<i class="fa fa-table"></i> Поле из строки т.ч. const childMeta = frappe.get_meta(tableField.options);
</button> if (childMeta && childMeta.fields) {
// Добавляем только числовые поля
childMeta.fields.forEach(childField => {
if (childField.fieldname && ['Int', 'Float', 'Currency'].includes(childField.fieldtype)) {
const tableLabel = tableField.label || tableField.fieldname;
const fieldLabel = childField.label || childField.fieldname;
const combinedFieldname = `${tableField.fieldname}_${childField.fieldname}`;
const $fieldBtn = $(`
<button class="btn btn-sm field-btn table-sum-field-btn draggable-item"
data-fieldname="${combinedFieldname}"
data-label="${tableLabel} → ${fieldLabel}"
data-group="table-fields"
data-fieldtype="${childField.fieldtype}"
draggable="true">
val(${combinedFieldname})
</button>
`);
$tableFieldsContainer.append($fieldBtn);
}
});
}
// Увеличиваем счетчик загруженных таблиц
tablesLoaded++;
// Если все таблицы загружены, продолжаем
if (tablesLoaded === tablesToLoad) {
$container.append($tableFieldsGroup);
continueWithOtherGroups();
}
});
}
});
}
// Функция для продолжения загрузки остальных групп
function continueWithOtherGroups() {
// 3. Добавляем раздел с полями текущей строки таблицы
const $rowFieldsGroup = $(`
<div class="field-group">
<div class="field-group-title">Поля текущей строки</div>
<div class="field-buttons-container row-fields-container" data-group="row-fields"></div>
</div> </div>
</div> `);
`);
$container.append($tableFieldGroup);
// НОВОЕ: Добавляем обработчик для кнопки выбора поля из строки табличной части
$tableFieldGroup.find('.select-table-field-in-row').on('click', function() {
const targetContainer = $modal.find(".table-row-formula");
openTableFieldSelector(frm, targetContainer, false);
});
// 6. Добавляем обработчики для кнопок полей
$modal.off('click', '.field-btn, .universal-field-btn, .report-field-btn').on('click', '.field-btn, .universal-field-btn, .report-field-btn', function() {
const fieldText = $(this).text().trim();
const fieldType = $(this).hasClass('universal-field-btn') ? 'universal-field' :
$(this).hasClass('report-field-btn') ? 'report-field' : 'field';
// Добавляем в формулу $container.append($rowFieldsGroup);
const $token = $(`<span class="formula-token ${fieldType}" data-value="${fieldText}" contenteditable="false" draggable="true">${fieldText}<span class="token-remove">×</span></span>`);
$formulaContainer.append($token).append(' ');
// Добавляем обработчики к токену // 4. Добавляем раздел с универсальными полями
addTokenHandlers($formulaContainer); if (frm.doc.universal_fields_storage) {
}); const universalFields = JSON.parse(frm.doc.universal_fields_storage || "{}");
if (callback) callback(); if (Object.keys(universalFields).length > 0) {
const $universalFieldGroup = $(`
<div class="field-group">
<div class="field-group-title">Универсальные поля</div>
<div class="field-buttons-container" data-group="universal-fields"></div>
</div>
`);
const $universalButtonsContainer = $universalFieldGroup.find('.field-buttons-container');
Object.keys(universalFields).forEach(fieldId => {
const field = universalFields[fieldId];
if (!field || !field.name) return;
const $fieldBtn = $(`
<button class="btn btn-sm universal-field-btn draggable-item"
data-fieldname="univ(${field.name})"
data-label="${field.name}"
data-group="universal-fields"
data-field-id="${fieldId}"
draggable="true">
univ(${field.name})
</button>
`);
$universalButtonsContainer.append($fieldBtn);
});
$container.append($universalFieldGroup);
}
}
// 5. Добавляем раздел с полями отчетов
if (frm.doc.report_fields_storage) {
const reportFields = JSON.parse(frm.doc.report_fields_storage || "{}");
if (Object.keys(reportFields).length > 0) {
const $reportFieldGroup = $(`
<div class="field-group">
<div class="field-group-title">Поля отчетов</div>
<div class="field-buttons-container" data-group="report-fields"></div>
</div>
`);
const $reportButtonsContainer = $reportFieldGroup.find('.field-buttons-container');
Object.keys(reportFields).forEach(fieldId => {
const field = reportFields[fieldId];
if (!field || !field.name) return;
const $fieldBtn = $(`
<button class="btn btn-sm report-field-btn draggable-item"
data-fieldname="report(${field.name})"
data-label="${field.name}"
data-group="report-fields"
data-field-id="${fieldId}"
draggable="true">
report(${field.name})
</button>
`);
$reportButtonsContainer.append($fieldBtn);
});
$container.append($reportFieldGroup);
}
}
// 6. Добавляем группу для полей из конкретных строк табличных частей
const $tableFieldGroup = $(`
<div class="field-group">
<div class="field-group-title">Поля из строк табличных частей</div>
<div class="field-buttons-container table-field-container">
<button class="btn btn-info btn-sm select-table-field-in-row">
<i class="fa fa-table"></i> Поле из строки т.ч.
</button>
</div>
</div>
`);
$container.append($tableFieldGroup);
// Добавляем обработчик для кнопки выбора поля из строки табличной части
$tableFieldGroup.find('.select-table-field-in-row').on('click', function() {
const targetContainer = $modal.find(".table-row-formula");
openTableFieldSelector(frm, targetContainer, false);
});
// 7. Добавляем обработчики для кнопок полей
$modal.off('click', '.field-btn, .universal-field-btn, .report-field-btn').on('click', '.field-btn, .universal-field-btn, .report-field-btn', function() {
const fieldText = $(this).text().trim();
const fieldType = $(this).hasClass('universal-field-btn') ? 'universal-field' :
$(this).hasClass('report-field-btn') ? 'report-field' : 'field';
// Добавляем в формулу
const $token = $(`<span class="formula-token ${fieldType}" data-value="${fieldText}" contenteditable="false" draggable="true">${fieldText}<span class="token-remove">×</span></span>`);
$formulaContainer.append($token).append(' ');
// Добавляем обработчики к токену
addTokenHandlers($formulaContainer);
});
if (callback) callback();
}
}); });
} }