table sums are now available in table row formulas
This commit is contained in:
parent
2dd18c4143
commit
d72ce0b06b
|
|
@ -114,8 +114,30 @@ 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() {
|
||||||
const selectedTable = $(this).val();
|
const selectedTable = $(this).val();
|
||||||
|
|
@ -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);
|
$container.append($rowFieldsGroup);
|
||||||
|
|
||||||
// НОВОЕ: Добавляем обработчик для кнопки выбора поля из строки табличной части
|
// 4. Добавляем раздел с универсальными полями
|
||||||
$tableFieldGroup.find('.select-table-field-in-row').on('click', function() {
|
if (frm.doc.universal_fields_storage) {
|
||||||
const targetContainer = $modal.find(".table-row-formula");
|
const universalFields = JSON.parse(frm.doc.universal_fields_storage || "{}");
|
||||||
openTableFieldSelector(frm, targetContainer, false);
|
|
||||||
});
|
|
||||||
|
|
||||||
// 6. Добавляем обработчики для кнопок полей
|
if (Object.keys(universalFields).length > 0) {
|
||||||
$modal.off('click', '.field-btn, .universal-field-btn, .report-field-btn').on('click', '.field-btn, .universal-field-btn, .report-field-btn', function() {
|
const $universalFieldGroup = $(`
|
||||||
const fieldText = $(this).text().trim();
|
<div class="field-group">
|
||||||
const fieldType = $(this).hasClass('universal-field-btn') ? 'universal-field' :
|
<div class="field-group-title">Универсальные поля</div>
|
||||||
$(this).hasClass('report-field-btn') ? 'report-field' : 'field';
|
<div class="field-buttons-container" data-group="universal-fields"></div>
|
||||||
|
</div>
|
||||||
|
`);
|
||||||
|
|
||||||
// Добавляем в формулу
|
const $universalButtonsContainer = $universalFieldGroup.find('.field-buttons-container');
|
||||||
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(' ');
|
|
||||||
|
|
||||||
// Добавляем обработчики к токену
|
Object.keys(universalFields).forEach(fieldId => {
|
||||||
addTokenHandlers($formulaContainer);
|
const field = universalFields[fieldId];
|
||||||
});
|
|
||||||
|
|
||||||
if (callback) callback();
|
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();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue