2023-03-13 11:27:09 +03:00

516 lines
16 KiB
TypeScript

import type { ProcessContext } from '../types';
import helper from './lib/helper';
import { createValidationSchema } from './validation';
import { getTransTax } from '@/api/1c/query';
import type { Elements } from '@/Components/Calculation/config/map/values';
import { selectObjectCategoryTax } from '@/config/default-options';
import { STALE_TIME } from '@/constants/request';
import * as CRMTypes from '@/graphql/crm.types';
import ValidationHelper from '@/stores/validation/helper';
import type { QueryFunctionContext } from '@tanstack/react-query';
import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc';
import { reaction } from 'mobx';
import { uid } from 'radash';
import { makeDisposable, normalizeOptions } from 'tools';
dayjs.extend(utc);
export function common({ store, apolloClient, queryClient }: ProcessContext) {
const { $calculation, $process } = store;
reaction(
() => $calculation.element('selectLeaseObjectType').getValue(),
async (leaseObjectTypeId) => {
if (!leaseObjectTypeId) {
$calculation.element('radioObjectRegistration').resetValue().unblock();
return;
}
const {
data: { evo_leasingobject_type },
} = await apolloClient.query({
query: CRMTypes.GetLeaseObjectTypeDocument,
variables: { leaseObjectTypeId },
});
if (
evo_leasingobject_type?.evo_id &&
['6', '9', '10', '11'].includes(evo_leasingobject_type.evo_id)
) {
$calculation.element('radioObjectRegistration').setValue(100_000_000).block();
} else {
$calculation.element('radioObjectRegistration').unblock();
}
}
);
makeDisposable(
() =>
reaction(
() =>
$calculation.$values.getValues([
'leaseObjectType',
'objectCategoryTax',
'objectRegistration',
]),
async ({ leaseObjectType: leaseObjectTypeId, objectRegistration, objectCategoryTax }) => {
if (objectRegistration === 100_000_001) {
if (objectCategoryTax && [100_000_006, 100_000_009].includes(objectCategoryTax)) {
$calculation.element('selectObjectTypeTax').setValue(100_000_002);
} else if (leaseObjectTypeId) {
const {
data: { evo_leasingobject_type },
} = await apolloClient.query({
query: CRMTypes.GetLeaseObjectTypeDocument,
variables: { leaseObjectTypeId },
});
if (evo_leasingobject_type?.evo_vehicle_type_tax) {
$calculation
.element('selectObjectTypeTax')
.setValue(evo_leasingobject_type?.evo_vehicle_type_tax);
} else {
$calculation.element('selectObjectTypeTax').resetValue();
}
}
} else {
$calculation.element('selectObjectTypeTax').resetValue();
}
}
),
() => $process.has('LoadKP')
);
reaction(
() =>
$calculation.$values.getValues([
'leaseObjectType',
'leaseObjectCategory',
'typePTS',
'objectRegistration',
]),
async ({
leaseObjectType: leaseObjectTypeId,
leaseObjectCategory,
typePTS,
objectRegistration,
}) => {
if (objectRegistration === 100_000_001 && typePTS === 100_000_001) {
$calculation.element('selectObjectCategoryTax').unblock();
if (leaseObjectTypeId) {
const {
data: { evo_leasingobject_type },
} = await apolloClient.query({
query: CRMTypes.GetLeaseObjectTypeDocument,
variables: { leaseObjectTypeId },
});
if (leaseObjectCategory && leaseObjectCategory === evo_leasingobject_type?.evo_category) {
$calculation
.element('selectObjectCategoryTax')
.setOptions(
selectObjectCategoryTax.filter((option) =>
evo_leasingobject_type?.evo_category_tr?.includes(option.value)
)
);
} else {
$calculation.element('selectObjectCategoryTax').resetOptions();
}
}
} else {
$calculation.element('selectObjectCategoryTax').resetValue().block();
}
}
);
reaction(
() => $calculation.$values.getValues(['leasingPeriod', 'vehicleTaxInYear']),
({ leasingPeriod, vehicleTaxInYear }) => {
if (vehicleTaxInYear > 0) {
$calculation
.element('tbxVehicleTaxInLeasingPeriod')
.setValue((vehicleTaxInYear / 12) * leasingPeriod);
} else {
$calculation.element('tbxVehicleTaxInLeasingPeriod').resetValue();
}
}
);
const mapObjectTypeTaxToCategory = {
100_000_000: 'D',
100_000_001: 'B',
100_000_002: 'C',
100_000_003: 'T',
100_000_004: 'A',
};
function getCarCategory(objectTypeTax: number) {
return mapObjectTypeTaxToCategory[objectTypeTax as keyof typeof mapObjectTypeTaxToCategory];
}
makeDisposable(
() =>
reaction(
() =>
$calculation.$values.getValues([
'objectRegistration',
'objectTypeTax',
'regionRegistration',
'leaseObjectYear',
'leaseObjectMotorPower',
]),
async ({
objectRegistration,
objectTypeTax,
regionRegistration,
leaseObjectYear,
leaseObjectMotorPower,
}) => {
if (
objectRegistration === null ||
objectRegistration !== 100_000_001 ||
objectTypeTax === null ||
regionRegistration === null ||
leaseObjectYear === 0 ||
leaseObjectMotorPower === 0
) {
$calculation.element('tbxVehicleTaxInYear').resetValue();
return;
}
const {
data: { evo_region },
} = await apolloClient.query({
query: CRMTypes.GetRegionDocument,
variables: {
regionId: regionRegistration,
},
});
const OKTMO = evo_region?.evo_oktmo;
const carCategory = getCarCategory(objectTypeTax);
if (OKTMO) {
const currentDate = dayjs().utc(false).toDate();
const request = (context: QueryFunctionContext) =>
getTransTax(
{
OKTMO,
calcDate: currentDate,
carCategory,
power: leaseObjectMotorPower,
year: leaseObjectYear,
},
context
);
const { tax, error } = await queryClient.fetchQuery(
['1c', 'trans-tax', carCategory, leaseObjectMotorPower, leaseObjectYear],
request,
{
staleTime: STALE_TIME,
}
);
if (!error && tax) {
$calculation.element('tbxVehicleTaxInYear').setValue(tax);
} else {
$calculation.element('tbxVehicleTaxInYear').resetValue();
}
} else {
$calculation.element('tbxVehicleTaxInYear').resetValue();
}
}
),
() => $process.has('LoadKP')
);
reaction(
() =>
$calculation.$values.getValues([
'objectRegionRegistration',
'objectRegistration',
'regionRegistration',
'typePTS',
'leaseObjectCategory',
'leaseObjectType',
]),
async ({
objectRegistration,
objectRegionRegistration: objectRegionRegistrationId,
regionRegistration: regionRegistrationId,
typePTS,
leaseObjectCategory,
leaseObjectType,
}) => {
if (!objectRegionRegistrationId || !regionRegistrationId) {
$calculation.element('selectRegistration').resetValue();
return;
}
const currentDate = dayjs().utc(false).format('YYYY-MM-DD');
const {
data: { evo_region },
} = await apolloClient.query({
query: CRMTypes.GetRegionDocument,
variables: { regionId: objectRegionRegistrationId },
});
const {
data: { evo_addproduct_types },
} = await apolloClient.query({
query: CRMTypes.GetRegistrationTypesDocument,
variables: { currentDate },
});
const options = evo_addproduct_types?.filter(
(x) =>
x?.evo_leasingobject_types?.find(
(evo_leasingobject_type) =>
evo_leasingobject_type?.evo_leasingobject_typeid === leaseObjectType
) &&
x.evo_whom_register === objectRegistration &&
Boolean(
leaseObjectCategory === 100_000_001
? x.evo_towtruck === true || x.evo_towtruck === false
: x.evo_towtruck === false
) &&
x.evo_gibdd_region === (objectRegionRegistrationId === regionRegistrationId) &&
Boolean(typePTS && x.evo_pts_type?.includes(typePTS)) &&
Boolean(
x.evo_accountid &&
evo_region?.accounts?.some(
(evo_region_account) => evo_region_account?.accountid === x.evo_accountid
)
)
);
$calculation.element('selectRegistration').setOptions(normalizeOptions(options));
}
);
reaction(
() => $calculation.element('selectRegistration').getValue(),
async (registrationId) => {
if (!registrationId) {
$calculation.element('labelRegistrationDescription').resetValue();
return;
}
const {
data: { evo_addproduct_type },
} = await apolloClient.query({
query: CRMTypes.GetAddProductTypeDocument,
variables: { addproductTypeId: registrationId },
});
if (evo_addproduct_type?.evo_description) {
$calculation
.element('labelRegistrationDescription')
.setValue(evo_addproduct_type?.evo_description);
} else {
$calculation.element('labelRegistrationDescription').resetValue();
}
}
);
reaction(
() => $calculation.element('selectLegalClientRegion').getValue(),
async (regionId) => {
if (!regionId) {
$calculation.element('selectLegalClientTown').resetOptions();
return;
}
const {
data: { evo_towns },
} = await apolloClient.query({
query: CRMTypes.GetTownsDocument,
variables: { regionId },
});
$calculation.element('selectLegalClientTown').setOptions(normalizeOptions(evo_towns));
}
);
reaction(
() => $calculation.$values.getValues(['regionRegistration', 'objectRegistration']),
async ({ regionRegistration: regionId, objectRegistration }) => {
if (!regionId) {
$calculation.element('selectTownRegistration').resetOptions();
return;
}
const {
data: { evo_towns },
} = await apolloClient.query({
query: CRMTypes.GetTownsDocument,
variables: { regionId },
});
if (objectRegistration === 100_000_001) {
const towns = evo_towns?.filter((x) => x?.evo_businessunit_evolution === true);
$calculation.element('selectTownRegistration').setOptions(normalizeOptions(towns));
} else {
$calculation.element('selectTownRegistration').setOptions(normalizeOptions(evo_towns));
}
}
);
const { getLegalRegion, getLegalTown, getRegion, getTown } = helper({ apolloClient });
reaction(
() => $calculation.$values.getValues(['lead', 'opportunity']),
async ({ lead, opportunity }) => {
if (!lead && !opportunity) {
$calculation.element('selectLegalClientRegion').resetValue().unblock();
$calculation.element('selectRegionRegistration').resetValue().unblock();
return;
}
const quote = $calculation.element('selectQuote').getValue();
const legalRegionId = await getLegalRegion({
lead,
opportunity,
quote,
});
if (legalRegionId) {
$calculation.element('selectLegalClientRegion').setValue(legalRegionId).block();
} else {
$calculation.element('selectLegalClientRegion').resetValue().unblock();
}
const regionId = await getRegion({
lead,
opportunity,
quote,
});
if (regionId) {
$calculation.element('selectRegionRegistration').setValue(regionId).block();
} else {
$calculation.element('selectRegionRegistration').resetValue().unblock();
}
},
{
delay: 10,
}
);
reaction(
() => $calculation.element('selectLegalClientRegion').getValue(),
async (regionId) => {
if (!regionId) {
$calculation.element('selectLegalClientTown').resetValue().unblock();
return;
}
const lead = $calculation.element('selectLead').getValue();
const opportunity = $calculation.element('selectOpportunity').getValue();
const quote = $calculation.element('selectQuote').getValue();
const townId = await getLegalTown({
lead,
opportunity,
quote,
regionId,
});
if (townId) {
$calculation.element('selectLegalClientTown').setValue(townId).block();
} else {
$calculation.element('selectLegalClientTown').resetValue().unblock();
}
}
);
reaction(
() => $calculation.$values.getValues(['regionRegistration', 'objectRegistration']),
async ({ regionRegistration: regionId, objectRegistration }) => {
if (!regionId) {
$calculation.element('selectTownRegistration').resetValue().unblock();
return;
}
const lead = $calculation.element('selectLead').getValue();
const opportunity = $calculation.element('selectOpportunity').getValue();
const quote = $calculation.element('selectQuote').getValue();
const townId = await getTown({
lead,
opportunity,
quote,
regionId,
});
if (townId && objectRegistration === 100_000_000) {
$calculation.element('selectTownRegistration').setValue(townId).block();
} else {
$calculation.element('selectTownRegistration').resetValue().unblock();
}
}
);
reaction(
() => $calculation.element('radioObjectRegistration').getValue(),
async (objectRegistration) => {
const {
data: { evo_regions },
} = await apolloClient.query({
query: CRMTypes.GetRegionsDocument,
});
if (objectRegistration === 100_000_001) {
const regions = evo_regions?.filter((x) => x?.evo_businessunit_evolution === true);
$calculation.element('selectRegionRegistration').setOptions(normalizeOptions(regions));
} else {
$calculation.element('selectRegionRegistration').setOptions(normalizeOptions(evo_regions));
}
}
);
}
const key = uid(7);
export function validation(context: ProcessContext) {
const { store } = context;
const { $calculation } = store;
const validationSchema = createValidationSchema(context);
const validationHelper = new ValidationHelper();
reaction(
() =>
$calculation.$values.getValues([
'leaseObjectCategory',
'maxMass',
'leaseObjectType',
'typePTS',
'objectRegistration',
'objectCategoryTax',
'insNSIB',
'vehicleTaxInYear',
]),
async (values) => {
validationHelper.removeErrors();
const validationResult = await validationSchema.safeParseAsync(values);
if (!validationResult.success) {
validationResult.error.errors.forEach(({ path, message }) => {
(path as Elements[]).forEach((elementName) => {
const removeError = $calculation.element(elementName).setError({ key, message });
if (removeError) validationHelper.add(removeError);
});
});
}
},
{
delay: 100,
}
);
}