diff --git a/src/client/process/bonuses/reactions.ts b/src/client/process/bonuses/reactions.ts new file mode 100644 index 0000000..6ee2535 --- /dev/null +++ b/src/client/process/bonuses/reactions.ts @@ -0,0 +1,107 @@ +import { openNotification } from 'client/Elements/Notification'; +import { ICalculationStore } from 'core/types/Calculation/Store'; +import { round } from 'lodash'; +import { reaction } from 'mobx'; +import { ElementStatus } from 'types/elements'; + +export default function ($calculation: ICalculationStore) { + /** + * @description + * При изменении значения необходимо значение поля tbxSaleBonus сравнивать со значением из записи Коэффициент + * для расчета evo_coefficient как сейчас + данная запись должна быть связана с Продуктом product + * из поля Продукт selectProduct evo_evo_coefficient_evo_baseproduct + * Если продукта нет или нет коэффициента по условиям, то поле tbxSaleBonus = 0 и закрыто для редактирования + */ + reaction( + () => $calculation.getValues(['saleBonus', 'product']), + ({ saleBonus, product }) => { + $calculation.setStatus('tbxSaleBonus', ElementStatus.Default); + const systemuser = $calculation.getStaticData('systemuser'); + + if (systemuser && product) { + const evo_sot_coefficient_type = $calculation + .getStaticData('evo_sot_coefficient_type') + .find(x => x.evo_id === 'BONUS_LEASING'); + const evo_coefficient_bonus = $calculation + .getStaticData('evo_coefficient') + .find( + x => + x.evo_job_titleid === systemuser[0].evo_job_titleid && + x.evo_sot_coefficient_typeid === + evo_sot_coefficient_type?.evo_sot_coefficient_typeid && + x.evo_baseproducts?.map(x => x.evo_id).includes(product), + ); + + if (evo_coefficient_bonus?.evo_sot_coefficient) { + const max_sale_bonus = + evo_coefficient_bonus.evo_sot_coefficient * 100; + if (parseFloat(saleBonus) > round(max_sale_bonus, 2)) { + $calculation.setValidation('tbxSaleBonus', false); + openNotification({ + type: 'error', + message: 'Ошибка', + description: + 'Размер бонуса МПЛ не может быть выше установленного по СОТ', + }); + return; + } else { + $calculation.setValidation('tbxSaleBonus', undefined); + } + } else { + $calculation.setValue('saleBonus', 0); + $calculation.setStatus('tbxSaleBonus', ElementStatus.Disabled); + } + } + }, + ); + + /** + * @description + * если в Продукте evo_cut_proportion_bonus_director " = Да, + * то tbxBonusCoefficient = tbxSaleBonus/evo_sot_coefficient, + * иначе tbxBonusCoefficient = 1 + * где evo_sot_coefficient ищем так: + * в справочнике Коэффициент для расчета (evo_coefficient) найти запись, у которой: + * +Тип коэффициента (evo_corfficient_type) = СОТ (100 000 002) +Статус (statecode) = активный (0) +Начало действия (evo_datefrom) меньше или равно текущей даты +Окончание действия (evo_dateto) больше или равно текущей даты +Должность (evo_evo_job_title_evo_coefficient_job_titleid) = Должности (evo_job_titleid) текущего пользователя (systemuser) +Тип коэффициента для СОТ (evo_sot_coefficient_typeid) = (evo_sot_coefficient_type.evo_id=BONUS_LEASING) +данная запись должна быть связана с Продуктом product из поля Продукт selectProduct + */ + + reaction( + () => { + const { saleBonus } = $calculation.values; + const product = $calculation.getOption('selectProduct'); + return { + saleBonus, + product, + }; + }, + ({ saleBonus, product }) => { + if (product?.evo_cut_proportion_bonus_director === true) { + const systemuser = $calculation.getStaticData('systemuser'); + const evo_sot_coefficient_type = $calculation + .getStaticData('evo_sot_coefficient_type') + .find(x => x.evo_id === 'BONUS_LEASING'); + const evo_coefficient_bonus = $calculation + .getStaticData('evo_coefficient') + .find( + x => + x.evo_job_titleid === systemuser[0].evo_job_titleid && + x.evo_sot_coefficient_typeid === + evo_sot_coefficient_type?.evo_sot_coefficient_typeid && + x.evo_baseproducts?.map(x => x.evo_id).includes(product.evo_id), + ); + const max_sale_bonus = + (evo_coefficient_bonus?.evo_sot_coefficient || 0) * 100; + $calculation.setValue('bonusCoefficient', saleBonus / max_sale_bonus); + } else { + $calculation.setValue('bonusCoefficient', 1); + } + }, + ); +} diff --git a/src/client/process/configurator/reactions/filters.ts b/src/client/process/configurator/reactions/filters.ts index fd764dd..37d786d 100644 --- a/src/client/process/configurator/reactions/filters.ts +++ b/src/client/process/configurator/reactions/filters.ts @@ -170,4 +170,26 @@ export default function ($calculation: ICalculationStore) { ); }, ); + + /** + * @description + * При изменении Продукта selectProduct необходимо в поле "Расчет от" + * radioCalcType фильтровать значения согласно списку + * в поле "Доступные Методы расчета в калькуляторе" evo_calculation_method в selectProduct + */ + reaction( + () => $calculation.getOption('selectProduct'), + product => { + if (product?.evo_calculation_method) { + $calculation.setFilter('radioCalcType', calcType => + calcType.filter(x => + product.evo_calculation_method?.includes(x.value), + ), + ); + } else { + $calculation.setFilter('radioCalcType', () => []); + } + }, + { fireImmediately: true }, + ); } diff --git a/src/client/stores/CalculationStore/Effects/actions/calculate/prepareData.ts b/src/client/stores/CalculationStore/Effects/actions/calculate/prepareData.ts index 4a7855e..bf1f0be 100644 --- a/src/client/stores/CalculationStore/Effects/actions/calculate/prepareData.ts +++ b/src/client/stores/CalculationStore/Effects/actions/calculate/prepareData.ts @@ -132,7 +132,9 @@ export default function (this: ICalculationStore): PreparedData { preparedValues.plEngineType = values.engineType; preparedValues.carCarrying = values.maxMass; preparedValues.bonus = (values.saleBonus as number) / 100; - preparedValues.bonusFix = 0; + preparedValues.bonusCoefficient = values.bonusCoefficient; + preparedValues.profitExpected = + this.getOption('selectTarif')?.evo_margin_min || 0; preparedValues.transTax = values.vehicleTaxInYear; preparedValues.transIncludeGr = values.vehicleTaxInYear > 0; @@ -349,7 +351,8 @@ export default function (this: ICalculationStore): PreparedData { x => x.evo_job_titleid === systemuser.evo_job_titleid && x.evo_sot_coefficient_typeid === - evo_sot_coefficient_type?.evo_sot_coefficient_typeid, + evo_sot_coefficient_type?.evo_sot_coefficient_typeid && + x.evo_baseproducts?.map(x => x.evo_id).includes(values.product), ); if (evo_coefficient) { @@ -357,6 +360,29 @@ export default function (this: ICalculationStore): PreparedData { } } + if ( + evo_coefficient_bonuses && + evo_coefficient_bonuses.length > 0 && + systemuser && + !Array.isArray(systemuser) + ) { + const evo_sot_coefficient_type = this.getStaticData( + 'evo_sot_coefficient_type', + ).find(x => x.evo_id === 'BONUS_FIX'); + + const evo_coefficient = evo_coefficient_bonuses.find( + x => + x.evo_job_titleid === systemuser.evo_job_titleid && + x.evo_sot_coefficient_typeid === + evo_sot_coefficient_type?.evo_sot_coefficient_typeid && + x.evo_baseproducts?.map(x => x.evo_id).includes(values.product), + ); + + if (evo_coefficient) { + preparedValues.bonusFix = evo_coefficient.evo_sot_coefficient || 0; + } + } + if ( evo_coefficient_bonuses && evo_coefficient_bonuses.length > 0 && @@ -369,7 +395,8 @@ export default function (this: ICalculationStore): PreparedData { const evo_coefficient = evo_coefficient_bonuses.find( x => x.evo_sot_coefficient_typeid === - evo_sot_coefficient_type?.evo_sot_coefficient_typeid, + evo_sot_coefficient_type?.evo_sot_coefficient_typeid && + x.evo_baseproducts?.map(x => x.evo_id).includes(values.product), ); if (evo_coefficient) { @@ -377,6 +404,138 @@ export default function (this: ICalculationStore): PreparedData { } } + if ( + evo_coefficient_bonuses && + evo_coefficient_bonuses.length > 0 && + systemuser + ) { + const evo_sot_coefficient_type = this.getStaticData( + 'evo_sot_coefficient_type', + ).find(x => x.evo_id === 'DIRECTOR_BONUS_FIX'); + + const evo_coefficient = evo_coefficient_bonuses.find( + x => + x.evo_sot_coefficient_typeid === + evo_sot_coefficient_type?.evo_sot_coefficient_typeid && + x.evo_baseproducts?.map(x => x.evo_id).includes(values.product), + ); + + if (evo_coefficient) { + preparedValues.directorBonusFix = + evo_coefficient.evo_sot_coefficient || 0; + } + } + + if ( + evo_coefficient_bonuses && + evo_coefficient_bonuses.length > 0 && + systemuser + ) { + const evo_sot_coefficient_type = this.getStaticData( + 'evo_sot_coefficient_type', + ).find(x => x.evo_id === 'DIRECTOR_EXTRA_BONUS'); + + const evo_coefficient = evo_coefficient_bonuses.find( + x => + x.evo_sot_coefficient_typeid === + evo_sot_coefficient_type?.evo_sot_coefficient_typeid && + x.evo_baseproducts?.map(x => x.evo_id).includes(values.product), + ); + + if (evo_coefficient) { + preparedValues.directorExtraBonus = + evo_coefficient.evo_sot_coefficient || 0; + } + } + + if ( + evo_coefficient_bonuses && + evo_coefficient_bonuses.length > 0 && + systemuser + ) { + const evo_sot_coefficient_type = this.getStaticData( + 'evo_sot_coefficient_type', + ).find(x => x.evo_id === 'REGIONAL_DIRECTOR_BONUS_FINGAP'); + + const evo_coefficient = evo_coefficient_bonuses.find( + x => + x.evo_sot_coefficient_typeid === + evo_sot_coefficient_type?.evo_sot_coefficient_typeid, + ); + + if (evo_coefficient) { + preparedValues.regionalDirectorBonusFinGAP = + (evo_coefficient.evo_sot_coefficient || 0) * + (insuranceFinGAPRow?.insCost?.value || 0); + } + } + + if ( + evo_coefficient_bonuses && + evo_coefficient_bonuses.length > 0 && + systemuser + ) { + const evo_sot_coefficient_type = this.getStaticData( + 'evo_sot_coefficient_type', + ).find(x => x.evo_id === 'REGIONAL_DIRECTOR_BONUS'); + + const evo_coefficient = evo_coefficient_bonuses.find( + x => + x.evo_sot_coefficient_typeid === + evo_sot_coefficient_type?.evo_sot_coefficient_typeid && + x.evo_baseproducts?.map(x => x.evo_id).includes(values.product), + ); + + if (evo_coefficient) { + preparedValues.regionalDirectorBonus = + evo_coefficient.evo_sot_coefficient || 0; + } + } + + if ( + evo_coefficient_bonuses && + evo_coefficient_bonuses.length > 0 && + systemuser + ) { + const evo_sot_coefficient_type = this.getStaticData( + 'evo_sot_coefficient_type', + ).find(x => x.evo_id === 'REGIONAL_DIRECTOR_BONUS_FIX'); + + const evo_coefficient = evo_coefficient_bonuses.find( + x => + x.evo_sot_coefficient_typeid === + evo_sot_coefficient_type?.evo_sot_coefficient_typeid && + x.evo_baseproducts?.map(x => x.evo_id).includes(values.product), + ); + + if (evo_coefficient) { + preparedValues.regionalDirectorBonusFix = + evo_coefficient.evo_sot_coefficient || 0; + } + } + + if ( + evo_coefficient_bonuses && + evo_coefficient_bonuses.length > 0 && + systemuser + ) { + const evo_sot_coefficient_type = this.getStaticData( + 'evo_sot_coefficient_type', + ).find(x => x.evo_id === 'REGIONAL_DIRECTOR_EXTRA_BONUS'); + + const evo_coefficient = evo_coefficient_bonuses.find( + x => + x.evo_sot_coefficient_typeid === + evo_sot_coefficient_type?.evo_sot_coefficient_typeid && + x.evo_baseproducts?.map(x => x.evo_id).includes(values.product), + ); + + if (evo_coefficient) { + preparedValues.regionalDirectorExtraBonus = + evo_coefficient.evo_sot_coefficient || 0; + } + } + if ( evo_coefficient_bonuses && evo_coefficient_bonuses.length > 0 && diff --git a/src/client/stores/CalculationStore/Effects/actions/createKP.ts b/src/client/stores/CalculationStore/Effects/actions/createKP.ts index 133517e..e0ec9ab 100644 --- a/src/client/stores/CalculationStore/Effects/actions/createKP.ts +++ b/src/client/stores/CalculationStore/Effects/actions/createKP.ts @@ -38,8 +38,11 @@ async function composeRequest(this: ICalculationStore) { const finGAP = this.stores.$finGAP.getSelectedRisks(); const insKaskoPriceLeasePeriodValue = insKaskoPriceLeasePeriod.call(this); + //@ts-ignore + const importProgramSum = this.importProgramSum(); const calculationValues = Object.assign({}, toJS(this.values), { insKaskoPriceLeasePeriod: insKaskoPriceLeasePeriodValue, + importProgramSum, }); const domainname = UserStore.getDomainName(); diff --git a/src/client/stores/CalculationStore/Effects/reactions/otherReactions.ts b/src/client/stores/CalculationStore/Effects/reactions/otherReactions.ts index 71023c5..ebcfe5d 100644 --- a/src/client/stores/CalculationStore/Effects/reactions/otherReactions.ts +++ b/src/client/stores/CalculationStore/Effects/reactions/otherReactions.ts @@ -3,7 +3,7 @@ import valuesConstants from 'core/constants/values'; import { pipe } from 'core/tools/func'; import { IReactionEffect } from 'core/types/Calculation/Store/effect'; import { Process } from 'core/types/Calculation/Store/process'; -import { get, intersection, round } from 'lodash'; +import { get, intersection } from 'lodash'; import { ElementStatus } from 'types/elements'; const reactionEffects: IReactionEffect[] = [ @@ -855,52 +855,6 @@ const reactionEffects: IReactionEffect[] = [ }, }), - calculationStore => ({ - expression: () => { - const { saleBonus, product } = calculationStore.values; - return { saleBonus, product }; - }, - effect: ({ saleBonus, product }) => { - calculationStore.setStatus('tbxSaleBonus', ElementStatus.Default); - const systemuser = calculationStore.getStaticData('systemuser'); - - if (systemuser && product) { - const evo_sot_coefficient_type = calculationStore - .getStaticData('evo_sot_coefficient_type') - .find(x => x.evo_id === 'BONUS_LEASING'); - const evo_coefficient_bonus = calculationStore - .getStaticData('evo_coefficient') - .find( - x => - x.evo_job_titleid === systemuser[0].evo_job_titleid && - x.evo_sot_coefficient_typeid === - evo_sot_coefficient_type?.evo_sot_coefficient_typeid && - x.evo_baseproducts?.map(x => x.evo_id).includes(product), - ); - - if (evo_coefficient_bonus?.evo_sot_coefficient) { - const max_sale_bonus = - evo_coefficient_bonus.evo_sot_coefficient * 100; - if (parseFloat(saleBonus) > round(max_sale_bonus, 2)) { - calculationStore.setValidation('tbxSaleBonus', false); - openNotification({ - type: 'error', - message: 'Ошибка', - description: - 'Размер бонуса МПЛ не может быть выше установленного по СОТ', - }); - return; - } else { - calculationStore.setValidation('tbxSaleBonus', undefined); - } - } else { - calculationStore.setValue('saleBonus', 0); - calculationStore.setStatus('tbxSaleBonus', ElementStatus.Disabled); - } - } - }, - }), - calculationStore => ({ expression: () => { const { configuration } = calculationStore.values; diff --git a/src/client/stores/CalculationStore/config/initialOptions.ts b/src/client/stores/CalculationStore/config/initialOptions.ts index eb75aee..66d150e 100644 --- a/src/client/stores/CalculationStore/config/initialOptions.ts +++ b/src/client/stores/CalculationStore/config/initialOptions.ts @@ -330,6 +330,10 @@ const initialOptions: Partial> = { name: 'Суммы', value: 100000001, }, + { + name: 'Маржи', + value: 100000002, + }, ], radioObjectRegistration: [ { diff --git a/src/client/stores/CalculationStore/index.ts b/src/client/stores/CalculationStore/index.ts index c2922c8..40eda51 100644 --- a/src/client/stores/CalculationStore/index.ts +++ b/src/client/stores/CalculationStore/index.ts @@ -1,3 +1,4 @@ +import injectBonusesReaction from 'client/process/bonuses/reactions'; import { injectConfiguratorReactions } from 'client/process/configurator/reactions'; import { injectFinGapReactions } from 'client/process/fingap/reactions'; import injectSubsidyReactions from 'client/process/subsidy-import-program/reactions'; @@ -41,6 +42,7 @@ injectFinGapReactions(CalculationStore); injectUsedWhthVATReactions(CalculationStore); injectConfiguratorReactions(CalculationStore); injectSubsidyReactions(CalculationStore); +injectBonusesReaction(CalculationStore); whenEffects.map(whenEffectBuilder => { const whenEffect = whenEffectBuilder(CalculationStore); diff --git a/src/core/services/CoreService/types/Calculation/prepared.ts b/src/core/services/CoreService/types/Calculation/prepared.ts index 3ac6cc1..389d44d 100644 --- a/src/core/services/CoreService/types/Calculation/prepared.ts +++ b/src/core/services/CoreService/types/Calculation/prepared.ts @@ -106,6 +106,14 @@ export interface PreparedValues { insuranceFinGAPNmper?: number; bonusFinGAP?: number; directorBonusFinGAP?: number; + directorBonusFix?: number; + directorExtraBonus?: number; + regionalDirectorBonusFinGAP?: number; + regionalDirectorBonus?: number; + regionalDirectorExtraBonus?: number; + regionalDirectorBonusFix?: number; + profitExpected?: number; + bonusCoefficient?: number; } export interface PaymentRow { diff --git a/src/core/services/CrmService/graphql/query/options/main_options.graphql b/src/core/services/CrmService/graphql/query/options/main_options.graphql index 77ae76c..33d59c1 100644 --- a/src/core/services/CrmService/graphql/query/options/main_options.graphql +++ b/src/core/services/CrmService/graphql/query/options/main_options.graphql @@ -76,6 +76,9 @@ query GetMainOptions( systemuserid } evo_sale_without_nds + evo_cut_proportion_bonus_director + evo_cut_irr_with_bonus + evo_calculation_method } selectRegistration: evo_addproduct_types( statecode: $statecode @@ -180,6 +183,8 @@ query GetMainOptions( evo_max_first_payment evo_min_last_payment evo_max_last_payment + evo_margin_min + evo_cut_irr_with_bonus_coefficient } selectRate: evo_rates( statecode: $statecode diff --git a/src/core/services/CrmService/graphql/schema.graphql b/src/core/services/CrmService/graphql/schema.graphql index 8075d42..a9e1e41 100644 --- a/src/core/services/CrmService/graphql/schema.graphql +++ b/src/core/services/CrmService/graphql/schema.graphql @@ -554,7 +554,12 @@ type evo_addproduct_type { type evo_baseproduct { createdon: DateTime evo_baseproductid: Uuid + evo_baseproducts(statecode: Int): [evo_baseproduct] evo_brands(statecode: Int): [evo_brand] + evo_calculation_method: [Int!] + evo_coefficients(statecode: Int): [evo_coefficient] + evo_cut_irr_with_bonus: Boolean + evo_cut_proportion_bonus_director: Boolean evo_datefrom: DateTime evo_dateto: DateTime evo_id: String @@ -1664,6 +1669,7 @@ type evo_contract { evo_price_without_discount: Decimal evo_price_without_discount_supplier_currency: Decimal evo_price_wthout_discount_nds_sup_currency: Decimal + evo_program_import_subsidyid: Uuid evo_program_import_subsidy_sum: Decimal evo_purchases_participation: Boolean evo_quoteid: Uuid @@ -1794,6 +1800,7 @@ type evo_vehicle_body_typeGraphQL { type evo_coefficient { createdon: DateTime + evo_baseproducts(statecode: Int): [evo_baseproduct] evo_businessunitid: Uuid evo_businessunits(statecode: Int): [evo_businessunit] evo_client_riskid: Uuid @@ -1858,6 +1865,7 @@ type evo_tarif { evo_baseproductid: Uuid evo_client_risks(statecode: Int): [evo_client_risk] evo_client_types(statecode: Int): [evo_client_type] + evo_cut_irr_with_bonus_coefficient: Decimal evo_datefrom: DateTime evo_dateto: DateTime evo_delivery_time: [Int!] @@ -1867,6 +1875,7 @@ type evo_tarif { evo_irr: Decimal evo_irr_plan: Decimal evo_leasingobject_types(statecode: Int): [evo_leasingobject_type] + evo_margin_min: Float evo_max_first_payment: Decimal evo_max_irr: Decimal evo_max_last_payment: Decimal diff --git a/src/core/services/CrmService/types/entities.ts b/src/core/services/CrmService/types/entities.ts index d8fa984..3508472 100644 --- a/src/core/services/CrmService/types/entities.ts +++ b/src/core/services/CrmService/types/entities.ts @@ -210,6 +210,9 @@ export interface IEvoBaseproduct extends BaseEntity { evo_brands?: IEvoBrand[]; systemusers?: ISystemUser[]; evo_sale_without_nds?: boolean; + evo_cut_proportion_bonus_director?: boolean; + evo_cut_irr_with_bonus?: boolean; + evo_calculation_method?: number[]; } export interface IEvoLeasingObjectType extends BaseEntity { @@ -416,6 +419,8 @@ export interface IEvoTarif extends BaseEntity { evo_model_exceptions?: IEvoModel[]; evo_rates?: IEvoRate[]; evo_delivery_time?: number[]; + evo_cut_irr_with_bonus_coefficient?: number; + evo_margin_min?: number; } export interface IEvoRate extends BaseEntity {