232 lines
7.5 KiB
TypeScript
232 lines
7.5 KiB
TypeScript
/* eslint-disable implicit-arrow-linebreak */
|
||
/* eslint-disable unicorn/consistent-function-scoping */
|
||
/* eslint-disable @typescript-eslint/naming-convention */
|
||
import type { ApolloClient } from '@apollo/client';
|
||
import { gql } from '@apollo/client';
|
||
import type { QueryClient, QueryFunctionContext } from '@tanstack/react-query';
|
||
import { calculateFinGAP } from 'api/core/query';
|
||
import type { RequestFinGAP } from 'api/core/types';
|
||
import type { Risk } from 'Components/Calculation/Form/Insurance/FinGAPTable/types';
|
||
import { STALE_TIME } from 'constants/request';
|
||
import dayjs from 'dayjs';
|
||
import utc from 'dayjs/plugin/utc';
|
||
import type * as CRMTypes from 'graphql/crm.types';
|
||
import { comparer, reaction, toJS } from 'mobx';
|
||
import type RootStore from 'stores/root';
|
||
import { flatten } from 'tools/object';
|
||
|
||
dayjs.extend(utc);
|
||
|
||
export default function commonReactions(
|
||
store: RootStore,
|
||
apolloClient: ApolloClient<object>,
|
||
queryClient: QueryClient
|
||
) {
|
||
const { $calculation, $tables } = store;
|
||
// Расчет итоговой суммы ФинГАП и запись в таблицу страхования
|
||
reaction(
|
||
() => $tables.fingap.totalSum,
|
||
(totalSum) => {
|
||
$tables.insurance.setRowValues('fingap', {
|
||
insCost: totalSum,
|
||
});
|
||
}
|
||
);
|
||
|
||
/**
|
||
Реакция на изменение Страховой компании у ФинГАП и Срока лизинга:
|
||
|
||
Если Страхованя компания = Не выбрано, то
|
||
|
||
Плательщик insuredFinGAP = ЛП (100 000 000) и закрыто для редактирования,
|
||
Стоимость за первый период inscostFinGAP = 0
|
||
Срок страхования insTermFinGAP = 12 мес (100 000 000) и закрыто для редактирования
|
||
|
||
иначе
|
||
|
||
Плательщик insuredFinGAP = открыто для редактирования,
|
||
Стоимость за первый период inscostFinGAP = 0
|
||
Срок страхования insTermFinGAP = Если срок лизинга tbxLeasingPeriod < 13,
|
||
то указываем Срок страхования insTermFinGAP = 12 мес
|
||
и закрываем для редактирования, иначе открыто для редактирования
|
||
*/
|
||
reaction(
|
||
() => {
|
||
const finGAPInsuranceCompany = $tables.insurance.getRowValue('fingap', 'insuranceCompany');
|
||
const leasingPeriod = $calculation.element('tbxLeasingPeriod').getValue();
|
||
|
||
return {
|
||
finGAPInsuranceCompany,
|
||
leasingPeriod,
|
||
};
|
||
},
|
||
({ finGAPInsuranceCompany, leasingPeriod }) => {
|
||
if (!finGAPInsuranceCompany) {
|
||
$tables.insurance.setRowValues('fingap', {
|
||
insured: 100_000_000,
|
||
insCost: 0,
|
||
insTerm: 100_000_000,
|
||
});
|
||
|
||
$tables.insurance.setRowStatuses('fingap', {
|
||
insured: 'Disabled',
|
||
insTerm: 'Disabled',
|
||
});
|
||
} else {
|
||
$tables.insurance.setRowValues('fingap', {
|
||
insured: 100_000_000,
|
||
insCost: 0,
|
||
insTerm: leasingPeriod < 13 ? 100_000_000 : undefined,
|
||
});
|
||
|
||
$tables.insurance.setRowStatuses('fingap', {
|
||
insured: 'Default',
|
||
insTerm: leasingPeriod < 13 ? 'Disabled' : 'Default',
|
||
});
|
||
}
|
||
},
|
||
{
|
||
equals: comparer.shallow,
|
||
}
|
||
);
|
||
|
||
// Очищаем таблицу ФинГАП, если не выбрана страховая компания
|
||
reaction(
|
||
() => $tables.insurance.getRowValue('fingap', 'insuranceCompany'),
|
||
(finGAPInsuranceCompany) => {
|
||
if (!finGAPInsuranceCompany) {
|
||
$tables.fingap.clear();
|
||
}
|
||
}
|
||
);
|
||
|
||
const QUERY_GET_FINGAP_ADDPRODUCT_TYPES = gql`
|
||
query GetFinGAPAddProductTypes($currentDate: DateTime) {
|
||
evo_addproduct_types(
|
||
statecode: 0
|
||
evo_datefrom_param: { lte: $currentDate }
|
||
evo_dateto_param: { gte: $currentDate }
|
||
evo_product_type: 100000006
|
||
) {
|
||
evo_addproduct_typeid
|
||
evo_name
|
||
evo_type_calc_cerebellum
|
||
evo_cost_service_provider_withoutnds
|
||
evo_addproduct_types {
|
||
evo_addproduct_typeid
|
||
}
|
||
}
|
||
}
|
||
`;
|
||
|
||
// Заполнение таблицы рисков ФинГАП + Запрос расчета финГАП в мозжечок
|
||
|
||
reaction(
|
||
() => {
|
||
const finGAPInsuranceCompany = $tables.insurance.getRowValue('fingap', 'insuranceCompany');
|
||
const paymentsValues = toJS($tables.payments.values);
|
||
const plPriceRub = $calculation.$values.getValue('plPriceRub');
|
||
const discountRub = $calculation.$values.getValue('discountRub');
|
||
const firstPaymentRub = $calculation.element('tbxFirstPaymentRub').getValue();
|
||
const leasingPeriod = $calculation.element('tbxLeasingPeriod').getValue();
|
||
|
||
return {
|
||
finGAPInsuranceCompany,
|
||
paymentsValues,
|
||
plPriceRub,
|
||
discountRub,
|
||
firstPaymentRub,
|
||
leasingPeriod,
|
||
};
|
||
},
|
||
async ({
|
||
finGAPInsuranceCompany,
|
||
paymentsValues,
|
||
plPriceRub,
|
||
discountRub,
|
||
firstPaymentRub,
|
||
leasingPeriod,
|
||
}) => {
|
||
if (!finGAPInsuranceCompany || $tables.payments.validation.hasErrors) return;
|
||
|
||
const {
|
||
data: { evo_addproduct_types },
|
||
} = await apolloClient.query<
|
||
CRMTypes.GetFinGapAddProductTypesQuery,
|
||
CRMTypes.GetFinGapAddProductTypesQueryVariables
|
||
>({
|
||
query: QUERY_GET_FINGAP_ADDPRODUCT_TYPES,
|
||
variables: {
|
||
currentDate: dayjs().utc().format('YYYY-MM-DD'),
|
||
},
|
||
});
|
||
|
||
const risks = evo_addproduct_types?.map(
|
||
// prettier-ignore
|
||
(evo_addproduct_type) => ({
|
||
key: evo_addproduct_type?.evo_addproduct_typeid,
|
||
riskId: evo_addproduct_type?.evo_addproduct_typeid,
|
||
riskName: evo_addproduct_type?.evo_name,
|
||
calcType: evo_addproduct_type?.evo_type_calc_cerebellum,
|
||
premiumPerc: evo_addproduct_type?.evo_cost_service_provider_withoutnds,
|
||
sum: 0,
|
||
premium: 0,
|
||
keys: evo_addproduct_type?.evo_addproduct_types?.map((k) => k?.evo_addproduct_typeid),
|
||
} as Risk)
|
||
);
|
||
|
||
if (!risks) return;
|
||
|
||
$tables.fingap.setRisks(risks);
|
||
|
||
function getFingapRequestDataFromRisk(risk: Risk): RequestFinGAP {
|
||
return {
|
||
calcType: risk.calcType,
|
||
payments: paymentsValues.map((payment) => ({
|
||
percentPayment: payment,
|
||
})),
|
||
values: {
|
||
plPrice: plPriceRub,
|
||
discount: discountRub,
|
||
firstPayment: firstPaymentRub,
|
||
leasingPeriod,
|
||
premiumPerc: risk.premiumPerc || 0,
|
||
},
|
||
};
|
||
}
|
||
|
||
function makeRequestGetFinGAP(request: RequestFinGAP) {
|
||
const queryCalculateFinGAP = (context: QueryFunctionContext) =>
|
||
calculateFinGAP(request, context);
|
||
|
||
return queryClient.fetchQuery(
|
||
['core', 'fingap', ...flatten(request)],
|
||
queryCalculateFinGAP,
|
||
{
|
||
staleTime: STALE_TIME,
|
||
}
|
||
);
|
||
}
|
||
|
||
Promise.all(
|
||
risks
|
||
.map((risk) => getFingapRequestDataFromRisk(risk))
|
||
.map((data) => makeRequestGetFinGAP(data))
|
||
).then((results) => {
|
||
const newRisks = risks.map((risk, i) => ({
|
||
...risk,
|
||
sum: results.at(i)?.sum || 0,
|
||
premium: results.at(i)?.premium || 0,
|
||
}));
|
||
|
||
$tables.fingap.setRisks(newRisks);
|
||
});
|
||
},
|
||
{
|
||
// Important: delay prohibits multiple reaction invocation
|
||
equals: comparer.structural,
|
||
delay: 100,
|
||
}
|
||
);
|
||
}
|