add validation #88

Merged
PotapovaA merged 1 commits from add-validation into test 2026-08-12 16:08:47 +03:00
3 changed files with 85 additions and 3 deletions

View File

@ -18,6 +18,35 @@ const zeroValueRequirementKeys = [
"data.q4.adj_current", "data.q4.adj_current",
]; ];
//Бронь <= Остаток после брони
const bookingLessBalance = [
["data.q1.booking", "data.q1.residual_after_booking"],
["data.q2.booking", "data.q2.residual_after_booking"],
["data.q3.booking", "data.q3.residual_after_booking"],
["data.q4.booking", "data.q4.residual_after_booking"],
];
const bookingLessBalanceByColumn = new Map(
bookingLessBalance.flatMap(([bookingKey, balanceKey]) => [
[bookingKey, { bookingKey, balanceKey }],
[balanceKey, { bookingKey, balanceKey }],
]),
);
//Перенос в фонд экономии <= Всего
const transferLessTotal = [
["data.q1.transfer_econ", "data.q1.total"],
["data.q2.transfer_econ", "data.q2.total"],
["data.q3.transfer_econ", "data.q3.total"],
["data.q4.transfer_econ", "data.q4.total"],
]
const transferLessTotalByColumn = new Map(
transferLessTotal.flatMap(([transferKey, totalKey]) => [
[transferKey, { transferKey: transferKey, totalKey: totalKey }],
[totalKey, { transferKey: transferKey, totalKey: totalKey }],
]),
);
export const validationRules = [ export const validationRules = [
{ {
id: "remaining-booking", id: "remaining-booking",
@ -42,4 +71,54 @@ export const validationRules = [
Number.isFinite(Number(value)) && Number.isFinite(Number(value)) &&
Number(value) !== 0, Number(value) !== 0,
}, },
{
id: "booking-less-balance",
columnKeys: bookingLessBalance.flat(),
errorColumnKeys: bookingLessBalance.map(([bookingKey]) => bookingKey),
message: "Сумма бронирования превышает остаток после бронирования",
isInvalid: (_value, row, columnKey) => {
const pair = bookingLessBalanceByColumn.get(columnKey);
if (!pair) return false;
const booking = pair.bookingKey.split(".").reduce((value, key) => value?.[key], row);
const balance = pair.balanceKey.split(".").reduce((value, key) => value?.[key], row);
return (
booking !== null &&
booking !== undefined &&
booking !== "" &&
balance !== null &&
balance !== undefined &&
balance !== "" &&
Number.isFinite(Number(booking)) &&
Number.isFinite(Number(balance)) &&
Number(booking) > Number(balance)
);
},
},
{
id: "transfer-less-total",
columnKeys: transferLessTotal.flat(),
errorColumnKeys: transferLessTotal.map(([transferKey]) => transferKey),
message: "Перенос в фонд экономии превышает всего",
isInvalid: (_value, row, columnKey) => {
const pair = transferLessTotalByColumn.get(columnKey);
if (!pair) return false;
const transfer = pair.transferKey.split(".").reduce((value, key) => value?.[key], row);
const total = pair.totalKey.split(".").reduce((value, key) => value?.[key], row);
return (
transfer !== null &&
transfer !== undefined &&
transfer !== "" &&
total !== null &&
total !== undefined &&
total !== "" &&
Number.isFinite(Number(transfer)) &&
Number.isFinite(Number(total)) &&
Number(transfer) > Number(total)
);
},
},
]; ];

View File

@ -19,7 +19,10 @@ export const useValidationRules = (data = [], columns = []) => {
const isCellInvalid = useCallback( const isCellInvalid = useCallback(
(columnId, value, row) => (columnId, value, row) =>
validationRules.some( validationRules.some(
(rule) => rule.columnKeys.includes(columnId) && (!rule.appliesToRow || rule.appliesToRow(row)) && rule.isInvalid(value), (rule) =>
rule.columnKeys.includes(columnId) &&
(!rule.appliesToRow || rule.appliesToRow(row)) &&
rule.isInvalid(value, row, columnId),
), ),
[], [],
); );

View File

@ -20,8 +20,8 @@ export const buildColumnHeaderPaths = (columns = [], path = [], map = {}) => {
export const collectInvalidErrors = (rows, rule, headerPaths, errors, seen) => { export const collectInvalidErrors = (rows, rule, headerPaths, errors, seen) => {
for (const row of rows) { for (const row of rows) {
if (!rule.appliesToRow || rule.appliesToRow(row)) { if (!rule.appliesToRow || rule.appliesToRow(row)) {
for (const columnKey of rule.columnKeys) { for (const columnKey of rule.errorColumnKeys || rule.columnKeys) {
if (!rule.isInvalid(getValueByPath(row, columnKey))) continue; if (!rule.isInvalid(getValueByPath(row, columnKey), row, columnKey)) continue;
const errorId = `${rule.id}:${columnKey}`; const errorId = `${rule.id}:${columnKey}`;
if (seen.has(errorId)) continue; if (seen.has(errorId)) continue;