Andrey Epifancev fa586c85cc feat(table): отрицательные суммы красным и правило «минус запрещён» (AURORA-1892)
Cell.jsx: formatNumber вынесен в utils/numberFormat.js и возвращает
{ text, isNegative }; отрицательные числа выделяются цветом (#C62828 на
светлом фоне, #FFCDD2 на тёмном) и font-weight 600, ноль остаётся «-».

constants/validation.js: фабрика nonNegativeRule и общий список
nonNegativeColumnKeys (план, бронь на 2026/2027, факт по месяцам и СПОД,
сумма платежа, предельная стоимость договора/ЦКК, сателлиты АХР
Аренда/Коммунальные/Безопасность, АХР Лимиты целиком). Корректировки и
переносы (adj_*, base_correction, revision_*, seq_*, target_change,
transfer_*) не включены — там минус — нормальная операция. Запрет
мягкий: подсветка и запись в «Контроль ошибок» через существующий
useValidationRules/isCellInvalid, сохранение не блокируется.

EditCell.jsx: handleSave предупреждает toast.warning при сохранении
отрицательного числа в защищённой колонке, значение всё равно
сохраняется. useValidationRules и RealtimeTable прокидывают
человекочитаемый заголовок колонки для текста предупреждения.

Тесты (node --test): numberFormat.test.js, validationUtils.test.js —
новые, 10/10 зелёных.
2026-11-01 12:20:06 +04:00

38 lines
1.2 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import assert from 'node:assert/strict';
import test from 'node:test';
import { formatNumber } from './numberFormat.js';
test('negative numbers are formatted ru-RU and flagged as negative', () => {
const result = formatNumber(-1234.5);
assert.equal(result.text, '-1 234,5');
assert.equal(result.isNegative, true);
});
test('zero is rendered as a dash and is never negative', () => {
const result = formatNumber(0);
assert.equal(result.text, '-');
assert.equal(result.isNegative, false);
});
test('positive numbers keep the familiar ru-RU grouping and are not negative', () => {
const result = formatNumber(1234.5);
assert.equal(result.text, '1 234,5');
assert.equal(result.isNegative, false);
});
test('asInteger drops the fractional digit', () => {
const integer = formatNumber(1234, true);
assert.equal(integer.text, '1 234');
assert.equal(integer.isNegative, false);
const negativeInteger = formatNumber(-1234, true);
assert.equal(negativeInteger.text, '-1 234');
assert.equal(negativeInteger.isNegative, true);
});
test('non-numeric input is returned as a string without crashing', () => {
const result = formatNumber('не число');
assert.equal(result.text, 'не число');
assert.equal(result.isNegative, false);
});