diff --git a/apps/web/Components/Calculation/Form/ELT/Kasko.tsx b/apps/web/Components/Calculation/Form/ELT/Kasko.tsx index 58fdab0..498f91c 100644 --- a/apps/web/Components/Calculation/Form/ELT/Kasko.tsx +++ b/apps/web/Components/Calculation/Form/ELT/Kasko.tsx @@ -1,129 +1,36 @@ /* eslint-disable sonarjs/cognitive-complexity */ import { PolicyTable, ReloadButton, Validation } from './Components'; import { columns } from './lib/config'; -import { makeEltKaskoRequest } from './lib/make-request'; +import { resetRow } from './lib/row'; import type { Row, StoreSelector } from './types'; -import { getEltKasko } from '@/api/elt/query'; -import { MAX_FRANCHISE, MAX_INSURANCE, MIN_INSURANCE } from '@/constants/values'; -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 { trpcClient } from '@/trpc/client'; 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 = { - ...omit(defaultRow, ['name', 'key', 'id']), - error: null, - kaskoSum: 0, - paymentPeriods: [ - { - kaskoSum: 0, - }, - ], -}; - export const Kasko = observer(() => { const store = useStore(); const { $calculation, $tables } = store; - const apolloClient = useApolloClient(); - const { init } = helper({ apolloClient, store }); - const handleOnClick = useCallback(async () => { - $tables.elt.kasko.abortController?.abort(); - $tables.elt.kasko.abortController = new AbortController(); + const calculateKasko = trpcClient.eltKasko.useMutation({ + onMutate: () => { + const rows = $tables.elt.kasko.getRows; + $tables.elt.kasko.setRows(rows.map((row) => ({ ...resetRow(row), status: 'fetching' }))); + }, + onSuccess: ({ rows }) => { + $tables.elt.kasko.setRows(rows); + }, + }); - const { kasko } = await init(); - $tables.elt.kasko.setRows(kasko); - const kaskoCompanyIds = sift( - $tables.insurance - .row('kasko') - .getOptions('insuranceCompany') - .map((x) => x.value) - ); - const values = $calculation.$values.getValues(); - - 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) { - const { - kaskoSum = 0, - message, - paymentPeriods, - requestId, - skCalcId, - totalFranchise = 0, - } = res; - let { error } = res; - - const sum = - values.leasingPeriod <= 16 ? kaskoSum : paymentPeriods?.[0]?.kaskoSum || 0; - - if (totalFranchise > MAX_FRANCHISE) { - error ||= `Франшиза по страховке превышает максимально допустимое значение: ${Intl.NumberFormat( - 'ru', - { - currency: 'RUB', - style: 'currency', - } - ).format(MAX_FRANCHISE)}`; - } - - if (sum > MAX_INSURANCE) { - error ||= `Сумма по страховке превышает максимально допустимое значение по стоимости КАСКО: ${Intl.NumberFormat( - 'ru', - { - currency: 'RUB', - style: 'currency', - } - ).format(MAX_INSURANCE)}`; - } - - if (sum < MIN_INSURANCE) { - error ||= `Сумма по страховке не должна быть меньше допустимого значения по стоимости КАСКО: ${Intl.NumberFormat( - 'ru', - { - currency: 'RUB', - style: 'currency', - } - ).format(MIN_INSURANCE)}`; - } - - $tables.elt.kasko.setRow({ - key, - message: error || message, - numCalc: '0', - requestId, - skCalcId, - status: error ? 'error' : null, - sum, - totalFranchise, - }); - } - }) - .catch((error) => { - const _err = error as Error; - $tables.elt.kasko.setRow({ - ...initialData, - key, - message: _err.message || String(error), - status: 'error', - }); - }); - } + function handleOnClick() { + calculateKasko.mutate({ + calculation: { + values: store.$calculation.$values.getValues(), + }, }); - }, [$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/lib/process-response.ts b/apps/web/Components/Calculation/Form/ELT/lib/process-response.ts index a665c9e..ef11b75 100644 --- a/apps/web/Components/Calculation/Form/ELT/lib/process-response.ts +++ b/apps/web/Components/Calculation/Form/ELT/lib/process-response.ts @@ -1,7 +1,8 @@ import type { Row } from '../types'; import type { ownOsagoRequest } from './make-request'; import type * as ELT from '@/api/elt/types'; -import { MAX_INSURANCE, MIN_INSURANCE } from '@/constants/values'; +import { MAX_FRANCHISE, MAX_INSURANCE, MIN_INSURANCE } from '@/constants/values'; +import type { CalculationValues } from '@/stores/calculation/values/types'; export function convertEltOsagoResponse(response: ELT.ResponseEltOsago, row: Row): Row { const { message, numCalc, premiumSum = 0, skCalcId } = response; @@ -70,3 +71,55 @@ export function convertOwnOsagoResult(result: ResponseOwnOsago | undefined, row: sum: result.evo_graph_price_withoutnds || 0, }; } + +export function convertEltKaskoResponse( + res: ELT.ResponseEltKasko, + row: Row, + values: CalculationValues +): Row { + const { kaskoSum = 0, message, paymentPeriods, requestId, skCalcId, totalFranchise = 0 } = res; + let { error } = res; + + const sum = values.leasingPeriod <= 16 ? kaskoSum : paymentPeriods?.[0]?.kaskoSum || 0; + + if (totalFranchise > MAX_FRANCHISE) { + error ||= `Франшиза по страховке превышает максимально допустимое значение: ${Intl.NumberFormat( + 'ru', + { + currency: 'RUB', + style: 'currency', + } + ).format(MAX_FRANCHISE)}`; + } + + if (sum > MAX_INSURANCE) { + error ||= `Сумма по страховке превышает максимально допустимое значение по стоимости КАСКО: ${Intl.NumberFormat( + 'ru', + { + currency: 'RUB', + style: 'currency', + } + ).format(MAX_INSURANCE)}`; + } + + if (sum < MIN_INSURANCE) { + error ||= `Сумма по страховке не должна быть меньше допустимого значения по стоимости КАСКО: ${Intl.NumberFormat( + 'ru', + { + currency: 'RUB', + style: 'currency', + } + ).format(MIN_INSURANCE)}`; + } + + return { + ...row, + message: error || message, + numCalc: '0', + requestId, + skCalcId, + status: error ? 'error' : null, + sum, + totalFranchise, + }; +} diff --git a/apps/web/api/elt/query.ts b/apps/web/api/elt/query.ts index 0e8976e..98cfb72 100644 --- a/apps/web/api/elt/query.ts +++ b/apps/web/api/elt/query.ts @@ -14,13 +14,10 @@ export async function getEltOsago(payload: ELT.RequestEltOsago) { ); } -export async function getEltKasko( - payload: ELT.RequestEltKasko, - { signal }: { signal: AbortSignal } -) { +export async function getEltKasko(payload: ELT.RequestEltKasko) { return withHandleError( axios - .post(URL_ELT_KASKO, payload, { signal, timeout: TIMEOUT }) + .post(URL_ELT_KASKO, payload, { timeout: TIMEOUT }) .then(({ data }) => data) ); } diff --git a/apps/web/server/routers/elt/index.ts b/apps/web/server/routers/elt/index.ts index dc955fe..2dbbec7 100644 --- a/apps/web/server/routers/elt/index.ts +++ b/apps/web/server/routers/elt/index.ts @@ -1,4 +1,5 @@ import { mergeRouters } from '../../trpc'; +import { eltKaskoRouter } from './kasko'; import { eltOsagoRouter } from './osago'; -export const eltRouter = mergeRouters(eltOsagoRouter); +export const eltRouter = mergeRouters(eltOsagoRouter, eltKaskoRouter); diff --git a/apps/web/server/routers/elt/kasko.ts b/apps/web/server/routers/elt/kasko.ts new file mode 100644 index 0000000..0f533b3 --- /dev/null +++ b/apps/web/server/routers/elt/kasko.ts @@ -0,0 +1,39 @@ +import { protectedProcedure } from '../../procedure'; +import { router } from '../../trpc'; +import { EltInputSchema, EltOutputSchema } from './types'; +import { getEltKasko } from '@/api/elt/query'; +import initializeApollo from '@/apollo/client'; +import { makeEltKaskoRequest } from '@/Components/Calculation/Form/ELT/lib/make-request'; +import { convertEltKaskoResponse } from '@/Components/Calculation/Form/ELT/lib/process-response'; +import eltHelper from '@/process/elt/lib/helper'; +import RootStore from '@/stores/root'; +import { createTRPCError } from '@/utils/trpc'; + +export const eltKaskoRouter = router({ + eltKasko: protectedProcedure + .input(EltInputSchema) + .output(EltOutputSchema) + .mutation(async ({ input }) => { + try { + const apolloClient = initializeApollo(); + const store = new RootStore(); + store.$calculation.$values.hydrate(input.calculation.values); + + const { init: initElt } = await eltHelper({ apolloClient, store }); + const { kasko: initRows } = await initElt(); + + const requests = initRows.map(async (row) => { + const eltRequest = await makeEltKaskoRequest({ apolloClient, store }, row); + const eltResponse = await getEltKasko(eltRequest); + + return convertEltKaskoResponse(eltResponse, row, input.calculation.values); + }); + + return { + rows: await Promise.all(requests), + }; + } catch (error) { + throw createTRPCError(error); + } + }), +}); diff --git a/apps/web/server/routers/elt/osago.ts b/apps/web/server/routers/elt/osago.ts index fe078b7..7425a7e 100644 --- a/apps/web/server/routers/elt/osago.ts +++ b/apps/web/server/routers/elt/osago.ts @@ -1,6 +1,6 @@ import { protectedProcedure } from '../../procedure'; import { router } from '../../trpc'; -import { EltOsagoInputSchema, EltOsagoOutputSchema } from './types'; +import { EltInputSchema, EltOutputSchema } from './types'; import { getEltOsago } from '@/api/elt/query'; import initializeApollo from '@/apollo/client'; import { @@ -17,8 +17,8 @@ import { createTRPCError } from '@/utils/trpc'; export const eltOsagoRouter = router({ eltOsago: protectedProcedure - .input(EltOsagoInputSchema) - .output(EltOsagoOutputSchema) + .input(EltInputSchema) + .output(EltOutputSchema) .mutation(async ({ input }) => { try { const apolloClient = initializeApollo(); diff --git a/apps/web/server/routers/elt/types.ts b/apps/web/server/routers/elt/types.ts index 1cf0402..da8f757 100644 --- a/apps/web/server/routers/elt/types.ts +++ b/apps/web/server/routers/elt/types.ts @@ -2,12 +2,12 @@ import { RowSchema } from '@/config/schema/elt'; import ValuesSchema from '@/config/schema/values'; import { z } from 'zod'; -export const EltOsagoInputSchema = z.object({ +export const EltInputSchema = z.object({ calculation: z.object({ values: ValuesSchema, }), }); -export const EltOsagoOutputSchema = z.object({ +export const EltOutputSchema = z.object({ rows: RowSchema.array(), });