505 lines
20 KiB
TypeScript
505 lines
20 KiB
TypeScript
/* eslint-disable sonarjs/cognitive-complexity */
|
||
/* eslint-disable complexity */
|
||
import type { ValidationContext } from '../types';
|
||
import type { Elements } from '@/Components/Calculation/config/map/values';
|
||
import ValuesSchema from '@/config/schema/values';
|
||
import * as CRMTypes from '@/graphql/crm.types';
|
||
import { getCurrentISODate } from '@/utils/date';
|
||
import { normalizeOptions } from '@/utils/entity';
|
||
import type { RefinementCtx } from 'zod';
|
||
import { z } from 'zod';
|
||
|
||
function helper({ apolloClient, ctx }: ValidationContext & { ctx: RefinementCtx }) {
|
||
return {
|
||
async validateRewardSum({
|
||
agentid,
|
||
conditionId,
|
||
sumFieldName,
|
||
sum,
|
||
}: {
|
||
agentid: string | null;
|
||
conditionId: string | null;
|
||
sum: number;
|
||
sumFieldName: Elements;
|
||
}) {
|
||
if (agentid) {
|
||
const {
|
||
data: { evo_reward_conditions },
|
||
} = await apolloClient.query({
|
||
query: CRMTypes.GetRewardConditionsDocument,
|
||
variables: {
|
||
agentid,
|
||
currentDate: getCurrentISODate(),
|
||
},
|
||
});
|
||
|
||
const requests = normalizeOptions(evo_reward_conditions)?.map(async ({ value }) => {
|
||
const {
|
||
data: { evo_reward_condition },
|
||
} = await apolloClient.query<
|
||
CRMTypes.GetRewardConditionQuery,
|
||
CRMTypes.GetRewardConditionQueryVariables
|
||
>({
|
||
query: CRMTypes.GetRewardConditionDocument,
|
||
variables: {
|
||
conditionId: value,
|
||
},
|
||
});
|
||
|
||
return evo_reward_condition;
|
||
});
|
||
|
||
const requiredReward = (await Promise.all(requests)).some(
|
||
(x) => x?.evo_agency_agreementidData?.evo_required_reward === true
|
||
);
|
||
|
||
if (sum === 0 && requiredReward) {
|
||
ctx.addIssue({
|
||
code: z.ZodIssueCode.custom,
|
||
message: 'Согласно агентскому договору обязательна выплата АВ. Заложите АВ в расчет',
|
||
path: [sumFieldName],
|
||
});
|
||
}
|
||
}
|
||
|
||
if (conditionId) {
|
||
const {
|
||
data: { evo_reward_condition },
|
||
} = await apolloClient.query<
|
||
CRMTypes.GetRewardConditionQuery,
|
||
CRMTypes.GetRewardConditionQueryVariables
|
||
>({
|
||
query: CRMTypes.GetRewardConditionDocument,
|
||
variables: {
|
||
conditionId,
|
||
},
|
||
});
|
||
|
||
if (evo_reward_condition?.evo_reward_summ && sum > evo_reward_condition?.evo_reward_summ) {
|
||
ctx.addIssue({
|
||
code: z.ZodIssueCode.custom,
|
||
message: 'Вознаграждение указано больше условия по агентскому договору!',
|
||
path: [sumFieldName],
|
||
});
|
||
}
|
||
|
||
if (
|
||
evo_reward_condition?.evo_reduce_reward === false &&
|
||
evo_reward_condition?.evo_reward_summ &&
|
||
sum < evo_reward_condition?.evo_reward_summ
|
||
) {
|
||
ctx.addIssue({
|
||
code: z.ZodIssueCode.custom,
|
||
message: 'Вознаграждение указано меньше условия по агентскому договору!',
|
||
path: [sumFieldName],
|
||
});
|
||
}
|
||
|
||
if (
|
||
evo_reward_condition?.evo_min_reward_summ &&
|
||
sum < evo_reward_condition?.evo_min_reward_summ
|
||
) {
|
||
ctx.addIssue({
|
||
code: z.ZodIssueCode.custom,
|
||
message: 'Вознаграждение указано меньше условия по агентскому договору!',
|
||
path: [sumFieldName],
|
||
});
|
||
}
|
||
}
|
||
},
|
||
|
||
async validateRewardWithoutOtherAgent({
|
||
conditionId,
|
||
fieldName,
|
||
}: {
|
||
conditionId: string | null;
|
||
fieldName: string;
|
||
}) {
|
||
if (conditionId) {
|
||
const {
|
||
data: { evo_reward_condition },
|
||
} = await apolloClient.query<
|
||
CRMTypes.GetRewardConditionQuery,
|
||
CRMTypes.GetRewardConditionQueryVariables
|
||
>({
|
||
query: CRMTypes.GetRewardConditionDocument,
|
||
variables: {
|
||
conditionId,
|
||
},
|
||
});
|
||
|
||
if (evo_reward_condition?.evo_agency_agreementidData?.evo_reward_without_other_agent) {
|
||
ctx.addIssue({
|
||
code: z.ZodIssueCode.custom,
|
||
message: 'Согласно условиям АД выплата допустима только этому агенту',
|
||
path: [fieldName],
|
||
});
|
||
}
|
||
}
|
||
},
|
||
};
|
||
}
|
||
|
||
const ERR_DOUBLE_REWARD = 'Вы закладываете вознаграждение одному и тому же агенту дважды';
|
||
|
||
const AgentsSchema = ValuesSchema.pick({
|
||
calcBroker: true,
|
||
calcDoubleAgent: true,
|
||
calcFinDepartment: true,
|
||
dealer: true,
|
||
dealerBroker: true,
|
||
dealerPerson: true,
|
||
indAgent: true,
|
||
});
|
||
|
||
const ConditionsSchema = ValuesSchema.pick({
|
||
calcBrokerRewardCondition: true,
|
||
calcDoubleAgentRewardCondition: true,
|
||
dealerBrokerRewardCondition: true,
|
||
dealerRewardCondition: true,
|
||
finDepartmentRewardCondtion: true,
|
||
indAgentRewardCondition: true,
|
||
});
|
||
|
||
const SumsSchema = ValuesSchema.pick({
|
||
calcBrokerRewardSum: true,
|
||
calcDoubleAgentRewardSumm: true,
|
||
dealerBrokerRewardSumm: true,
|
||
dealerRewardSumm: true,
|
||
finDepartmentRewardSumm: true,
|
||
indAgentRewardSumm: true,
|
||
});
|
||
|
||
export function createValidationSchema(context: ValidationContext) {
|
||
const { apolloClient } = context;
|
||
|
||
return ValuesSchema.pick({ brand: true })
|
||
.merge(AgentsSchema)
|
||
.merge(ConditionsSchema)
|
||
.merge(SumsSchema)
|
||
.superRefine(async (values, ctx) => {
|
||
const {
|
||
calcBroker,
|
||
calcBrokerRewardCondition,
|
||
calcBrokerRewardSum,
|
||
calcDoubleAgent,
|
||
calcDoubleAgentRewardCondition,
|
||
calcDoubleAgentRewardSumm,
|
||
calcFinDepartment,
|
||
dealer: dealerId,
|
||
dealerBroker,
|
||
dealerBrokerRewardCondition,
|
||
dealerBrokerRewardSumm,
|
||
dealerPerson,
|
||
dealerRewardCondition,
|
||
dealerRewardSumm,
|
||
finDepartmentRewardCondtion,
|
||
finDepartmentRewardSumm,
|
||
indAgent,
|
||
indAgentRewardCondition,
|
||
indAgentRewardSumm,
|
||
brand: brandId,
|
||
} = values;
|
||
|
||
/**
|
||
* Добавить валидацию на кнопку Рассчитать:
|
||
* если tbxDealerRewardSumm > 0 и
|
||
* если selectDealerPerson = selectDealerBroker и tbxDealerBrokerRewardSumm > 0, то ругаться на selectDealerPerson
|
||
* если selectDealerPerson = selectIndAgent и tbxIndAgentRewardSumm > 0, то ругаться на selectDealerPerson
|
||
* если selectDealerPerson = selectCalcDoubleAgent и tbxCalcDoubleAgentRewardSumm > 0, то ругаться на selectDealerPerson
|
||
* если selectDealerPerson = selectCalcBroker tbxCalcBrokerRewardSum > 0, то ругаться на selectDealerPerson
|
||
* если selectDealerPerson = selectFinDepartment и tbxFinDepartmentRewardSumm > 0, то ругаться на selectDealerPerson
|
||
* 2.если tbxDealerBrokerRewardSumm > 0 и
|
||
*
|
||
* если selectDealerBroker = selectDealerPerson и tbxDealerRewardSumm > 0, то ругаться на selectDealerBroker
|
||
* если selectDealerBroker = selectIndAgent и tbxIndAgentRewardSumm > 0, то ругаться на selectDealerBroker
|
||
* если selectDealerBroker = selectCalcDoubleAgent и tbxCalcDoubleAgentRewardSumm > 0, то ругаться на selectDealerBroker
|
||
* если selectDealerBroker = selectCalcBroker tbxCalcBrokerRewardSum > 0, то ругаться на selectDealerBroker
|
||
* если selectDealerBroker = selectFinDepartment и tbxFinDepartmentRewardSumm > 0, то ругаться на selectDealerBroker
|
||
* 3. если tbxIndAgentRewardSumm > 0 и
|
||
*
|
||
* если selectIndAgent = selectDealerPerson и tbxDealerRewardSumm > 0, то ругаться на selectIndAgent
|
||
* если selectIndAgent = selectDealerBroker и tbxDealerBrokerRewardSumm > 0, то ругаться на selectIndAgent
|
||
* если selectIndAgent = selectCalcDoubleAgent и tbxCalcDoubleAgentRewardSumm > 0, то ругаться на selectIndAgent
|
||
* если selectIndAgent = selectCalcBroker tbxCalcBrokerRewardSum > 0, то ругаться на selectIndAgent
|
||
* если selectIndAgent = selectFinDepartment и tbxFinDepartmentRewardSumm > 0, то ругаться на selectIndAgent
|
||
* 4. если tbxCalcDoubleAgentRewardSumm > 0 и
|
||
*
|
||
* если selectCalcDoubleAgent = selectDealerPerson и tbxDealerRewardSumm > 0, то ругаться на selectCalcDoubleAgent
|
||
* если selectCalcDoubleAgent = selectDealerBroker и tbxDealerBrokerRewardSumm > 0, то ругаться на selectCalcDoubleAgent
|
||
* если selectCalcDoubleAgent = sselectIndAgent и tbxIndAgentRewardSumm > 0, то ругаться на selectCalcDoubleAgent
|
||
* если selectCalcDoubleAgent = selectCalcBroker tbxCalcBrokerRewardSum > 0, то ругаться на selectCalcDoubleAgent
|
||
* если selectCalcDoubleAgent = selectFinDepartment и tbxFinDepartmentRewardSumm > 0, то ругаться на selectCalcDoubleAgent
|
||
* 5. если tbxCalcBrokerRewardSum > 0 и
|
||
*
|
||
* если selectCalcBroker = selectDealerPerson и tbxDealerRewardSumm > 0, то ругаться на selectCalcBroker
|
||
* если selectCalcBroker = selectDealerBroker и tbxDealerBrokerRewardSumm > 0, то ругаться на selectCalcBroker
|
||
* если selectCalcBroker = sselectIndAgent и tbxIndAgentRewardSumm > 0, то ругаться на selectCalcBroker
|
||
* если selectCalcBroker = selectCalcDoubleAgent и tbxCalcDoubleAgentRewardSumm > 0, то ругаться на selectCalcBroker
|
||
* если selectCalcBroker = selectFinDepartment и tbxFinDepartmentRewardSumm > 0, то ругаться на selectCalcBroker
|
||
* 6. если tbxFinDepartmentRewardSumm > 0 и
|
||
*
|
||
* если selectFinDepartment = selectDealerPerson и tbxDealerRewardSumm > 0, то ругаться на selectFinDepartment
|
||
* если selectFinDepartment = selectDealerBroker и tbxDealerBrokerRewardSumm > 0, то ругаться на selectFinDepartment
|
||
* если selectFinDepartment = sselectIndAgent и tbxIndAgentRewardSumm > 0, то ругаться на selectFinDepartment
|
||
* если selectFinDepartment = selectCalcDoubleAgent и tbxCalcDoubleAgentRewardSumm > 0, то ругаться на selectFinDepartment
|
||
* если selectFinDepartment = selectCalcBroker tbxCalcBrokerRewardSum > 0, то ругаться на selectFinDepartment
|
||
*/
|
||
|
||
if (
|
||
dealerRewardSumm > 0 &&
|
||
Boolean(dealerPerson) &&
|
||
((dealerPerson === dealerBroker && dealerBrokerRewardSumm > 0) ||
|
||
(dealerPerson === indAgent && indAgentRewardSumm > 0) ||
|
||
(dealerPerson === calcDoubleAgent && calcDoubleAgentRewardSumm > 0) ||
|
||
(dealerPerson === calcBroker && calcBrokerRewardSum > 0) ||
|
||
(dealerPerson === calcFinDepartment && finDepartmentRewardSumm > 0))
|
||
) {
|
||
ctx.addIssue({
|
||
code: z.ZodIssueCode.custom,
|
||
message: ERR_DOUBLE_REWARD,
|
||
path: ['selectDealerPerson'],
|
||
});
|
||
}
|
||
|
||
if (
|
||
dealerBrokerRewardSumm > 0 &&
|
||
Boolean(dealerBroker) &&
|
||
((dealerBroker === dealerPerson && dealerRewardSumm > 0) ||
|
||
(dealerBroker === indAgent && indAgentRewardSumm > 0) ||
|
||
(dealerBroker === calcDoubleAgent && calcDoubleAgentRewardSumm > 0) ||
|
||
(dealerBroker === calcBroker && calcBrokerRewardSum > 0) ||
|
||
(dealerBroker === calcFinDepartment && finDepartmentRewardSumm > 0))
|
||
) {
|
||
ctx.addIssue({
|
||
code: z.ZodIssueCode.custom,
|
||
message: ERR_DOUBLE_REWARD,
|
||
path: ['selectDealerBroker'],
|
||
});
|
||
}
|
||
|
||
if (
|
||
indAgentRewardSumm > 0 &&
|
||
Boolean(indAgent) &&
|
||
((indAgent === dealerPerson && dealerRewardSumm > 0) ||
|
||
(indAgent === dealerBroker && dealerBrokerRewardSumm > 0) ||
|
||
(indAgent === calcDoubleAgent && calcDoubleAgentRewardSumm > 0) ||
|
||
(indAgent === calcBroker && calcBrokerRewardSum > 0) ||
|
||
(indAgent === calcFinDepartment && finDepartmentRewardSumm > 0))
|
||
) {
|
||
ctx.addIssue({
|
||
code: z.ZodIssueCode.custom,
|
||
message: ERR_DOUBLE_REWARD,
|
||
path: ['selectIndAgent'],
|
||
});
|
||
}
|
||
|
||
if (
|
||
calcDoubleAgentRewardSumm > 0 &&
|
||
Boolean(calcDoubleAgent) &&
|
||
((calcDoubleAgent === dealerPerson && dealerRewardSumm > 0) ||
|
||
(calcDoubleAgent === dealerBroker && dealerBrokerRewardSumm > 0) ||
|
||
(calcDoubleAgent === indAgent && indAgentRewardSumm > 0) ||
|
||
(calcDoubleAgent === calcBroker && calcBrokerRewardSum > 0) ||
|
||
(calcDoubleAgent === calcFinDepartment && finDepartmentRewardSumm > 0))
|
||
) {
|
||
ctx.addIssue({
|
||
code: z.ZodIssueCode.custom,
|
||
message: ERR_DOUBLE_REWARD,
|
||
path: ['selectCalcDoubleAgent'],
|
||
});
|
||
}
|
||
|
||
if (
|
||
calcBrokerRewardSum > 0 &&
|
||
Boolean(calcBroker) &&
|
||
((calcBroker === dealerPerson && dealerRewardSumm > 0) ||
|
||
(calcBroker === dealerBroker && dealerBrokerRewardSumm > 0) ||
|
||
(calcBroker === indAgent && indAgentRewardSumm > 0) ||
|
||
(calcBroker === calcDoubleAgent && calcDoubleAgentRewardSumm > 0) ||
|
||
(calcBroker === calcFinDepartment && finDepartmentRewardSumm > 0))
|
||
) {
|
||
ctx.addIssue({
|
||
code: z.ZodIssueCode.custom,
|
||
message: ERR_DOUBLE_REWARD,
|
||
path: ['selectCalcBroker'],
|
||
});
|
||
}
|
||
|
||
if (
|
||
finDepartmentRewardSumm > 0 &&
|
||
Boolean(calcFinDepartment) &&
|
||
((calcFinDepartment === dealerPerson && dealerRewardSumm > 0) ||
|
||
(calcFinDepartment === dealerBroker && dealerBrokerRewardSumm > 0) ||
|
||
(calcFinDepartment === indAgent && indAgentRewardSumm > 0) ||
|
||
(calcFinDepartment === calcDoubleAgent && calcDoubleAgentRewardSumm > 0) ||
|
||
(calcFinDepartment === calcBroker && calcBrokerRewardSum > 0))
|
||
) {
|
||
ctx.addIssue({
|
||
code: z.ZodIssueCode.custom,
|
||
message: ERR_DOUBLE_REWARD,
|
||
path: ['selectCalcFinDepartment'],
|
||
});
|
||
}
|
||
|
||
/**
|
||
* В валидацию на кнопку Рассчитать внести изменение:
|
||
* 1) поле selectDealerPerson убрать из списка обязательных для расчета полей
|
||
* 2) добавить валидацию на поле selectDealerPerson :
|
||
* Если в поле selectDealer указан account, у которого evo_return_leasing_dealer = False (или null)
|
||
* и поле selectDealerPerson = null, то выводить ошибку и поле selectDealerPerson обводить красной рамкой,
|
||
* иначе все ок
|
||
*/
|
||
if (dealerId) {
|
||
const {
|
||
data: { dealer },
|
||
} = await apolloClient.query({
|
||
query: CRMTypes.GetDealerDocument,
|
||
variables: {
|
||
dealerId,
|
||
},
|
||
});
|
||
|
||
if (!dealerPerson && !dealer?.evo_return_leasing_dealer)
|
||
ctx.addIssue({
|
||
code: z.ZodIssueCode.custom,
|
||
message: 'Не заполнено поле',
|
||
path: ['selectDealerPerson'],
|
||
});
|
||
} else {
|
||
ctx.addIssue({
|
||
code: z.ZodIssueCode.custom,
|
||
message: 'Не заполнено поле',
|
||
path: ['selectDealer'],
|
||
});
|
||
}
|
||
|
||
const { validateRewardSum, validateRewardWithoutOtherAgent } = helper({ ...context, ctx });
|
||
|
||
await validateRewardSum({
|
||
agentid: dealerPerson,
|
||
conditionId: dealerRewardCondition,
|
||
sum: dealerRewardSumm,
|
||
sumFieldName: 'tbxDealerRewardSumm',
|
||
});
|
||
|
||
await validateRewardSum({
|
||
agentid: dealerBroker,
|
||
conditionId: dealerBrokerRewardCondition,
|
||
sum: dealerBrokerRewardSumm,
|
||
sumFieldName: 'tbxDealerBrokerRewardSumm',
|
||
});
|
||
|
||
await validateRewardSum({
|
||
agentid: indAgent,
|
||
conditionId: indAgentRewardCondition,
|
||
sum: indAgentRewardSumm,
|
||
sumFieldName: 'tbxIndAgentRewardSumm',
|
||
});
|
||
|
||
await validateRewardSum({
|
||
agentid: calcDoubleAgent,
|
||
conditionId: calcDoubleAgentRewardCondition,
|
||
sum: calcDoubleAgentRewardSumm,
|
||
sumFieldName: 'tbxCalcDoubleAgentRewardSumm',
|
||
});
|
||
|
||
await validateRewardSum({
|
||
agentid: calcBroker,
|
||
conditionId: calcBrokerRewardCondition,
|
||
sum: calcBrokerRewardSum,
|
||
sumFieldName: 'tbxCalcBrokerRewardSum',
|
||
});
|
||
|
||
await validateRewardSum({
|
||
agentid: calcFinDepartment,
|
||
conditionId: finDepartmentRewardCondtion,
|
||
sum: finDepartmentRewardSumm,
|
||
sumFieldName: 'tbxFinDepartmentRewardSumm',
|
||
});
|
||
|
||
/**
|
||
* Если в 2х и более полях RewardSumm значения больше 0 И в полях RewardCondtion есть хотя бы одна запись,
|
||
* у которой evo_reward_condition.evo_agency_agreementid. Выплата без других агентов
|
||
* (evo_reward_without_other_agent) = True,
|
||
* то выводить ошибку "Согласно условиям АД выплата допустима только этому агенту" на то RewardCondtion,
|
||
* у которого evo_reward_condition.evo_agency_agreementid равно True
|
||
* иначе все ок
|
||
*/
|
||
if (
|
||
[
|
||
calcBrokerRewardSum,
|
||
calcDoubleAgentRewardSumm,
|
||
dealerBrokerRewardSumm,
|
||
dealerRewardSumm,
|
||
finDepartmentRewardSumm,
|
||
indAgentRewardSumm,
|
||
].filter((x) => x > 0).length > 1
|
||
) {
|
||
await validateRewardWithoutOtherAgent({
|
||
conditionId: calcBrokerRewardCondition,
|
||
fieldName: 'selectCalcBrokerRewardCondition',
|
||
});
|
||
|
||
await validateRewardWithoutOtherAgent({
|
||
conditionId: calcDoubleAgentRewardCondition,
|
||
fieldName: 'selectCalcDoubleAgentRewardCondition',
|
||
});
|
||
|
||
await validateRewardWithoutOtherAgent({
|
||
conditionId: dealerBrokerRewardCondition,
|
||
fieldName: 'selectDealerBrokerRewardCondition',
|
||
});
|
||
|
||
await validateRewardWithoutOtherAgent({
|
||
conditionId: dealerRewardCondition,
|
||
fieldName: 'selectDealerRewardCondition',
|
||
});
|
||
|
||
await validateRewardWithoutOtherAgent({
|
||
conditionId: finDepartmentRewardCondtion,
|
||
fieldName: 'selectFinDepartmentRewardCondtion',
|
||
});
|
||
|
||
await validateRewardWithoutOtherAgent({
|
||
conditionId: indAgentRewardCondition,
|
||
fieldName: 'selectIndAgentRewardCondition',
|
||
});
|
||
}
|
||
|
||
if (brandId) {
|
||
const {
|
||
data: { evo_brand },
|
||
} = await apolloClient.query({
|
||
query: CRMTypes.GetBrandDocument,
|
||
variables: { brandId },
|
||
});
|
||
|
||
if (
|
||
evo_brand?.evo_maximum_percentage_av &&
|
||
indAgentRewardSumm +
|
||
calcDoubleAgentRewardSumm +
|
||
dealerRewardSumm +
|
||
calcBrokerRewardSum +
|
||
dealerBrokerRewardSumm +
|
||
finDepartmentRewardSumm >
|
||
evo_brand?.evo_maximum_percentage_av
|
||
) {
|
||
ctx.addIssue({
|
||
code: z.ZodIssueCode.custom,
|
||
message:
|
||
'В данном расчете АВ закладывается выше установленного максимума. Уменьшите размер АВ',
|
||
path: [
|
||
'tbxDealerRewardSumm',
|
||
'tbxDealerBrokerRewardSumm',
|
||
'tbxIndAgentRewardSumm',
|
||
'tbxCalcDoubleAgentRewardSumm',
|
||
'tbxCalcBrokerRewardSum',
|
||
'tbxFinDepartmentRewardSumm',
|
||
],
|
||
});
|
||
}
|
||
}
|
||
});
|
||
}
|