2023-07-04 10:42:55 +03:00

225 lines
7.7 KiB
TypeScript
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.

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 type * as CRMTypes from '@/graphql/crm.types';
import type { ProcessContext } from '@/process/types';
import { disposableReaction } from '@/utils/mobx';
import { gql } from '@apollo/client';
import type { QueryFunctionContext } from '@tanstack/react-query';
import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc';
import { comparer, reaction, toJS } from 'mobx';
import { flatten } from 'tools/object';
dayjs.extend(utc);
export default function reactions({ store, apolloClient, queryClient }: ProcessContext) {
const { $calculation, $tables, $process } = store;
// Расчет итоговой суммы ФинГАП и запись в таблицу страхования
reaction(
() => $tables.fingap.totalSum,
(totalSum) => {
$tables.insurance.row('fingap').setValue('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.row('fingap').getValue('insuranceCompany');
const leasingPeriod = $calculation.element('tbxLeasingPeriod').getValue();
return {
finGAPInsuranceCompany,
leasingPeriod,
};
},
({ finGAPInsuranceCompany, leasingPeriod }) => {
// eslint-disable-next-line no-negated-condition
if (!finGAPInsuranceCompany) {
$tables.insurance.row('fingap').column('insured').setValue(100_000_000).block();
$tables.insurance.row('fingap').column('insCost').setValue(0);
$tables.insurance.row('fingap').column('insTerm').setValue(100_000_000).block();
} else {
$tables.insurance.row('fingap').column('insured').unblock();
if (leasingPeriod < 13) {
$tables.insurance.row('fingap').column('insTerm').setValue(100_000_000).block();
} else {
$tables.insurance.row('fingap').column('insTerm').unblock();
}
}
},
{
equals: comparer.shallow,
fireImmediately: true,
}
);
// Очищаем таблицу ФинГАП, если не выбрана страховая компания
reaction(
() => $tables.insurance.row('fingap').getValue('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
}
}
}
`;
// Заполнение таблицы рисков ФинГАП + Запрос расчета финГАП в мозжечок
disposableReaction(
() => $process.has('Calculate'),
() => {
const finGAPInsuranceCompany = $tables.insurance.row('fingap').getValue('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();
const hasPaymentsErrors = $tables.payments.validation.hasErrors;
return {
discountRub,
finGAPInsuranceCompany,
firstPaymentRub,
hasPaymentsErrors,
leasingPeriod,
paymentsValues,
plPriceRub,
};
},
async ({
finGAPInsuranceCompany,
paymentsValues,
plPriceRub,
discountRub,
firstPaymentRub,
leasingPeriod,
hasPaymentsErrors,
}) => {
if (!finGAPInsuranceCompany || hasPaymentsErrors) {
$tables.fingap.clear();
return;
}
const {
data: { evo_addproduct_types },
} = await apolloClient.query<
CRMTypes.GetFinGapAddProductTypesQuery,
CRMTypes.GetFinGapAddProductTypesQueryVariables
>({
query: QUERY_GET_FINGAP_ADDPRODUCT_TYPES,
variables: {
currentDate: dayjs().utc(false).toISOString(),
},
});
const risks = evo_addproduct_types?.map(
(evo_addproduct_type) =>
({
calcType: evo_addproduct_type?.evo_type_calc_cerebellum,
key: evo_addproduct_type?.evo_addproduct_typeid,
keys: evo_addproduct_type?.evo_addproduct_types?.map(
(addproduct_type) => addproduct_type?.evo_addproduct_typeid
),
premium: 0,
premiumPerc: evo_addproduct_type?.evo_cost_service_provider_withoutnds,
riskId: evo_addproduct_type?.evo_addproduct_typeid,
riskName: evo_addproduct_type?.evo_name,
sum: 0,
} 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: {
discount: discountRub,
firstPayment: firstPaymentRub,
leasingPeriod,
plPrice: plPriceRub,
premiumPerc: risk.premiumPerc || 0,
},
};
}
// eslint-disable-next-line unicorn/consistent-function-scoping
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,
premium: results.at(i)?.premium || 0,
sum: results.at(i)?.sum || 0,
}));
$tables.fingap.setRisks(newRisks);
});
},
{
// Important: delay prohibits multiple reaction invocation
delay: 100,
equals: comparer.structural,
}
);
}