AURORA-1938: фонд экономии считается на «Смете РФ» (FORM_2), откат FORM_4-части 0055 (#335) #336
@ -214,8 +214,9 @@ const RealtimeTable = ({ formType, formId, sheetName, direction, year }) => {
|
||||
columnId,
|
||||
isAdmin: isAdminUser,
|
||||
stageColumns: stageColumnsSet,
|
||||
formType,
|
||||
}),
|
||||
[isAdminUser, stageColumnsSet],
|
||||
[isAdminUser, stageColumnsSet, formType],
|
||||
);
|
||||
|
||||
// AURORA-1891: cellIsEditable(row, columnId) не знает про сам column.def —
|
||||
@ -371,12 +372,13 @@ const RealtimeTable = ({ formType, formId, sheetName, direction, year }) => {
|
||||
getCellErrors,
|
||||
denomination,
|
||||
sheetName,
|
||||
formType,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error creating columns:', error);
|
||||
return [];
|
||||
}
|
||||
}, [columnsConfig, columnsCurStage, userRoleId, handleCellUpdateError, handleClickRowCell, handleUpdateCell, getCellErrors, denomination, sheetName]);
|
||||
}, [columnsConfig, columnsCurStage, userRoleId, handleCellUpdateError, handleClickRowCell, handleUpdateCell, getCellErrors, denomination, sheetName, formType]);
|
||||
|
||||
// Мемоизация ячеек MRT (memoMode: 'cells') сравнивает только объект cell. Состояние вне данных строки,
|
||||
// от которого зависят стили закрепления и подсветка фильтров, сбрасывает её новым массивом колонок.
|
||||
|
||||
@ -126,6 +126,7 @@ export const getTableColumns = ({
|
||||
getCellErrors,
|
||||
denomination = 'thousand',
|
||||
sheetName,
|
||||
formType,
|
||||
}) => {
|
||||
const columnColors = { ...columnsConfig.colors };
|
||||
const columns = structuredClone(columnsConfig.columns);
|
||||
@ -159,6 +160,7 @@ export const getTableColumns = ({
|
||||
columnId,
|
||||
isAdmin: userRoleId === ROLES_NAME_ID.admin,
|
||||
stageColumns,
|
||||
formType,
|
||||
})
|
||||
) {
|
||||
return false;
|
||||
|
||||
@ -62,7 +62,7 @@ const DATA_PREFIX = 'data.';
|
||||
* OTCH9F). columnId — это React Table column.id в формате accessorKey, т.е.
|
||||
* всегда с префиксом "data." для полей строки (например "data.q1.booking").
|
||||
*/
|
||||
export const isComputedColumn = (columnId) => {
|
||||
export const isComputedColumn = (columnId, formType) => {
|
||||
if (typeof columnId !== 'string' || !columnId.startsWith(DATA_PREFIX)) return false;
|
||||
|
||||
const parts = columnId.slice(DATA_PREFIX.length).split('.');
|
||||
@ -81,6 +81,11 @@ export const isComputedColumn = (columnId) => {
|
||||
// qN.<field> из списка вычисляемых полей квартала.
|
||||
if (QUARTER_SCOPE_PATTERN.test(scope) && QUARTER_COMPUTED_FIELDS.has(field)) return true;
|
||||
|
||||
// AURORA-1938: на FORM_2 («Смета РФ») перенос в фонд экономии считается на сервере
|
||||
// (миграция 0063; _apply_form_cell отвергает запись для FORM_2). На FORM_4
|
||||
// («Проектная деятельность») transfer_econ — обычное редактируемое поле.
|
||||
if (formType === 'FORM_2' && QUARTER_SCOPE_PATTERN.test(scope) && field === 'transfer_econ') return true;
|
||||
|
||||
// fact_qN.total — сателлиты AHR_RENT/AHR_UTILITY/AHR_SECURITY.
|
||||
if (FACT_QUARTER_SCOPE_PATTERN.test(scope) && field === 'total') return true;
|
||||
|
||||
@ -96,12 +101,12 @@ export const isComputedColumn = (columnId) => {
|
||||
};
|
||||
|
||||
/**
|
||||
* isCellEditable({ rowType, columnId, isAdmin, stageColumns })
|
||||
* isCellEditable({ rowType, columnId, isAdmin, stageColumns, formType })
|
||||
*
|
||||
* rowType === 'INPUT' && !isComputedColumn(columnId) && (isAdmin || stageColumns.has(columnId))
|
||||
* rowType === 'INPUT' && !isComputedColumn(columnId, formType) && (isAdmin || stageColumns.has(columnId))
|
||||
*
|
||||
* stageColumns — Set с ключами вида "data.<column>" (columnsCurStage из
|
||||
* useRealtimeData, отражающий окно текущего этапа пользователя).
|
||||
*/
|
||||
export const isCellEditable = ({ rowType, columnId, isAdmin, stageColumns }) =>
|
||||
rowType === 'INPUT' && !isComputedColumn(columnId) && (isAdmin || stageColumns.has(columnId));
|
||||
export const isCellEditable = ({ rowType, columnId, isAdmin, stageColumns, formType }) =>
|
||||
rowType === 'INPUT' && !isComputedColumn(columnId, formType) && (isAdmin || stageColumns.has(columnId));
|
||||
|
||||
@ -144,3 +144,32 @@ test('plain non-"data." column ids (row number, grouping headers) are never comp
|
||||
assert.equal(isComputedColumn(undefined), false);
|
||||
assert.equal(isComputedColumn(null), false);
|
||||
});
|
||||
|
||||
test('AURORA-1938: transfer_econ is computed on FORM_2 only (FORM_4 keeps it editable)', () => {
|
||||
for (const q of ['q1', 'q2', 'q3', 'q4']) {
|
||||
const columnId = `data.${q}.transfer_econ`;
|
||||
assert.equal(isComputedColumn(columnId, 'FORM_2'), true, `${columnId} must be computed on FORM_2`);
|
||||
assert.equal(isComputedColumn(columnId, 'FORM_4'), false, `${columnId} must stay editable on FORM_4`);
|
||||
assert.equal(isComputedColumn(columnId), false);
|
||||
}
|
||||
assert.equal(
|
||||
isCellEditable({
|
||||
rowType: 'INPUT',
|
||||
columnId: 'data.q1.transfer_econ',
|
||||
isAdmin: true,
|
||||
stageColumns: new Set(['data.q1.transfer_econ']),
|
||||
formType: 'FORM_2',
|
||||
}),
|
||||
false,
|
||||
);
|
||||
assert.equal(
|
||||
isCellEditable({
|
||||
rowType: 'INPUT',
|
||||
columnId: 'data.q1.transfer_econ',
|
||||
isAdmin: true,
|
||||
stageColumns: new Set(),
|
||||
formType: 'FORM_4',
|
||||
}),
|
||||
true,
|
||||
);
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user