move elt osago code to server side

This commit is contained in:
vchikalkin 2024-07-12 18:53:10 +03:00
parent 76f1174ec6
commit 48a527a6c5
9 changed files with 174 additions and 113 deletions

View File

@ -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);

View File

@ -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<ProcessContext, 'apolloClient' | 'store'>,
row: Row
): Promise<NonNullable<CRMTypes.GetOsagoAddproductTypesQuery['evo_addproduct_types']>[number]> {

View File

@ -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<ReturnType<typeof ownOsagoRequest>>;
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,
};
}

View File

@ -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,
};
}

View File

@ -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<ELT.ResponseEltOsago>(URL_ELT_OSAGO, payload, { signal, timeout: TIMEOUT })
.post<ELT.ResponseEltOsago>(URL_ELT_OSAGO, payload, { timeout: TIMEOUT })
.then(({ data }) => data)
);
}

View File

@ -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;

View File

@ -0,0 +1,4 @@
import { mergeRouters } from '../../trpc';
import { eltOsagoRouter } from './osago';
export const eltRouter = mergeRouters(eltOsagoRouter);

View File

@ -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);
}
}),
});

View File

@ -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(),
});