/* eslint-disable no-case-declarations */ import { counting, max, min, shift, sort } from 'radash'; import type RootStore from 'stores/root'; import { areEqual, isSorted } from 'tools/array'; import { SEASONS_PERIODS, SEASONS_PERIOD_NUMBER } from './lib/seasons-constants'; export default function validatePaymentsTable({ $calculation, $tables }: RootStore) { switch ($calculation.element('radioGraphType').getValue()) { // Дегрессия case 100_000_001: { if (!$calculation.element('selectSeasonType').getValue()) { return 'Не выбран тип дегрессии'; } /** * в таблице платежей в столбце Соотношение платежей * для строк с 2 до "Срок лизинга-1" минимальное значение должно быть равно 3 */ { const MIN_PAYMENT = 3; const leasingPeriod = $calculation.element('tbxLeasingPeriod').getValue(); const targetPayments = $tables.payments.values.slice(1, leasingPeriod - 1); if (!targetPayments.every((payment) => payment >= MIN_PAYMENT)) { return `Минимальное значение платежа должно быть равно ${MIN_PAYMENT}`; } } /** * при Дегрессии все значения не должны быть равны друг другу * + что при Легком старте 2,3 и 4 платежи не должны быть равны 100 */ { const leasingPeriod = $calculation.element('tbxLeasingPeriod').getValue(); const targetPayments = $tables.payments.values.slice(1, leasingPeriod - 1); if (new Set(targetPayments).size === 1) { return 'Платежи не должны быть равны друг другу'; } } /** * Проверка на возрастание */ { const leasingPeriod = $calculation.element('tbxLeasingPeriod').getValue(); const targetPayments = $tables.payments.values.slice(1, leasingPeriod - 1); for (let i = 2; i < targetPayments.length - 1; i += 1) { if (targetPayments[i] > targetPayments[i - 1]) { return 'Платежи должны убывать'; } } } /* eslint-disable max-len */ /** * Если вид графика = Дегрессия И значения в "Соотношении платежей" у 2, 3 и 4 платежа отличаются друг от друга не более чем на 10 * (т.е. берем значения в этих полях, определяем максимальное и минимальное значение и смотрим на их разницу) * то не осуществлять Расчет графика и выводить ошибку "Нельзя осуществить расчет - указана очень жетская дегрессия. * На 2-4 платежах Соотношение платежа должен отличаться не более чем на 10%", * иначе осуществлять расчет */ /* eslint-enable */ { const targetPayments = $tables.payments.values.slice(1, 4); if ((max(targetPayments) || 0) - (min(targetPayments) || 0) > 10) { return 'Указана очень жесткая дегрессия'; } } /* eslint-disable max-len */ /** * Если вид графика = Дегрессия И значения в "Соотношении платежей" для строк с 2 До "Срок лизинга-1" как минимум 2 раза по 2 платежа должны между собой быть равны * (т.е. берем значения "Соотношения платежей" для строк с 2 до "Срок лизинга-1" и делаем сводную таблицу - если кол-во одинаковых значение больше 2 встречаются 2 и более раза), * то осуществлять расчет, * иначе не осуществлять Расчет графика и выводить ошибку "Нельзя осуществить расчет - указана очень жетская дегрессия. Не менее чем у 4х платежей "Соотношение платежа" должно не отличаться между самой", */ /* eslint-enable */ { const leasingPeriod = $calculation.element('tbxLeasingPeriod').getValue(); const targetPayments = $tables.payments.values.slice(1, leasingPeriod - 1); const counts = counting(targetPayments, (v) => v); if (Object.values(counts).filter((count) => count > 1).length < 2) { return 'Указана очень жесткая дегрессия. Не менее чем у 4х платежей соотношение должно не отличаться между собой'; } } break; } case 100_000_003: { const leasingPeriod = $calculation.element('tbxLeasingPeriod').getValue(); if (leasingPeriod < 14) { return 'При сезонном виде графика срок лизинга должен быть больше 14 месяцев'; } const seasonType = $calculation.element('selectSeasonType').getValue(); if (!seasonType) { return 'Не выбран тип сезонности'; } const highSeasonStartOption = $calculation.element('selectHighSeasonStart').getOption(); if (!highSeasonStartOption) { return 'Не выбрано смещение сезонности'; } { const seasons = $tables.payments.values.slice(1, SEASONS_PERIOD_NUMBER + 1); const shiftNumber = Number.parseInt(highSeasonStartOption.label, 10) - 2; const unshiftedSeasons = shift(seasons, -shiftNumber); const positions = SEASONS_PERIODS[seasonType]; const seasonsValues = positions.map((position) => unshiftedSeasons[position]); if (isSorted(seasonsValues)) { return 'Сезонные платежи должны убывать'; } } break; } // Легкий старт case 100_000_004: { const targetPayments = $tables.payments.values.slice(1, 4); const sortedPayments = sort(targetPayments, (x) => x); const areEqualPayments = new Set(targetPayments).size === 1; if (!areEqual(targetPayments, sortedPayments) || areEqualPayments) { return '2, 3, 4 платежи должны возрастать'; } break; } default: { return null; } } return null; }