/* eslint-disable complexity */ /* eslint-disable sonarjs/cognitive-complexity */ import type { ValidationContext } from '../types'; import type * as Insurance from '@/Components/Calculation/Form/Insurance/InsuranceTable/types'; import { FinGAPSchema } from '@/config/schema/fingap'; import { InsuranceSchema } from '@/config/schema/insurance'; import ValuesSchema from '@/config/schema/values'; import * as CRMTypes from '@/graphql/crm.types'; import { z } from 'zod'; export function createValidationSchema({ apolloClient }: ValidationContext) { return ValuesSchema.pick({ brand: true, firstPaymentPerc: true, insDecentral: true, leaseObjectType: true, leasingPeriod: true, leasingWithoutKasko: true, maxSpeed: true, partialVAT: true, plPriceRub: true, product: true, quote: true, recalcWithRevision: true, }) .extend({ fingap: FinGAPSchema, insurance: InsuranceSchema, }) .superRefine( async ( { leasingPeriod, recalcWithRevision, quote: quoteId, leasingWithoutKasko, insDecentral, insurance, brand: brandId, fingap: fingapRisks, partialVAT, leaseObjectType: leaseObjectTypeId, firstPaymentPerc, plPriceRub, maxSpeed, }, ctx ) => { if (quoteId) { const { data: { quote }, } = await apolloClient.query({ query: CRMTypes.GetQuoteDocument, variables: { quoteId }, }); if ( recalcWithRevision && quote?.evo_one_year_insurance === true && leasingPeriod > 15 && insurance.values.kasko.insTerm === 100_000_001 ) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Срок страхования КАСКО должен быть 12 месяцев, т.к. оформляется Однолетний полис', path: ['insurance'], }); } const { kasko } = insurance.values; if ( recalcWithRevision && quote?.evo_promotion && [100_000_000, 100_000_001].some((x) => quote.evo_promotion?.includes(x)) && quote.evo_programsolution && quote.evo_programsolution === 100_000_000 && quote.evo_kasko_payer !== kasko.insured ) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'По акции после одобрения нельзя менять Плательщика по КАСКО', path: ['insurance'], }); } } (['osago', 'kasko'] as Insurance.Keys[]).forEach((key) => { const { insCost, insured, policyType, insuranceCompany, insTerm } = insurance.values[key]; if (insured === 100_000_001 && insCost < 1000) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: `Укажите стоимость ${policyType}, включаемую в график (>1000)`, path: ['insurance'], }); } if (!insuranceCompany) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: `Укажите страховую компанию ${policyType}`, path: ['insurance'], }); } if (!insTerm) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: `Укажите срок страхования ${policyType}`, path: ['insurance'], }); } if (!insured) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: `Укажите плательщика ${policyType}`, path: ['insurance'], }); } }); const { fingap } = insurance.values; if (fingap.insuranceCompany && !fingap.insured) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: `Укажите плательщика ${fingap.policyType}`, path: ['insurance'], }); } if (fingap.insuranceCompany && fingap.insCost < 1000) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: `Укажите стоимость ${fingap.policyType}, включаемую в график (>1000)`, path: ['insurance'], }); } if (fingap.insuranceCompany && !fingap.insTerm) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: `Укажите срок страхования ${fingap.policyType}`, path: ['insurance'], }); } if (fingap.insuranceCompany && !fingapRisks?.length) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: `Выберите риски`, path: ['fingap'], }); } if (!fingap.insuranceCompany && fingap.insCost > 0) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: `Укажите страховую компанию ${fingap.policyType}`, path: ['insurance'], }); } if ( !leasingWithoutKasko && !insDecentral && insurance.values.osago.insuranceCompany && insurance.values.kasko.insuranceCompany !== insurance.values.osago.insuranceCompany ) { const { data: { account }, } = await apolloClient.query({ query: CRMTypes.GetInsuranceCompanyDocument, variables: { accountId: insurance.values.osago.insuranceCompany }, }); if (account?.evo_osago_with_kasko) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Невозможно страхование ОСАГО отдельно от КАСКО - страховая компания должна быть одна!', path: ['insurance'], }); } } if (brandId) { const { data: { evo_brand }, } = await apolloClient.query({ query: CRMTypes.GetBrandDocument, variables: { brandId }, }); const { data: { accounts }, } = await apolloClient.query({ query: CRMTypes.GetInsuranceCompaniesDocument, }); const defaultKaskoOptions = accounts?.filter((x) => x?.evo_type_ins_policy?.includes(100_000_000) ); if (evo_brand?.evo_id === 'BRAND49') { const renessansCompany = defaultKaskoOptions?.find((x) => x?.evo_inn === '7725497022'); if ( renessansCompany && insurance.values.kasko.insuranceCompany !== renessansCompany.value ) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Для Harley-Davidson СК для КАСКО может быть только ' + renessansCompany.label, path: ['insurance'], }); } } } if (partialVAT && insurance.values.kasko.insured === 100_000_001) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'При частичном НДС нельзя включать КАСКО в график', path: ['cbxPartialVAT'], }); } let evo_leasingobject_type: CRMTypes.GetLeaseObjectTypeQuery['evo_leasingobject_type'] = null; if (leaseObjectTypeId) { const { data } = await apolloClient.query({ query: CRMTypes.GetLeaseObjectTypeDocument, variables: { leaseObjectTypeId }, }); ({ evo_leasingobject_type } = data); } if ( evo_leasingobject_type?.evo_id === '1' && firstPaymentPerc < 25 && plPriceRub > 20_000_000 && insurance.values.kasko.insured === 100_000_001 ) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'При дорогом авто и авансе меньше 25% нельзя включать КАСКО в график', path: ['tbxLeaseObjectPrice'], }); } if ( evo_leasingobject_type?.evo_id && ['9'].includes(evo_leasingobject_type?.evo_id) && maxSpeed < 20 && insurance.values.osago.insured === 100_000_001 ) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Нельзя включать в график ОСАГО по Спецтехнике, т.к. полис не требуется', path: ['insurance'], }); } } ); }