import { IGetCalculationRequest } from 'core/types/Calculation/Requests'; import { DateTime } from 'luxon'; import { getEntities } from './crmManager'; import { PreparedPayments } from 'core/types/Calculation/Prepare'; import { calcPrice } from 'client/stores/CalculationStore/Effects/lib/tools'; import valuesConstants from 'core/constants/values'; export const prepareCalculationData = ({ values, tables, username, }: IGetCalculationRequest): any => { const currentDate = DateTime.local().toUTC().toJSDate(); const entities = getEntities([ { entityName: 'evo_coefficient', alias: 'evo_coefficient_season', where: { evo_corfficient_type: 100000000, statecode: 0, //TODO: // evo_datefrom: '<= currentDate', // evo_dateto: '>= currentDate', // evo_min_period: `<= ${values.leasingPeriod}`, // evo_max_period: `>= ${values.leasingPeriod}`, }, fields: [ 'evo_correction_coefficient', 'evo_graph_type', 'evo_season_type', ], }, { alias: 'evo_coefficient_bonus', entityName: 'evo_coefficient', where: { evo_corfficient_type: 100000002, statecode: 0, //TODO: // evo_datefrom: '<= currentDate', // evo_dateto: '>= currentDate', }, fields: [ 'evo_job_titleid', 'evo_sot_coefficient_typeid', 'evo_sot_coefficient', ], }, { entityName: 'evo_currencychange', where: { evo_coursedate: currentDate, statecode: 0, }, fields: ['isocurrencycode', 'evo_currencychange'], }, { entityName: 'evo_sot_coefficient_type', where: { statecode: 0, }, fields: ['evo_sot_coefficient_typeid', 'evo_id'], }, { entityName: 'evo_addproduct_type', where: { statecode: 0, //TODO: // evo_datefrom: '<= currentDate', // evo_dateto: '>= currentDate', // evo_min_period: `<= ${values.leasingPeriod}`, // evo_max_period: `>= ${values.leasingPeriod}`, }, fields: [ 'evo_addproduct_typeid', 'evo_graph_price_withoutnds', 'evo_cost_service_provider_withoutnds', 'evo_retro_bonus_withoutnds', 'evo_prime_cost', 'evo_graph_price', { entityName: 'evo_planpayment', fields: [ 'evo_name', 'evo_cost_equipment_withoutnds', 'evo_cost_price_telematics_withoutnds', 'evo_cost_telematics_withoutnds', ], }, ], }, { entityName: 'evo_tarif', where: { evo_tarifid: values.Tarif, }, fields: ['evo_irr_plan'], }, { entityName: 'evo_coefficient', where: { evo_corfficient_type: 100000001, statecode: 0, //TODO: // evo_datefrom: '<= currentDate', // evo_dateto: '>= currentDate', // evo_min_period: `<= ${values.leasingPeriod}`, // evo_max_period: `>= ${values.leasingPeriod}`, }, fields: [ 'evo_risk_delta', { entityName: 'evo_client_risk', where: { evo_client_riskid: values.clientRisk, }, }, { entityName: 'evo_client_type', where: { evo_client_typeid: values.clientType, }, }, { entityName: 'evo_leasingobject_type', where: { evo_leasingobject_typeid: values.leaseObjectType, }, }, ], }, { entityName: 'evo_leasingobject_type', where: { evo_leasingobject_typeid: values.leaseObjectType, }, fields: [ 'evo_id', 'evo_expluatation_period1', 'evo_expluatation_period2', 'evo_depreciation_rate1', 'evo_depreciation_rate2', ], }, ]); let preparedPayments: PreparedPayments = []; for (let i = 0; i <= values.leasingPeriod; i++) { preparedPayments[i].numberPayment = i + 1; preparedPayments[i].percentPayment = i === 0 ? 0 : tables.tablePayments[i].paymentRelation; preparedPayments[i].sumPayment[i] = 0; if (values.tracker && entities.evo_addproduct_type) { const evo_addproduct_type = entities.evo_addproduct_type.find( x => x.evo_addproduct_typeid === values.tracker, ); if (evo_addproduct_type && evo_addproduct_type.evo_planpayments) { const evo_planpayment = evo_addproduct_type.evo_planpayments.find( x => x.evo_name === (i + 1).toString(), ); if (evo_planpayment) { preparedPayments[i].gpsBasePayment = (evo_planpayment.evo_cost_price_telematics_withoutnds || 0) + (evo_planpayment.evo_cost_equipment_withoutnds || 0); preparedPayments[i].gpsCostPayment = evo_planpayment.evo_cost_telematics_withoutnds || 0; } } if (values.telematics && entities.evo_addproduct_type) { const evo_addproduct_type = entities.evo_addproduct_type.find( x => x.evo_addproduct_typeid === values.telematics, ); if (evo_addproduct_type && evo_addproduct_type.evo_planpayments) { const evo_planpayment = evo_addproduct_type.evo_planpayments.find( x => x.evo_name === (i + 1).toString(), ); if (evo_planpayment) { preparedPayments[i].tlmBasePayment = (evo_planpayment.evo_cost_price_telematics_withoutnds || 0) + (evo_planpayment.evo_cost_equipment_withoutnds || 0); preparedPayments[i].tlmCostPayment = evo_planpayment.evo_cost_telematics_withoutnds || 0; } } } } } //@ts-ignore let preparedValues: PreparedValues = {}; preparedValues.calcDate = currentDate; preparedValues.calcType = 100000000; preparedValues.irrExpected = (values.IRR_Perc as number) / 100; preparedValues.npvniExpected = 0; preparedValues.totalExpected = 0; preparedValues.nmper = values.leasingPeriod; preparedValues.leasing0K = values.product === 'LEASING0' ? ((preparedValues.nmper as number) - 2) * (0.0234 / ((1 - 1 / 1.0234) ^ ((preparedValues.nmper as number) - 2))) : 1; preparedValues.loanRate = (values.creditRate as number) / 100; preparedValues.balanceHolder = values.balanceHolder; preparedValues.dogDate = preparedValues.calcDate; preparedValues.paymentDateNew = undefined; preparedValues.deliveryTime = values.deliveryTime; preparedValues.firstPaymentAbs = undefined; preparedValues.firstPaymentNdsAbs = undefined; preparedValues.firstPaymentWithNdsAbs = undefined; preparedValues.lastPayment = (values.lastPaymentPerc as number) / 100; preparedValues.lastPaymentSum = (values.lastPaymentRub as number) / (1 + valuesConstants.VAT); preparedValues.scheduleOfPayments = values.graphType; preparedValues.comissionRub = (values.comissionRub as number) / (1 + valuesConstants.VAT); preparedValues.plTypeId = values.leaseObjectType; preparedValues.brandId = values.brand; preparedValues.modelId = values.model; preparedValues.configurationId = values.configuration; preparedValues.plYear = values.leaseObjectYear; preparedValues.carCapacity = values.leaseObjectMotorPower; preparedValues.motorVolume = values.engineVolume; preparedValues.plEngineType = values.engineType; preparedValues.carCarrying = values.maxMass; preparedValues.bonus = (values.saleBonus as number) / 100; preparedValues.bonusFix = 0; preparedValues.transTax = 0; preparedValues.transIncludeGr = false; preparedValues.transportTaxGrYear = 0; preparedValues.transportTaxGr = 0; let insuranceKaskoRow = tables.tableInsurance.find( x => x.policyType === 'КАСКО', ); let insuranceNSRow = tables.tableInsurance.find(x => x.policyType === 'НС'); let insuranceDGORow = tables.tableInsurance.find(x => x.policyType === 'ДГО'); let insuranceOSAGORow = tables.tableInsurance.find( x => x.policyType === 'ОСАГО', ); if ( insuranceKaskoRow && insuranceNSRow && insuranceDGORow && insuranceOSAGORow ) { if (insuranceKaskoRow.insured === 100000001) { preparedValues.insuranceKasko = insuranceKaskoRow.insCost + insuranceDGORow.insCost + insuranceNSRow.insCost; } else { preparedValues.insuranceKasko = 0; } } if (insuranceKaskoRow) { preparedValues.nmperInsurance = insuranceKaskoRow.insTerm === 100000001 ? values.leasingPeriod : 12; } if (insuranceOSAGORow) { preparedValues.insuranceOsago = insuranceOSAGORow.insured === 100000001 ? insuranceOSAGORow.insCost : 0; } preparedValues.insurance = preparedValues.insuranceOsago + preparedValues.insuranceKasko; preparedValues.insuranceKaskoNmper = preparedValues.nmperInsurance >= 16 ? (preparedValues.insuranceKasko * preparedValues.nmperInsurance) / 12 : preparedValues.insuranceKasko; preparedValues.insuranceContract = preparedValues.insuranceKaskoNmper + preparedValues.insuranceOsago; preparedValues.repayment = 25.0; if (values.firstPaymentPerc < 30) { switch (values.graphType) { case 100000003: if ( entities.evo_coefficient_season && entities.evo_coefficient_season.length > 0 ) { const evo_coefficient = entities.evo_coefficient_season.find( x => x.evo_season_type === values.seasonType && x.evo_graph_type === 100000003, ); if (evo_coefficient) preparedValues.firstPayment = (values.firstPaymentPerc + evo_coefficient.evo_correction_coefficient) / 100; } break; case 100000004: if ( entities.evo_coefficient_season && entities.evo_coefficient_season.length > 0 ) { const evo_coefficient = entities.evo_coefficient_season.find( x => x.evo_graph_type === 100000004, ); if (evo_coefficient) preparedValues.firstPayment = (values.firstPaymentPerc + evo_coefficient.evo_correction_coefficient) / 100; } break; //TODO: beautify default: preparedValues.firstPayment = values.firstPaymentPerc / 100; break; } } else { preparedValues.firstPayment = values.firstPaymentPerc / 100; } if (entities.evo_currencychange) { const evo_currencychange_supplier = entities.evo_currencychange.find( x => x.transactioncurrencyid === values.supplierCurrency, ); if (evo_currencychange_supplier) { preparedValues.plPrice = calcPrice( evo_currencychange_supplier.isocurrencycode, values.leaseObjectPrice, evo_currencychange_supplier.evo_currencychange || 0, ) / (1 + valuesConstants.VAT); preparedValues.discount = calcPrice( evo_currencychange_supplier.isocurrencycode, values.supplierDiscountRub, evo_currencychange_supplier.evo_currencychange || 0, ) / (1 + valuesConstants.VAT); } } preparedValues.acceptSum = preparedValues.plPrice - preparedValues.discount; preparedValues.firstPaymentSum = preparedValues.firstPayment * preparedValues.plPrice; preparedValues.agentsSum = (values.indAgentRewardSumm / 100) * preparedValues.acceptSum * valuesConstants.ESN; preparedValues.doubleAgentsSum = (values.calcDoubleAgentRewardSumm / 100) * preparedValues.acceptSum * valuesConstants.ESN; preparedValues.deliverySum = (values.dealerRewardSumm / 100) * preparedValues.acceptSum; preparedValues.brokerSum = (values.calcBrokerRewardSum / 100) * preparedValues.acceptSum; preparedValues.brokerOfDeliverySum = (values.dealerBrokerRewardSumm / 100) * preparedValues.acceptSum; preparedValues.financialDeptOfDeliverySum = (values.finDepartmentRewardSumm / 100) * preparedValues.acceptSum; if (values.importerRewardRub > 0) { preparedValues.importerSum = values.importerRewardRub; } else { preparedValues.importerSum = (values.importerRewardPerc / 100) * preparedValues.acceptSum; } if (entities.evo_sot_coefficient_type) { const evo_sot_coefficient_type = entities.evo_sot_coefficient_type.find( x => x.evo_id === 'EXTRA_BONUS', ); if (evo_sot_coefficient_type && entities.evo_coefficient_bonus) { const evo_coefficient = entities.evo_coefficient_bonus.find( x => x.evo_job_titleid === username && x.evo_sot_coefficient_typeid === evo_sot_coefficient_type.evo_sot_coefficient_typeid, ); if (evo_coefficient && evo_coefficient.evo_sot_coefficient) preparedValues.extraBonus = evo_coefficient.evo_sot_coefficient; } } if (entities.evo_sot_coefficient_type) { const evo_sot_coefficient_type = entities.evo_sot_coefficient_type.find( x => x.evo_id === 'DIRECTOR_BONUS', ); if (evo_sot_coefficient_type && entities.evo_coefficient_bonus) { const evo_coefficient = entities.evo_coefficient_bonus.find( x => x.evo_sot_coefficient_typeid === evo_sot_coefficient_type.evo_sot_coefficient_typeid, ); if (evo_coefficient && evo_coefficient.evo_sot_coefficient) preparedValues.directorBonus = evo_coefficient.evo_sot_coefficient; } } if (entities.evo_sot_coefficient_type) { const evo_sot_coefficient_type = entities.evo_sot_coefficient_type.find( x => x.evo_id === 'MARKET_RATE', ); if (evo_sot_coefficient_type && entities.evo_coefficient_bonus) { const evo_coefficient = entities.evo_coefficient_bonus.find( x => x.evo_sot_coefficient_typeid === evo_sot_coefficient_type.evo_sot_coefficient_typeid, ); if (evo_coefficient && evo_coefficient.evo_sot_coefficient) preparedValues.marketRate = evo_coefficient.evo_sot_coefficient; } } if (entities.evo_sot_coefficient_type) { const evo_sot_coefficient_type = entities.evo_sot_coefficient_type.find( x => x.evo_id === 'DISTRICT_RATE', ); if (evo_sot_coefficient_type && entities.evo_coefficient_bonus) { const evo_coefficient = entities.evo_coefficient_bonus.find( x => x.evo_sot_coefficient_typeid === evo_sot_coefficient_type.evo_sot_coefficient_typeid, ); if (evo_coefficient && evo_coefficient.evo_sot_coefficient) preparedValues.districtRate = evo_coefficient.evo_sot_coefficient; } } if (entities.evo_sot_coefficient_type) { const evo_sot_coefficient_type = entities.evo_sot_coefficient_type.find( x => x.evo_id === 'SALARY_RATE', ); if (evo_sot_coefficient_type && entities.evo_coefficient_bonus) { const evo_coefficient = entities.evo_coefficient_bonus.find( x => x.evo_sot_coefficient_typeid === evo_sot_coefficient_type.evo_sot_coefficient_typeid, ); if (evo_coefficient && evo_coefficient.evo_sot_coefficient) preparedValues.salaryRate = evo_coefficient.evo_sot_coefficient; } } if (entities.evo_addproduct_type) { const evo_addproduct_type = entities.evo_addproduct_type.find( x => x.evo_addproduct_typeid === values.technicalCard, ); if (evo_addproduct_type) { if (evo_addproduct_type.evo_graph_price_withoutnds) preparedValues.rats = evo_addproduct_type.evo_graph_price_withoutnds; if (evo_addproduct_type.evo_cost_service_provider_withoutnds) preparedValues.baseRatCost = evo_addproduct_type.evo_cost_service_provider_withoutnds; if (evo_addproduct_type.evo_retro_bonus_withoutnds) preparedValues.retroBonus = evo_addproduct_type.evo_retro_bonus_withoutnds; } else { preparedValues.rats = 0; preparedValues.baseRatCost = 0; preparedValues.retroBonus = 0; } } if (entities.evo_addproduct_type) { const evo_addproduct_type = entities.evo_addproduct_type.find( x => x.evo_addproduct_typeid === values.registration, ); if (evo_addproduct_type) { if (evo_addproduct_type.evo_graph_price_withoutnds) preparedValues.registration = evo_addproduct_type.evo_graph_price_withoutnds; if (evo_addproduct_type.evo_cost_service_provider_withoutnds) preparedValues.baseRegistration = evo_addproduct_type.evo_cost_service_provider_withoutnds; } else { preparedValues.registration = 0; preparedValues.baseRegistration = 0; } } if (entities.evo_addproduct_type) { const evo_addproduct_type = entities.evo_addproduct_type.find( x => x.evo_addproduct_typeid === values.tracker, ); if (evo_addproduct_type) { if (evo_addproduct_type.evo_graph_price_withoutnds) preparedValues.trackerCost = evo_addproduct_type.evo_graph_price_withoutnds; } else { preparedValues.trackerCost = 0; } } if (entities.evo_addproduct_type) { const evo_addproduct_type = entities.evo_addproduct_type.find( x => x.evo_addproduct_typeid === values.telematics, ); if (evo_addproduct_type) { if (evo_addproduct_type.evo_graph_price_withoutnds) preparedValues.tLMCost = evo_addproduct_type.evo_graph_price_withoutnds; } else { preparedValues.tLMCost = 0; } } const nsibBaseValue = (preparedValues.plPrice + (preparedValues.insuranceContract * preparedValues.rats + preparedValues.registration + preparedValues.trackerCost + preparedValues.tLMCost + preparedValues.transportTaxGr + preparedPayments.map(x => x.tlmCostPayment).reduce((a, b) => a + b, 0) + preparedPayments .map(x => x.gpsCostPayment) .reduce((a, b) => a + b, 0)) * preparedValues.leasing0K - preparedValues.firstPaymentSum - (values.product === 'LEASING0' ? 0 : preparedValues.discount)) * (1 + valuesConstants.VAT); if (nsibBaseValue > valuesConstants.NSIB_MAX) { preparedValues.nsibBase = valuesConstants.NSIB_MAX; } else { preparedValues.nsibBase = nsibBaseValue; } if (entities.evo_addproduct_type) { const evo_addproduct_type = entities.evo_addproduct_type.find( x => x.evo_addproduct_typeid === values.insNSIB, ); if (evo_addproduct_type) { if (evo_addproduct_type.evo_graph_price) preparedValues.nsibBrutto = (((evo_addproduct_type.evo_graph_price / 100) * preparedValues.nsibBase) / 12) * preparedValues.nmper; if (evo_addproduct_type.evo_prime_cost) preparedValues.nsibNetto = (((evo_addproduct_type.evo_prime_cost / 100) * preparedValues.nsibBase) / 12) * preparedValues.nmper; } else { preparedValues.nsibBrutto = 0; preparedValues.nsibNetto = 0; } } if (entities.evo_sot_coefficient_type) { const evo_sot_coefficient_type = entities.evo_sot_coefficient_type.find( x => x.evo_id === 'BONUS_RAT_PR', ); if (evo_sot_coefficient_type && entities.evo_coefficient_bonus) { const evo_coefficient = entities.evo_coefficient_bonus.find( x => x.evo_job_titleid === username && x.evo_sot_coefficient_typeid === evo_sot_coefficient_type.evo_sot_coefficient_typeid, ); if (evo_coefficient && evo_coefficient.evo_sot_coefficient) preparedValues.ratBonus = evo_coefficient.evo_sot_coefficient * preparedValues.rats; } } if (entities.evo_sot_coefficient_type) { const evo_sot_coefficient_type = entities.evo_sot_coefficient_type.find( x => x.evo_id === 'BONUS_NSIB_PR', ); if (evo_sot_coefficient_type && entities.evo_coefficient_bonus) { const evo_coefficient = entities.evo_coefficient_bonus.find( x => x.evo_job_titleid === username && x.evo_sot_coefficient_typeid === evo_sot_coefficient_type.evo_sot_coefficient_typeid, ); if (evo_coefficient && evo_coefficient.evo_sot_coefficient) preparedValues.ratBonus = evo_coefficient.evo_sot_coefficient * preparedValues.nsibBrutto; } } if (entities.evo_sot_coefficient_type) { const evo_sot_coefficient_type = entities.evo_sot_coefficient_type.find( x => x.evo_id === 'BONUS_NS_PR', ); if (evo_sot_coefficient_type && entities.evo_coefficient_bonus) { const evo_coefficient = entities.evo_coefficient_bonus.find( x => x.evo_job_titleid === username && x.evo_sot_coefficient_typeid === evo_sot_coefficient_type.evo_sot_coefficient_typeid, ); if ( evo_coefficient && evo_coefficient.evo_sot_coefficient && insuranceNSRow ) preparedValues.ratBonus = evo_coefficient.evo_sot_coefficient * insuranceNSRow.insCost; } } if (values.insDecentral === true) { if ( insuranceDGORow && insuranceDGORow.insCost && insuranceNSRow && insuranceNSRow.insCost ) { preparedValues.insuranceBonus = -1 * (preparedValues.acceptSum * valuesConstants.KASKO_PR * valuesConstants.KASKO_BONUS_PR + (((insuranceDGORow.insCost + insuranceNSRow.insCost) * valuesConstants.KASKO_BONUS_PR) / (1 + valuesConstants.VAT)) * (preparedValues.insuranceKaskoNmper > 12 && preparedValues.insuranceKaskoNmper < 16 ? preparedValues.insuranceKaskoNmper / 12 : 1)); } } else { preparedValues.insuranceBonus = 0; } preparedValues.cityc = values.townRegistration || values.regionRegistration; if ( entities.evo_tarif && entities.evo_tarif.length > 0 && entities.evo_tarif[0].evo_irr_plan ) { preparedValues.iRR_MSFO_Plan = entities.evo_tarif[0].evo_irr_plan / 100; } if (entities.evo_coefficient && entities.evo_coefficient.length > 0) { const evo_coefficient_delta = entities.evo_coefficient.filter( x => x.evo_client_risks && x.evo_client_risks.length > 0 && x.evo_client_types && x.evo_client_types.length > 0 && x.evo_leasingobject_types && x.evo_leasingobject_types.length > 0, ); if ( evo_coefficient_delta && evo_coefficient_delta.length > 0 && evo_coefficient_delta[0].evo_risk_delta ) { preparedValues.npvniDelta = evo_coefficient_delta[0].evo_risk_delta; } else { preparedValues.npvniDelta = 0; } } if ( entities.evo_leasingobject_type && entities.evo_leasingobject_type.length > 0 && entities.evo_leasingobject_type[0].evo_id ) { let deprecation_rate = 1; if ( (entities.evo_leasingobject_type[0].evo_id === '1' && (values.engineType === 100000000 || values.engineType === 100000004) && values.engineVolume <= 3.5) || (entities.evo_leasingobject_type[0].evo_id === '2' && (values.engineType === 100000000 || values.engineType === 100000004 || values.engineType === 100000001) && values.maxMass <= 3500) || (entities.evo_leasingobject_type[0].evo_id !== '1' && entities.evo_leasingobject_type[0].evo_id !== '2') ) { if (entities.evo_leasingobject_type[0].evo_expluatation_period1) preparedValues.nmperDeprecation = entities.evo_leasingobject_type[0].evo_expluatation_period1; if (entities.evo_leasingobject_type[0].evo_depreciation_rate1) deprecation_rate = entities.evo_leasingobject_type[0].evo_depreciation_rate1; } else { if (entities.evo_leasingobject_type[0].evo_expluatation_period2) preparedValues.nmperDeprecation = entities.evo_leasingobject_type[0].evo_expluatation_period2; if (entities.evo_leasingobject_type[0].evo_depreciation_rate2) deprecation_rate = entities.evo_leasingobject_type[0].evo_depreciation_rate2; } if ( preparedValues.nmperDeprecation === 85 || preparedValues.nmperDeprecation === 61 ) { preparedValues.deprecationTime = deprecation_rate * 3; } else { preparedValues.deprecationTime = deprecation_rate; } } const { plPrice, insurance, rats, registration, trackerCost, tLMCost, transportTaxGr, leasing0K, nsibBrutto, insuranceContract, comissionRub, discount, baseRegistration, nsibNetto, nmper, firstPaymentSum, } = preparedValues; preparedValues.calculationCost = plPrice + (insurance + rats + registration + trackerCost + tLMCost + transportTaxGr) * leasing0K; preparedValues.priceUpTotal = plPrice + trackerCost + tLMCost + preparedPayments.map(x => x.tlmCostPayment).reduce((a, b) => a + b, 0) + preparedPayments.map(x => x.gpsCostPayment).reduce((a, b) => a + b, 0) + registration + insuranceContract + rats + nsibBrutto + transportTaxGr; preparedValues.acquisitionExpenses = plPrice + insurance - comissionRub - discount + trackerCost + tLMCost + baseRegistration + rats; preparedValues.npvBase = plPrice + ((nsibNetto * 12) / nmper + insurance + baseRegistration + trackerCost + tLMCost + rats - discount - comissionRub - firstPaymentSum); preparedValues.niAtInception = preparedValues.acquisitionExpenses - firstPaymentSum; preparedValues.dogCredit = plPrice + (insurance + rats + registration + trackerCost + tLMCost + transportTaxGr) * leasing0K - firstPaymentSum + (nsibNetto * 12) / nmper - (values.product === 'LEASING0' ? 0 : discount); preparedValues.dogCreditLeasing = plPrice + insurance + registration + trackerCost + tLMCost + rats - discount - comissionRub - firstPaymentSum; return { preparedPayments, preparedValues, }; };