From 48a527a6c543ea5440eb96916d474bf35f73d316 Mon Sep 17 00:00:00 2001 From: vchikalkin Date: Fri, 12 Jul 2024 18:53:10 +0300 Subject: [PATCH] move elt osago code to server side --- .../Components/Calculation/Form/ELT/Osago.tsx | 123 +++--------------- .../Calculation/Form/ELT/lib/make-request.ts | 2 +- .../Form/ELT/lib/process-response.ts | 72 ++++++++++ .../Calculation/Form/ELT/lib/row.ts | 12 ++ apps/web/api/elt/query.ts | 7 +- apps/web/server/routers/_app.ts | 3 +- apps/web/server/routers/elt/index.ts | 4 + apps/web/server/routers/elt/osago.ts | 51 ++++++++ apps/web/server/routers/elt/types.ts | 13 ++ 9 files changed, 174 insertions(+), 113 deletions(-) create mode 100644 apps/web/Components/Calculation/Form/ELT/lib/process-response.ts create mode 100644 apps/web/Components/Calculation/Form/ELT/lib/row.ts create mode 100644 apps/web/server/routers/elt/index.ts create mode 100644 apps/web/server/routers/elt/osago.ts create mode 100644 apps/web/server/routers/elt/types.ts diff --git a/apps/web/Components/Calculation/Form/ELT/Osago.tsx b/apps/web/Components/Calculation/Form/ELT/Osago.tsx index 667f91f..9d75fd8 100644 --- a/apps/web/Components/Calculation/Form/ELT/Osago.tsx +++ b/apps/web/Components/Calculation/Form/ELT/Osago.tsx @@ -2,125 +2,36 @@ /* eslint-disable sonarjs/cognitive-complexity */ import { PolicyTable, ReloadButton, Validation } from './Components'; import { columns } from './lib/config'; -import { makeEltOsagoRequest, makeOwnOsagoRequest } from './lib/make-request'; +import { resetRow } from './lib/row'; import type { Row, StoreSelector } from './types'; -import { getEltOsago } from '@/api/elt/query'; -import { 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 = ({ osago }) => osago; -const initialData = { - ...omit(defaultRow, ['name', 'key', 'id']), - error: null, - premiumSum: 0, -}; - export const Osago = observer(() => { const store = useStore(); const { $tables } = store; - const apolloClient = useApolloClient(); - const { init } = helper({ apolloClient, store }); - const handleOnClick = useCallback(async () => { - $tables.elt.osago.abortController?.abort(); - $tables.elt.osago.abortController = new AbortController(); + const calculateOsago = trpcClient.eltOsago.useMutation({ + onMutate: () => { + const rows = $tables.elt.osago.getRows; + $tables.elt.osago.setRows(rows.map((row) => ({ ...resetRow(row), status: 'fetching' }))); + }, + onSuccess: ({ rows }) => { + $tables.elt.osago.setRows(rows); + }, + }); - const { osago } = await init(); - $tables.elt.osago.setRows(osago); - 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); - - if (row.metodCalc === 'CRM') { - makeOwnOsagoRequest({ apolloClient, store }, row).then((res) => { - if (!res) { - $tables.elt.osago.setRow({ - key, - message: - 'Для получения расчета ОСАГО следует использовать калькулятор ЭЛТ или Индивидуальный запрос', - numCalc: undefined, - skCalcId: undefined, - status: 'error', - sum: 0, - totalFranchise: 0, - }); - } else { - $tables.elt.osago.setRow({ - key, - message: null, - numCalc: res.evo_id || undefined, - status: null, - sum: res.evo_graph_price_withoutnds || undefined, - }); - } - }); - } else { - makeEltOsagoRequest({ apolloClient, store }, row) - .then((payload) => - getEltOsago(payload, { signal: $tables.elt.osago.abortController.signal }) - ) - .then((res) => { - if (res) { - const { message, numCalc, premiumSum = 0, skCalcId } = res; - let { error } = res; - if (premiumSum > MAX_INSURANCE) { - error ||= `Сумма по страховке превышает максимально допустимое значение по стоимости ОСАГО: ${Intl.NumberFormat( - 'ru', - { - currency: 'RUB', - style: 'currency', - } - ).format(MAX_INSURANCE)}`; - } - if (premiumSum < MIN_INSURANCE) { - error ||= `Сумма по страховке не должна быть меньше допустимого значения по стоимости ОСАГО: ${Intl.NumberFormat( - 'ru', - { - currency: 'RUB', - style: 'currency', - } - ).format(MIN_INSURANCE)}`; - } - $tables.elt.osago.setRow({ - key, - message: error || message, - numCalc: `${numCalc}`, - skCalcId, - status: error ? 'error' : null, - sum: premiumSum, - }); - } - }) - .catch((error) => { - const _err = error as Error; - $tables.elt.osago.setRow({ - ...initialData, - key, - message: _err.message || String(error), - status: 'error', - }); - }); - } - } + async function handleOnClick() { + calculateOsago.mutate({ + calculation: { + values: store.$calculation.$values.getValues(), + }, }); - }, [$tables.elt.osago, $tables.insurance, apolloClient, init, store]); + } function handleOnSelectRow(row: Row) { $tables.insurance.row('osago').column('insuranceCompany').setValue(row.key); diff --git a/apps/web/Components/Calculation/Form/ELT/lib/make-request.ts b/apps/web/Components/Calculation/Form/ELT/lib/make-request.ts index d82d045..f02b50a 100644 --- a/apps/web/Components/Calculation/Form/ELT/lib/make-request.ts +++ b/apps/web/Components/Calculation/Form/ELT/lib/make-request.ts @@ -8,7 +8,7 @@ import { getCurrentDateString } from '@/utils/date'; import dayjs from 'dayjs'; import { first, sort } from 'radash'; -export async function makeOwnOsagoRequest( +export async function ownOsagoRequest( { store, apolloClient }: Pick, row: Row ): Promise[number]> { diff --git a/apps/web/Components/Calculation/Form/ELT/lib/process-response.ts b/apps/web/Components/Calculation/Form/ELT/lib/process-response.ts new file mode 100644 index 0000000..a665c9e --- /dev/null +++ b/apps/web/Components/Calculation/Form/ELT/lib/process-response.ts @@ -0,0 +1,72 @@ +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'; + +export function convertEltOsagoResponse(response: ELT.ResponseEltOsago, row: Row): Row { + const { message, numCalc, premiumSum = 0, skCalcId } = response; + let { error } = response; + if (premiumSum > MAX_INSURANCE) { + error ||= `Сумма по страховке превышает максимально допустимое значение по стоимости ОСАГО: ${Intl.NumberFormat( + 'ru', + { + currency: 'RUB', + style: 'currency', + } + ).format(MAX_INSURANCE)}`; + } + if (premiumSum < MIN_INSURANCE) { + error ||= `Сумма по страховке не должна быть меньше допустимого значения по стоимости ОСАГО: ${Intl.NumberFormat( + 'ru', + { + currency: 'RUB', + style: 'currency', + } + ).format(MIN_INSURANCE)}`; + } + + return { + ...row, + message: error || message, + numCalc: `${numCalc}`, + skCalcId, + status: error ? 'error' : null, + sum: premiumSum, + }; +} + +type ResponseOwnOsago = Awaited>; + +export function convertOwnOsagoResult(result: ResponseOwnOsago | undefined, row: Row): Row { + if (!result) { + return { + ...row, + message: + 'Для получения расчета ОСАГО следует использовать калькулятор ЭЛТ или Индивидуальный запрос', + numCalc: '', + skCalcId: '', + status: 'error', + sum: 0, + totalFranchise: 0, + }; + } + + if (!result.evo_id) { + return { + ...row, + message: 'Сервер не вернул идентификатор страховки evo_id', + numCalc: '', + skCalcId: '', + status: 'error', + sum: result.evo_graph_price_withoutnds || 0, + }; + } + + return { + ...row, + message: null, + numCalc: result.evo_id, + status: null, + sum: result.evo_graph_price_withoutnds || 0, + }; +} diff --git a/apps/web/Components/Calculation/Form/ELT/lib/row.ts b/apps/web/Components/Calculation/Form/ELT/lib/row.ts new file mode 100644 index 0000000..b99071f --- /dev/null +++ b/apps/web/Components/Calculation/Form/ELT/lib/row.ts @@ -0,0 +1,12 @@ +import type { Row } from '../types'; +import { defaultRow } from '@/stores/tables/elt/default-values'; + +export function resetRow(row: Row): Row { + return { + ...defaultRow, + id: row.id, + key: row.key, + metodCalc: row.metodCalc, + name: row.name, + }; +} diff --git a/apps/web/api/elt/query.ts b/apps/web/api/elt/query.ts index 6711811..0e8976e 100644 --- a/apps/web/api/elt/query.ts +++ b/apps/web/api/elt/query.ts @@ -6,13 +6,10 @@ import axios from 'axios'; const { URL_ELT_KASKO, URL_ELT_OSAGO } = getUrls(); -export async function getEltOsago( - payload: ELT.RequestEltOsago, - { signal }: { signal: AbortSignal } -) { +export async function getEltOsago(payload: ELT.RequestEltOsago) { return withHandleError( axios - .post(URL_ELT_OSAGO, payload, { signal, timeout: TIMEOUT }) + .post(URL_ELT_OSAGO, payload, { timeout: TIMEOUT }) .then(({ data }) => data) ); } diff --git a/apps/web/server/routers/_app.ts b/apps/web/server/routers/_app.ts index 160ddb4..2562d18 100644 --- a/apps/web/server/routers/_app.ts +++ b/apps/web/server/routers/_app.ts @@ -1,8 +1,9 @@ import { mergeRouters } from '../trpc'; import { calculateRouter } from './calculate'; +import { eltRouter } from './elt'; import { quoteRouter } from './quote'; import { tarifRouter } from './tarif'; -export const appRouter = mergeRouters(quoteRouter, calculateRouter, tarifRouter); +export const appRouter = mergeRouters(quoteRouter, calculateRouter, tarifRouter, eltRouter); export type AppRouter = typeof appRouter; diff --git a/apps/web/server/routers/elt/index.ts b/apps/web/server/routers/elt/index.ts new file mode 100644 index 0000000..dc955fe --- /dev/null +++ b/apps/web/server/routers/elt/index.ts @@ -0,0 +1,4 @@ +import { mergeRouters } from '../../trpc'; +import { eltOsagoRouter } from './osago'; + +export const eltRouter = mergeRouters(eltOsagoRouter); diff --git a/apps/web/server/routers/elt/osago.ts b/apps/web/server/routers/elt/osago.ts new file mode 100644 index 0000000..fe078b7 --- /dev/null +++ b/apps/web/server/routers/elt/osago.ts @@ -0,0 +1,51 @@ +import { protectedProcedure } from '../../procedure'; +import { router } from '../../trpc'; +import { EltOsagoInputSchema, EltOsagoOutputSchema } from './types'; +import { getEltOsago } from '@/api/elt/query'; +import initializeApollo from '@/apollo/client'; +import { + makeEltOsagoRequest, + ownOsagoRequest, +} from '@/Components/Calculation/Form/ELT/lib/make-request'; +import { + convertEltOsagoResponse, + convertOwnOsagoResult, +} 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 eltOsagoRouter = router({ + eltOsago: protectedProcedure + .input(EltOsagoInputSchema) + .output(EltOsagoOutputSchema) + .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 { osago: initRows } = await initElt(); + + const requests = initRows.map(async (row) => { + if (row.metodCalc === 'CRM') { + const ownRequest = await ownOsagoRequest({ apolloClient, store }, row); + + return convertOwnOsagoResult(ownRequest, row); + } + + const eltRequest = await makeEltOsagoRequest({ apolloClient, store }, row); + const eltResponse = await getEltOsago(eltRequest); + + return convertEltOsagoResponse(eltResponse, row); + }); + + return { + rows: await Promise.all(requests), + }; + } catch (error) { + throw createTRPCError(error); + } + }), +}); diff --git a/apps/web/server/routers/elt/types.ts b/apps/web/server/routers/elt/types.ts new file mode 100644 index 0000000..1cf0402 --- /dev/null +++ b/apps/web/server/routers/elt/types.ts @@ -0,0 +1,13 @@ +import { RowSchema } from '@/config/schema/elt'; +import ValuesSchema from '@/config/schema/values'; +import { z } from 'zod'; + +export const EltOsagoInputSchema = z.object({ + calculation: z.object({ + values: ValuesSchema, + }), +}); + +export const EltOsagoOutputSchema = z.object({ + rows: RowSchema.array(), +});