329 lines
12 KiB
TypeScript
329 lines
12 KiB
TypeScript
/* eslint-disable sonarjs/cognitive-complexity */
|
||
/* eslint-disable complexity */
|
||
import type { ownOsagoRequest } from './request';
|
||
import type * as ELT from '@/api/elt/types';
|
||
import type { Row } from '@/Components/Calculation/Form/ELT/types';
|
||
import { MAX_FRANCHISE, MAX_INSURANCE, MIN_INSURANCE } from '@/constants/values';
|
||
import * as CRMTypes from '@/graphql/crm.types';
|
||
import type { ProcessContext } from '@/process/types';
|
||
import { defaultRow } from '@/stores/tables/elt/default-values';
|
||
import { getCurrentDateString } from '@/utils/date';
|
||
import dayjs from 'dayjs';
|
||
import { sort } from 'radash';
|
||
import { round } from 'tools';
|
||
|
||
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,
|
||
};
|
||
}
|
||
|
||
type ConvertEltKaskoResponseInput = {
|
||
context: Pick<ProcessContext, 'apolloClient' | 'store'>;
|
||
response: ELT.ResponseEltKasko;
|
||
row: Row;
|
||
};
|
||
|
||
export async function convertEltKaskoResponse(input: ConvertEltKaskoResponseInput): Promise<Row> {
|
||
const { context, response, row } = input;
|
||
const { apolloClient, store } = context;
|
||
|
||
const { kaskoSum = 0, message, paymentPeriods } = response;
|
||
let { requestId, skCalcId, totalFranchise = 0, error } = response;
|
||
|
||
const { $calculation } = store;
|
||
const leasingPeriod = $calculation.element('tbxLeasingPeriod').getValue();
|
||
let sum = 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)}`;
|
||
}
|
||
|
||
const {
|
||
data: { account: insuranceCompany },
|
||
} = await apolloClient.query({
|
||
query: CRMTypes.GetInsuranceCompanyDocument,
|
||
variables: { accountId: row.key },
|
||
});
|
||
|
||
if (
|
||
insuranceCompany?.evo_kasko_fact_part !== null &&
|
||
insuranceCompany?.evo_kasko_plan_part !== undefined &&
|
||
insuranceCompany?.evo_kasko_plan_part !== null &&
|
||
insuranceCompany?.evo_kasko_plan_part !== undefined &&
|
||
insuranceCompany?.evo_kasko_fact_part > insuranceCompany?.evo_kasko_plan_part
|
||
) {
|
||
requestId = defaultRow.requestId;
|
||
skCalcId = defaultRow.skCalcId;
|
||
sum = defaultRow.sum;
|
||
totalFranchise = defaultRow.totalFranchise;
|
||
error = 'Расчет возможен только через отдел страхования ЛК';
|
||
}
|
||
|
||
const leaseObjectCategory = $calculation.element('selectLeaseObjectCategory').getValue();
|
||
const leaseObjectYear = $calculation.element('tbxLeaseObjectYear').getValue();
|
||
const leaseObjectMotorPower = $calculation.element('tbxLeaseObjectMotorPower').getValue();
|
||
const engineType = $calculation.element('selectEngineType').getValue();
|
||
const tbxMileage = $calculation.element('tbxMileage').getValue();
|
||
const brand = $calculation.element('selectBrand').getValue();
|
||
const model = $calculation.element('selectModel').getValue();
|
||
const selectLeaseObjectUseFor = $calculation.element('selectLeaseObjectUseFor').getValue();
|
||
const legalClientRegion = $calculation.element('selectLegalClientRegion').getValue();
|
||
const dealerPerson = $calculation.element('selectDealerPerson').getValue();
|
||
const cbxLeaseObjectUsed = $calculation.element('cbxLeaseObjectUsed').getValue();
|
||
const cost =
|
||
$calculation.$values.getValue('plPriceRub') -
|
||
$calculation.$values.getValue('discountRub') -
|
||
$calculation.$values.getValue('importProgramSum') +
|
||
$calculation.$values.getValue('addEquipmentPrice');
|
||
|
||
let lead: CRMTypes.GetLeadQuery['lead'] = null;
|
||
const leadid = $calculation.element('selectLead').getValue();
|
||
if (leadid) {
|
||
const { data } = await apolloClient.query({
|
||
query: CRMTypes.GetLeadDocument,
|
||
variables: { leadid },
|
||
});
|
||
({ lead } = data);
|
||
}
|
||
const insuranceOPF = lead?.evo_inn?.length === 12 ? 100_000_001 : 100_000_000;
|
||
|
||
const currentDate = getCurrentDateString();
|
||
|
||
const {
|
||
data: { evo_insurance_ruleses },
|
||
} = await apolloClient.query({
|
||
query: CRMTypes.GetEltInsuranceRulesDocument,
|
||
variables: {
|
||
currentDate,
|
||
},
|
||
});
|
||
|
||
const filteredRules = evo_insurance_ruleses?.filter(
|
||
(rule) =>
|
||
rule &&
|
||
rule.evo_insurer_accountid === insuranceCompany?.accountid &&
|
||
rule.evo_risk === 100_000_000 &&
|
||
leaseObjectCategory &&
|
||
rule.evo_category?.includes(leaseObjectCategory) &&
|
||
rule.evo_min_period !== null &&
|
||
rule.evo_max_period !== null &&
|
||
leasingPeriod !== null &&
|
||
rule.evo_min_period <= leasingPeriod &&
|
||
rule.evo_max_period >= leasingPeriod &&
|
||
(rule.evo_object_type === 100_000_000 ||
|
||
(rule.evo_object_type === 100_000_001 && cbxLeaseObjectUsed === false) ||
|
||
(rule.evo_object_type === 100_000_002 && cbxLeaseObjectUsed === true)) &&
|
||
selectLeaseObjectUseFor &&
|
||
rule.evo_use_for?.includes(selectLeaseObjectUseFor) &&
|
||
rule.evo_min_price !== null &&
|
||
rule.evo_max_price !== null &&
|
||
cost !== null &&
|
||
rule.evo_min_price <= cost &&
|
||
rule.evo_max_price >= cost &&
|
||
rule.evo_min_year !== null &&
|
||
rule.evo_max_year !== null &&
|
||
leaseObjectYear !== null &&
|
||
rule.evo_min_year <= leaseObjectYear &&
|
||
rule.evo_max_year >= leaseObjectYear &&
|
||
rule.evo_min_power !== null &&
|
||
rule.evo_max_power !== null &&
|
||
leaseObjectMotorPower !== null &&
|
||
rule.evo_min_power <= leaseObjectMotorPower &&
|
||
rule.evo_max_power >= leaseObjectMotorPower &&
|
||
engineType &&
|
||
rule.evo_enginie_type?.includes(engineType) &&
|
||
rule.evo_opf?.includes(insuranceOPF) &&
|
||
rule.evo_min_mileage !== null &&
|
||
rule.evo_max_mileage !== null &&
|
||
tbxMileage !== null &&
|
||
rule.evo_min_mileage <= tbxMileage &&
|
||
rule.evo_max_mileage >= tbxMileage &&
|
||
(rule.evo_brand === 100_000_000 ||
|
||
(rule.evo_brand === 100_000_001 &&
|
||
rule.evo_brands?.some((x) => x?.evo_brandid === brand)) ||
|
||
(rule.evo_brand === 100_000_002 &&
|
||
!rule.evo_brands?.some((x) => x?.evo_brandid === brand))) &&
|
||
(rule.evo_model === 100_000_000 ||
|
||
(rule.evo_model === 100_000_001 &&
|
||
rule.evo_models?.some((x) => x?.evo_modelid === model)) ||
|
||
(rule.evo_model === 100_000_002 &&
|
||
!rule.evo_models?.some((x) => x?.evo_modelid === model))) &&
|
||
(rule.evo_region === 100_000_000 ||
|
||
(rule.evo_region === 100_000_001 &&
|
||
rule.evo_regions?.some((x) => x?.evo_regionid === legalClientRegion)) ||
|
||
(rule.evo_region === 100_000_002 &&
|
||
!rule.evo_regions?.some((x) => x?.evo_regionid === legalClientRegion))) &&
|
||
(rule.evo_dealer === 100_000_000 ||
|
||
(rule.evo_dealer === 100_000_001 &&
|
||
rule.accounts?.some((x) => x?.accountid === dealerPerson)) ||
|
||
(rule.evo_dealer === 100_000_002 &&
|
||
!rule.accounts?.some((x) => x?.accountid === dealerPerson)))
|
||
);
|
||
|
||
// Обработка найденных записей по приоритету
|
||
const sortedRules = filteredRules
|
||
? sort(filteredRules, (x) => dayjs(x?.evo_datefrom).date(), true)
|
||
: [];
|
||
|
||
type Rule =
|
||
| NonNullable<CRMTypes.GetEltInsuranceRulesQuery['evo_insurance_ruleses']>[number]
|
||
| undefined;
|
||
const priorities = [100_000_000, 100_000_003, 100_000_001, 100_000_002];
|
||
const selectedRule = priorities.reduce(
|
||
(found, priority) => found || sortedRules.find((rule) => rule?.evo_rules_type === priority),
|
||
null as Rule
|
||
);
|
||
|
||
const insuranceCondition = selectedRule?.evo_id ?? null;
|
||
|
||
if (selectedRule) {
|
||
const rule_evo_discount = selectedRule.evo_discount ?? 0;
|
||
|
||
switch (selectedRule.evo_rules_type) {
|
||
// "не выводить результат расчета"
|
||
case 100_000_000: {
|
||
sum = 0;
|
||
requestId = defaultRow.requestId;
|
||
skCalcId = defaultRow.skCalcId;
|
||
if (selectedRule.evo_message) error = selectedRule.evo_message;
|
||
totalFranchise = 0;
|
||
break;
|
||
}
|
||
|
||
// "проверка на мин.тариф"
|
||
case 100_000_001: {
|
||
const newSum = round((sum / cost) * 100, 2);
|
||
if (newSum < rule_evo_discount) {
|
||
sum = 0;
|
||
requestId = defaultRow.requestId;
|
||
skCalcId = defaultRow.skCalcId;
|
||
if (selectedRule.evo_message) error = selectedRule.evo_message;
|
||
totalFranchise = 0;
|
||
}
|
||
break;
|
||
}
|
||
|
||
// "скидка за счет КВ"
|
||
case 100_000_002: {
|
||
sum = (((sum / cost) * 100 - rule_evo_discount) / 100) * cost;
|
||
requestId = defaultRow.requestId;
|
||
skCalcId = defaultRow.skCalcId;
|
||
if (selectedRule.evo_message) error = selectedRule.evo_message;
|
||
totalFranchise = 0;
|
||
break;
|
||
}
|
||
|
||
// "акционный тариф"
|
||
case 100_000_003: {
|
||
sum = (rule_evo_discount / 100) * cost;
|
||
requestId = defaultRow.requestId;
|
||
skCalcId = defaultRow.skCalcId;
|
||
if (selectedRule.evo_message) error = selectedRule.evo_message;
|
||
totalFranchise = 0;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
return {
|
||
...row,
|
||
insuranceCondition,
|
||
message: error || message,
|
||
numCalc: '0',
|
||
requestId,
|
||
skCalcId,
|
||
status: error ? 'error' : null,
|
||
sum,
|
||
totalFranchise,
|
||
};
|
||
}
|