2023-03-29 10:07:34 +03:00

199 lines
5.7 KiB
TypeScript

/* eslint-disable canonical/sort-keys */
import { protectedProcedure, publicProcedure } from '../../procedure';
import { router } from '../../trpc';
import { createRequestData } from '../calculate/lib/request';
import { transformCalculateResults } from '../calculate/lib/transform';
import { validate } from '../calculate/lib/validation';
import type { Context } from '../calculate/types';
import {
CreateQuoteInputDataSchema,
CreateQuoteOutputDataSchema,
GetQuoteInputDataSchema,
GetQuoteOutputDataSchema,
} from './types';
import { calculate } from '@/api/core/query';
import { createKP } from '@/api/crm/query';
import type { User } from '@/api/user/types';
import initializeApollo from '@/apollo/client';
import defaultValues from '@/config/default-values';
import * as insuranceTable from '@/config/tables/insurance-table';
import * as CRMTypes from '@/graphql/crm.types';
import * as addProduct from '@/process/add-product';
import * as bonuses from '@/process/bonuses';
import * as configurator from '@/process/configurator';
import * as fingapProcess from '@/process/fingap';
import * as gibdd from '@/process/gibdd';
import * as insuranceProcess from '@/process/insurance';
import * as leasingObject from '@/process/leasing-object';
import * as paymentsProcess from '@/process/payments';
import * as price from '@/process/price';
import * as subsidy from '@/process/subsidy';
import * as supplierAgent from '@/process/supplier-agent';
import type { CalculationValues } from '@/stores/calculation/values/types';
import { QueryClient } from '@tanstack/react-query';
const { DEFAULT_FINGAP_ROW, DEFAULT_KASKO_ROW, DEFAULT_OSAGO_ROW } = insuranceTable;
const defaultInsurance = {
values: {
fingap: DEFAULT_FINGAP_ROW,
kasko: DEFAULT_KASKO_ROW,
osago: DEFAULT_OSAGO_ROW,
},
};
const defaultFingap = { keys: [] };
const defaultPayments = { values: [] };
export const quoteRouter = router({
getQuote: publicProcedure
.input(GetQuoteInputDataSchema)
.output(GetQuoteOutputDataSchema)
.query(async ({ input }) => {
const processData = await Promise.all(
[
configurator,
supplierAgent,
paymentsProcess,
price,
bonuses,
leasingObject,
fingapProcess,
gibdd,
subsidy,
insuranceProcess,
addProduct,
].map(({ getKPData }) => getKPData(input))
);
const values = processData.reduce(
(obj, data) => Object.assign(obj, data.values),
defaultValues
);
const payments = processData.find((x) => x.payments)?.payments ?? defaultPayments;
const insurance = processData.find((x) => x.insurance)?.insurance ?? defaultInsurance;
const fingap = processData.find((x) => x.fingap)?.fingap ?? defaultFingap;
return {
values,
payments,
insurance,
fingap,
};
}),
createQuote: protectedProcedure
.input(CreateQuoteInputDataSchema)
.output(CreateQuoteOutputDataSchema)
.mutation(async ({ input, ctx }) => {
const apolloClient = initializeApollo();
const queryClient = new QueryClient();
if (ctx.unlimited === false) {
const validationResult = await validate({
context: {
apolloClient,
queryClient,
user: ctx.user,
},
input,
});
if (validationResult.success === false) {
return {
error: validationResult.error,
success: false,
};
}
}
let user: Pick<User, 'domainName'> = { domainName: ctx.user.domainName };
if (ctx.unlimited && input.values.user) {
user = { domainName: input.values.user };
}
const requestData = await createRequestData({
context: {
apolloClient,
queryClient,
...ctx,
user,
},
input,
});
const calculateResult = await calculate(requestData);
if (calculateResult.errors?.length > 0) {
return {
error: calculateResult.errors[0],
success: false,
};
}
const createKPResult = await createKP({
domainName: user.domainName,
finGAP: input.fingap,
insurance: Object.values(input.insurance.values),
calculation: {
calculationValues: await compatValues(input.values, { apolloClient }),
...calculateResult,
preparedPayments: requestData.preparedPayments,
additionalData: requestData.additionalData,
},
});
if (createKPResult.success === false) {
return {
success: false,
error: createKPResult.message || createKPResult.fullMessage,
};
}
const result = transformCalculateResults({
calculateInput: input,
requestCalculate: requestData,
responseCalculate: calculateResult,
});
return {
data: result,
success: true,
};
}),
});
async function compatValues(
values: CalculationValues,
{ apolloClient }: Pick<Context, 'apolloClient'>
) {
let product = null;
if (values.product) {
const {
data: { evo_baseproduct },
} = await apolloClient.query({
query: CRMTypes.GetProductDocument,
variables: {
productId: values.product,
},
});
if (evo_baseproduct?.evo_id) product = evo_baseproduct?.evo_id;
}
let rate = null;
if (values.rate) {
const {
data: { evo_rate },
} = await apolloClient.query({
fetchPolicy: 'network-only',
query: CRMTypes.GetRateDocument,
variables: {
rateId: values.rate,
},
});
if (evo_rate?.evo_id) rate = evo_rate?.evo_id;
}
return { ...values, product, rate };
}