PotapovaA ecbd89cc71 fix
2026-08-17 13:30:02 +03:00

214 lines
6.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Требование №1. Контроль превышения бронирования над сметой.
const remainingBookingKeys = [
"data.q1.rem_booking",
"data.q2.rem_booking",
"data.q3.rem_booking",
"data.q4.rem_booking",
"data.q1.residual_after_booking",
"data.q2.residual_after_booking",
"data.q3.residual_after_booking",
"data.q4.residual_after_booking",
];
// Требование №1 работает для всех форм и листов, кроме CAP и OPER формы 4.
const remainingBookingRuleScope = {
excludedScopes: [
{ formType: "FORM_4", sheetName: "CAP" },
{ formType: "FORM_4", sheetName: "OPER" },
],
};
// Для листов CAP и OPER формы 4 требование №1 проверяет только остаток за 4 квартал.
const remainingBooking4FormKeys = ["data.q4.residual_after_booking"];
const remainingBooking4FormRuleScope = {
includedScopes: [
{ formType: "FORM_4", sheetName: "CAP" },
{ formType: "FORM_4", sheetName: "OPER" },
],
};
// Требование №2. Контроль столбца «Текущие корректировки = 0».
const zeroValueRequirementKeys = [
"data.q1.adj_current",
"data.q2.adj_current",
"data.q3.adj_current",
"data.q4.adj_current",
];
// Бронь <= Остаток после брони для формы 2.
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 }],
]),
);
// Экономия <= Всего для форм 1 и 4.
const economyLessTotal = [
["data.q1.economy", "data.q1.total"],
["data.q2.economy", "data.q2.total"],
["data.q3.economy", "data.q3.total"],
["data.q4.economy", "data.q4.total"],
];
const economyLessTotalByColumn = new Map(
economyLessTotal.flatMap(([economyKey, totalKey]) => [
[economyKey, { economyKey, totalKey }],
[totalKey, { economyKey, totalKey }],
]),
);
//Перенос в фонд экономии <= Всего
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 }],
]),
);
const bookingLessBalanceRuleScope = {
includedScopes: [{ formType: "FORM_2" }],
};
export const validationRules = [
{
...remainingBookingRuleScope,
id: "remaining-booking",
columnKeys: remainingBookingKeys,
message: "Сумма бронирования превышает сумму, предусмотренную сметой",
isInvalid: (value) =>
value !== null &&
value !== undefined &&
value !== "" &&
Number.isFinite(Number(value)) &&
Number(value) < 0,
},
{
...remainingBooking4FormRuleScope,
id: "remaining-booking-4-form",
columnKeys: remainingBooking4FormKeys,
message: "Сумма бронирования превышает сумму, предусмотренную сметой",
isInvalid: (value) =>
value !== null &&
value !== undefined &&
value !== "" &&
Number.isFinite(Number(value)) &&
Number(value) < 0,
},
{
id: "current-adjustments-zero",
columnKeys: zeroValueRequirementKeys,
message: "Текущие корректировки должны быть равны 0",
appliesToRow: (row) => row?.depth === 0 || row?.row_type === "ROOT",
isInvalid: (value) =>
value !== null &&
value !== undefined &&
value !== "" &&
Number.isFinite(Number(value)) &&
Number(value) !== 0,
},
{
...bookingLessBalanceRuleScope,
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)
);
},
},
{
includedScopes: [{ formType: "FORM_1" }, { formType: "FORM_4" }],
id: "economy-less-total",
columnKeys: economyLessTotal.flat(),
errorColumnKeys: economyLessTotal.map(([economyKey]) => economyKey),
message: "Экономия должна быть меньше значения «Всего»",
isInvalid: (_value, row, columnKey) => {
const pair = economyLessTotalByColumn.get(columnKey);
if (!pair) return false;
const economy = pair.economyKey
.split(".")
.reduce((value, key) => value?.[key], row);
const total = pair.totalKey
.split(".")
.reduce((value, key) => value?.[key], row);
return (
economy !== null &&
economy !== undefined &&
economy !== "" &&
total !== null &&
total !== undefined &&
total !== "" &&
Number.isFinite(Number(economy)) &&
Number.isFinite(Number(total)) &&
Number(economy) > Number(total)
);
},
},
{
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)
);
},
},
];