Compare commits
4 Commits
dev
...
release/dy
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
04d8a89b3e | ||
|
|
9eb86fc24f | ||
|
|
c983166cba | ||
|
|
7d16bf2e53 |
@ -2,7 +2,7 @@ import type { FormTabRows } from '../lib/render-rows';
|
|||||||
|
|
||||||
const defaultRowStyle = { gridTemplateColumns: '1fr' };
|
const defaultRowStyle = { gridTemplateColumns: '1fr' };
|
||||||
|
|
||||||
export const rows: FormTabRows = [
|
export const mainRows: FormTabRows = [
|
||||||
{ title: 'Выбор Интереса/ЛС' },
|
{ title: 'Выбор Интереса/ЛС' },
|
||||||
[['selectLead'], defaultRowStyle],
|
[['selectLead'], defaultRowStyle],
|
||||||
[['selectOpportunity'], defaultRowStyle],
|
[['selectOpportunity'], defaultRowStyle],
|
||||||
@ -14,10 +14,33 @@ export const rows: FormTabRows = [
|
|||||||
gridTemplateColumns: ['1fr 0.15fr'],
|
gridTemplateColumns: ['1fr 0.15fr'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
export const unlimitedMainRows: FormTabRows = [
|
||||||
|
{ title: 'Выбор Интереса/ЛС' },
|
||||||
|
[['selectUser'], defaultRowStyle],
|
||||||
|
[['selectLead'], defaultRowStyle],
|
||||||
|
[['selectOpportunity'], defaultRowStyle],
|
||||||
|
[['cbxRecalcWithRevision'], defaultRowStyle],
|
||||||
|
[['selectQuote'], defaultRowStyle],
|
||||||
|
[
|
||||||
|
['btnCalculate', 'btnCreateKPMini'],
|
||||||
|
{
|
||||||
|
gridTemplateColumns: ['1fr 0.15fr'],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
export const paramsRows: FormTabRows = [
|
||||||
{ title: 'Параметры расчета' },
|
{ title: 'Параметры расчета' },
|
||||||
[['labelIrrInfo'], defaultRowStyle],
|
|
||||||
[['radioCalcType'], defaultRowStyle],
|
[['radioCalcType'], defaultRowStyle],
|
||||||
[['tbxIRR_Perc'], defaultRowStyle],
|
[['tbxIRR_Perc'], defaultRowStyle],
|
||||||
[['tbxTotalPayments'], defaultRowStyle],
|
[['tbxTotalPayments'], defaultRowStyle],
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export const unlimitedParamsRows: FormTabRows = [
|
||||||
|
{ title: 'Параметры расчета' },
|
||||||
|
[['radioCalcType'], defaultRowStyle],
|
||||||
|
[['tbxIRR_Perc', 'tbxPi'], { gridTemplateColumns: '1fr 1fr' }],
|
||||||
|
[['tbxTotalPayments'], defaultRowStyle],
|
||||||
|
];
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import renderFormRows from '../lib/render-rows';
|
import renderFormRows from '../lib/render-rows';
|
||||||
import { rows } from './config';
|
import * as config from './config';
|
||||||
import Background from '@/Components/Layout/Background';
|
import Background from '@/Components/Layout/Background';
|
||||||
|
import { useStore } from '@/stores/hooks';
|
||||||
import { min } from '@/styles/mq';
|
import { min } from '@/styles/mq';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
|
|
||||||
@ -17,5 +18,19 @@ const Wrapper = styled(Background)`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
export default function Settings() {
|
export default function Settings() {
|
||||||
return <Wrapper>{renderFormRows(rows)}</Wrapper>;
|
const { $process } = useStore();
|
||||||
|
|
||||||
|
const mainRows = $process.has('Unlimited')
|
||||||
|
? renderFormRows(config.unlimitedMainRows)
|
||||||
|
: renderFormRows(config.mainRows);
|
||||||
|
const paramsRows = $process.has('Unlimited')
|
||||||
|
? renderFormRows(config.unlimitedParamsRows)
|
||||||
|
: renderFormRows(config.paramsRows);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Wrapper>
|
||||||
|
{mainRows}
|
||||||
|
{paramsRows}
|
||||||
|
</Wrapper>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -133,6 +133,7 @@ const components = wrapComponentsMap({
|
|||||||
tbxVIN: e.Input,
|
tbxVIN: e.Input,
|
||||||
selectUser: e.Select,
|
selectUser: e.Select,
|
||||||
cbxSupplierFinancing: e.Switch,
|
cbxSupplierFinancing: e.Switch,
|
||||||
|
tbxPi: e.InputNumber,
|
||||||
|
|
||||||
/** Readonly Elements */
|
/** Readonly Elements */
|
||||||
labelLeaseObjectRisk: e.Text,
|
labelLeaseObjectRisk: e.Text,
|
||||||
|
|||||||
@ -481,7 +481,19 @@ const props: Partial<ElementsProps> = {
|
|||||||
optionFilterProp: 'label',
|
optionFilterProp: 'label',
|
||||||
},
|
},
|
||||||
tbxIRR_Perc: {
|
tbxIRR_Perc: {
|
||||||
min: 0,
|
min: -500,
|
||||||
|
max: 500,
|
||||||
|
step: 0.0001,
|
||||||
|
precision: 6,
|
||||||
|
parser,
|
||||||
|
formatter: createFormatter({ minimumFractionDigits: 6, maximumFractionDigits: 6 }),
|
||||||
|
addonAfter: '%',
|
||||||
|
style: {
|
||||||
|
width: '100%',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
tbxPi: {
|
||||||
|
min: -500,
|
||||||
max: 500,
|
max: 500,
|
||||||
step: 0.0001,
|
step: 0.0001,
|
||||||
precision: 6,
|
precision: 6,
|
||||||
|
|||||||
@ -15,9 +15,15 @@ import { LoadingOutlined } from 'ui/elements/icons';
|
|||||||
|
|
||||||
const defaultLinkProps: ComponentProps<typeof Link> = {
|
const defaultLinkProps: ComponentProps<typeof Link> = {
|
||||||
children: 'Открыть в CRM',
|
children: 'Открыть в CRM',
|
||||||
|
size: 'small',
|
||||||
|
style: { padding: 0 },
|
||||||
type: 'link',
|
type: 'link',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const formatter = Intl.NumberFormat('ru', {
|
||||||
|
minimumFractionDigits: 2,
|
||||||
|
}).format;
|
||||||
|
|
||||||
const overrideRender: Partial<Record<keyof typeof map, RenderProps>> = {
|
const overrideRender: Partial<Record<keyof typeof map, RenderProps>> = {
|
||||||
selectHighSeasonStart: {
|
selectHighSeasonStart: {
|
||||||
render: () => {
|
render: () => {
|
||||||
@ -179,6 +185,40 @@ const overrideRender: Partial<Record<keyof typeof map, RenderProps>> = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
tbxIRR_Perc: {
|
||||||
|
render: () => {
|
||||||
|
const elementName = 'tbxIRR_Perc';
|
||||||
|
const title = titles.tbxIRR_Perc;
|
||||||
|
const valueName = map.tbxIRR_Perc;
|
||||||
|
const Component = components.tbxIRR_Perc;
|
||||||
|
const props = elementsProps.tbxIRR_Perc;
|
||||||
|
const { builder } = types.tbxIRR_Perc();
|
||||||
|
|
||||||
|
const Element = builder(Component, {
|
||||||
|
elementName,
|
||||||
|
valueName,
|
||||||
|
});
|
||||||
|
|
||||||
|
const RenderedComponent = observer(() => {
|
||||||
|
const { $calculation } = useStore();
|
||||||
|
const { min, max } = $calculation.$values.getValue('irrInfo');
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Container>
|
||||||
|
<Head
|
||||||
|
htmlFor={elementName}
|
||||||
|
title={title}
|
||||||
|
addon={`${formatter(min)}% - ${formatter(max)}%`}
|
||||||
|
/>
|
||||||
|
<Element {...props} min={min} max={max} />
|
||||||
|
</Container>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
return <RenderedComponent />;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
tbxVehicleTaxInYear: {
|
tbxVehicleTaxInYear: {
|
||||||
render: () => {
|
render: () => {
|
||||||
const elementName = 'tbxVehicleTaxInYear';
|
const elementName = 'tbxVehicleTaxInYear';
|
||||||
|
|||||||
@ -127,6 +127,7 @@ const titles: Record<ActionElements | ValuesElements, string> = {
|
|||||||
tbxVIN: 'VIN',
|
tbxVIN: 'VIN',
|
||||||
selectUser: 'Пользователь',
|
selectUser: 'Пользователь',
|
||||||
cbxSupplierFinancing: 'Финансирование поставщика',
|
cbxSupplierFinancing: 'Финансирование поставщика',
|
||||||
|
tbxPi: 'PI',
|
||||||
|
|
||||||
/** Link Elements */
|
/** Link Elements */
|
||||||
linkDownloadKp: '',
|
linkDownloadKp: '',
|
||||||
|
|||||||
@ -192,6 +192,7 @@ const types = wrapElementsTypes({
|
|||||||
tbxVIN: t.Value,
|
tbxVIN: t.Value,
|
||||||
selectUser: t.Options,
|
selectUser: t.Options,
|
||||||
cbxSupplierFinancing: t.Switch,
|
cbxSupplierFinancing: t.Switch,
|
||||||
|
tbxPi: t.Number,
|
||||||
|
|
||||||
labelLeaseObjectRisk: t.Readonly,
|
labelLeaseObjectRisk: t.Readonly,
|
||||||
tbxInsKaskoPriceLeasePeriod: t.Readonly,
|
tbxInsKaskoPriceLeasePeriod: t.Readonly,
|
||||||
|
|||||||
@ -130,6 +130,7 @@ const elementsToValues = wrapElementsMap({
|
|||||||
tbxVIN: 'vin',
|
tbxVIN: 'vin',
|
||||||
selectUser: 'user',
|
selectUser: 'user',
|
||||||
cbxSupplierFinancing: 'supplierFinancing',
|
cbxSupplierFinancing: 'supplierFinancing',
|
||||||
|
tbxPi: 'pi',
|
||||||
|
|
||||||
/** Readonly Elements */
|
/** Readonly Elements */
|
||||||
labelLeaseObjectRisk: 'leaseObjectRiskName',
|
labelLeaseObjectRisk: 'leaseObjectRiskName',
|
||||||
|
|||||||
@ -193,14 +193,14 @@ export const radioCalcType = [
|
|||||||
label: 'IRR',
|
label: 'IRR',
|
||||||
value: 100_000_000,
|
value: 100_000_000,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
label: 'Суммы',
|
|
||||||
value: 100_000_001,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
label: 'PI',
|
label: 'PI',
|
||||||
value: 100_000_099,
|
value: 100_000_099,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: 'Суммы',
|
||||||
|
value: 100_000_001,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export const selectRequirementTelematic = [
|
export const selectRequirementTelematic = [
|
||||||
@ -503,6 +503,7 @@ const defaultOptions: CalculationOptions = {
|
|||||||
tbxVIN: [],
|
tbxVIN: [],
|
||||||
selectUser: [],
|
selectUser: [],
|
||||||
cbxSupplierFinancing: [],
|
cbxSupplierFinancing: [],
|
||||||
|
tbxPi: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
export default defaultOptions;
|
export default defaultOptions;
|
||||||
|
|||||||
@ -126,6 +126,7 @@ const defaultStatuses: CalculationStatuses = {
|
|||||||
tbxMileage: 'Default',
|
tbxMileage: 'Default',
|
||||||
tbxMinPriceChange: 'Default',
|
tbxMinPriceChange: 'Default',
|
||||||
tbxParmentsDecreasePercent: 'Default',
|
tbxParmentsDecreasePercent: 'Default',
|
||||||
|
tbxPi: 'Default',
|
||||||
tbxQuoteName: 'Default',
|
tbxQuoteName: 'Default',
|
||||||
tbxRedemptionPaymentSum: 'Disabled',
|
tbxRedemptionPaymentSum: 'Disabled',
|
||||||
tbxSaleBonus: 'Default',
|
tbxSaleBonus: 'Default',
|
||||||
|
|||||||
@ -65,7 +65,7 @@ const defaultValues: CalculationValues = {
|
|||||||
insUnlimitDrivers: true,
|
insUnlimitDrivers: true,
|
||||||
insurance: true,
|
insurance: true,
|
||||||
IRR_Perc: 20,
|
IRR_Perc: 20,
|
||||||
irrInfo: '-',
|
irrInfo: { min: 0, max: 0 },
|
||||||
kpUrl: null,
|
kpUrl: null,
|
||||||
lastPaymentPerc: 1,
|
lastPaymentPerc: 1,
|
||||||
lastPaymentRedemption: true,
|
lastPaymentRedemption: true,
|
||||||
@ -101,6 +101,7 @@ const defaultValues: CalculationValues = {
|
|||||||
opportunity: null,
|
opportunity: null,
|
||||||
opportunityUrl: null,
|
opportunityUrl: null,
|
||||||
parmentsDecreasePercent: 94,
|
parmentsDecreasePercent: 94,
|
||||||
|
pi: 0,
|
||||||
plPriceRub: 0,
|
plPriceRub: 0,
|
||||||
priceWithDiscount: false,
|
priceWithDiscount: false,
|
||||||
product: null,
|
product: null,
|
||||||
@ -134,12 +135,12 @@ const defaultValues: CalculationValues = {
|
|||||||
townRegistration: null,
|
townRegistration: null,
|
||||||
tracker: null,
|
tracker: null,
|
||||||
typePTS: null,
|
typePTS: null,
|
||||||
|
user: null,
|
||||||
VATInLeaseObjectPrice: 0,
|
VATInLeaseObjectPrice: 0,
|
||||||
vehicleTaxInLeasingPeriod: 0,
|
vehicleTaxInLeasingPeriod: 0,
|
||||||
vehicleTaxInYear: 0,
|
vehicleTaxInYear: 0,
|
||||||
withTrailer: false,
|
|
||||||
vin: null,
|
vin: null,
|
||||||
user: null,
|
withTrailer: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default defaultValues;
|
export default defaultValues;
|
||||||
|
|||||||
@ -90,6 +90,7 @@ const ValuesSchema = z.object({
|
|||||||
objectTypeTax: z.number().nullable(),
|
objectTypeTax: z.number().nullable(),
|
||||||
opportunity: z.string().nullable(),
|
opportunity: z.string().nullable(),
|
||||||
parmentsDecreasePercent: z.number(),
|
parmentsDecreasePercent: z.number(),
|
||||||
|
pi: z.number(),
|
||||||
priceWithDiscount: z.boolean(),
|
priceWithDiscount: z.boolean(),
|
||||||
product: z.string().nullable(),
|
product: z.string().nullable(),
|
||||||
quote: z.string().nullable(),
|
quote: z.string().nullable(),
|
||||||
@ -119,12 +120,12 @@ const ValuesSchema = z.object({
|
|||||||
townRegistration: z.string().nullable(),
|
townRegistration: z.string().nullable(),
|
||||||
tracker: z.string().nullable(),
|
tracker: z.string().nullable(),
|
||||||
typePTS: z.number().nullable(),
|
typePTS: z.number().nullable(),
|
||||||
|
user: z.string().nullable(),
|
||||||
VATInLeaseObjectPrice: z.number(),
|
VATInLeaseObjectPrice: z.number(),
|
||||||
vehicleTaxInLeasingPeriod: z.number(),
|
vehicleTaxInLeasingPeriod: z.number(),
|
||||||
vehicleTaxInYear: z.number(),
|
vehicleTaxInYear: z.number(),
|
||||||
withTrailer: z.boolean(),
|
|
||||||
vin: z.string().nullable(),
|
vin: z.string().nullable(),
|
||||||
user: z.string().nullable(),
|
withTrailer: z.boolean(),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Link Values
|
* Link Values
|
||||||
@ -141,7 +142,10 @@ const ValuesSchema = z.object({
|
|||||||
depreciationGroup: z.string().nullable(),
|
depreciationGroup: z.string().nullable(),
|
||||||
discountRub: z.number(),
|
discountRub: z.number(),
|
||||||
insKaskoPriceLeasePeriod: z.number(),
|
insKaskoPriceLeasePeriod: z.number(),
|
||||||
irrInfo: z.string().nullable(),
|
irrInfo: z.object({
|
||||||
|
min: z.number(),
|
||||||
|
max: z.number(),
|
||||||
|
}),
|
||||||
leaseObjectRiskName: z.string().nullable(),
|
leaseObjectRiskName: z.string().nullable(),
|
||||||
plPriceRub: z.number(),
|
plPriceRub: z.number(),
|
||||||
registrationDescription: z.string().nullable(),
|
registrationDescription: z.string().nullable(),
|
||||||
|
|||||||
@ -2,10 +2,6 @@ import helper from '../lib/helper';
|
|||||||
import type { ProcessContext } from '@/process/types';
|
import type { ProcessContext } from '@/process/types';
|
||||||
import { reaction } from 'mobx';
|
import { reaction } from 'mobx';
|
||||||
|
|
||||||
export const formatter = Intl.NumberFormat('ru', {
|
|
||||||
minimumFractionDigits: 2,
|
|
||||||
}).format;
|
|
||||||
|
|
||||||
export default function reactions({ store, apolloClient }: ProcessContext) {
|
export default function reactions({ store, apolloClient }: ProcessContext) {
|
||||||
const { $calculation } = store;
|
const { $calculation } = store;
|
||||||
|
|
||||||
@ -38,7 +34,7 @@ export default function reactions({ store, apolloClient }: ProcessContext) {
|
|||||||
async (values) => {
|
async (values) => {
|
||||||
const { min, max } = await getIrr(values);
|
const { min, max } = await getIrr(values);
|
||||||
|
|
||||||
$calculation.element('labelIrrInfo').setValue(`${formatter(min)}% - ${formatter(max)}%`);
|
$calculation.element('labelIrrInfo').setValue({ max, min });
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -858,7 +858,7 @@ export async function createRequestData({
|
|||||||
},
|
},
|
||||||
|
|
||||||
async npvniExpected() {
|
async npvniExpected() {
|
||||||
return 0;
|
return values.pi / 100;
|
||||||
},
|
},
|
||||||
|
|
||||||
async nsBonus() {
|
async nsBonus() {
|
||||||
|
|||||||
@ -104,6 +104,7 @@ export function transformCalculateResults({
|
|||||||
IRR_Perc: columns?.cashflowMsfoColumn?.nominal * 100,
|
IRR_Perc: columns?.cashflowMsfoColumn?.nominal * 100,
|
||||||
downloadKp: null,
|
downloadKp: null,
|
||||||
lastPaymentRub: last(columns?.sumWithVatColumn?.values) || 0,
|
lastPaymentRub: last(columns?.sumWithVatColumn?.values) || 0,
|
||||||
|
pi: columns?.piColumn.values[0] * 100,
|
||||||
totalPayments: columns?.sumWithVatColumn?.values[0] - inputValues.subsidySum,
|
totalPayments: columns?.sumWithVatColumn?.values[0] - inputValues.subsidySum,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -25,6 +25,7 @@ export const OutputDataSchema = z.object({
|
|||||||
IRR_Perc: true,
|
IRR_Perc: true,
|
||||||
downloadKp: true,
|
downloadKp: true,
|
||||||
lastPaymentRub: true,
|
lastPaymentRub: true,
|
||||||
|
pi: true,
|
||||||
totalPayments: true,
|
totalPayments: true,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|||||||
@ -14,15 +14,15 @@ export function Radio({ value = null, options, spaceProps, onChange, ...props }:
|
|||||||
if (onChange) onChange(event.target.value);
|
if (onChange) onChange(event.target.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const buttons = options?.map((option) => (
|
||||||
|
<AntRadio key={option.value as Key} value={option.value}>
|
||||||
|
{option.label}
|
||||||
|
</AntRadio>
|
||||||
|
));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AntRadio.Group onChange={handleChange} value={value} {...props}>
|
<AntRadio.Group onChange={handleChange} value={value} {...props}>
|
||||||
<Space {...spaceProps}>
|
{spaceProps ? <Space {...spaceProps}>{buttons}</Space> : buttons}
|
||||||
{options?.map((option) => (
|
|
||||||
<AntRadio key={option.value as Key} value={option.value}>
|
|
||||||
{option.label}
|
|
||||||
</AntRadio>
|
|
||||||
))}
|
|
||||||
</Space>
|
|
||||||
</AntRadio.Group>
|
</AntRadio.Group>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user