trpc: add create-kp prodecure
This commit is contained in:
parent
f2fed86fc7
commit
4b2fee5e69
1
.env
1
.env
@ -8,6 +8,7 @@ USERS_SUPER=["akalinina","vchikalkin"]
|
||||
####### URLS ########
|
||||
URL_GET_USER_DIRECT=
|
||||
URL_CRM_GRAPHQL_DIRECT=
|
||||
URL_CRM_CREATEKP_DIRECT=
|
||||
URL_CORE_FINGAP_DIRECT=
|
||||
URL_CORE_CALCULATE_DIRECT=
|
||||
URL_1C_TRANSTAX_DIRECT=
|
||||
@ -13,11 +13,9 @@ export async function calculateFinGAP(payload: RequestFinGAP, { signal }: QueryF
|
||||
return data;
|
||||
}
|
||||
|
||||
export async function calculate(payload: RequestCalculate, { signal }: QueryFunctionContext) {
|
||||
export async function calculate(payload: RequestCalculate): Promise<ResponseCalculate> {
|
||||
return await axios
|
||||
.post<ResponseCalculate>(URL_CORE_CALCULATE, payload, {
|
||||
signal,
|
||||
})
|
||||
.post<ResponseCalculate>(URL_CORE_CALCULATE, payload)
|
||||
.then((response) => response.data)
|
||||
.catch((error) => error.response.data);
|
||||
}
|
||||
|
||||
@ -137,13 +137,13 @@ const AdditionalDataSchema = z.object({
|
||||
|
||||
export type AdditionalData = z.infer<typeof AdditionalDataSchema>;
|
||||
|
||||
export const CalculateRequestSchema = z.object({
|
||||
export const RequestCalculateSchema = z.object({
|
||||
additionalData: AdditionalDataSchema,
|
||||
preparedPayments: PreparedPaymentSchema,
|
||||
preparedValues: PreparedValuesSchema,
|
||||
});
|
||||
|
||||
export type RequestCalculate = z.infer<typeof CalculateRequestSchema>;
|
||||
export type RequestCalculate = z.infer<typeof RequestCalculateSchema>;
|
||||
|
||||
const PostValuesSchema = z.object({
|
||||
baseCost: z.number(),
|
||||
|
||||
12
apps/web/api/crm/query.ts
Normal file
12
apps/web/api/crm/query.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import type { RequestCreateKP, ResponseCreateKP } from './types';
|
||||
import getUrls from '@/config/urls';
|
||||
import axios from 'axios';
|
||||
|
||||
const { URL_CRM_CREATEKP } = getUrls();
|
||||
|
||||
export async function createKP(payload: RequestCreateKP): Promise<ResponseCreateKP> {
|
||||
return await axios
|
||||
.post(URL_CRM_CREATEKP, payload)
|
||||
.then((response) => ({ ...response.data, success: true }))
|
||||
.catch((error) => ({ ...error.response.data, success: false }));
|
||||
}
|
||||
41
apps/web/api/crm/types.ts
Normal file
41
apps/web/api/crm/types.ts
Normal file
@ -0,0 +1,41 @@
|
||||
import { RequestCalculateSchema, ResponseCalculateSchema } from '../core/types';
|
||||
import { RiskSchema } from '@/config/schema/fingap';
|
||||
import { RowSchema } from '@/config/schema/insurance';
|
||||
import ValuesSchema from '@/config/schema/values';
|
||||
import { z } from 'zod';
|
||||
|
||||
export const RequestCreateKPSchema = z.object({
|
||||
calculation: z
|
||||
.object({
|
||||
calculationValues: ValuesSchema,
|
||||
})
|
||||
.and(
|
||||
RequestCalculateSchema.omit({
|
||||
preparedValues: true,
|
||||
})
|
||||
)
|
||||
.and(
|
||||
ResponseCalculateSchema.omit({
|
||||
errors: true,
|
||||
})
|
||||
),
|
||||
domainName: z.string(),
|
||||
finGAP: RiskSchema.array(),
|
||||
insurance: RowSchema.array(),
|
||||
});
|
||||
|
||||
export type RequestCreateKP = z.infer<typeof RequestCreateKPSchema>;
|
||||
|
||||
export const ResponseCreateKPSchema = z.union([
|
||||
z.object({
|
||||
evo_quotename: z.string(),
|
||||
success: z.literal(true),
|
||||
}),
|
||||
z.object({
|
||||
fullMessage: z.string(),
|
||||
message: z.string(),
|
||||
success: z.literal(false),
|
||||
}),
|
||||
]);
|
||||
|
||||
export type ResponseCreateKP = z.infer<typeof ResponseCreateKPSchema>;
|
||||
@ -6,6 +6,7 @@ const envSchema = z.object({
|
||||
URL_1C_TRANSTAX_DIRECT: z.string(),
|
||||
URL_CORE_CALCULATE_DIRECT: z.string(),
|
||||
URL_CORE_FINGAP_DIRECT: z.string(),
|
||||
URL_CRM_CREATEKP_DIRECT: z.string(),
|
||||
URL_CRM_GRAPHQL_DIRECT: z.string(),
|
||||
URL_GET_USER_DIRECT: z.string(),
|
||||
USE_DEV_COLORS: z.unknown().optional().transform(Boolean),
|
||||
|
||||
@ -12,6 +12,7 @@ const serverRuntimeConfigSchema = envSchema.pick({
|
||||
URL_1C_TRANSTAX_DIRECT: true,
|
||||
URL_CORE_CALCULATE_DIRECT: true,
|
||||
URL_CORE_FINGAP_DIRECT: true,
|
||||
URL_CRM_CREATEKP_DIRECT: true,
|
||||
URL_CRM_GRAPHQL_DIRECT: true,
|
||||
URL_GET_USER_DIRECT: true,
|
||||
});
|
||||
|
||||
@ -15,6 +15,7 @@ function getUrls() {
|
||||
URL_CORE_FINGAP_DIRECT,
|
||||
URL_1C_TRANSTAX_DIRECT,
|
||||
URL_CORE_CALCULATE_DIRECT,
|
||||
URL_CRM_CREATEKP_DIRECT,
|
||||
PORT,
|
||||
} = serverRuntimeConfigSchema.parse(serverRuntimeConfig);
|
||||
|
||||
@ -24,6 +25,7 @@ function getUrls() {
|
||||
URL_1C_TRANSTAX: URL_1C_TRANSTAX_DIRECT,
|
||||
URL_CORE_CALCULATE: URL_CORE_CALCULATE_DIRECT,
|
||||
URL_CORE_FINGAP: URL_CORE_FINGAP_DIRECT,
|
||||
URL_CRM_CREATEKP: URL_CRM_CREATEKP_DIRECT,
|
||||
URL_CRM_GRAPHQL: URL_CRM_GRAPHQL_DIRECT,
|
||||
URL_GET_USER: URL_GET_USER_DIRECT,
|
||||
};
|
||||
@ -38,6 +40,7 @@ function getUrls() {
|
||||
URL_1C_TRANSTAX: withBasePath(urls.URL_1C_TRANSTAX_PROXY),
|
||||
URL_CORE_CALCULATE: withBasePath(urls.URL_CORE_CALCULATE_PROXY),
|
||||
URL_CORE_FINGAP: withBasePath(urls.URL_CORE_FINGAP_PROXY),
|
||||
URL_CRM_CREATEKP: withBasePath(urls.URL_CRM_CREATEKP_PROXY),
|
||||
URL_CRM_GRAPHQL: withBasePath(urls.URL_CRM_GRAPHQL_PROXY),
|
||||
URL_GET_USER: withBasePath(urls.URL_GET_USER_PROXY),
|
||||
};
|
||||
|
||||
@ -2,6 +2,7 @@ module.exports = {
|
||||
URL_1C_TRANSTAX_PROXY: '/api/1c/transtax',
|
||||
URL_CORE_CALCULATE_PROXY: '/api/core/calculate',
|
||||
URL_CORE_FINGAP_PROXY: '/api/core/fingap',
|
||||
URL_CRM_CREATEKP_PROXY: '/api/crm/create-kp',
|
||||
URL_CRM_GRAPHQL_PROXY: '/api/graphql/crm',
|
||||
URL_GET_USER_PROXY: '/api/auth/user',
|
||||
};
|
||||
|
||||
@ -1,14 +1,12 @@
|
||||
import type { ProcessContext } from '../types';
|
||||
import { toJS } from 'mobx';
|
||||
import notification from 'ui/elements/notification';
|
||||
|
||||
const key = 'ACTION_CALCULATE';
|
||||
const message = 'Ошибка во время расчета графика';
|
||||
const errorMessage = 'Ошибка во время расчета графика!';
|
||||
const successMessage = 'Расчет графика завершен успешно!';
|
||||
|
||||
/**
|
||||
* @param {import('../types').ProcessContext} context
|
||||
* @param {*} onCompleted
|
||||
*/
|
||||
export async function action({ store, trpcClient }) {
|
||||
export async function action({ store, trpcClient }: ProcessContext) {
|
||||
const { $calculation, $tables, $results } = store;
|
||||
|
||||
$calculation.$status.setStatus('btnCalculate', 'Loading');
|
||||
@ -36,19 +34,24 @@ export async function action({ store, trpcClient }) {
|
||||
notification.error({
|
||||
description: res.error,
|
||||
key,
|
||||
message,
|
||||
message: errorMessage,
|
||||
});
|
||||
} else {
|
||||
$results.setPayments(res.data.resultPayments);
|
||||
$results.setValues(res.data.resultValues);
|
||||
$calculation.$values.setValues(res.data.values);
|
||||
|
||||
notification.success({
|
||||
key,
|
||||
message: successMessage,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
notification.error({
|
||||
description: JSON.stringify(error),
|
||||
key,
|
||||
message,
|
||||
message: errorMessage,
|
||||
});
|
||||
})
|
||||
.finally(() => {
|
||||
@ -1 +1,67 @@
|
||||
export function action() {}
|
||||
import { updateSelectQuote } from '../lead-opportunity/reactions/common';
|
||||
import type { ProcessContext } from '../types';
|
||||
import { toJS } from 'mobx';
|
||||
import notification from 'ui/elements/notification';
|
||||
|
||||
const key = 'ACTION_CREATEKP';
|
||||
const errorMessage = 'Ошибка во время создания КП!';
|
||||
const successMessage = 'КП создано!';
|
||||
|
||||
export function action({ store, trpcClient, apolloClient }: ProcessContext) {
|
||||
const { $calculation, $tables, $results } = store;
|
||||
|
||||
$calculation.$status.setStatus('btnCalculate', 'Loading');
|
||||
$calculation.$status.setStatus('btnCreateKP', 'Loading');
|
||||
$results.clear();
|
||||
|
||||
const values = $calculation.$values.getValues();
|
||||
|
||||
const insurance = {
|
||||
fingap: toJS($tables.insurance.row('fingap').getValues()),
|
||||
kasko: toJS($tables.insurance.row('kasko').getValues()),
|
||||
osago: toJS($tables.insurance.row('osago').getValues()),
|
||||
};
|
||||
|
||||
const fingap = $tables.fingap.getSelectedRisks();
|
||||
|
||||
const payments = toJS($tables.payments.values);
|
||||
|
||||
trpcClient.createQuote
|
||||
.mutate({
|
||||
fingap,
|
||||
insurance: { values: insurance },
|
||||
payments: { values: payments },
|
||||
values,
|
||||
})
|
||||
.then(async (res) => {
|
||||
if (res.success === false) {
|
||||
notification.error({
|
||||
description: res.error,
|
||||
key,
|
||||
message: errorMessage,
|
||||
});
|
||||
} else {
|
||||
$results.setPayments(res.data.resultPayments);
|
||||
$results.setValues(res.data.resultValues);
|
||||
$calculation.$values.setValues(res.data.values);
|
||||
|
||||
notification.success({
|
||||
key,
|
||||
message: successMessage,
|
||||
});
|
||||
|
||||
await updateSelectQuote({ apolloClient, store });
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
notification.error({
|
||||
description: JSON.stringify(error),
|
||||
key,
|
||||
message: errorMessage,
|
||||
});
|
||||
})
|
||||
.finally(() => {
|
||||
$calculation.$status.setStatus('btnCalculate', 'Default');
|
||||
$calculation.$status.setStatus('btnCreateKP', 'Default');
|
||||
});
|
||||
}
|
||||
|
||||
@ -92,33 +92,44 @@ export default function reactions({ store, apolloClient }: ProcessContext) {
|
||||
|
||||
reaction(
|
||||
() => $calculation.$values.getValues(['recalcWithRevision', 'lead']),
|
||||
async ({ lead: leadid, recalcWithRevision }) => {
|
||||
if (leadid) {
|
||||
const {
|
||||
data: { quotes },
|
||||
} = await apolloClient.query({
|
||||
fetchPolicy: 'network-only',
|
||||
query: CRMTypes.GetQuotesDocument,
|
||||
variables: {
|
||||
leadid,
|
||||
},
|
||||
});
|
||||
|
||||
if (recalcWithRevision) {
|
||||
const filteredQuotes = quotes?.filter(
|
||||
(quote) =>
|
||||
quote?.evo_recalc_limit &&
|
||||
quote.evo_recalc_limit > 0 &&
|
||||
quote.evo_statuscodeidData?.evo_id === '2.3' &&
|
||||
!quote.evo_purchases_participation
|
||||
);
|
||||
$calculation.element('selectQuote').setOptions(normalizeOptions(filteredQuotes));
|
||||
} else {
|
||||
$calculation.element('selectQuote').setOptions(normalizeOptions(quotes));
|
||||
}
|
||||
} else {
|
||||
$calculation.element('selectQuote').reset();
|
||||
}
|
||||
async () => {
|
||||
await updateSelectQuote({ apolloClient, store });
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export async function updateSelectQuote({
|
||||
store,
|
||||
apolloClient,
|
||||
}: Pick<ProcessContext, 'apolloClient' | 'store'>) {
|
||||
const { $calculation } = store;
|
||||
const leadid = $calculation.element('selectLead').getValue();
|
||||
const recalcWithRevision = $calculation.element('cbxRecalcWithRevision').getValue();
|
||||
|
||||
if (leadid) {
|
||||
const {
|
||||
data: { quotes },
|
||||
} = await apolloClient.query({
|
||||
fetchPolicy: 'network-only',
|
||||
query: CRMTypes.GetQuotesDocument,
|
||||
variables: {
|
||||
leadid,
|
||||
},
|
||||
});
|
||||
|
||||
if (recalcWithRevision) {
|
||||
const filteredQuotes = quotes?.filter(
|
||||
(quote) =>
|
||||
quote?.evo_recalc_limit &&
|
||||
quote.evo_recalc_limit > 0 &&
|
||||
quote.evo_statuscodeidData?.evo_id === '2.3' &&
|
||||
!quote.evo_purchases_participation
|
||||
);
|
||||
$calculation.element('selectQuote').setOptions(normalizeOptions(filteredQuotes));
|
||||
} else {
|
||||
$calculation.element('selectQuote').setOptions(normalizeOptions(quotes));
|
||||
}
|
||||
} else {
|
||||
$calculation.element('selectQuote').reset();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,52 +1,3 @@
|
||||
/* eslint-disable zod/require-strict */
|
||||
import { RiskSchema } from '@/config/schema/fingap';
|
||||
import { KeysSchema, RowSchema } from '@/config/schema/insurance';
|
||||
import PaymentsSchema from '@/config/schema/payments';
|
||||
import ValuesSchema from '@/config/schema/values';
|
||||
import { z } from 'zod';
|
||||
|
||||
const { quote, recalcWithRevision, lead, opportunity } = ValuesSchema.shape;
|
||||
|
||||
export const GetQuoteInputDataSchema = z
|
||||
.object({
|
||||
values: z
|
||||
.object({
|
||||
lead,
|
||||
opportunity,
|
||||
quote: quote.unwrap(),
|
||||
recalcWithRevision,
|
||||
})
|
||||
.required(),
|
||||
})
|
||||
.strict();
|
||||
|
||||
export type GetQuoteInputData = z.infer<typeof GetQuoteInputDataSchema>;
|
||||
|
||||
const FinGAPSchema = z.object({
|
||||
keys: z.array(RiskSchema.shape.key),
|
||||
});
|
||||
|
||||
const InsuranceSchema = z.object({
|
||||
values: z.record(KeysSchema, RowSchema),
|
||||
});
|
||||
|
||||
export const GetQuoteOutputDataSchema = z
|
||||
.object({
|
||||
fingap: FinGAPSchema,
|
||||
insurance: InsuranceSchema,
|
||||
payments: PaymentsSchema,
|
||||
values: ValuesSchema,
|
||||
})
|
||||
.strict();
|
||||
|
||||
export type GetQuoteOutputData = z.infer<typeof GetQuoteOutputDataSchema>;
|
||||
|
||||
export const GetQuoteProcessDataSchema = GetQuoteOutputDataSchema.omit({
|
||||
values: true,
|
||||
})
|
||||
.extend({
|
||||
values: ValuesSchema.partial(),
|
||||
})
|
||||
.partial();
|
||||
|
||||
export type GetQuoteProcessData = z.infer<typeof GetQuoteProcessDataSchema>;
|
||||
export type { GetQuoteInputData } from '@/server/routers/quote/types';
|
||||
export type { GetQuoteOutputData } from '@/server/routers/quote/types';
|
||||
export type { GetQuoteProcessData } from '@/server/routers/quote/types';
|
||||
|
||||
@ -5,9 +5,7 @@ import { validate } from './lib/validation';
|
||||
import { CalculateInputSchema, CalculateOutputSchema } from './types';
|
||||
import { calculate } from '@/api/core/query';
|
||||
import initializeApollo from '@/apollo/client';
|
||||
import { STALE_TIME } from '@/constants/request';
|
||||
import { protectedProcedure } from '@/server/procedure';
|
||||
import type { QueryFunctionContext } from '@tanstack/react-query';
|
||||
import { QueryClient } from '@tanstack/react-query';
|
||||
|
||||
export const calculateRouter = router({
|
||||
@ -44,13 +42,7 @@ export const calculateRouter = router({
|
||||
user: ctx.user,
|
||||
});
|
||||
|
||||
const calculateResult = await queryClient.fetchQuery(
|
||||
['calculate'],
|
||||
(context: QueryFunctionContext) => calculate(requestData, context),
|
||||
{
|
||||
staleTime: STALE_TIME,
|
||||
}
|
||||
);
|
||||
const calculateResult = await calculate(requestData);
|
||||
|
||||
if (calculateResult.errors?.length > 0) {
|
||||
return {
|
||||
|
||||
@ -29,16 +29,15 @@ export const OutputDataSchema = z.object({
|
||||
|
||||
export type OutputData = z.infer<typeof OutputDataSchema>;
|
||||
|
||||
export const CalculateOutputSchema = z
|
||||
.object({
|
||||
export const CalculateOutputSchema = z.union([
|
||||
z.object({
|
||||
data: OutputDataSchema,
|
||||
success: z.boolean(),
|
||||
})
|
||||
.or(
|
||||
z.object({
|
||||
error: z.string(),
|
||||
success: z.boolean(),
|
||||
})
|
||||
);
|
||||
success: z.literal(true),
|
||||
}),
|
||||
z.object({
|
||||
error: z.string(),
|
||||
success: z.literal(false),
|
||||
}),
|
||||
]);
|
||||
|
||||
export type CalculateOutput = z.infer<typeof CalculateOutputSchema>;
|
||||
|
||||
@ -1,69 +0,0 @@
|
||||
/* eslint-disable canonical/sort-keys */
|
||||
import { publicProcedure } from '../procedure';
|
||||
import { router } from '../trpc';
|
||||
import defaultValues from '@/config/default-values';
|
||||
import * as insuranceTable from '@/config/tables/insurance-table';
|
||||
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 loadKP from '@/process/load-kp';
|
||||
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';
|
||||
|
||||
const { GetQuoteInputDataSchema, GetQuoteOutputDataSchema } = loadKP;
|
||||
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,
|
||||
};
|
||||
}),
|
||||
});
|
||||
153
apps/web/server/routers/quote/index.ts
Normal file
153
apps/web/server/routers/quote/index.ts
Normal file
@ -0,0 +1,153 @@
|
||||
/* 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 {
|
||||
CreateQuoteInputDataSchema,
|
||||
CreateQuoteOutputDataSchema,
|
||||
GetQuoteInputDataSchema,
|
||||
GetQuoteOutputDataSchema,
|
||||
} from './types';
|
||||
import { calculate } from '@/api/core/query';
|
||||
import { createKP } from '@/api/crm/query';
|
||||
import initializeApollo from '@/apollo/client';
|
||||
import defaultValues from '@/config/default-values';
|
||||
import * as insuranceTable from '@/config/tables/insurance-table';
|
||||
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 { 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();
|
||||
|
||||
const validationResult = await validate({
|
||||
context: {
|
||||
apolloClient,
|
||||
queryClient,
|
||||
user: ctx.user,
|
||||
},
|
||||
input,
|
||||
});
|
||||
|
||||
if (validationResult.success === false) {
|
||||
return {
|
||||
error: validationResult.error,
|
||||
success: false,
|
||||
};
|
||||
}
|
||||
|
||||
const requestData = await createRequestData({
|
||||
context: {
|
||||
apolloClient,
|
||||
queryClient,
|
||||
user: ctx.user,
|
||||
},
|
||||
input,
|
||||
user: ctx.user,
|
||||
});
|
||||
|
||||
const calculateResult = await calculate(requestData);
|
||||
|
||||
if (calculateResult.errors?.length > 0) {
|
||||
return {
|
||||
error: calculateResult.errors[0],
|
||||
success: false,
|
||||
};
|
||||
}
|
||||
|
||||
const createKPResult = await createKP({
|
||||
domainName: ctx.user.domainName,
|
||||
finGAP: input.fingap,
|
||||
insurance: Object.values(input.insurance.values),
|
||||
calculation: {
|
||||
calculationValues: input.values,
|
||||
...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,
|
||||
};
|
||||
}),
|
||||
});
|
||||
59
apps/web/server/routers/quote/types.ts
Normal file
59
apps/web/server/routers/quote/types.ts
Normal file
@ -0,0 +1,59 @@
|
||||
/* eslint-disable zod/require-strict */
|
||||
import { CalculateInputSchema } from '../calculate/types';
|
||||
import { RiskSchema } from '@/config/schema/fingap';
|
||||
import { KeysSchema, RowSchema } from '@/config/schema/insurance';
|
||||
import PaymentsSchema from '@/config/schema/payments';
|
||||
import ValuesSchema from '@/config/schema/values';
|
||||
import { z } from 'zod';
|
||||
|
||||
const { quote, recalcWithRevision, lead, opportunity } = ValuesSchema.shape;
|
||||
|
||||
export const GetQuoteInputDataSchema = z
|
||||
.object({
|
||||
values: z
|
||||
.object({
|
||||
lead,
|
||||
opportunity,
|
||||
quote: quote.unwrap(),
|
||||
recalcWithRevision,
|
||||
})
|
||||
.required(),
|
||||
})
|
||||
.strict();
|
||||
|
||||
export type GetQuoteInputData = z.infer<typeof GetQuoteInputDataSchema>;
|
||||
|
||||
const FinGAPSchema = z.object({
|
||||
keys: z.array(RiskSchema.shape.key),
|
||||
});
|
||||
|
||||
const InsuranceSchema = z.object({
|
||||
values: z.record(KeysSchema, RowSchema),
|
||||
});
|
||||
|
||||
export const GetQuoteOutputDataSchema = z
|
||||
.object({
|
||||
fingap: FinGAPSchema,
|
||||
insurance: InsuranceSchema,
|
||||
payments: PaymentsSchema,
|
||||
values: ValuesSchema,
|
||||
})
|
||||
.strict();
|
||||
|
||||
export type GetQuoteOutputData = z.infer<typeof GetQuoteOutputDataSchema>;
|
||||
|
||||
export const GetQuoteProcessDataSchema = GetQuoteOutputDataSchema.omit({
|
||||
values: true,
|
||||
})
|
||||
.extend({
|
||||
values: ValuesSchema.partial(),
|
||||
})
|
||||
.partial();
|
||||
|
||||
export type GetQuoteProcessData = z.infer<typeof GetQuoteProcessDataSchema>;
|
||||
|
||||
export const CreateQuoteInputDataSchema = CalculateInputSchema.extend({
|
||||
fingap: RiskSchema.array(),
|
||||
});
|
||||
|
||||
export { CalculateOutputSchema as CreateQuoteOutputDataSchema } from '../calculate/types';
|
||||
@ -3,7 +3,7 @@ import type { ValidationParams } from '../../validation/types';
|
||||
import type * as FinGAP from '@/Components/Calculation/Form/Insurance/FinGAPTable/types';
|
||||
import type RootStore from '@/stores/root';
|
||||
import type { IObservableArray } from 'mobx';
|
||||
import { makeAutoObservable, observable } from 'mobx';
|
||||
import { makeAutoObservable, observable, toJS } from 'mobx';
|
||||
|
||||
export default class FinGAPTable {
|
||||
private root: RootStore;
|
||||
@ -24,6 +24,10 @@ export default class FinGAPTable {
|
||||
this.root = rootStore;
|
||||
}
|
||||
|
||||
public getSelectedRisks() {
|
||||
return toJS(this.risks.filter((x) => this.selectedKeys.has(x.key)));
|
||||
}
|
||||
|
||||
public setRisks = (risks: FinGAP.Risk[]) => {
|
||||
this.risks.replace(risks);
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user