diff --git a/apps/web/Components/Calculation/Form/ELT/Kasko.tsx b/apps/web/Components/Calculation/Form/ELT/Kasko.tsx index f3f3272..9d57c95 100644 --- a/apps/web/Components/Calculation/Form/ELT/Kasko.tsx +++ b/apps/web/Components/Calculation/Form/ELT/Kasko.tsx @@ -9,15 +9,15 @@ import helper from '@/process/elt/lib/helper'; import { useStore } from '@/stores/hooks'; import { defaultRow } from '@/stores/tables/elt/default-values'; import { useApolloClient } from '@apollo/client'; -import type { QueryFunctionContext } from '@tanstack/react-query'; -import { useQueries } from '@tanstack/react-query'; import { observer } from 'mobx-react-lite'; +import { omit, sift } from 'radash'; +import { useCallback } from 'react'; import { Flex } from 'ui/grid'; const storeSelector: StoreSelector = ({ kasko }) => kasko; const initialData = { - ...defaultRow, + ...omit(defaultRow, ['name', 'key', 'id']), error: null, kaskoSum: 0, paymentPeriods: [ @@ -25,72 +25,48 @@ const initialData = { kaskoSum: 0, }, ], - sum: 0, }; export const Kasko = observer(() => { const store = useStore(); const { $tables, $calculation } = store; - const apolloClient = useApolloClient(); - const { init } = helper({ apolloClient, store }); - const queries = useQueries({ - queries: $tables.elt.kasko.getRows.map((row) => { - const { id, key, name } = row; + const handleOnClick = useCallback(async () => { + $tables.elt.kasko.abortController?.abort(); + $tables.elt.kasko.abortController = new AbortController(); - return { - enabled: false, - initialData: { ...initialData, id, key, name }, - queryFn: async (context: QueryFunctionContext) => { - const payload = await makeEltKaskoRequest({ apolloClient, store }, row); - const res = await getEltKasko(payload, context); - - if (res) { - const companyRes = res?.[id]; - - return { ...companyRes, id, key, name }; - } - - return { ...initialData, id, key, name }; - }, - queryKey: ['elt', 'kasko', id], - refetchOnWindowFocus: false, - retry: false, - }; - }), - }); - - async function handleOnClick() { const { kasko } = await init(); $tables.elt.kasko.setRows(kasko); - - const kaskoCompanyIds = $tables.insurance - .row('kasko') - .getOptions('insuranceCompany') - .map((x) => x.value); + const kaskoCompanyIds = sift( + $tables.insurance + .row('kasko') + .getOptions('insuranceCompany') + .map((x) => x.value) + ); const values = $calculation.$values.getValues(); - queries - .filter(({ data }) => data?.key && kaskoCompanyIds.includes(data.key)) - .forEach(({ refetch, data, remove }) => { - remove(); - if (data?.key) $tables.elt.kasko.setRow({ key: data?.key, status: 'fetching' }); - - refetch() + kaskoCompanyIds.forEach((key) => { + const row = $tables.elt.kasko.getRow(key); + if (row) { + $tables.elt.kasko.setRow({ key, status: 'fetching' }); + makeEltKaskoRequest({ apolloClient, store }, row) + .then((payload) => + getEltKasko(payload, { signal: $tables.elt.kasko.abortController?.signal }) + ) .then((res) => { - if (res.data) { + if (res) { + const companyRes = res?.[row.id]; const { - key, kaskoSum = 0, message, skCalcId, totalFranchise = 0, requestId, paymentPeriods, - } = res.data; - let { error } = res.data; + } = companyRes; + let { error } = companyRes; if (totalFranchise > MAX_FRANCHISE) { error ||= `Франшиза по страховке превышает максимально допустимое значение: ${Intl.NumberFormat( @@ -129,22 +105,22 @@ export const Kasko = observer(() => { requestId, skCalcId, status: error ? 'error' : null, - sum: values.leasingPeriod <= 16 ? kaskoSum : paymentPeriods?.at(0)?.kaskoSum || 0, + sum: values.leasingPeriod <= 16 ? kaskoSum : paymentPeriods?.[0]?.kaskoSum || 0, totalFranchise, }); } }) .catch((error) => { - if (data?.key) - $tables.elt.kasko.setRow({ - ...defaultRow, - key: data?.key, - message: error, - status: 'error', - }); + $tables.elt.kasko.setRow({ + ...initialData, + key, + message: error, + status: 'error', + }); }); - }); - } + } + }); + }, [$calculation.$values, $tables.elt.kasko, $tables.insurance, apolloClient, init, store]); function handleOnSelectRow(row: Row) { $tables.insurance.row('kasko').column('insuranceCompany').setValue(row.key); diff --git a/apps/web/Components/Calculation/Form/ELT/Osago.tsx b/apps/web/Components/Calculation/Form/ELT/Osago.tsx index d53c77c..11ecde5 100644 --- a/apps/web/Components/Calculation/Form/ELT/Osago.tsx +++ b/apps/web/Components/Calculation/Form/ELT/Osago.tsx @@ -9,75 +9,51 @@ import helper from '@/process/elt/lib/helper'; import { useStore } from '@/stores/hooks'; import { defaultRow } from '@/stores/tables/elt/default-values'; import { useApolloClient } from '@apollo/client'; -import type { QueryFunctionContext } from '@tanstack/react-query'; -import { useQueries } from '@tanstack/react-query'; import { observer } from 'mobx-react-lite'; +import { omit, sift } from 'radash'; +import { useCallback } from 'react'; import { Flex } from 'ui/grid'; const storeSelector: StoreSelector = ({ osago }) => osago; const initialData = { - ...defaultRow, + ...omit(defaultRow, ['name', 'key', 'id']), error: null, premiumSum: 0, - sum: 0, }; export const Osago = observer(() => { const store = useStore(); const { $tables } = store; - const apolloClient = useApolloClient(); - const { init } = helper({ apolloClient, store }); - const queries = useQueries({ - queries: $tables.elt.osago.getRows.map((row) => { - const { id, key, name } = row; + const handleOnClick = useCallback(async () => { + $tables.elt.osago.abortController?.abort(); + $tables.elt.osago.abortController = new AbortController(); - return { - enabled: false, - initialData: { ...initialData, id, key, name }, - queryFn: async (context: QueryFunctionContext) => { - const payload = await makeEltOsagoRequest({ apolloClient, store }, row); - const res = await getEltOsago(payload, context); - - if (res) { - const companyRes = res?.[id]; - - return { ...companyRes, id, key, name }; - } - - return { ...initialData, id, key, name }; - }, - queryKey: ['elt', 'osago', id], - refetchOnWindowFocus: false, - retry: false, - }; - }), - }); - - async function handleOnClick() { const { osago } = await init(); $tables.elt.osago.setRows(osago); - - const osagoCompanyIds = $tables.insurance - .row('osago') - .getOptions('insuranceCompany') - .map((x) => x.value); - - queries - .filter(({ data }) => data?.key && osagoCompanyIds.includes(data?.key)) - .forEach(({ refetch, data, remove }) => { - remove(); - if (data?.key) $tables.elt.osago.setRow({ key: data?.key, status: 'fetching' }); - - refetch() + const osagoCompanyIds = sift( + $tables.insurance + .row('osago') + .getOptions('insuranceCompany') + .map((x) => x.value) + ); + osagoCompanyIds.forEach((key) => { + const row = $tables.elt.osago.getRow(key); + if (row) { + row.status = 'fetching'; + $tables.elt.osago.setRow(row); + makeEltOsagoRequest({ apolloClient, store }, row) + .then((payload) => + getEltOsago(payload, { signal: $tables.elt.osago.abortController.signal }) + ) .then((res) => { - if (res.data) { - const { key, numCalc, premiumSum = 0, message, skCalcId } = res.data; - let { error } = res.data; - + if (res) { + const companyRes = res?.[row.id]; + const { numCalc, premiumSum = 0, message, skCalcId } = companyRes; + let { error } = companyRes; if (premiumSum > MAX_INSURANCE) { error ||= `Сумма по страховке превышает максимально допустимое значение по стоимости ОСАГО: ${Intl.NumberFormat( 'ru', @@ -87,7 +63,6 @@ export const Osago = observer(() => { } ).format(MAX_INSURANCE)}`; } - if (premiumSum < MIN_INSURANCE) { error ||= `Сумма по страховке не должна быть меньше допустимого значения по стоимости ОСАГО: ${Intl.NumberFormat( 'ru', @@ -97,7 +72,6 @@ export const Osago = observer(() => { } ).format(MIN_INSURANCE)}`; } - $tables.elt.osago.setRow({ key, message: error || message, @@ -109,16 +83,16 @@ export const Osago = observer(() => { } }) .catch((error) => { - if (data?.key) - $tables.elt.osago.setRow({ - ...defaultRow, - key: data?.key, - message: error, - status: 'error', - }); + $tables.elt.osago.setRow({ + ...initialData, + key, + message: error, + status: 'error', + }); }); - }); - } + } + }); + }, [$tables.elt.osago, $tables.insurance, apolloClient, init, store]); function handleOnSelectRow(row: Row) { $tables.insurance.row('osago').column('insuranceCompany').setValue(row.key); @@ -133,14 +107,12 @@ export const Osago = observer(() => { title: 'Страховая компания ОСАГО', }; } - if (column.key === 'status') { return { ...column, title: handleOnClick()} />, }; } - if (column.key === 'totalFranchise') { return { ...column, diff --git a/apps/web/api/elt/query.ts b/apps/web/api/elt/query.ts index 318ac54..6711811 100644 --- a/apps/web/api/elt/query.ts +++ b/apps/web/api/elt/query.ts @@ -2,12 +2,14 @@ import type * as ELT from './types'; import getUrls from '@/config/urls'; import { TIMEOUT } from '@/constants/request'; import { withHandleError } from '@/utils/axios'; -import type { QueryFunctionContext } from '@tanstack/react-query'; import axios from 'axios'; const { URL_ELT_KASKO, URL_ELT_OSAGO } = getUrls(); -export async function getEltOsago(payload: ELT.RequestEltOsago, { signal }: QueryFunctionContext) { +export async function getEltOsago( + payload: ELT.RequestEltOsago, + { signal }: { signal: AbortSignal } +) { return withHandleError( axios .post(URL_ELT_OSAGO, payload, { signal, timeout: TIMEOUT }) @@ -15,7 +17,10 @@ export async function getEltOsago(payload: ELT.RequestEltOsago, { signal }: Quer ); } -export async function getEltKasko(payload: ELT.RequestEltKasko, { signal }: QueryFunctionContext) { +export async function getEltKasko( + payload: ELT.RequestEltKasko, + { signal }: { signal: AbortSignal } +) { return withHandleError( axios .post(URL_ELT_KASKO, payload, { signal, timeout: TIMEOUT }) diff --git a/apps/web/process/elt/reactions/common.ts b/apps/web/process/elt/reactions/common.ts index c5149fd..47eeac5 100644 --- a/apps/web/process/elt/reactions/common.ts +++ b/apps/web/process/elt/reactions/common.ts @@ -47,6 +47,8 @@ export default function reactions(context: ProcessContext) { if (initialValues) { $tables.elt.osago.setRows(initialValues.osago); } + + $tables.elt.osago.abortController?.abort(); }, { delay: 10, @@ -100,6 +102,8 @@ export default function reactions(context: ProcessContext) { if (initialValues) { $tables.elt.kasko.setRows(initialValues.kasko); } + + $tables.elt.kasko.abortController?.abort(); }, { delay: 10, diff --git a/apps/web/process/insurance/reactions.ts b/apps/web/process/insurance/reactions.ts index 1d4a2ea..63058e6 100644 --- a/apps/web/process/insurance/reactions.ts +++ b/apps/web/process/insurance/reactions.ts @@ -114,8 +114,14 @@ export function common({ store, apolloClient }: ProcessContext) { ); debouncedReaction( - () => $calculation.$values.getValues(['leasingPeriod', 'leasingWithoutKasko']), - async ({ leasingPeriod, leasingWithoutKasko }) => { + () => + $calculation.$values.getValues([ + 'leasingPeriod', + 'leasingWithoutKasko', + 'dealer', + 'leaseObjectCategory', + ]), + async ({ leasingPeriod, leasingWithoutKasko, dealer: dealerId, leaseObjectCategory }) => { const { data: { accounts }, } = await apolloClient.query({ @@ -166,6 +172,29 @@ export function common({ store, apolloClient }: ProcessContext) { $tables.insurance.row('kasko').column('insTerm').block(); $tables.insurance.row('kasko').column('insured').unblock(); } + + /** + * @see 'apps\web\process\supplier-agent\reactions\leaseback.ts' + */ + if (dealerId) { + const { + data: { dealer }, + } = await apolloClient.query({ + query: CRMTypes.GetDealerDocument, + variables: { + dealerId, + }, + }); + + if (dealer?.evo_return_leasing_dealer === true) { + $tables.insurance.row('kasko').column('insured').setValue(100_000_000).block(); + } + // объединили реакцию для прицепа и возвратного лизинга + const isTrailer = leaseObjectCategory === 100_000_004; + if (isTrailer || dealer?.evo_return_leasing_dealer === true) { + $tables.insurance.row('osago').column('insured').setValue(100_000_000).block(); + } + } } }, { diff --git a/apps/web/process/supplier-agent/reactions/leaseback.ts b/apps/web/process/supplier-agent/reactions/leaseback.ts index 0340a81..4fc7100 100644 --- a/apps/web/process/supplier-agent/reactions/leaseback.ts +++ b/apps/web/process/supplier-agent/reactions/leaseback.ts @@ -3,7 +3,7 @@ import type { ProcessContext } from '@/process/types'; import { reaction } from 'mobx'; export function common({ store, apolloClient }: ProcessContext) { - const { $calculation, $tables } = store; + const { $calculation } = store; /** * Дополнить реакцию на изменение поля Салон приобретения selectDealer: * @@ -35,41 +35,9 @@ export function common({ store, apolloClient }: ProcessContext) { if (dealer?.evo_return_leasing_dealer === true) { $calculation.element('selectDealerPerson').block().resetValue(); - $tables.insurance.row('kasko').setValue('insured', 100_000_000).block('insured'); $calculation.element('cbxLeaseObjectUsed').setValue(true); } else { $calculation.element('selectDealerPerson').unblock(); - $tables.insurance.row('kasko').resetStatus('insured'); - } - } - ); - - // объединили реакцию для прицепа и возвратного лизинга - reaction( - () => ({ - dealerId: $calculation.element('selectDealer').getValue(), - leaseObjectCategory: $calculation.element('selectLeaseObjectCategory').getValue(), - }), - async ({ dealerId, leaseObjectCategory }) => { - const isTrailer = leaseObjectCategory === 100_000_004; - let returnLeasing = false; - - if (dealerId) { - const { - data: { dealer }, - } = await apolloClient.query({ - query: CRMTypes.GetDealerDocument, - variables: { - dealerId, - }, - }); - returnLeasing = dealer?.evo_return_leasing_dealer === true; - } - - if (isTrailer || returnLeasing) { - $tables.insurance.row('osago').setValue('insured', 100_000_000).block('insured'); - } else { - $tables.insurance.row('osago').resetStatus('insured'); } } ); diff --git a/apps/web/stores/tables/elt/policy.ts b/apps/web/stores/tables/elt/policy.ts index 776c648..e3c179d 100644 --- a/apps/web/stores/tables/elt/policy.ts +++ b/apps/web/stores/tables/elt/policy.ts @@ -17,6 +17,8 @@ export default class PolicyStore { private rows: IObservableArray; private selectedKey: string | null = null; + public abortController = new AbortController(); + constructor({ rootStore, validationConfig }: ConstructorInput) { this.rows = observable([]); makeAutoObservable(this); @@ -55,6 +57,10 @@ export default class PolicyStore { if (index >= 0) this.rows[index] = { ...this.rows[index], ...row }; }; + public getRow(key: string) { + return this.rows.find((x) => x.key === key); + } + public get getRows() { return toJS(this.rows); }