/* 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 { getCurrentDateString } 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: getCurrentDateString(), }, }); 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', }); let evo_broker_accountid: string | null = null; if (dealerPerson) { const { data: { dealer_person }, } = await apolloClient.query({ query: CRMTypes.GetDealerPersonDocument, variables: { dealerPersonId: dealerPerson, }, }); evo_broker_accountid = dealer_person?.evo_broker_accountid || null; } await validateRewardSum({ agentid: dealerBroker || evo_broker_accountid, 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', ], }); } } }); }