/* eslint-disable sonarjs/cognitive-complexity */ /* eslint-disable complexity */ import type { ValidationContext } from '../types'; import type { Elements } from '@/Components/Calculation/config/map/values'; import { FinGAPSchema } from '@/config/schema/fingap'; import { InsuranceSchema } from '@/config/schema/insurance'; import ValuesSchema from '@/config/schema/values'; import { MAX_MASS, VEHICLE_SEATS } from '@/constants/values'; import * as CRMTypes from '@/graphql/crm.types'; import { z } from 'zod'; export function createValidationSchema({ apolloClient }: ValidationContext) { return ValuesSchema.pick({ IRR_Perc: true, addEquipmentPrice: true, countSeats: true, dealerPerson: true, discountRub: true, engineVolume: true, firstPaymentPerc: true, importProgramSum: true, insNSIB: true, lastPaymentPerc: true, leaseObjectCategory: true, leaseObjectCount: true, leaseObjectMotorPower: true, leaseObjectPriceWthtVAT: true, leaseObjectUsed: true, leaseObjectYear: true, maxMass: true, objectRegistration: true, partialVAT: true, plPriceRub: true, product: true, quote: true, recalcWithRevision: true, technicalCard: true, }) .extend({ fingap: FinGAPSchema, insurance: InsuranceSchema, }) .superRefine( async ( { addEquipmentPrice, dealerPerson: dealerPersonId, importProgramSum, leaseObjectPriceWthtVAT, leaseObjectUsed, product: productId, quote: quoteId, recalcWithRevision, discountRub, plPriceRub, firstPaymentPerc, leaseObjectCount, maxMass, countSeats, leaseObjectYear, lastPaymentPerc, leaseObjectCategory, partialVAT, IRR_Perc, leaseObjectMotorPower, engineVolume, insNSIB, technicalCard, objectRegistration, fingap: fingapRisks, insurance, }, ctx ) => { if (!recalcWithRevision) { return; } if (!quoteId) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Не указано предложение, по которому осуществляется Пересчет без пересмотра', path: ['selectQuote'], }); } if (dealerPersonId && quoteId && productId) { const { data: { dealer_person }, } = await apolloClient.query({ query: CRMTypes.GetDealerPersonDocument, variables: { dealerPersonId }, }); const { data: { quote }, } = await apolloClient.query({ query: CRMTypes.GetQuoteDocument, variables: { quoteId }, }); const maxCondition1 = leaseObjectUsed === false && dealer_person?.evo_supplier_type !== 100_000_001 && quote?.evo_max_price_change && !partialVAT && plPriceRub - discountRub + addEquipmentPrice - importProgramSum > quote.evo_max_price_change; const maxCondition2 = leaseObjectUsed === false && dealer_person?.evo_supplier_type !== 100_000_001 && quote?.evo_max_price_change && partialVAT && leaseObjectPriceWthtVAT > quote.evo_max_price_change - (quote.evo_nds_in_price_supplier_currency || 0); const maxCondition3 = (leaseObjectUsed === true || dealer_person?.evo_supplier_type === 100_000_001) && quote?.evo_supplier_currency_price && plPriceRub - discountRub + addEquipmentPrice - importProgramSum > quote.evo_supplier_currency_price - (quote.evo_discount_supplier_currency || 0) + (quote.evo_equip_price || 0) - (quote.evo_program_import_subsidy_sum || 0); const minCondition1 = !partialVAT && quote?.evo_min_change_price && plPriceRub - discountRub + addEquipmentPrice - importProgramSum < quote.evo_min_change_price; const minCondition2 = partialVAT && quote?.evo_min_change_price && leaseObjectPriceWthtVAT < quote.evo_min_change_price - (quote.evo_nds_in_price_supplier_currency || 0); if (maxCondition1 || maxCondition2) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Указанная стоимость предмета лизинга больше возможного изменения стоимости предмета лизинга при пересчете без пересмотра. ' + 'Уменьшите стоимость предмета лизинга', path: ['tbxLeaseObjectPrice'], }); } else if (maxCondition3) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'При пересчете без пересмотра КП с ПЛ БУ или с непрофессиональным поставщиком недопустимо увеличение стоимости. Создайте новое КП и отправьте его на рассмотрение андеррайтингу для повторной проверки оценщиком.', path: ['tbxLeaseObjectPrice'], }); } else if (minCondition1 || minCondition2) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Указанная стоимость предмета лизинга меньше возможного изменения стоимости предмета лизинга при пересчете без пересмотра. ' + 'Увеличьте стоимость предмета лизинга', path: ['tbxLeaseObjectPrice'], }); } } if (quoteId) { const { data: { quote }, } = await apolloClient.query({ query: CRMTypes.GetQuoteDocument, variables: { quoteId }, }); if ( firstPaymentPerc < (quote?.evo_approved_first_payment || 0) + (quote?.evo_percent_subsidy || 0) ) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: `Указанный первый платеж меньше одобренного ${quote?.evo_approved_first_payment}. При пересчете без пересмотра изменение первого платежа возможно только в большую сторону от одобренного значения`, path: ['tbxFirstPaymentPerc'], }); } if (quote?.evo_recalc_limit && leaseObjectCount > quote.evo_recalc_limit) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Количество ПЛ превышает лимит пересчета без пересмотра', path: ['tbxLeaseObjectCount'], }); } if ( quote?.evo_max_mass && ((quote.evo_max_mass < MAX_MASS && maxMass >= MAX_MASS) || (quote?.evo_max_mass >= MAX_MASS && maxMass < MAX_MASS)) ) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Указанная разрешенная макс. масса выходит из утвержденного диапазона. Для изменения параметра требуется пересмотр сделки', path: ['tbxMaxMass'], }); } if ( leaseObjectCategory === 100_000_003 && quote?.evo_seats && ((quote.evo_seats < VEHICLE_SEATS && countSeats >= VEHICLE_SEATS) || (quote.evo_seats >= VEHICLE_SEATS && countSeats < VEHICLE_SEATS)) ) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Указанное кол-во мест выходит из утвержденного диапазона. Для изменения параметра требуется пересмотр сделки', path: ['tbxCountSeats'], }); } if (quote?.evo_year && leaseObjectYear < quote.evo_year) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'При пересчете без пересмотра год выпуска нельзя уменьшать', path: ['tbxLeaseObjectYear'], }); } if ( quote?.evo_last_payment_perc && lastPaymentPerc > 1 && lastPaymentPerc > quote.evo_last_payment_perc ) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'При пересчете без пересмотра последний платеж можно уменьшать или увеличивать до 1%', path: ['tbxLastPaymentPerc'], }); } if (partialVAT !== quote?.evo_sale_without_nds) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Нельзя менять частичный НДС при пересчете без пересмотра', path: ['selectProduct'], }); } if (quote?.evo_committee_quote === 100_000_000 && quote.evo_accept_quoteid) { const { data: { quote: accept_quote }, } = await apolloClient.query({ query: CRMTypes.GetQuoteDocument, variables: { quoteId: quote.evo_accept_quoteid }, }); if (accept_quote?.evo_msfo_irr && IRR_Perc - accept_quote?.evo_msfo_irr > 0.1) ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Нельзя увеличивать IRR после рассмотрения предложения на КК', path: ['tbxIRR_Perc'] as Elements[], }); if ( accept_quote?.evo_power && Math.abs(leaseObjectMotorPower - accept_quote.evo_power) > 10 ) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Нельзя корректировать мощность более чем на 10 л.с. после рассмотрения предложения на КК', path: ['tbxLeaseObjectMotorPower'] as Elements[], }); } if ( accept_quote?.evo_engine_volume && Math.abs(engineVolume - accept_quote.evo_engine_volume) > 0.1 ) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Нельзя корректировать объем двигателя более чем на 0.1 л после рассмотрения предложения на КК', path: ['tbxEngineVolume'] as Elements[], }); } if (insNSIB && !accept_quote?.evo_nsib) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Нельзя включать в график НСИБ после рассмотрения предложения на КК', path: ['selectInsNSIB'] as Elements[], }); } if ( technicalCard && !accept_quote?.evo_addproduct_types?.some((x) => x?.evo_product_type === 100_000_000) ) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Нельзя включать в график карту тех.помощи после рассмотрения предложения на КК', path: ['selectTechnicalCard'] as Elements[], }); } if ( objectRegistration && objectRegistration !== accept_quote?.evo_db_accept_registration ) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Нельзя менять регистрацию после рассмотрения предложения на КК', path: ['radioObjectRegistration'] as Elements[], }); } if ( insurance.values.fingap.insured === 100_000_001 && fingapRisks?.length > 0 && fingapRisks.some( (fingapRisk) => !accept_quote?.evo_product_risks?.some( (evo_product_risk) => fingapRisk.riskId === evo_product_risk?.evo_addproduct_typeid ) ) ) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Нельзя включать новые риски Safe Finance после рассмотрения предложения на КК', path: ['fingap'], }); } if ( insurance.values.fingap.insured === 100_000_001 && accept_quote?.evo_fingap_payer && insurance.values.fingap.insured !== accept_quote?.evo_fingap_payer ) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Нельзя включать в график SafeFinance после рассмотрения предложения на КК', path: ['insurance'], }); } if ( insurance.values.osago.insured === 100_000_001 && accept_quote?.evo_osago_payer && insurance.values.osago.insured !== accept_quote?.evo_osago_payer ) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Нельзя включать в график ОСАГО после рассмотрения предложения на КК', path: ['insurance'], }); } if ( insurance.values.kasko.insured === 100_000_001 && accept_quote?.evo_kasko_payer && insurance.values.kasko.insured !== accept_quote?.evo_kasko_payer ) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Нельзя включать в график КАСКО после рассмотрения предложения на КК', path: ['insurance'], }); } } } } ); }