339 lines
8.7 KiB
TypeScript
339 lines
8.7 KiB
TypeScript
/* eslint-disable function-paren-newline */
|
|
/* eslint-disable implicit-arrow-linebreak */
|
|
import type { ApolloClient } from '@apollo/client';
|
|
import type { QueryClient } from '@tanstack/react-query';
|
|
import { selectSeasonType } from 'config/default-options';
|
|
import { reaction, toJS } from 'mobx';
|
|
import { sort } from 'radash/dist/array';
|
|
import type RootStore from 'stores/root';
|
|
import type { Row } from 'stores/tables/payments/types';
|
|
import { areEqual } from 'tools/array';
|
|
|
|
export default function paymentsReactions(
|
|
store: RootStore,
|
|
apolloClient: ApolloClient<object>,
|
|
queryClient: QueryClient
|
|
) {
|
|
const { $calculation, $tables } = store;
|
|
|
|
reaction(
|
|
() => $calculation.getElementValue('tbxFirstPaymentPerc'),
|
|
(firstPaymentPerc) => {
|
|
$tables.payments.setValue(0, firstPaymentPerc);
|
|
}
|
|
);
|
|
|
|
reaction(
|
|
() => $calculation.getElementValue('tbxLastPaymentPerc'),
|
|
(lastPaymentPerc) => {
|
|
const paymentsLength = $tables.payments.values.length;
|
|
$tables.payments.setValue(paymentsLength - 1, lastPaymentPerc);
|
|
}
|
|
);
|
|
|
|
/**
|
|
* Аннуитет
|
|
*/
|
|
reaction(
|
|
() => {
|
|
const graphType = $calculation.getElementValue('radioGraphType');
|
|
const leasingPeriod = $calculation.getElementValue('tbxLeasingPeriod');
|
|
|
|
return {
|
|
graphType,
|
|
leasingPeriod,
|
|
};
|
|
},
|
|
({ graphType, leasingPeriod }) => {
|
|
if (graphType === 100_000_000) {
|
|
const middlePayments: Row[] = Array.from(
|
|
{
|
|
length: leasingPeriod - 2,
|
|
},
|
|
() => ({
|
|
value: 100,
|
|
status: 'Disabled',
|
|
})
|
|
);
|
|
|
|
const firstPaymentPerc = $calculation.getElementValue('tbxFirstPaymentPerc');
|
|
const lastPaymentPerc = $calculation.getElementValue('tbxLastPaymentPerc');
|
|
|
|
$tables.payments.setRows([
|
|
{
|
|
value: firstPaymentPerc,
|
|
status: 'Disabled',
|
|
},
|
|
...middlePayments,
|
|
{
|
|
value: lastPaymentPerc,
|
|
status: 'Disabled',
|
|
},
|
|
]);
|
|
}
|
|
},
|
|
{
|
|
fireImmediately: true,
|
|
}
|
|
);
|
|
|
|
/**
|
|
* Равноубывающий
|
|
*/
|
|
reaction(
|
|
() => {
|
|
const graphType = $calculation.getElementValue('radioGraphType');
|
|
const leasingPeriod = $calculation.getElementValue('tbxLeasingPeriod');
|
|
const parmentsDecreasePercent = $calculation.getElementValue('tbxParmentsDecreasePercent');
|
|
|
|
return {
|
|
graphType,
|
|
leasingPeriod,
|
|
parmentsDecreasePercent,
|
|
};
|
|
},
|
|
({ graphType, leasingPeriod, parmentsDecreasePercent }) => {
|
|
if (graphType === 100_000_002) {
|
|
const middlePayments: Row[] = Array.from(
|
|
{
|
|
length: leasingPeriod - 2,
|
|
},
|
|
(_, k) => {
|
|
const payment = 100 * (parmentsDecreasePercent / 100) ** k;
|
|
|
|
return {
|
|
value: Number(payment.toFixed(2)),
|
|
status: 'Disabled',
|
|
};
|
|
}
|
|
);
|
|
|
|
const firstPaymentPerc = $calculation.getElementValue('tbxFirstPaymentPerc');
|
|
const lastPaymentPerc = $calculation.getElementValue('tbxLastPaymentPerc');
|
|
|
|
$tables.payments.setRows([
|
|
{
|
|
value: firstPaymentPerc,
|
|
status: 'Disabled',
|
|
},
|
|
...middlePayments,
|
|
{
|
|
value: lastPaymentPerc,
|
|
status: 'Disabled',
|
|
},
|
|
]);
|
|
}
|
|
}
|
|
);
|
|
|
|
/**
|
|
* Легкий старт
|
|
*/
|
|
reaction(
|
|
() => {
|
|
const graphType = $calculation.getElementValue('radioGraphType');
|
|
const leasingPeriod = $calculation.getElementValue('tbxLeasingPeriod');
|
|
|
|
return {
|
|
graphType,
|
|
leasingPeriod,
|
|
};
|
|
},
|
|
({ graphType, leasingPeriod }) => {
|
|
if (graphType === 100_000_004) {
|
|
const editablePayments: Row[] = [
|
|
{
|
|
value: 25,
|
|
status: 'Default',
|
|
},
|
|
{
|
|
value: 50,
|
|
status: 'Default',
|
|
},
|
|
{
|
|
value: 75,
|
|
status: 'Default',
|
|
},
|
|
];
|
|
|
|
const payments: Row[] = Array.from(
|
|
{
|
|
length: leasingPeriod - 5,
|
|
},
|
|
() => ({
|
|
value: 100,
|
|
status: 'Disabled',
|
|
})
|
|
);
|
|
|
|
const firstPaymentPerc = $calculation.getElementValue('tbxFirstPaymentPerc');
|
|
const lastPaymentPerc = $calculation.getElementValue('tbxLastPaymentPerc');
|
|
|
|
$tables.payments.setRows([
|
|
{
|
|
value: firstPaymentPerc,
|
|
status: 'Disabled',
|
|
},
|
|
...editablePayments,
|
|
...payments,
|
|
{
|
|
value: lastPaymentPerc,
|
|
status: 'Disabled',
|
|
},
|
|
]);
|
|
}
|
|
}
|
|
);
|
|
|
|
const errorText = 'При виде графика "Легкий старт" 2, 3, 4 платежи должны возрастать';
|
|
let removeError: () => void;
|
|
|
|
reaction(
|
|
() => {
|
|
const graphType = $calculation.getElementValue('radioGraphType');
|
|
const payments = $tables.payments.values;
|
|
|
|
return {
|
|
payments: toJS(payments),
|
|
graphType,
|
|
};
|
|
},
|
|
({ payments, graphType }) => {
|
|
if (graphType === 100_000_004) {
|
|
const targetPayments = payments.slice(1, 4);
|
|
const sortedPayments = sort(targetPayments, (x) => x);
|
|
const areEqualPayments = new Set(targetPayments).size === 1;
|
|
|
|
if (!areEqual(targetPayments, sortedPayments) || areEqualPayments) {
|
|
removeError = $tables.payments.validation.addError(errorText);
|
|
} else if (removeError) removeError();
|
|
} else if (removeError) removeError();
|
|
}
|
|
);
|
|
|
|
/**
|
|
* Дегрессия
|
|
*/
|
|
const degressionSeasonTypes = new Set([
|
|
100_000_003, 100_000_004, 100_000_005, 100_000_006, 100_000_007,
|
|
]);
|
|
|
|
reaction(
|
|
() => {
|
|
const graphType = $calculation.getElementValue('radioGraphType');
|
|
|
|
return graphType;
|
|
},
|
|
(graphType) => {
|
|
if (!graphType || graphType !== 100_000_001) {
|
|
$calculation.setElementOptions('selectSeasonType', []);
|
|
|
|
return;
|
|
}
|
|
|
|
const selectSeasonTypeOptions = selectSeasonType.filter((option) =>
|
|
degressionSeasonTypes.has(option.value)
|
|
);
|
|
$calculation.setElementOptions('selectSeasonType', selectSeasonTypeOptions);
|
|
}
|
|
);
|
|
|
|
const degressionSteps: { [key: number]: Array<number> } = {
|
|
100_000_003: [100, 50, 25],
|
|
100_000_004: [100, 30, 10],
|
|
100_000_005: [100, 70, 40],
|
|
100_000_006: [100, 7, 3],
|
|
};
|
|
|
|
reaction(
|
|
() => {
|
|
const degressionType = $calculation.getElementValue('selectSeasonType');
|
|
const leasingPeriod = $calculation.getElementValue('tbxLeasingPeriod');
|
|
const graphType = $calculation.getElementValue('radioGraphType');
|
|
|
|
return {
|
|
degressionType,
|
|
leasingPeriod,
|
|
graphType,
|
|
};
|
|
},
|
|
({ degressionType, leasingPeriod, graphType }) => {
|
|
if (graphType === 100_000_001) {
|
|
let payments: Row[] = [];
|
|
|
|
switch (degressionType) {
|
|
case 100_000_007: {
|
|
const editablePayments: Row[] = Array.from(
|
|
{
|
|
length: leasingPeriod - 3,
|
|
},
|
|
() => ({
|
|
value: 100,
|
|
status: 'Default',
|
|
})
|
|
);
|
|
|
|
payments = [
|
|
{
|
|
value: 100,
|
|
status: 'Disabled',
|
|
},
|
|
...editablePayments,
|
|
];
|
|
|
|
break;
|
|
}
|
|
case 100_000_003:
|
|
case 100_000_004:
|
|
case 100_000_005:
|
|
case 100_000_006: {
|
|
const [step1, step2, step3] = degressionSteps[degressionType];
|
|
const paymentsInStep = Math.ceil((leasingPeriod - 2) / 3);
|
|
|
|
payments = Array.from(
|
|
{
|
|
length: leasingPeriod - 2,
|
|
},
|
|
(_v, i) => {
|
|
let value = step3;
|
|
|
|
if (i <= paymentsInStep * 2 - 1) {
|
|
value = step2;
|
|
}
|
|
|
|
if (i <= paymentsInStep - 1) {
|
|
value = step1;
|
|
}
|
|
|
|
return {
|
|
value,
|
|
status: 'Disabled',
|
|
};
|
|
}
|
|
);
|
|
break;
|
|
}
|
|
default: {
|
|
break;
|
|
}
|
|
}
|
|
|
|
const firstPaymentPerc = $calculation.getElementValue('tbxFirstPaymentPerc');
|
|
const lastPaymentPerc = $calculation.getElementValue('tbxLastPaymentPerc');
|
|
|
|
$tables.payments.setRows([
|
|
{
|
|
value: firstPaymentPerc,
|
|
status: 'Disabled',
|
|
},
|
|
...payments,
|
|
{
|
|
value: lastPaymentPerc,
|
|
status: 'Disabled',
|
|
},
|
|
]);
|
|
}
|
|
}
|
|
);
|
|
}
|